introduced internal chess engine, fixed bugs
This commit is contained in:
@@ -153,12 +153,17 @@ class ChessBoard:
|
||||
return len(self.move_history) >= 75
|
||||
|
||||
def is_fivefold_repetition(self) -> bool:
|
||||
|
||||
return self.highest_repetiton_amount() >= 5
|
||||
|
||||
def outcome(self) -> Outcome:
|
||||
if self.is_checkmate():
|
||||
return Outcome.from_color(self.turn)
|
||||
if self.is_stalemate() or self.is_seventyfive_moves or self.is_fivefold_repetition:
|
||||
if self.is_stalemate():
|
||||
return Outcome.DRAW
|
||||
if self.is_seventyfive_moves():
|
||||
return Outcome.DRAW
|
||||
if self.is_fivefold_repetition():
|
||||
return Outcome.DRAW
|
||||
return Outcome.NOT_FINISHED
|
||||
|
||||
@@ -204,7 +209,7 @@ class ChessBoard:
|
||||
def init_default(cls) -> "ChessBoard":
|
||||
empty_board = [[BoardField() for _ in range(8)] for _ in range(8)]
|
||||
brd = cls(
|
||||
empty_board, 0, [], empty_board
|
||||
empty_board, 0, [], copy.deepcopy(empty_board)
|
||||
)
|
||||
|
||||
# place pawns
|
||||
@@ -232,8 +237,8 @@ class ChessBoard:
|
||||
for col, piece_type in enumerate(back_rank):
|
||||
brd.place(7, col, piece_type, Color.WHITE)
|
||||
|
||||
#set the inital board for later ref
|
||||
brd.initial_board = brd.fields
|
||||
# set the initial board for later ref (must be a copy, not a reference)
|
||||
brd.initial_board = copy.deepcopy(brd.fields)
|
||||
|
||||
return brd
|
||||
|
||||
@@ -427,10 +432,15 @@ class ChessBoard:
|
||||
else:
|
||||
# occupied
|
||||
if target_field.piece.color == piece.color:
|
||||
if non_sliding:
|
||||
continue
|
||||
# for sliding pieces a blocker stops further squares
|
||||
break
|
||||
else:
|
||||
# opponent piece
|
||||
# opponent piece: capture is allowed
|
||||
moves.append(BoardMove(pos, BoardPos((tr, tc))))
|
||||
if non_sliding:
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
@@ -739,3 +749,39 @@ class ChessBoard:
|
||||
bm = BoardMove(src, dst, move_type, promotion_piece=promo_piece)
|
||||
return self.make_move(bm, color)
|
||||
|
||||
def print_legal_moves(self, color: Color) -> None:
|
||||
moves = self.generate_moves(color)
|
||||
|
||||
if not moves:
|
||||
print(f"{color.name}: no legal moves")
|
||||
return
|
||||
|
||||
move_strings = []
|
||||
for move in moves:
|
||||
from_sq = self.pos_to_algebraic(move.m_from)
|
||||
to_sq = self.pos_to_algebraic(move.m_to)
|
||||
move_str = f"{from_sq}-{to_sq}"
|
||||
|
||||
# Add move type notation
|
||||
if move.move_type.name == "CASTLING_KINGSIDE":
|
||||
move_str += " (O-O)"
|
||||
elif move.move_type.name == "CASTLING_QUEENSIDE":
|
||||
move_str += " (O-O-O)"
|
||||
elif move.move_type.name == "EN_PASSANT":
|
||||
move_str += " (e.p.)"
|
||||
elif move.promotion_piece:
|
||||
move_str += f" (={move.promotion_piece.name[0]})"
|
||||
|
||||
move_strings.append(move_str)
|
||||
|
||||
print(f"\n{color.name} Legal Moves ({len(moves)} total):")
|
||||
print("-" * 50)
|
||||
|
||||
# Print in columns (6 moves per row)
|
||||
moves_per_row = 6
|
||||
for i in range(0, len(move_strings), moves_per_row):
|
||||
row = move_strings[i:i + moves_per_row]
|
||||
print(" " + " | ".join(f"{m:12}" for m in row))
|
||||
print("-" * 50 + "\n")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user