天天看点

2020计算机博弈大赛第三天 程序数据结构

在设计整个程序之前,先设计好数据结构:

数据结构根据用途划分:

临时步结构,用于存储程序计算出的临时的下棋位置

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()

           

来第四篇,围棋规则模块(一)->围棋规则模块