Added logic so move is invalid if it opens a check

master
Tibor Bizjak 2019-09-10 15:22:15 +02:00
parent 582a635e17
commit fbf001a9b2
1 changed files with 32 additions and 28 deletions

View File

@ -170,13 +170,14 @@ class Game:
return self.is_attacked(color, sq) return self.is_attacked(color, sq)
def is_mate(self): def is_mate(self):
sq = self.occupying(Piece(self.turn, "king"))[0] return self.is_check() and self.is_stall()
if not self.is_check():
return False def is_stall(self):
for move in self.all_legal_moves(): for move in self.all_legal_moves():
new = deepcopy(self) new = deepcopy(self)
new.move(*move) if self.board[move[0]].piece == "pawn" and move[1][1]==home_ranks[invert(self.turn)]:
if not new.is_check(self.turn): move += ("queen",)
if new.move(*move):
return False return False
return True return True
@ -215,18 +216,22 @@ class Game:
self.board[rook_move[0]] = Piece() self.board[rook_move[0]] = Piece()
self.can_castle[color]["queen"] = False self.can_castle[color]["queen"] = False
self.can_castle[color]["king"] = False self.can_castle[color]["king"] = False
self.moves.append(king_move)
return True
def move(self, source, target, promotion=None): def move(self, source, target, promotion=None):
if not self.is_legal(source, target, promotion): new = deepcopy(self)
if not new.is_legal(source, target, promotion):
return False return False
board = self.board
board = new.board
moved = board[source] moved = board[source]
eaten = board[target] eaten = board[target]
if promotion == None: if promotion == None:
promotion = moved promotion = moved
else: else:
promotion = Piece(self.turn, promotion) promotion = Piece(new.turn, promotion)
if moved.piece == "pawn" and target in moves(source, bishop_dirs) and eaten==None: if moved.piece == "pawn" and target in moves(source, bishop_dirs) and eaten==None:
# En passant # En passant
@ -236,18 +241,22 @@ class Game:
# Castling # Castling
if moved.piece == "rook": if moved.piece == "rook":
self.can_castle[self.turn][moved.side] = False new.can_castle[new.turn][moved.side] = False
if eaten.piece == "rook": if eaten.piece == "rook":
self.can_castle[eaten.color][eaten.side] = False new.can_castle[eaten.color][eaten.side] = False
if moved.piece == "king": if moved.piece == "king":
self.can_castle[self.turn]["queen"] = False new.can_castle[new.turn]["queen"] = False
self.can_castle[self.turn]["king"] = False new.can_castle[new.turn]["king"] = False
self.moves.append((source, target))
self.stack.append(eaten)
board[source] = Piece() board[source] = Piece()
board[target] = promotion board[target] = promotion
if new.is_check(self.turn):
return False
self.moves.append((source, target))
self.board = new.board
self.can_castle = new.can_castle
self.turn = invert(moved.color) self.turn = invert(moved.color)
return True return True
@ -370,18 +379,13 @@ class Game:
def test(): def test():
game = Game() game = Game()
assert len(squares) == 8**2 game.board = {sq : Piece() for sq in squares}
assert sum(map(len, init_positions.values())) == 8*4 game.board['a8'] = Piece("white", "king")
moves = [('d2', 'd4'), ('d7', 'd5'), ('d1', 'd3'), ('h7', 'h5'), game.board['f6'] = Piece("black", "pawn")
('c1', 'h6'), ('g7', 'h6'), ('b1', 'c3'), ('d8', 'd6'), game.board['f5'] = Piece("white", "pawn")
('e2', 'e3'), ('d6', 'f4'), ('e1', 'd1'), ('f4', 'g4')] game.board['c7'] = Piece("black", "queen")
for m in moves: game.board['h1'] = Piece("black", "king")
game.move(*m) print(game, game.is_stall())
print (game.is_check()) print(game.all_legal_moves())
print (game)
game.board['e1'] = game.board['c1'] = game.board['d2'] = Piece("white","pawn")
print (game.is_mate(), "mate")
print(game)
test() test()