在设计整个程序之前,先设计好数据结构:
数据结构根据用途划分:
临时步结构,用于存储程序计算出的临时的下棋位置
ji
class Step:
point = None
游戏状态类,用于记录围棋的状态
class GameStatus(object):
"""
记录游戏状态的类
ourColor:我方颜色
opponentColor:对方颜色
curColor: 当前执棋者的颜色
ourStep:我方下棋的步数
oppoentStep:对方下棋的步数
round:回合数
isGuessMode:设置是否为猜棋模式
komi:中国规则:黑胜0.5目,贴目:6.5目
koPoints:劫点的元组列表
blackCaptured: 黑棋被吃掉的棋子数目
whiteCaptured: 白棋被吃掉的棋子数目
recent: 最近一次行棋的坐标
"""
komi = 6.5
ourColor = Chess.EMPTY
opponentColor = Chess.EMPTY
curColor = Chess.EMPTY
ourStep = 0
opponentStep = 0
round = 0
isGuessMode = False
koPoint = (-1, -1)
koTimes = 0
blackCaputured = 0
whiteCaputured = 0
recent = tuple()
refused = False
guessNum = 5
@staticmethod
def resetGameStatus(gameStatus):
"""
复盘游戏状态专用方法
:param gameStatus:
:return:
"""
GameStatus.komi = gameStatus.komi
GameStatus.ourStep = gameStatus.ourStep
GameStatus.opponentStep = gameStatus.opponentStep
GameStatus.round = gameStatus.round
GameStatus.isGuessMode = gameStatus.isGuessMode
GameStatus.koTimes = gameStatus.koTimes
GameStatus.koPoint = gameStatus.koPoint
GameStatus.blackCaputured = gameStatus.blackCaputured
GameStatus.whiteCaputured = gameStatus.whiteCaputured
GameStatus.recent = gameStatus.recent
GameStatus.refused = gameStatus.refused
GameStatus.ourColor = gameStatus.ourColor
GameStatus.curColor = gameStatus.curColor
GameStatus.opponentColor = gameStatus.opponentColor
GameStatus.guessNum = gameStatus.guessNum
def reset(self, gameStatus):
self.ourStep = 0
self.opponentStep = 0
self.round = 0
self.isGuessMode = False
self.koTimes = 0
self.koPoint = (-1, -1)
self.blackCaputured = 0
self.whiteCaputured = 0
self.recent = tuple()
self.refused = False
self.guessNum = 3
def __init__(self):
self.komi = copy.copy(GameStatus.komi)
self.ourColor = copy.copy(GameStatus.ourColor)
self.opponentColor = copy.copy(GameStatus.opponentColor)
self.curColor = copy.copy(GameStatus.curColor)
self.ourStep = copy.copy(GameStatus.ourStep)
self.opponentStep = copy.copy(GameStatus.opponentStep)
self.round = copy.copy(GameStatus.round)
self.isGuessMode = copy.copy(GameStatus.isGuessMode)
self.koPoint = copy.copy(GameStatus.koPoint)
self.koTimes = copy.copy(GameStatus.koTimes)
self.blackCaputured = copy.copy(GameStatus.blackCaputured)
self.whiteCaputured = copy.copy(GameStatus.whiteCaputured)
self.recent = copy.copy(GameStatus.recent)
self.refused = copy.copy(GameStatus.refused)
self.guessNum = copy.copy(GameStatus.guessNum)
def __copy__(self):
newGameStatus = GameStatus()
newGameStatus.komi = copy.copy(self.komi)
newGameStatus.ourColor = copy.copy(self.ourColor)
newGameStatus.opponentColor = copy.copy(self.opponentColor)
newGameStatus.curColor = copy.copy(self.curColor)
newGameStatus.ourStep = copy.copy(self.ourStep)
newGameStatus.opponentStep = copy.copy(self.opponentStep)
newGameStatus.round = copy.copy(self.round)
newGameStatus.isGuessMode = copy.copy(self.isGuessMode)
newGameStatus.koPoint = copy.copy(self.koPoint)
newGameStatus.koTimes = copy.copy(self.koTimes)
newGameStatus.blackCaputured = copy.copy(self.blackCaputured)
newGameStatus.whiteCaputured = copy.copy(self.whiteCaputured)
newGameStatus.recent = copy.copy(self.recent)
newGameStatus.refused = copy.copy(self.refused)
newGameStatus.guessNum = copy.copy(self.guessNum)
return newGameStatus
def __str__(self):
"""
为log做准备
:return:
"""
return " 当前颜色: {}\n 我方颜色: {}\n 对方颜色: {}\n 我方下棋步数: {}\n 对方下棋步数: {}\n 回合数: {}\n Ko点: {}\n 黑棋被吃: {}\n 白棋被吃: {}\n 是否为猜棋模式: {}\n 猜棋模式 剩余次数: {}\n".\
format(self.curColor, self.ourColor, self.opponentColor, self.ourStep, self.opponentStep, self.round, self.koPoint, self.blackCaputured, self.whiteCaputured, self.isGuessMode, self.guessNum)
棋盘类
# 基础棋盘 9*9 初始值为EMPTY
class Board(object):
"""
baseBoard为静态变量,最好用下面的静态方法获取
size为棋盘大小
neighbors存的是对应点的周围点(上下左右)
diagonals存的是对应点的对角点
"""
global BOARD_SIZE
baseBoardSize = BOARD_SIZE
valueBoardSize = BOARD_SIZE
emptyBoard = np.array([[Chess.EMPTY for i in range(BOARD_SIZE)] for i in range(BOARD_SIZE)])
baseBoard = np.array([[Chess.EMPTY for i in range(BOARD_SIZE)] for i in range(BOARD_SIZE)])
#没有用到
valueBoard = np.array([[0 for i in range(BOARD_SIZE)] for i in range(BOARD_SIZE)])
neighbors = {}
diagonals = {}
def __repr__(self):
return repr((Board.baseBoardSize, Board.valueBoardSize, Board.emptyBoard, Board.baseBoard, Board.valueBoard, Board.neighbors, Board.diagonals))
@staticmethod
def printValueBoard():
"""
在命令行里打印价值棋盘
:return:
"""
show = ""
for x in range(Board.valueBoardSize):
show += "\n"
for y in range(Board.valueBoardSize):
show += str(Board.valueBoard[x][y]) + " "
print(show)
@staticmethod
def getCopyOfEmptyBoard():
return np.copy(Board.emptyBoard)
@staticmethod
def placeStone(point, color):
"""
在基础棋盘指定位置设置对应颜色
:param point: 位置, 可以为元组或者Point对象
:param color: 颜色(枚举)
:return: None
"""
if isinstance(point, Point):
point = point.toTuple()
Board.baseBoard[point] = color
@staticmethod
def placeStones(points, color):
"""
在基础棋盘指定的位置列表设置对应颜色
:param points: 位置列表, 可以为元组或者Point
:param color: 颜色(枚举)
:return: None
"""
for point in points:
if isinstance(point, Point):
point = point.toTuple()
Board.baseBoard[point] = color
@staticmethod
def baseBoardToString():
"""
在命令行里打印出基础棋盘
:return:
"""
printMap = {
Chess.WHITE: 'O',
Chess.EMPTY: '.',
Chess.BLACK: 'X',
Chess.FILL: '#',
Chess.KO: '*',
}
show = "" + str(printMap) + "\n" + " 0 1 2 3 4 5 6 7 8"
for x in range(Board.baseBoardSize):
show += '\n' + str(x) + " "
for y in range(Board.baseBoardSize):
show += printMap[Board.baseBoard[x][y]] + " "
return show
@staticmethod
def getCopyOfStaticBaseBoard():
"""
返回基础棋盘的拷贝
:return:基础棋盘的拷贝
"""
return np.copy(Board.baseBoard)
@staticmethod
def getStaticBaseBoard():
"""
:return 静态的基础棋盘
"""
return Board.baseBoard
@staticmethod
def clearBaseBoard():
"""
重新设置基础棋盘的所有点为0
"""
for i in range(Board.baseBoardSize):
for j in range(Board.baseBoardSize):
Board.baseBoard[i][j] = Chess.EMPTY
@staticmethod
def getStaticValueBoard():
"""
:return: 静态的价值棋盘
"""
return Board.valueBoard
@staticmethod
def clearValueBoard():
"""
初始化价值棋盘
:return:
"""
for i in range(Board.valueBoardSize):
for j in range(Board.valueBoardSize):
Board.valueBoard[i][j] = 0
@staticmethod
def setPiecesByPoint(point, playerColor):
"""
下棋
:param point:下棋的位置
:param playerColor:下棋的角色值为Chess.WHITE或者Chess.BLACK
:return:
"""
if isinstance(point, Point):
point = point.toTuple()
Board.baseBoard[point[0]][point[1]] = playerColor
def setPiecesByTuple(point, playColor):
Board.baseBoard[point] = playColor
@staticmethod
def setPiecesByXY(x, y, playerColor):
"""
下棋
:param x:下棋的行值
:param y: 下棋的列值
:param playerColor:下棋的角色值为Chess.WHITE或者Chess.BLACK
:return:
"""
Board.baseBoard[x][y] = playerColor
而最后在写一个初始化方法,用于初始化数据结构:
neighbors用于记录棋盘上每个位置的相邻位置的集合
而diagonals用于记录棋盘上每个位置的对角位置的集合
这两个数据结构用于之后写对眼,禁着点的判断,以及气追踪器类。
checkBounds是一个过滤函数,用于输出合法点。
def init():
"""
初始化棋盘
:return:None
"""
def checkBounds(point):
"""
判断当前点是否越界
:param point:当前点(元组对象)
:return:True:未越界 False:越界
"""
return point[0] % Board.baseBoardSize == point[0] and point[1] % Board.baseBoardSize == point[1]
log.info("init game...")
Board.clearBaseBoard()
Board.clearValueBoard()
for i in range(Board.baseBoardSize):
for j in range(Board.baseBoardSize):
Board.neighbors[(i, j)] = list(filter(checkBounds, [(i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)]))
Board.diagonals[(i, j)] = list(filter(checkBounds, [(i + 1, j + 1), (i + 1, j - 1), (i - 1, j + 1), (i - 1, j - 1)]))
GameStatus.ourStep = 0
GameStatus.opponentStep = 0
GameStatus.round = 0
log.info('load model...')
gp.load_model()
来第四篇,围棋规则模块(一)->围棋规则模块