PlayChess类
PlayChess类用于幻影围棋的行棋,对于平台发过来的每条指令有实现的处理逻辑。
"""这是幻影围棋的行棋引擎"""def __init__(self, condition=None, mcts=None, position=None):self.condition = condition if condition is not None else gr.Condition()self.gameStatus = gf.GameStatusself.position = position if position is not None else Position()self.mcts = mcts if mcts is not None else gmcts.MCTS(value_fn=gp.win_probability, policy_fn=gp.next_probability, rollout_policy_fn=gp.next_probability)
Position类用于给MCT决策引擎提供棋盘数据与下棋逻辑。
def printStatus(self):"""输出当前状态:return:"""log.info(gf.Board.baseBoardToString())log.info('\n' + str(self.condition.libTracker.groupIndexMap))log.info('\n' + str(self.condition.libTracker.libertyCacheMap))log.info('\n' + str(gf.GameStatus()))def refuse(self, point):"""当行棋被拒绝时执行这个方法:param point::return:"""gf.GameStatus.refused = Truegf.Board.setPiecesByPoint(point, gf.GameStatus.opponentColor)try:self.condition.libTracker.addStone(color=gf.GameStatus.opponentColor, point=point)except gr.IllegalMove as illegal:passexcept Exception as e:passself.printStatus()position = Position()Record.saveStatus(position)def suggestMove(self):self.position = Position()log.info(self.position.baseBoardToString())log.info('start mct...')log.info(self.position.baseBoardToString())self.mcts = gmcts.MCTS(value_fn=gp.win_probability, policy_fn=gp.next_probability, rollout_policy_fn=gp.fast_next_probability)move = self.mcts.get_move(self.position)log.info("try to move " + str(move))return movedef takeStones(self, points, taked=False):"""当我方提子或者被对方提子时执行这个方法:param points::param taked: 如果我方被提子,设置为True:return:"""if taked is True:if gf.GameStatus.ourColor == gf.Chess.WHITE:gf.GameStatus.whiteCaputured += len(points)else:gf.GameStatus.blackCaputured += len(points)elif taked is False:if gf.GameStatus.opponentColor == gf.Chess.WHITE:gf.GameStatus.whiteCaputured += len(points)else:gf.GameStatus.blackCaputured += len(points)if taked is True:# 如果我方被提子的话,说明被提子的周围全是敌方的棋子oppoStones = gr.findTakeStonesAroundPoints(points)for point in oppoStones:gf.Board.placeStone(point, gf.GameStatus.opponentColor)gf.Board.placeStones(points, gf.Chess.EMPTY)#判断该点是否为我方劫点,如果是,则不能立即提回if taked is True and len(points) == 1 and (gr.isKo(points[0], self.condition.baseBoard) is gf.GameStatus.opponentColor):gf.GameStatus.koPoint = points[0]gf.GameStatus.koTimes += 1self.condition.libTracker = gr.LibertyTracker.newTrackerFromBaseBoard(gf.Board.getStaticBaseBoard())self.printStatus()def oppoMoveStone(self):if gf.GameStatus.refused is True:gf.GameStatus.curColor = gf.GameStatus.ourColorreturngf.GameStatus.curColor = gf.GameStatus.ourColorgf.GameStatus.opponentStep += 1def moveStone(self, point):"""accept后执行下棋操作:param point::return:"""if gf.GameStatus.koTimes > 0:gf.GameStatus.koPoint = (-1, -1)gf.GameStatus.koTimes = 0gf.GameStatus.refused = Falseif isinstance(point, gf.Point):point = point.toTuple()gf.Board.placeStone(point, gf.GameStatus.ourColor)try:capturedStones = self.condition.libTracker.addStone(color=gf.GameStatus.ourColor, point=point)if point == gf.GameStatus.koPoint:gf.GameStatus.koTimes += 1if (len(capturedStones) == 1) and (gr.isKo(point, gf.Board.baseBoard) == gf.GameStatus.opponentColor):gf.GameStatus.koPoint = list(capturedStones)[0]gf.GameStatus.round += 1gf.GameStatus.ourStep += 1self.printStatus()except gr.IllegalMove as illegal:log.exception(illegal)except Exception as e:passposition = Position()Record.saveStatus(position)
suggestMove方法调用MCT决策引擎得到下棋点并返回,这里重点讲下moveStone方法和takeStones方法:
moveStone方法:
def moveStone(self, point):"""accept后执行下棋操作:param point::return:"""if gf.GameStatus.koTimes > 0:gf.GameStatus.koPoint = (-1, -1)gf.GameStatus.koTimes = 0gf.GameStatus.refused = Falseif isinstance(point, gf.Point):point = point.toTuple()gf.Board.placeStone(point, gf.GameStatus.ourColor)try:capturedStones = self.condition.libTracker.addStone(color=gf.GameStatus.ourColor, point=point)if point == gf.GameStatus.koPoint:gf.GameStatus.koTimes += 1if (len(capturedStones) == 1) and (gr.isKo(point, gf.Board.baseBoard) == gf.GameStatus.opponentColor):gf.GameStatus.koPoint = list(capturedStones)[0]gf.GameStatus.round += 1gf.GameStatus.ourStep += 1self.printStatus()except gr.IllegalMove as illegal:log.exception(illegal)except Exception as e:passposition = Position()Record.saveStatus(position)
moveStone用于accept后在棋盘上下棋,该方法首先会更新劫点信息,(如果之前有过打劫判断的话,就把劫点重置)在棋盘上下棋后addStone方法更新棋子气等信息,得到被吃掉的棋子的集合,这里有个对打劫的判断:
if (len(capturedStones) == 1) and (gr.isKo(point, gf.Board.baseBoard) == gf.GameStatus.opponentColor):gf.GameStatus.koPoint = list(capturedStones)[0]
最后调用Record类保存当前状态。
takeStones方法:
def takeStones(self, points, taked=False):"""当我方提子或者被对方提子时执行这个方法:param points::param taked: 如果我方被提子,设置为True:return:"""if taked is True:if gf.GameStatus.ourColor == gf.Chess.WHITE:gf.GameStatus.whiteCaputured += len(points)else:gf.GameStatus.blackCaputured += len(points)elif taked is False:if gf.GameStatus.opponentColor == gf.Chess.WHITE:gf.GameStatus.whiteCaputured += len(points)else:gf.GameStatus.blackCaputured += len(points)if taked is True:# 如果我方被提子的话,说明被提子的周围全是敌方的棋子oppoStones = gr.findTakeStonesAroundPoints(points)for point in oppoStones:gf.Board.placeStone(point, gf.GameStatus.opponentColor)gf.Board.placeStones(points, gf.Chess.EMPTY)#判断该点是否为我方劫点,如果是,则不能立即提回if taked is True and len(points) == 1 and (gr.isKo(points[0], self.condition.baseBoard) is gf.GameStatus.opponentColor):gf.GameStatus.koPoint = points[0]gf.GameStatus.koTimes += 1self.condition.libTracker = gr.LibertyTracker.newTrackerFromBaseBoard(gf.Board.getStaticBaseBoard())self.printStatus()
如果我方被提子的话,有种情况就是进入了打劫环节,此时我方不能立即提回。takeStone方法在把对应点设为EMPTY后重新生成一个libertyTracker。