五子棋程序设计带来的坐标系思考


五子棋程序设计带来的坐标系思考

  1. 游戏规则

    棋盘大小:15*15

    空棋盘开局,黑棋先下,白棋后下,一次只能下一子.棋子下在交叉点上,棋子下在棋盘上之后,不能移动.

    当相同颜色的五颗棋子连在一起的时候,就认为胜负已分.连在一起的方法有4个:水平,垂直,左上右下,左下右上;如果整个棋盘都摆满棋子之后,仍旧不分胜负,则认为和局.

  2. 编程遇到的问题

    1. 怎么样定义棋盘的坐标

      编程的时候数组或者列表的下标都是从0开始的,但是五子棋棋盘的坐标是从1开始的,如何解决两者之间的不协调?

      第一种方法:把每个二维数组或列表的索引值全部加1,比如说五子棋棋盘第4行第6列,则对应的坐标是arr[3] [5].

      第二种方法:直接忽略x=0和y=0这一行一列.分配内存时,直接分配16*16的内存空间做为棋盘即可.

      • 经过敲代码后发现,第一种方法需要来回切换,比较繁琐,代码量增加.因此采用第二种方法
    2. 坐标系

      对于计算机来说,一般会把左上角作为坐标系原点.从左往右是水平方向y,从上往下是垂直方向x

      比如(4,6)表示第4行第6列,如下图:

      计算机坐标系

      对于五子棋棋盘来说,4个角落的坐标点分别为:

      • 左上角:(1,1)
      • 左下角:(15,1)
      • 右上角:(1,15)
      • 右下角:(15,15)
    3. 胜负判断

      相同颜色的五颗棋子连在一起,则胜负已分.有以下几种极端情况:

      • 从左到右:判断(x,y-4)~(x,y+4)这9个坐标中是否有连续5颗棋子连在一起
      • 从上到下:判断(x-4,y)~(x+4,y)这9个坐标中是否有连续5颗棋子连在一起
      • 左上右下:判断(x-4,y-4)~(x+4,y+4)这9个坐标中是否有连续5颗棋子连在一起
      • 左下右上:判断(x+4,y-4)~(x-4,y+4)这9个坐标中是否有连续5颗棋子连在一起
  3. 代码如下

    创建一个棋盘类

    chessboard.py

    #棋盘类
    class ChessBoard:
        # 棋盘大小
        BOARD_SIZE = 15
        # 初始化
        def __init__(self):
            self.board = []
            for i in range(ChessBoard.BOARD_SIZE+1):
                tmp = []
                for j in range(ChessBoard.BOARD_SIZE+1):
                    tmp.append(0)
                self.board.append(tmp)
    
        #清空棋盘
        def initBoard(self):
            for i in range(1,ChessBoard.BOARD_SIZE+1):
                for j in range(1,ChessBoard.BOARD_SIZE+1):
                    self.board[i][j] = '+'  # 实现方法initBoard(),对棋盘进行初始化,把所有的空格都设置成'+'符号
    
    
        # 打印棋盘
        def printBoard(self):
            # 打印列号
            print('  ',end=' ')
            for i in range(1,ChessBoard.BOARD_SIZE+1):
                ch = chr(96+i)
                print(ch,end=' ')
            print()
            # 打印行号和棋盘
            for i in range(1,ChessBoard.BOARD_SIZE+1):
                # 打印行号
                print('%2d' % i,end=' ')
                # 打印棋盘
                for j in range(1,ChessBoard.BOARD_SIZE+1):
                    print(self.board[i][j],end=' ')
                print()
    
        # 放置棋子
        # 参数1 pos位置坐标 类型是长度为2的列表或元组
        # 参数2 color棋子颜色
        def setChess(self,pos,color):
            x = pos[0]
            y = pos[1]
            self.board[x][y] = color
    
        # 放置棋子
        def setChessMan(self,chessMan):
                pos = chessMan.getPos()
                color = chessMan.getColor()
                self.setChess(pos,color)
    
        # 根据位置读取棋子的颜色
        def getChess(self,pos):
            x,y = pos
            return self.board[x][y]
    
        # 判断某个坐标点是否为空
        def isEmpty(self,pos):
            chess = self.getChess(pos)
            if chess == '+':
                return True
            #非空即黑或白
            return False
    
    

    创建一个棋子类

    chessman.py

    #棋子类
    class ChessMan:
        # 初始化
        def __init__(self):
            self.color = 'x'
            self.pos = (0,0)
        # 设置颜色
        def setColor(self,color):
            self.color = color
        # 获取颜色
        def getColor(self):
            return self.color
        # 设置位置
        def setPos(self,pos):
            self.pos = pos
        # 获取位置
        def getPos(self):
            return self.pos
    

    测试代码

    main.py

    # from 文件名 import 类名
    from chessboard import *
    from chessman import *
    
    # 测试打印棋盘
    def test1():
        board = ChessBoard()
        board.initBoard()
        board.printBoard()
    
    
    #测试摆放棋子
    def test2():
        board = ChessBoard()
        board.initBoard()
        #测试setChess()摆放棋子
        board.setChess((3,5),'x')
        #测试setChessMan()摆放棋子
        chessMan = ChessMan()
        chessMan.setColor('o')
        chessMan.setPos((4,6))
        board.setChessMan(chessMan)
        board.printBoard()
        ret = board.isEmpty((3,6))
        print(ret)
    
    if __name__ == '__main__':  # 相当于一个入口,当其他模块被调用的时候,先运行此模块
        test2()
    

文章作者: 冬瓜冬瓜排骨汤
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 冬瓜冬瓜排骨汤 !
  目录