五子棋程序设计带来的坐标系思考
游戏规则
棋盘大小:15*15
空棋盘开局,黑棋先下,白棋后下,一次只能下一子.棋子下在交叉点上,棋子下在棋盘上之后,不能移动.
当相同颜色的五颗棋子连在一起的时候,就认为胜负已分.连在一起的方法有4个:水平,垂直,左上右下,左下右上;如果整个棋盘都摆满棋子之后,仍旧不分胜负,则认为和局.
编程遇到的问题
怎么样定义棋盘的坐标
编程的时候数组或者列表的下标都是从0开始的,但是五子棋棋盘的坐标是从1开始的,如何解决两者之间的不协调?
第一种方法:把每个二维数组或列表的索引值全部加1,比如说五子棋棋盘第4行第6列,则对应的坐标是arr[3] [5].
第二种方法:直接忽略x=0和y=0这一行一列.分配内存时,直接分配16*16的内存空间做为棋盘即可.
- 经过敲代码后发现,第一种方法需要来回切换,比较繁琐,代码量增加.因此采用第二种方法
坐标系
对于计算机来说,一般会把左上角作为坐标系原点.从左往右是水平方向y,从上往下是垂直方向x
比如(4,6)表示第4行第6列,如下图:
对于五子棋棋盘来说,4个角落的坐标点分别为:
- 左上角:(1,1)
- 左下角:(15,1)
- 右上角:(1,15)
- 右下角:(15,15)
胜负判断
相同颜色的五颗棋子连在一起,则胜负已分.有以下几种极端情况:
- 从左到右:判断(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颗棋子连在一起
代码如下
创建一个棋盘类
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()