class GameState: def __init__(self): ''' 有关信息: 1. 棋盘尺寸为7*9(横向) 2. 按照以下命名格式对棋盘中的棋子进行标注: (b|r)(1|2|3|4|5|6|7) 3. ''' self.board = [ ['00','00','b7','00','00','00','r1','00','00'], ['00','b2','00','00','00','00','00','r3','00'], ['00','00','b4','00','00','00','r5','00','00'], ['00','00','b6','00','00','00','r6','00','00'], ['00','00','b5','00','00','00','r4','00','00'], ['00','b3','00','00','00','00','00','r2','00'], ['00','00','b1','00','00','00','r7','00','00'], ] #用数字1-7代替棋子的强弱关系 self.moveFunctions = { "1": self.getMseMoves, "2": self.getEagMoves, "3": self.getFoxMoves, "4": self.getStdMoves, "5": self.getStdMoves, "6": self.getLionMoves, "7": self.getStdMoves, } self.blue_trap_loc=[(2,0),(3,1),(4,0)] self.red_trap_loc=[(3,7),(2,8),(4,8)] self.blue_home=(3,0) self.red_home=(3,8) #蓝方(左)先行 self.red_to_move=False self.conquered=False self.MASSACRE=False self.color = 'r' if self.red_to_move else 'b' # 判断特殊位置 def inHome(self,row,col,color): if color=="b": if (row,col)==self.blue_home: return True else: if (row,col)==self.red_home: return True return False def inWater(self,row,col): if row in [1,2,4,5]: if col in [3,4,5]: return True return False def inTrap(self,row,col,color): if color=="b": if (row,col) in self.blue_trap_loc: return True else: if (row,col) in self.red_trap_loc: return True return False def Eliminate(self,row,col,nxt_row,nxt_col):#下一步可吃对手的棋 return self.board[nxt_row][nxt_col] == '00' or self.board[nxt_row][nxt_col][0] != self.board[row][col][0] and (eval(self.board[row][col][1]) >= eval(self.board[nxt_row][nxt_col][1]) or self[row][col][1]==1 and self.board[row][col][1]==7) # 定义移动方式 #---------------------------------- # 以下为移动方式的相关规定: # 1.下一步的可行位置以二维数组的格式进行记录。 # 2.getValidMoves返回值为下一步可行位置构成的集合。 #---------------------------------- def getAllMoves(self): moves=[] for row in range(len(self.board)): for col in range(len(self.board[row])): player = self.board[row][col][0] if (player == 'r' and self.red_to_move or player == 'b' and not self.red_to_move): self.moveFunctions[self.board[row][col][1]](row,col,moves) return moves def getStdMoves(self,row,col,moves):#输入当前的位置,将可行路径输出给moves directions = [(1,0),(0,1),(-1,0),(0,-1)] enemy_color = 'b' if self.red_to_move else 'r' for direction in directions: new_row = row + direction[0]*1 new_col = col + direction[1]*1 if 0<=new_row<=8 and 0<=new_col<=6 : nxt_piece = self.board[new_row][new_col] if nxt_piece == '00' and not self.inWater(new_row,new_col) and not self.inHome(new_row,new_col,self.color):#如果下一个位置是空的,则可以移动 moves.append(Move((row,col),(new_row,new_col),self.board)) elif nxt_piece[0]==enemy_color and not self.inWater(new_row,new_col) and not self.inHome(new_row,new_col,self.color) and self.Eliminate(row,col,new_row,new_col):#如果是敌方棋子,且不在水里,且可以消除,则添加到可行路径中 moves.append(Move((row,col),(new_row,new_col),self.board)) return moves def getMseMoves(self,row,col,moves): directions = [(1,0),(0,1),(-1,0),(0,-1)] enemy_color = 'b' if self.red_to_move else 'r' for direction in directions: new_row = row + direction[0]*1 new_col = col + direction[0]*1 if 0<=new_row<=8 and 0<=new_col<=6 : nxt_piece = self.board[new_row][new_col] if nxt_piece == '00' and not self.inHome(new_row,new_col,self.color): moves.append(Move((row,col),(new_row,new_col),self.board)) elif nxt_piece[0]==enemy_color and self.Eliminate(row,col,new_row,new_col): moves.append(Move((row,col),(new_row,new_col),self.board)) return moves def getEagMoves(self,row,col,moves): #可能存在一些问题,主要是移动方式的判断以及在陷阱的判断 enemy_color = 'b' if self.red_to_move else 'r' moveNum_row = -6 moveNum_col = -8 new_row = row new_col = col while(moveNum_row <= 6 ): new_row = row + moveNum_row if 0<=new_row<=6: nxt_piece = self.board[new_row][col] if nxt_piece == '00': moves.append(Move((row,col),(new_row,new_col),self.board)) elif nxt_piece[0]==enemy_color and not self.inWater(new_row,col) and not self.inHome(row,new_col,self.color) and self.Eliminate(row,col,new_row,new_col): moves.append(Move((row,col),(new_row,new_col),self.board)) else : break moveNum_row += 1 while(moveNum_row <= 8): new_col = col + moveNum_col if 0 <= new_col <= 8: nxt_piece = self.board[row][new_col] if nxt_piece == '00' and not self.inWater(row,new_col) and not self.inHome(row,new_col,self.color): moves.append(Move((row,col),(new_row,new_col),self.board)) elif nxt_piece[0]==enemy_color and self.Eliminate(row,col,new_row,new_col): moves.append(Move((row,col),(new_row,new_col),self.board)) else : break moveNum_col += 1 return moves def getFoxMoves(self,row,col,moves): directions = [(1,0),(0,1),(-1,0),(0,-1),(1,1),(1,-1),(-1,1),(-1,-1)] enemy_color = 'b' if self.red_to_move else 'r' for direction in directions: new_row = row + direction[0]*1 new_col = col + direction[1]*1 if 0<=new_row<=8 and 0<=new_col<=6 : nxt_piece = self.board[new_row][new_col] if nxt_piece == '00' and not self.inWater(new_row,new_col) and not self.inHome(new_row,new_col,self.color):#如果下一个位置是空的,则可以移动 moves.append(Move((row,col),(new_row,new_col),self.board)) elif nxt_piece[0]==enemy_color and not self.inWater(new_row,new_col) and not self.inHome(new_row,new_col,self.color) and self.Eliminate(row,col,new_row,new_col):#如果是敌方棋子,且不在水里,且可以消除,则添加到可行路径中 moves.append(Move((row,col),(new_row,new_col),self.board)) return moves def getLionMoves(self,row,col,moves): directions = ((-1, 0), (0, -1), (1, 0), (0, 1)) enemy_color = "b" if self.red_to_move else "r" for direction in directions: for i in range(1, 2): end_row = row + direction[0] * 1 end_col = col + direction[1] * 1 if 0 <= end_row <= 8 and 0 <= end_col <= 6: # check for possible moves only in boundaries of the board end_piece = self.board[end_row][end_col] if end_piece == "--" and not self.inWater(end_row,end_col) and self.moveNotOwnDen(end_row,end_col,enemy_color): # empty space is valid and Not in Water moves.append(Move((row, col), (end_row, end_col), self.board)) elif end_piece == "--" and self.inWater(end_row,end_col): jump_row = end_row - row #Vertical jump jump_col = end_col - col #Horizontal jump if jump_row != 0 and self.jumpConditions(row,col,end_row,end_col,jump_row,jump_col,enemy_color): moves.append(Move((row, col), (end_row+(3*jump_row), end_col), self.board)) elif jump_col != 0 and self.jumpConditions(row,col,end_row,end_col,jump_row,jump_col,enemy_color): moves.append((end_row, end_col+(2*jump_col))) elif end_piece[0] == enemy_color and not self.inWater(end_row,end_col) and self.canAttack(row, col, end_row, end_col): # capture enemy piece moves.append(Move((row, col), (end_row, end_col), self.board)) break else: # friendly piece break else: # off board break # 判断是否胜利 def conquer(self): if self.board[3][0][0] == 'r' or self.board[3][8][0] == 'b': self.conquered = True return self.conquered #移动操作 def makeMove(self,move):#cur是当前位置,nxt是下一个位置,参数传入为元组 self.board[move.end_row][move.end_col] = self.board[move.start_row][move.start_col] self.board[move.start_row][move.start_col] = '00' class Move: def __init__(self,start_loc,end_loc,board): self.start_row = start_loc[0] self.start_col = start_loc[1] self.end_row = end_loc[0] self.end_col = end_loc[1] self.nxt_piece = board[self.end_row][self.end_col] self.cur_piece = board[self.start_row][self.start_col] self.attack = self.nxt_piece != '00'