精华内容
下载资源
问答
  • 翻转翻转翻转棋

    2020-03-05 15:04:23
    之前在学校写的一个翻转棋程序,虽然看起来很简陋,还是值得纪念一下第一个”游戏“ 哈哈。人比较懒,我就直接粘贴我作业里写的内容了,重要的步骤会翻译下的。 Game Description 游戏简介 At the start: there ...

    只用if,loop,array的翻转翻转棋

    之前在学校写的一个翻转棋程序,虽然看起来很简陋,还是值得纪念一下第一个”游戏“ 哈哈。人比较懒,我就直接粘贴我作业里写的内容了,重要的步骤会翻译下的。

    在这里插入图片描述

    1. Game Description 游戏简介

    At the start: there are four pieces on the board, two white and two black. You must try to capture opponent pieces and flip them over so they turn into your color.

    Example: You have the black pieces. There is one black piece on the board; next to it are 4 white pieces in a line. You put a black piece at the end of the line, now you have 4 white pieces between 2 black pieces, so those white pieces turn to black.

    翻转棋(黑白棋)的玩法:把夹击的棋子变成自己的颜色。

    1. Programming basics 用到的java编程知识

      非常适合初学者写来玩玩!因为真的只需要用到if,loop,array的知识就行了!

    for loop:

    for (*int i=0; i) {do something;}

    if condition:

    if (condition) {do something;}

    while loop:

    while (condition) {do something;}

    Array: store variables

    e.g. int []x : an array int[] [] x: 2D array

    1. Main logic 主要逻辑

    -Use 1 to represent black pieces, 2 to represent white pieces.

    用1来表示黑棋,2来表示白棋,0表示空位。

    -A 2D array to simulate the board. Then, when we put integers in the array, we are putting pieces on the board.

    用2D array来模仿棋盘

      int[][]a=new int[8][8];
      a[3][3]=1; a[3][4]=2;
      a[4][3]=2; a[4][4]=1;  //初始状态的棋子
    
       for (int r=0;r<a.length;r++)
          {for (int n=0;n<a[0].length;n++)    
           {System.out.print(a[r][n]+" ");}
          System.out.println();}    //打印出棋盘
    

    -Use Scanner to get the players’ input.

    用Scanner来得到棋手的落子位置,两人玩家分别的(x,y) 坐标。

         Scanner P = new Scanner(System.in);  Scanner Q = new Scanner(System.in);
         Scanner M = new Scanner(System.in);  Scanner N = new Scanner(System.in);
    

    -Use while loops to alternative moves. First black, then white, and continue.

    用while loop来轮流下棋,先是黑棋,再是白棋。

    -Use while loops to check if the position in the array is occupied. If it is, then make the player enter a different position. Use if conditions to check if we can make that move to reverse pieces. If not, then make the player enter a different position.

    用while loop来检验落子的位置是否已经有子,如果已经有棋子了,让玩家重新输入下棋位置。用if来检验下棋的位置是否可以翻转棋子,如果不行,则重新输入。

    -Use for loops and if conditions to check if we reverse the pieces. Remember: as long as player 1’s pieces are between player 2’s pieces, the color of the pieces will change into that of player 2. In our simulation, we change the numbers. Change 1 to 2 or 2 to 1.

    检验是否可以翻转棋子:

    从每一横行,竖列,斜线来考虑。

    -When checking the reverse condition, we need to consider from rows, columns, and diagonals.

    比如,我们先检验横行中是否有翻转,

    -Now check each row first! Get the position of the player’s input first. Check the input’s right side using a for loop & if condition: once we meet the same number, stop this check. Initialize the variable count, which counts how many positions are there between these two numbers. Then, initialize another variable count2 (for example), which counts how many opponents’ pieces are there between these two numbers. If count is equal to count2, then we change every number between them into the opponents’ numbers. (0 to 1 or 0 to 2).

    首先获取玩家输入的位置。使用for循环和if条件来检测落子位置的右边横行:一旦我们遇到相同的数字,停止检查。初始化变量count,它数出在这两个相同数字之间多少个位置。然后,初始化另一个变量count2,数出这两个数字之间有多少个对手的棋子。如果count = count2,则将它们之间的每个数字都变成对方的数字

    -Similar logic for the columns and diagonals.

    对于竖列和斜线,用相似的逻辑来检查。

    举个栗子,这是check column的code:

     int count = 0; int count2=0;
     for (int qq=-P1;qq<=7-P1;qq++) 
      {
           if (a[P1+qq][Q1]==1) 
         { 
             for (int aa=1;aa<=Math.abs(qq)-1;aa++)       
             {
              if(qq>=0&&a[P1+aa][Q1]==2){count++;} //上
              if(qq<0&&a[P1-aa][Q1]==2){count2++;} //下
             } //for loop to check the player2 counts
               
         if (count==(Math.abs(qq)-1)&&count!=0)
         {mm=1;
          for (int ii=1;ii<(Math.abs(qq)-1);ii++)
           {a[P1+ii][Q1]=1;} //上
         }
         if (count2==(Math.abs(qq)-1)&&count2!=0)
         {mm=1;
          for (int iii=1;iii<=(Math.abs(qq)-1);iii++)
           {a[P1-iii][Q1]=1;} //下
         }      
               
         }
           count=0; count2=0;
      } 
    

    还有一些小细节需要注意,在这就不多赘述了。比如当黑棋没有棋可下时,这时候应该白棋继续;如果双方都无棋可下时,就直接开始数棋判断输赢。但只要把整体框架和“翻转”的这一步写好了,其它细节都可以慢慢添加。

    这个code仅供参考,翻转棋小游戏还是很适合拿来练手的!

    展开全文
  • C# 翻转棋游戏源程序

    2014-07-15 19:29:30
    C# 翻转棋游戏源程序
  • Csharp 翻转棋游戏源程序,可以学习算法
  • 刚学习C++编写的一个翻转棋小游戏,只要将所有棋子反转成同一个颜色即可进入下一关。
  • 用MFC自己写的一个黑白人机对战程序,人工智能还不错。
  • 黑白翻转棋原理及实现链接

    千次阅读 2018-12-02 01:11:31
    黑白翻转棋(奥赛罗棋)的一些原理讲解和实现代码的链接,都是博主参考过的。 等有时间会自己写一篇原理介绍及代码实现。 以下是参考网站链接: 貌似是某个学校布置作业的网站,有详细专业的java源码 有原理介绍且有...
    展开全文
  • 关于十字翻转棋的解法研究

    千次阅读 2016-01-17 15:46:33
    首先说什么是十字翻转棋,十字翻转棋又叫开窗游戏,游戏规则如下: 在n*n的方格中随机分布着一些关着的窗子,当你打开或关闭一个窗子时,它的上下左右四个方向的窗子开关状态也会翻转。目标是将这些关着的窗子都...

    首先说什么是十字翻转棋,十字翻转棋又叫开窗游戏,游戏规则如下:

    在n*n的方格中随机分布着一些关着的窗子,当你打开或关闭一个窗子时,它的上下左右四个方向的窗子开关状态也会翻转。目标是将这些关着的窗子都打开,游戏结束。 

    这里有一个我自己编写的html5开窗游戏,大家可以先去玩一下:

    开窗游戏

    游戏相对还比较简单,只是一个3*3的难度,当游戏维度增加后,难度也会加大。下面我们来探讨一下如何快速找出一个最优解。

    玩几次游戏发现如下两个规律:

    1.任何一个位置我们点击1次和点击3次结果是相同的,因为每点一下,这个点击所影响的窗子是固定的,所以如果一个位置需要点击,我们只点击一下就可以了。

    2.任何一个位置的窗子状态只和它上中下左右5个位置的点击状态有关系,和他们的点击顺序无关。

    由1,2分析可知,在n*n的格子中,达到win状态时这n*n个格子每个格子只有是否被点击两种状态,而与达到这两种状态的点击次数无关,和点击顺序也无关。这个大家可以自己思考一下。

    也就是说最后我们只需确定哪些格子需要点,哪些格子不需要点。

    我们就拿3*3的难度来推理一下。

    c1c2c3
    c4c5c6
    c7c8c9

    假设格子的原始状态为 {cn}, cn有两个值 0代表开着的,1代表关着的 那么要把所有窗子都开着就是要把所有数字都变成0

    x1x2x3
    x4x5x6
    x7x8x9

    假设最终格子的点击状态为 {xn},xn也有两种状态 1代表要点击,0代表不点击

    我们假设 运算f(x,c)   {x=0,1}{c=0,1}  

    x表示是否受点击影响 0代表不受点击影响,1代表受点击影响

    c表示格子原始状态 0表示开启状态,1表示关闭状态

    f(x,c)    表示作用后对应格子的状态  

    经过分析, f有如下特点:

        f(1,0)=1;    //受点击影响 将原先1变为0

        f(1,1)=0;    //受点击影响 将原先0变成1

        f(0,1)=1;    //不受点击影响,保持原来的1

        f(0,0)=0;    //不受点击影响,保持原来的0

    聪明的你应该发现,这其实是异或运算^

    再来分析第一个格子,

    它的原始状态是c1,分析发现能够影响它的点击状态是x1,x2,x4 而其他x对它皆没有影响,而目标最终的状态是0,所以我们得到下面的式子:

    f(x4 , f(x2 , f(x1 , c1))) = 0 

    而我们又知道 f 是异或运算,所以上面的式子可以写成

    x4^x2^x1^c1=0

    又因为异或服从交换律,且两边同时异或c1 得到下面的变形

    x1^x2^x4=c1;

    依次类推我们可以写出其他的式子,最后整理好的式子如下:

    x1^x2^   x4                = c1
    
    x1^x2^x3^   x5             = c2
    
       x2^x3^      x6          = c3
       
    x1^      x4^x5^   x7       = c4
    
       x2^   x4^x5^x6^   x8    = c5
       
          x3^   x5^x6^      x9 = c6
          
             x4^      x7^x8    = c7
             
                x5^   x7^x8^x9 = c8
                
                   x6^   x8^x9 = c9
    将其写成矩阵形式:


     1 1 0 1 0 0 0 0 0    x1     c1      (1)
     1 1 1 0 1 0 0 0 0    x2     c2      (2)
     0 1 1 0 0 1 0 0 0    x3     c3      (3)
     1 0 0 1 1 0 1 0 0    x4     c4      (4)
     0 1 0 1 1 1 0 1 0    x5     c5      (5)
     0 0 1 0 1 1 0 0 1    x6     c6      (6)
     0 0 0 1 0 0 1 1 0    x7     c7      (7)
     0 0 0 0 1 0 1 1 1    x8     c8      (8)
     0 0 0 0 0 1 0 1 1    x9     c9      (9)

    最终问题划归为求解这个异或矩阵方程~

    我们把左边那个矩阵定义为A  使用向量的写法  

    AX=C 

    只不过这里矩阵乘法中对应的加法运算要改为异或运算。

    线性代数里面有一类问题叫线性方程组的求解,最终划归出来的矩阵形式和这个一模一样。所以我们可以采用解线性方程组的那套算法来解这个方程。


    最基本的原则是销元,算法描述如下:

    1.用 (1)^(2)  可以得到一个没有x1的等式替代(2),同样用(1)^(3)替代(3) 依次类推,可以得到8个没有x1的等式。

    2.再用(2)^(3) 可以得到一个没有x2的等式替代(3);

    3.照这样做下去,可以得到一组上三角矩阵。

    4.此时的(9)式就只有x9一个变量,而对应的c9则也就是x9的值。

    5.然后将x9代入(8)式可以解出x8

    6.继续将 x8,x9代入(7)式可以解出x7


    依次类推,可以解出xn  也就是我们要的解。

    还记得这种方法应该叫做 高斯消元法。


    另一种解法和这个解法类似,只是不用回代:

    1.用 (1)^(2)  可以得到一个没有x1的等式替代(2),同样用(1)^(3)替代(3) 依次类推,可以得到8个没有x1的等式。(第一步相同)

    2.用(2)^(1) 可以得到一个没有x2的等式替代(1),(2)^(3)-->(3);(2)^(4)-->(4);...(2)^(9)-->(9);   (第二步有所不同,是同样用(2)式将(1)式中的x2消除)

    3.同样的(3)^(1)-->(1);    (3)^(2)-->(2);   ...   (3)^(9)-->(9);

    照这样做下去,可以得到一组对角矩阵,或者可以说是单位矩阵

    而此时cn对应的就是方程组的解。


    扩展到n*n的规模,我们发现只是对应的矩阵A变化了,其他算法不变。

    针对问题本身,cn是一个参数,是传入值,矩阵A根据不同规模不同,但也是有规律的,可以用程序生成,具体的生成算法这里就不说了。


    以下是我用JavaScript写的一个算法,针对3*3的规模解法:

    var AI = AI||{};
    AI.resolve = function(cArray){
        var rect33 = [
            [1,1,0,1,0,0,0,0,0],
            [1,1,1,0,1,0,0,0,0],
            [0,1,1,0,0,1,0,0,0],
            [1,0,0,1,1,0,1,0,0],
            [0,1,0,1,1,1,0,1,0],
            [0,0,1,0,1,1,0,0,1],
            [0,0,0,1,0,0,1,1,0],
            [0,0,0,0,1,0,1,1,1],
            [0,0,0,0,0,1,0,1,1],
        ];
        function resolveRect(rect,cArray){
            var length = rect.length;
            for(var i=0;i<length;i++){
                for(var j=i+1;j<length;j++){
                    var r1 = rect[i];
                    var r2 = rect[j];
                    if(r2[i]==1){
                        if(r1[i]==1){//销元
                            addRect(r1,r2);
                            var c1 = cArray[i];
                            var c2 = cArray[j];
                            cArray[j] = addRect(c1,c2);
                        }else{//交换
                            var temp = rect[i];
                            rect[i]=rect[j];
                            rect[j]=temp;
                            temp = cArray[i];
                            cArray[i]=cArray[j];
                            cArray[j]=temp;
                        }
                    }
                }
                if(rect[i][i]!=1){
                    throw "无解!!";
                    return;
                }else{
                    for(var j=0;j<i;j++){
                        var r1 = rect[i];
                        var r2 = rect[j];
                        if(r2[i]==1){
                            addRect(r1,r2);
                            var c1 = cArray[i];
                            var c2 = cArray[j];
                            cArray[j] = addRect(c1,c2);
                        }
                    }
                }
            }
        }
        function addRect(r1,r2){
            if(typeof r2 == "number")return r2^r1;
            var len = r2.length;
            for(var i=0;i<len;i++){
                r2[i]=r2[i]^r1[i];
            }
        }
        resolveRect(rect33,cArray);
        console.log(rect33);
        console.log(cArray);
    }

    可以推算这个解法的时间复杂度是n^2  空间复杂度也是n^2 当然空间上是可以优化的,因为有大部分的0是不需要存储的,优化的问题就不讲了。

    顺带说一下,关于这个h5游戏是怎么做出来的,之后会有专门的文章或者视频来讲,敬请期待

    另外游戏的源码和解法的源码都可以访问github地址:git@github.com:gagaprince/gaga_c.git

    里面有一个叫 game_kaichuang 的分支。


    转载请注明出处:http://gagalulu.wang/blog/detail/10 您的支持是我最大的动力!




    展开全文
  • 利用上一篇的框架,再写了个翻转棋程序,为了调试minimax算法,花了两天的时间。 几点改进说明: 拆分成四个文件:board.py,player.py,ai.py,othello.py。使得整个结构更清晰,更通用,更易于维护。 AI 的...
  • 利用上一篇的框架,再写了个翻转棋程序,为了调试minimax算法,花了两天的时间。 几点改进说明: 拆分成四个文件:board.py,player.py,ai.py,othello.py。使得整个结构更清晰,更通用,更易于维护。 AI 的水平...

    利用上一篇的框架,再写了个翻转棋的程序,为了调试minimax算法,花了两天的时间。

    几点改进说明:

    • 拆分成四个文件:board.py,player.py,ai.py,othello.py。使得整个结构更清晰,更通用,更易于维护。
    • AI 的水平跟 minimax 的递归深度,以及评价函数有关。基于此,我把 minimax 和评价函数都放到 AI 类里面
    • AIPlayer 使用了多重继承。继承了 Player 与 AI 两个类
    • Game 类中把原run函数里的生成两个玩家的部分提出来,写成一个函数make_two_players,使得 run函数结构更清晰

    • AI 玩家等级不要选择 0:beginer。会报错,还没调试好

    board.py

    
    '''
    作者:hhh5460
    时间:2017年7月1日
    '''
    
    class Board(object):
        def __init__(self):
            self.empty = '.'
            self._board = [[self.empty for _ in range(8)] for _ in range(8)] # 规格:8*8
            self._board[3][4], self._board[4][3] = 'X', 'X'
            self._board[3][3], self._board[4][4] = 'O', 'O'
            
        # 增加 Board[][] 索引语法
        def __getitem__(self, index):
            return self._board[index]
        
        # 打印棋盘
        def print_b(self):
            board = self._board
            print(' ', ' '.join(list('ABCDEFGH')))
            for i in range(8):
                print(str(i+1),' '.join(board[i]))
                
        # 棋局终止
        def teminate(self):
            list1 = list(self.get_legal_actions('X'))
            list2 = list(self.get_legal_actions('O'))
            return [False, True][len(list1) == 0 and len(list2) == 0]
            
        # 判断赢家
        def get_winner(self):
            s1, s2 = 0, 0
            for i in range(8):
                for j in range(8):
                    if self._board[i][j] == 'X':
                        s1 += 1
                    if self._board[i][j] == 'O':
                        s2 += 1
            if s1 > s2:
                return 0 # 黑胜
            elif s1 < s2:
                return 1 # 白胜
            elif s1 == s2:
                return 2 # 平局
        # 落子
        def _move(self, action, color):
            x,y = action
            self._board[x][y] = color
            
            return self._flip(action, color)
            
        
            
        
        # 翻子(返回list)
        def _flip(self, action, color):
            flipped_pos = []
            
            for line in self._get_lines(action):
                for i,p in enumerate(line):
                    if self._board[p[0]][p[1]] == self.empty: 
                        break
                    elif self._board[p[0]][p[1]] == color:
                        flipped_pos.extend(line[:i])
                        break
            
            for p in flipped_pos:
                self._board[p[0]][p[1]] = color
                
            return flipped_pos
            
        # 撤销
        def _unmove(self, action, flipped_pos, color):
            self._board[action[0]][action[1]] = self.empty
            
            uncolor = ['X', 'O'][color=='X']
            for p in flipped_pos:
                self._board[p[0]][p[1]] = uncolor
                
        # 生成8个方向的下标数组,方便后续操作
        def _get_lines(self, action):
            '''说明:刚开始我是用一维棋盘来考虑的,后来改为二维棋盘。偷懒,不想推倒重来,简单地修改了一下'''
            board_coord = [(i,j) for i in range(8) for j in range(8)] # 棋盘坐标
            
            r,c = action
            ix = r*8 + c
            r, c = ix//8, ix%8
            left = board_coord[r*8:ix] # 要反转
            right = board_coord[ix+1:(r+1)*8]
            top = board_coord[c:ix:8] # 要反转
            bottom = board_coord[ix+8:8*8:8]
            
            if r <= c:
                lefttop = board_coord[c-r:ix:9] # 要反转
                rightbottom = board_coord[ix+9:(7-(c-r))*8+7+1:9]
            else:
                lefttop = board_coord[(r-c)*8:ix:9] # 要反转
                rightbottom = board_coord[ix+9:7*8+(7-(c-r))+1:9]
            
            if r+c<=7:
                leftbottom = board_coord[ix+7:(r+c)*8:7]
                righttop = board_coord[r+c:ix:7] # 要反转
            else:
                leftbottom = board_coord[ix+7:7*8+(r+c)-7+1:7]
                righttop = board_coord[((r+c)-7)*8+7:ix:7] # 要反转
            
            # 有四个要反转,方便判断
            left.reverse()
            top.reverse()
            lefttop.reverse()
            righttop.reverse()
            lines = [left, top, lefttop, righttop, right, bottom, leftbottom, rightbottom]
            return lines
            
        # 检测,位置是否有子可翻
        def _can_fliped(self, action, color):
            flipped_pos = []
            
            for line in self._get_lines(action):
                for i,p in enumerate(line):
                    if self._board[p[0]][p[1]] == self.empty: 
                        break
                    elif self._board[p[0]][p[1]] == color:
                        flipped_pos.extend(line[:i])
                        break
            return [False, True][len(flipped_pos) > 0]
            
        # 合法走法
        def get_legal_actions(self, color):
            uncolor = ['X', 'O'][color=='X']
            uncolor_near_points = [] # 反色邻近的空位
            
            board = self._board
            for i in range(8):
                for j in range(8):
                    if board[i][j] == uncolor:
                        for dx,dy in [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1)]:
                            x, y = i+dx, j+dy
                            if 0 <= x <=7 and 0 <= y <=7 and board[x][y] == self.empty and (x, y) not in uncolor_near_points:
                                uncolor_near_points.append((x, y))
            for p in uncolor_near_points:
                if self._can_fliped(p, color):
                    yield p
    
    # 测试
    if __name__ == '__main__':
        board = Board()
        board.print_b()
        print(list(board.get_legal_actions('X')))

    player.py

    
    from ai import AI
    
    '''
    作者:hhh5460
    时间:2017年7月1日
    '''
    
    # 玩家
    class Player(object):
        def __init__(self, color):
            self.color = color
            
        # 思考
        def think(self, board):
            pass
            
        # 落子
        def move(self, board, action):
            flipped_pos = board._move(action, self.color)
            return flipped_pos
            
        # 悔子
        def unmove(self, board, action, flipped_pos):
            board._unmove(action, flipped_pos, self.color)
    
    
    
    # 人类玩家
    class HumanPlayer(Player):
        def __init__(self, color):
            super().__init__(color)
        
        def think(self, board):
            while True:
                action = input("Turn to '{}'. \nPlease input a point.(such as 'A1'): ".format(self.color)) # A1~H8
                r, c = action[1], action[0].upper()
                if  r in '12345678' and c in 'ABCDEFGH': # 合法性检查1
                    x, y = '12345678'.index(r), 'ABCDEFGH'.index(c)
                    if (x,y) in board.get_legal_actions(self.color):  # 合法性检查2
                        return x, y
    
    
    # 电脑玩家(多重继承)
    class AIPlayer(Player, AI):
        
        def __init__(self, color, level_ix=0):
            super().__init__(color)              # init Player
            super(Player, self).__init__(level_ix)  # init AI
            
        
        def think(self, board):
            print("Turn to '{}'. \nPlease wait a moment. AI is thinking...".format(self.color))
            uncolor = ['X','O'][self.color=='X']
            opfor = AIPlayer(uncolor) # 假想敌,陪练
            action = self.brain(board, opfor, 4)
            return action

    ai.py

    
    import random
    
    '''
    作者:hhh5460
    时间:2017年7月1日
    '''
    
    class AI(object):
        '''
        三个水平等级:初级(beginner)、中级(intermediate)、高级(advanced)
        '''
        def __init__(self, level_ix =0):
            # 玩家等级
            self.level = ['beginner','intermediate','advanced'][level_ix]
            # 棋盘位置权重,参考:https://github.com/k-time/ai-minimax-agent/blob/master/ksx2101.py
            self.board_weights = [
                [120, -20,  20,   5,   5,  20, -20, 120],
                [-20, -40,  -5,  -5,  -5,  -5, -40, -20],
                [ 20,  -5,  15,   3,   3,  15,  -5,  20],
                [  5,  -5,   3,   3,   3,   3,  -5,   5],
                [  5,  -5,   3,   3,   3,   3,  -5,   5],
                [ 20,  -5,  15,   3,   3,  15,  -5,  20],
                [-20, -40,  -5,  -5,  -5,  -5, -40, -20],
                [120, -20,  20,   5,   5,  20, -20, 120]
            ]
            
        # 评估函数(仅根据棋盘位置权重)
        def evaluate(self, board, color):
            uncolor = ['X','O'][color=='X']
            score = 0
            for i in range(8):
                for j in range(8):
                    if board[i][j] == color:
                        score += self.board_weights[i][j]
                    elif board[i][j] == uncolor:
                        score -= self.board_weights[i][j]
            return score
    
        # AI的大脑
        def brain(self, board, opponent, depth):
            if self.level == 'beginer':         # 初级水平
                _, action = self.randomchoice(board)
            elif self.level == 'intermediate':  # 中级水平
                _, action = self.minimax(board, opponent, depth)
            elif self.level == 'advanced':      # 高级水平
                _, action = self.minimax_alpha_beta(board, opponent, depth)
            assert action is not None, 'action is None'
            return action
        
        # 随机选(从合法走法列表中随机选)
        def randomchoice(self, board):
            color = self.color
            action_list = list(board.get_legal_actions(color))
            return None, random.choice(action_list)
        
        # 极大极小算法,限制深度
        def minimax(self, board, opfor, depth=4): # 其中 opfor 是假想敌、陪练
            '''参考:https://github.com/k-time/ai-minimax-agent/blob/master/ksx2101.py'''
            color = self.color
            
            if depth == 0:
                return self.evaluate(board, color), None
            
            action_list = list(board.get_legal_actions(color))
            if not action_list:
                return self.evaluate(board, color), None
            
            best_score = -100000
            best_action = None
    
            for action in action_list:
                flipped_pos = self.move(board, action) # 落子
                score, _ = opfor.minimax(board, self, depth-1) # 深度优先,轮到陪练
                self.unmove(board, action, flipped_pos) # 回溯
                
                score = -score
                if score > best_score:
                    best_score = score
                    best_action = action
    
            return best_score, best_action
            
        # 极大极小算法,带alpha-beta剪枝
        def minimax_alpha_beta(self, board, opfor, depth=8, my_best=-float('inf'), opp_best=float('inf')):
            '''参考:https://github.com/k-time/ai-minimax-agent/blob/master/ksx2101.py'''
            color = self.color
            
            if depth == 0:
                return self.evaluate(board, color), None
            
            action_list = list(board.get_legal_actions(color))
            if not action_list:
                return self.evaluate(board, color), None
            
            best_score = my_best
            best_action = None
            
            for action in action_list:
                flipped_pos = self.move(board, action)  # 落子
                score, _ = opfor.minimax_alpha_beta(board, self, depth-1, -opp_best, -best_score) # 深度优先,轮到陪练
                self.unmove(board, action, flipped_pos) # 回溯
                
                score = -score
                if score > best_score:
                    best_score = score
                    best_action = action
                    
                if best_score > opp_best:
                    break
    
            return best_score, best_action
    

    othello.py

    
    from board import Board
    from player import HumanPlayer, AIPlayer
    
    '''
    作者:hhh5460
    时间:2017年7月1日
    '''
    
    # 游戏
    class Game(object):
        def __init__(self):
            self.board = Board()
            self.current_player = None
            
        # 生成两个玩家
        def make_two_players(self):
            ps = input("Please select two player's type:\n\t0.Human\n\t1.AI\nSuch as:0 0\n:")
            p1, p2 = [int(p) for p in ps.split(' ')]
            if p1 == 1 or p2 == 1: # 至少有一个AI玩家
                level_ix = int(input("Please select the level of AI player.\n\t0: beginner\n\t1: intermediate\n\t2: advanced\n:"))
                if p1 == 0:
                    player1 = HumanPlayer('X')
                    player2 = AIPlayer('O', level_ix)
                elif p2 == 0:
                    player1 = AIPlayer('X', level_ix)
                    player2 = HumanPlayer('O')
                else:
                    player1 = AIPlayer('X', level_ix)
                    player2 = AIPlayer('O', level_ix)
            else:
                player1, player2 = HumanPlayer('X'), HumanPlayer('O') # 先手执X,后手执O
            
            return player1, player2
        
        
        # 切换玩家(游戏过程中)
        def switch_player(self, player1, player2):
            if self.current_player is None:
                return player1
            else:
                return [player1, player2][self.current_player == player1]
        
        # 打印赢家
        def print_winner(self, winner): # winner in [0,1,2]
            print(['Winner is player1','Winner is player2','Draw'][winner])
        
        # 运行游戏
        def run(self):
            # 生成两个玩家
            player1, player2 = self.make_two_players()
            
            # 游戏开始
            print('\nGame start!\n')
            self.board.print_b() # 显示棋盘
            while True:
                self.current_player = self.switch_player(player1, player2) # 切换当前玩家
                
                action = self.current_player.think(self.board) # 当前玩家对棋盘进行思考后,得到招法
                
                if action is not None: 
                    self.current_player.move(self.board, action)   # 当前玩家执行招法,改变棋盘
                
                self.board.print_b() # 显示当前棋盘
                
                if self.board.teminate(): # 根据当前棋盘,判断棋局是否终止
                    winner = self.board.get_winner() # 得到赢家 0,1,2
                    break
            
            self.print_winner(winner)
            print('Game over!')
            
            self.board.print_history()
        
        
    if __name__ == '__main__':
        Game().run()
    
    

    效果图

    709432-20170701161023118-2042106579.jpg

    转载于:https://www.cnblogs.com/hhh5460/p/7102676.html

    展开全文
  • 主要是用C#编写的一个小游戏——翻转棋程序代码不时很复杂,可以供初学者下载使用
  • [Python] 黑白棋(翻转棋)小游戏

    千次阅读 2020-05-22 20:02:35
    [Python] 黑白棋(翻转棋)小游戏 游戏介绍 黑白棋(Reversi or Othello)在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。 规则 黑白棋的每颗棋子由黑白两色组成,一面白,一面...
  • 利用上一篇的框架,再写了个翻转棋程序,为了调试minimax算法,花了两天的时间。几点改进说明:拆分成四个文件:board.py,player.py,ai.py,othello.py。使得整个结构更清晰,更通用,更易于维护。AI 的水平跟 ...
  • html5游戏开发教程实战 五子棋 四子棋 围棋 翻转棋四种对弈游戏,仅仅100行代码
  • 直接上代码: import pygame # 确认导入成功 print(pygame.ver) EMPTY = 0 BLACK = 1 WHITE = 2 MOVEOUT = 0 blackColor = [0, 0, 0] whiteColor = [255, 255, 255] ... def __init__(self...
  • html5游戏开发教程实战:五子棋、四子棋、围棋、翻转棋四种对弈游戏,仅仅100行代码,代码下载地址:http://www.zuidaima.com/share/1839614057712640.htm
  • 一、效果图 二、源代码链接 链接:https://pan.baidu.com/s/17PUAc2rPP1wsRJ_Bu91ZSg 提取码:ha3t 复制这段内容后打开百度网盘手机App,操作更方便哦
  • ... ...本文是一个非常具有挑战性的编程,因为100行代码,约莫10000个字符左右,将实现围棋、五子棋、四子棋和翻转棋四种双人对弈游戏。请注意,这四个对弈游戏不是初级编程者的习作,而是有着棋...
  • 习题4-3 黑白(Othello, ACM/ICPC World Finals 1992, UVa220) 你的任务是模拟黑白游戏的进程。黑白的规则为:黑白双方轮流放棋子,每次必须 让新放的棋子“夹住”至少一枚对方棋子,然后把所有被新放...
  • ...本文是一个非常具有挑战性的编程,因为100行代码,约莫10000个字符左右,将实现围棋、五子棋、四子棋和翻转棋四种双人对弈游戏。请注意,这四个对弈游戏不是初级编程者的习作,而是有着棋盘...
  • 象棋程序在大家的帮助下基本完成了,但是有个比较重要的部分就是翻转棋盘和悔棋,感觉悔棋难度比翻转棋盘更大一些,但现在问题是红黑双方交换的时候棋子是过来了,不过棋子上的字也跟着倒了,如下图所示(图片是自己...
  • 黑白棋,又叫反棋(Reversi)、奥赛罗棋(Othello)、苹果棋或翻转棋。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。 棋子:黑白棋棋子每颗由黑白两色组成,一面白,...
  • 棋盘翻转

    2016-09-24 16:05:45
    有一个4*4的棋盘,棋盘上...(x,y+1)格子也会被翻为相对的颜色,让你写一个程序,看最后将棋盘全部翻为白色格子或者是黑色格子用的最少的步数是多少?如果无法把所有格子都翻为白色或者是黑色,那么输出“Impossible”!
  • 实现了黑白棋的完整规则,并实现了一定的人机对弈...黑白棋,又叫反棋(Reversi)、奥赛罗棋(Othello)、苹果棋或翻转棋。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。
  • 亚马逊棋程序设计思路总结

    千次阅读 2019-10-06 21:19:45
    亚马逊棋程序设计思路总结 1、比赛模式 (1)开启服务器等待GUI发送棋盘 (2)初始化游戏和神经网路 (3)将新棋盘(board)使用蒙特卡洛树搜索得到下一步策略pi ‘此处的策略分为,选皇后点(start)、选落点(end...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,759
精华内容 703
关键字:

翻转棋程序