2023-01-30 21:39:13 +00:00
|
|
|
import 'dart:developer';
|
2023-08-14 15:04:25 +00:00
|
|
|
|
2023-01-30 21:39:13 +00:00
|
|
|
import 'package:mchess/utils/chess_utils.dart';
|
|
|
|
|
2023-01-30 22:40:46 +00:00
|
|
|
typedef ChessMoveHistory = List<ChessMove>;
|
2023-08-14 22:39:10 +00:00
|
|
|
typedef ChessPosition = Map<ChessCoordinate, ChessPiece>;
|
2023-01-30 21:39:13 +00:00
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
class ChessPositionManager {
|
|
|
|
static ChessPositionManager _instance = ChessPositionManager._internal();
|
2023-06-08 18:23:00 +00:00
|
|
|
static ChessMoveHistory history = ChessMoveHistory.empty(growable: true);
|
2023-08-14 22:39:10 +00:00
|
|
|
ChessPosition position;
|
2023-01-30 21:39:13 +00:00
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
ChessPositionManager({required this.position});
|
2023-01-30 21:39:13 +00:00
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
factory ChessPositionManager._internal() {
|
|
|
|
return ChessPositionManager(position: _getStartingPosition());
|
2023-06-08 18:23:00 +00:00
|
|
|
}
|
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
ChessPosition get copyOfCurrentPosition => Map.from(position);
|
2023-08-14 15:04:25 +00:00
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
ChessPosition get currentPosition => position;
|
2023-06-08 18:23:00 +00:00
|
|
|
ChessMove? get lastMove {
|
|
|
|
if (history.isEmpty) return null;
|
|
|
|
return history.last;
|
|
|
|
}
|
2023-08-25 10:11:23 +00:00
|
|
|
ChessMoveHistory get allMoves => history;
|
2023-06-08 18:23:00 +00:00
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
ChessPosition fromPGNString(String pgn) {
|
|
|
|
ChessPosition pos = {};
|
2023-08-14 15:04:25 +00:00
|
|
|
List<String> 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()}');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
void logPosition(ChessPosition p) {
|
2023-08-14 15:04:25 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
void recordMove(ChessCoordinate from, ChessCoordinate to, ChessPosition pos) {
|
|
|
|
position = pos;
|
2023-08-14 15:04:25 +00:00
|
|
|
|
|
|
|
history.add(ChessMove(from: from, to: to));
|
|
|
|
|
|
|
|
logPosition(position);
|
|
|
|
logHistory(history);
|
|
|
|
}
|
|
|
|
|
|
|
|
void resetToStartingPosition() {
|
|
|
|
history = ChessMoveHistory.empty(growable: true);
|
2023-08-14 22:39:10 +00:00
|
|
|
_instance = ChessPositionManager(position: _getStartingPosition());
|
2023-08-14 15:04:25 +00:00
|
|
|
}
|
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
static ChessPositionManager getInstance() {
|
2023-08-14 15:04:25 +00:00
|
|
|
return _instance;
|
|
|
|
}
|
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
static ChessPosition _getStartingPosition() {
|
|
|
|
ChessPosition pos = {};
|
2023-01-30 21:39:13 +00:00
|
|
|
|
|
|
|
for (int i = 1; i <= 8; i++) {
|
2023-07-03 17:41:12 +00:00
|
|
|
pos[ChessCoordinate(i, 7)] =
|
|
|
|
ChessPiece(ChessPieceClass.pawn, ChessColor.black);
|
|
|
|
pos[ChessCoordinate(i, 2)] =
|
|
|
|
ChessPiece(ChessPieceClass.pawn, ChessColor.white);
|
2023-01-30 21:39:13 +00:00
|
|
|
}
|
|
|
|
|
2023-07-03 17:41:12 +00:00
|
|
|
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);
|
2023-01-30 21:39:13 +00:00
|
|
|
|
2023-07-03 17:41:12 +00:00
|
|
|
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);
|
2023-01-30 21:39:13 +00:00
|
|
|
|
2023-06-08 18:23:00 +00:00
|
|
|
return pos;
|
2023-01-30 21:39:13 +00:00
|
|
|
}
|
|
|
|
}
|