diff --git a/chess.py b/chess.py index d45a375..f4b9c16 100644 --- a/chess.py +++ b/chess.py @@ -11,6 +11,9 @@ ranks = 'RNBQKBNR' def next_turn(turn): return 'B' if turn == 'W' else 'W' +def get_turn_pieces(turn, whites, blacks): + return (whites, blacks) if turn == 'W' else (blacks, whites) + def create_board(): whites = {} whites.update({vec2(c, 0): rank for (c, rank) in zip(range(8), ranks)}) @@ -40,14 +43,19 @@ def get_human_move(turn): s = input(turn + ' to move: ') return tuple(map(vec2_from_text, s.split())) +def get_start_move(start_move): + print(start_move) + return tuple(map(vec2_from_text, start_move.split())) + + def get_computer_move(turn, whites, blacks): return random.choice(get_valid_moves(turn, whites, blacks)) -def get_valid_dsts(src, whites, blacks): +def get_valid_dsts(src, turn, whites, blacks): # todo: castling # todo: en passant - is_white_turn = src in whites - self_pieces, oppo_pieces = (whites, blacks) if is_white_turn else (blacks, whites) + # todo: promotion + self_pieces, oppo_pieces = get_turn_pieces(turn, whites, blacks) piece = self_pieces[src] valid_dsts = set() @@ -69,8 +77,8 @@ def get_valid_dsts(src, whites, blacks): delta += dir if piece == 'P': # Pawn - dy = 1 if is_white_turn else -1 - sy = 1 if is_white_turn else 6 + dy = 1 if turn == 'W' else -1 + sy = 1 if turn == 'W' else 6 dst_fw1 = src + vec2(0, dy) dst_fw2 = src + vec2(0, dy * 2) dst_tkl = src + vec2(-1, dy) @@ -99,10 +107,10 @@ def get_valid_dsts(src, whites, blacks): def get_valid_moves(turn, whites, blacks): self_pieces = whites if turn == 'W' else blacks - return [(src, dst) for src in self_pieces for dst in get_valid_dsts(src, whites, blacks)] + return [(src, dst) for src in self_pieces for dst in get_valid_dsts(src, turn, whites, blacks)] -def next_board(src, dst, whites, blacks): - self_pieces, oppo_pieces = (whites, blacks) if src in whites else (blacks, whites) +def next_board(src, dst, turn, whites, blacks): + self_pieces, oppo_pieces = get_turn_pieces(turn, whites, blacks) self_pieces[dst] = self_pieces[src] # Move src -> dst del self_pieces[src] # Remove src if dst in oppo_pieces: # Remove dst if it was an opponent @@ -111,14 +119,14 @@ def next_board(src, dst, whites, blacks): # Valid moves filtered such that the opponent cannot take the current player's king def get_legal_moves(turn, whites, blacks): - self_pieces, oppo_pieces = (whites, blacks) if turn == 'W' else (blacks, whites) + self_pieces, oppo_pieces = get_turn_pieces(turn, whites, blacks) valid_moves = get_valid_moves(turn, whites, blacks) legal_moves = [] for src, dst in valid_moves: - n_whites, n_blacks = next_board(src, dst, whites.copy(), blacks.copy()) + n_whites, n_blacks = next_board(src, dst, turn, whites.copy(), blacks.copy()) n_turn = next_turn(turn) - n_self_pieces, n_oppo_pieces = (n_whites, n_blacks) if n_turn == 'W' else (n_blacks, n_whites) - n_valid_moves = get_valid_moves(n_turn, whites, blacks) + n_self_pieces, n_oppo_pieces = get_turn_pieces(n_turn, n_whites, n_blacks) + n_valid_moves = get_valid_moves(n_turn, n_whites, n_blacks) legal = True for n_src, n_dst in n_valid_moves: if n_dst in n_oppo_pieces and n_oppo_pieces[n_dst] == 'K': @@ -129,7 +137,7 @@ def get_legal_moves(turn, whites, blacks): return legal_moves def is_in_check(turn, whites, blacks): - self_pieces, oppo_pieces = (whites, blacks) if turn == 'W' else (blacks, whites) + self_pieces, oppo_pieces = get_turn_pieces(turn, whites, blacks) n_turn = next_turn(turn) threat_moves = get_valid_moves(n_turn, whites, blacks) for src, dst in threat_moves: @@ -139,28 +147,43 @@ def is_in_check(turn, whites, blacks): turn = 'W' whites, blacks = create_board() +start_moves = [ + 'D2 D4', + 'E7 E5', + 'D4 E5', + 'D8 E7', + 'E5 E6', + 'E7 E6', + 'E2 E4', + 'F7 F5', + #'E4 F5' # Should not be legal +] while True: print(turn, 'to move') print_board(whites, blacks) legal_moves = get_legal_moves(turn, whites, blacks) - print(len(legal_moves), 'valid moves') - for src, dst in legal_moves: - print(src, '->', dst) + print(len(legal_moves), 'legal moves') + self_pieces, oppo_pieces = get_turn_pieces(turn, whites, blacks) if len(legal_moves) == 0: print('game is over') break # if turn == 'W': - while True: - try: - src, dst = get_human_move(turn) - if not (src, dst) in legal_moves: - print('invalid move') - else: - break - except ValueError: - print('invalid input') + if len(start_moves): + src, dst = get_start_move(start_moves.pop(0)) + else: + for src, dst in legal_moves: + print(f"{self_pieces[src]} {src}{'x' if dst in oppo_pieces else ' '}{dst}") + while True: + try: + src, dst = get_human_move(turn) + if not (src, dst) in legal_moves: + print('not a legal move') + else: + break + except ValueError: + print('invalid input') # else: # src, dst = get_computer_move(turn, whites, blacks) - whites, blacks = next_board(src, dst, whites, blacks) + whites, blacks = next_board(src, dst, turn, whites, blacks) turn = next_turn(turn)