You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SafariChess/SafariChess_backend.py

187 lines
8.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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])
# 定义移动方式
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((new_row,new_col))
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((new_row,new_col))
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((new_row,new_col))
elif nxt_piece[0]==enemy_color and self.Eliminate(row,col,new_row,new_col):
moves.append((new_row,new_col))
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((new_row,col))
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((new_row,col))
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((row,new_col))
elif nxt_piece[0]==enemy_color and self.Eliminate(row,col,new_row,new_col):
moves.append((row,new_col))
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((new_row,new_col))
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((new_row,new_col))
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(Move((row, col), (end_row, end_col+(2*jump_col)), self.board))
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