From e68196be3970bc8a6b4735061058c7923fe94752 Mon Sep 17 00:00:00 2001 From: Tibor Bizjak Date: Fri, 6 Sep 2019 17:10:43 +0200 Subject: [PATCH] Added parser for algebraic notation and turn variable to Game class --- chess.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/chess.py b/chess.py index 9a817f7..cfe11bb 100644 --- a/chess.py +++ b/chess.py @@ -21,6 +21,12 @@ init_positions = {"pawn" : cross(files, pawn_ranks), "king" : cross("e", home_ranks) } +AN_names = {'R' : "rook", + 'N' : "knight", + 'B' : "bishop", + 'Q' : "queen", + 'K' : "king"} + def get_rank(sq): return int(sq[1]) @@ -39,6 +45,49 @@ def invert(color): return "black" return "white" +class Empty: + def __repr__(self): + return str(vars(self)) + +def parse_AN(move): + def suffix_in(l, dval=False, i=1): + nonlocal move + x = move[-i:] + if x in list(l): + move = move[:-i] + return x + return dval + + queenside = ["{}-{}-{}".format(c,c,c) for c in "0O"] + kingside = ["{}-{}".format(c,c) for c in "0O"] + + r = Empty() + r.kingside = r.queenside = False + if move in queenside: + r.queenside = True + return r + if move in kingside: + r.kingside = True + return r + + r.move = move + r.mate = suffix_in('#') == '#' + r.check = suffix_in('+') == '+' + r.promotion = suffix_in(AN_names) + if r.promotion: + r.promotion = AN_names[r.promotion] + _ = suffix_in('=') + r.dest = suffix_in(squares, i=2) + r.capture = suffix_in("xX") != False + r.rank = suffix_in(ranks, None) + r.file = suffix_in(files, None) + r.piece = suffix_in(AN_names, 'pawn') + if len(move) > 0 or (r.promotion and r.piece != "pawn") or not r.dest: + return False + if r.piece != "pawn": + r.piece = AN_names[r.piece] + return r + up, down = (0, 1), (0, -1) left, right = (-1, 0), (1, 0) rook_dirs = (up, down, left, right) @@ -71,6 +120,7 @@ class Game: self.make_board() self.moves = [] self.stack = [] + self.turn = "white" def __repr__(self): # Unicode board representation @@ -119,10 +169,12 @@ class Game: board[source] = Piece() board[target] = moved + self.turn = invert(moved.color) return True def is_legal(self, source, target): - return target in self.possible_moves(source) + color = self.board[source].color + return color == self.turn and target in self.possible_moves(source) def is_attacked(self, color, sq): enemy_color = invert(color) @@ -217,7 +269,7 @@ def test(): game = Game() assert len(squares) == 8**2 assert sum(map(len, init_positions.values())) == 8*4 - moves = [("a2", "a3"), ("b1", "c3"), ("c3", "b5"), ("b5", "c7")] + moves = [("a2", "a3"), ("b1", "c3"), ("c3", "b5"), ("b8", "c6")] for m in moves: game.move(*m) print (game) @@ -228,4 +280,3 @@ def test(): print(game.possible_moves("c3")) print(game.is_attacked("black", "d8")) -test()