import 'dart:developer'; import 'package:mchess/utils/chess_utils.dart'; typedef ChessMoveHistory = List; typedef ChessPositionType = Map; class ChessPosition { static ChessPosition _instance = ChessPosition._internal(); static ChessMoveHistory history = ChessMoveHistory.empty(growable: true); final ChessPositionType position; ChessPosition({required this.position}); factory ChessPosition._internal() { return ChessPosition(position: _getStartingPosition()); } ChessPositionType get copyOfCurrentPosition => Map.from(position); ChessPositionType get currentPosition => position; ChessMove? get lastMove { if (history.isEmpty) return null; return history.last; } ChessPositionType fromPGNString(String pgn) { ChessPositionType pos = {}; List rowStrings; rowStrings = pgn.split('/'); for (int row = 1; row <= 8; row++) { for (int col = 1; col <= 8; col++) { var piece = rowStrings.elementAt(row - 1)[col - 1]; if (piece == '-') { continue; } pos[ChessCoordinate(col, row)] = pieceFromShortname[piece]!; } } return pos; } ChessPiece? getPieceAt(ChessCoordinate coordinate) { return position[ChessCoordinate(coordinate.column, coordinate.row)]; } void logHistory(ChessMoveHistory hist) { for (var element in hist) { log('${element.from.toAlphabetical()} -> ${element.to.toAlphabetical()}'); } } void logPosition(ChessPositionType p) { String logString = ''; for (int row = 8; row > 0; row--) { for (int col = 1; col <= 8; col++) { var coord = ChessCoordinate(col, row); if (p.containsKey(coord)) { logString = '$logString ${p[coord]?.shortName}'; } else { logString = '$logString .'; } } logString = '$logString\n'; } log(logString); } void recordMove(ChessCoordinate from, ChessCoordinate to) { position[to] = position[from] ?? const ChessPiece.none(); position[from] = const ChessPiece.none(); history.add(ChessMove(from: from, to: to)); logPosition(position); logHistory(history); } void resetToStartingPosition() { history = ChessMoveHistory.empty(growable: true); _instance = ChessPosition(position: _getStartingPosition()); } static ChessPosition getInstance() { return _instance; } static ChessPositionType _getStartingPosition() { ChessPositionType pos = {}; for (int i = 1; i <= 8; i++) { pos[ChessCoordinate(i, 7)] = ChessPiece(ChessPieceClass.pawn, ChessColor.black); pos[ChessCoordinate(i, 2)] = ChessPiece(ChessPieceClass.pawn, ChessColor.white); } pos[ChessCoordinate(1, 8)] = ChessPiece(ChessPieceClass.rook, ChessColor.black); pos[ChessCoordinate(2, 8)] = ChessPiece(ChessPieceClass.knight, ChessColor.black); pos[ChessCoordinate(3, 8)] = ChessPiece(ChessPieceClass.bishop, ChessColor.black); pos[ChessCoordinate(4, 8)] = ChessPiece(ChessPieceClass.queen, ChessColor.black); pos[ChessCoordinate(5, 8)] = ChessPiece(ChessPieceClass.king, ChessColor.black); pos[ChessCoordinate(6, 8)] = ChessPiece(ChessPieceClass.bishop, ChessColor.black); pos[ChessCoordinate(7, 8)] = ChessPiece(ChessPieceClass.knight, ChessColor.black); pos[ChessCoordinate(8, 8)] = ChessPiece(ChessPieceClass.rook, ChessColor.black); pos[ChessCoordinate(1, 1)] = ChessPiece(ChessPieceClass.rook, ChessColor.white); pos[ChessCoordinate(2, 1)] = ChessPiece(ChessPieceClass.knight, ChessColor.white); pos[ChessCoordinate(3, 1)] = ChessPiece(ChessPieceClass.bishop, ChessColor.white); pos[ChessCoordinate(4, 1)] = ChessPiece(ChessPieceClass.queen, ChessColor.white); pos[ChessCoordinate(5, 1)] = ChessPiece(ChessPieceClass.king, ChessColor.white); pos[ChessCoordinate(6, 1)] = ChessPiece(ChessPieceClass.bishop, ChessColor.white); pos[ChessCoordinate(7, 1)] = ChessPiece(ChessPieceClass.knight, ChessColor.white); pos[ChessCoordinate(8, 1)] = ChessPiece(ChessPieceClass.rook, ChessColor.white); return pos; } }