beginning of transition

This commit is contained in:
simoncreates
2026-03-03 20:06:50 +01:00
parent 7887986a5a
commit 813134ad68
3 changed files with 146 additions and 16 deletions
+104 -4
View File
@@ -1,11 +1,13 @@
from enum import Enum, auto
from dataclasses import dataclass
from typing import Iterator, Optional, List, Tuple
import random
import copy
FILES = "abcdefgh"
RANKS = "12345678"
class PieceType(Enum):
PAWN = auto()
KNIGHT = auto()
@@ -26,6 +28,19 @@ class Color(Enum):
else:
return Color.WHITE
class Outcome(Enum):
DRAW = auto()
WHITE_WIN = auto()
BLACK_WIN = auto()
NOT_FINISHED = auto()
@classmethod
def from_color(cls, color: Color) -> "Outcome":
if color == Color.WHITE:
return Outcome.WHITE_WIN
else:
return Outcome.BLACK_WIN
@dataclass
class BoardPos:
@@ -99,6 +114,87 @@ class ChessBoard:
fields: List[List[BoardField]]
num_moves: int
move_history: List[Tuple['BoardMove', Optional[Piece]]]
initial_board: List[List[BoardField]]
@property
def turn(self) -> "Color":
len_mv_history = len(self.move_history)
if len_mv_history > 0:
first_moved_piece_color = self.initial_move_color
if len_mv_history % 2 == 0:
return first_moved_piece_color
else:
return first_moved_piece_color.opposite
else:
return Color.WHITE
@property
def initial_move_color(self) -> Color:
first_move = self.move_history[0]
from_pos = first_move[0].m_from
# look up what color the piece had that moved first
# (odd solution but i think its quite fine)
first_moved_field = self.initial_board[from_pos.x][from_pos.y]
first_moved_piece_color = Color.WHITE
if first_moved_field.piece is not None:
first_moved_piece_color = first_moved_field.piece.color
return first_moved_piece_color
def is_checkmate(self) -> bool:
cur_turn_color = self.turn
return len(self.generate_moves(cur_turn_color)) == 0 and self.is_field_attacked(self.pos_of_king(cur_turn_color), cur_turn_color.opposite)
def is_stalemate(self) -> bool:
cur_turn_color = self.turn
return len(self.generate_moves(cur_turn_color)) == 0
def is_seventyfive_moves(self) -> bool:
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:
return Outcome.DRAW
return Outcome.NOT_FINISHED
def highest_repetiton_amount(self) -> int:
if self.move_history:
starting_color = self.initial_move_color
else:
starting_color = Color.WHITE
dummy = ChessBoard(
copy.deepcopy(self.initial_board),
0,
[],
copy.deepcopy(self.initial_board),
)
color = starting_color
states: list[str] = []
states.append(str(dummy))
for mv, _ in self.move_history:
dummy.make_move(mv, color)
color = color.opposite
states.append(str(dummy))
counts: dict[str, int] = {}
max_count = 0
for state in states:
counts[state] = counts.get(state, 0) + 1
if counts[state] > max_count:
max_count = counts[state]
return max_count
def place(self, row: int, col: int, piece_type: PieceType, color: Color):
self.fields[row][col].piece = Piece(piece_type, color)
@@ -106,8 +202,9 @@ class ChessBoard:
# initialize default starting position
@classmethod
def init_default(cls) -> "ChessBoard":
empty_board = [[BoardField() for _ in range(8)] for _ in range(8)]
brd = cls(
[[BoardField() for _ in range(8)] for _ in range(8)], 0, []
empty_board, 0, [], empty_board
)
# place pawns
@@ -135,6 +232,9 @@ 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
return brd
# attempt to make move for color
@@ -317,7 +417,7 @@ class ChessBoard:
color.opposite,
):
# check if the last move moved the pawn there from the starting square
last_move = self.move_history[move_history_len][0]
last_move = self.move_history[-1][0] # final move, not past-the-end
if last_move.m_from == BoardPos((tr, tc + en_passant_dir)) and last_move.m_to == BoardPos((tr, tc - en_passant_dir)):
moves.append(BoardMove(pos, BoardPos((tr, tc))))