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.GameStatus
self.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 = True
gf.Board.setPiecesByPoint(point, gf.GameStatus.opponentColor)
try:
self.condition.libTracker.addStone(color=gf.GameStatus.opponentColor, point=point)
except gr.IllegalMove as illegal:
pass
except Exception as e:
pass
self.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 move
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 += 1
self.condition.libTracker = gr.LibertyTracker.newTrackerFromBaseBoard(gf.Board.getStaticBaseBoard())
self.printStatus()
def oppoMoveStone(self):
if gf.GameStatus.refused is True:
gf.GameStatus.curColor = gf.GameStatus.ourColor
return
gf.GameStatus.curColor = gf.GameStatus.ourColor
gf.GameStatus.opponentStep += 1
def moveStone(self, point):
"""
accept后执行下棋操作
:param point:
:return:
"""
if gf.GameStatus.koTimes > 0:
gf.GameStatus.koPoint = (-1, -1)
gf.GameStatus.koTimes = 0
gf.GameStatus.refused = False
if 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 += 1
if (len(capturedStones) == 1) and (gr.isKo(point, gf.Board.baseBoard) == gf.GameStatus.opponentColor):
gf.GameStatus.koPoint = list(capturedStones)[0]
gf.GameStatus.round += 1
gf.GameStatus.ourStep += 1
self.printStatus()
except gr.IllegalMove as illegal:
log.exception(illegal)
except Exception as e:
pass
position = 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 = 0
gf.GameStatus.refused = False
if 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 += 1
if (len(capturedStones) == 1) and (gr.isKo(point, gf.Board.baseBoard) == gf.GameStatus.opponentColor):
gf.GameStatus.koPoint = list(capturedStones)[0]
gf.GameStatus.round += 1
gf.GameStatus.ourStep += 1
self.printStatus()
except gr.IllegalMove as illegal:
log.exception(illegal)
except Exception as e:
pass
position = 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 += 1
self.condition.libTracker = gr.LibertyTracker.newTrackerFromBaseBoard(gf.Board.getStaticBaseBoard())
self.printStatus()
如果我方被提子的话,有种情况就是进入了打劫环节,此时我方不能立即提回。takeStone方法在把对应点设为EMPTY后重新生成一个libertyTracker。