mchess-client/lib/chess_bloc/chess_position.dart
Marco 1cb5ffb82b Handle board status message
This is another step to allow reconnecting after connection loss or
browser closing.

When the game is left with the X button on the bottom right, we will
close the websocket connection, to let the server know, that we are
gone.

The server still has issues that prevent this from working flawlessly.
2023-12-09 20:41:34 +01:00

145 lines
4.2 KiB
Dart

import 'dart:developer';
import 'package:mchess/utils/chess_utils.dart';
typedef ChessMoveHistory = List<ChessMove>;
typedef ChessPosition = Map<ChessCoordinate, ChessPiece>;
class ChessPositionManager {
static ChessPositionManager _instance = ChessPositionManager._internal();
static ChessMoveHistory history = ChessMoveHistory.empty(growable: true);
ChessPosition position;
ChessPositionManager({required this.position});
factory ChessPositionManager._internal() {
return ChessPositionManager(position: _getStartingPosition());
}
ChessPosition get copyOfCurrentPosition => Map.from(position);
ChessPosition get currentPosition => position;
ChessMove? get lastMove {
if (history.isEmpty) return null;
return history.last;
}
ChessPosition fromPGNString(String pgn) {
ChessPosition pos = {};
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()}');
}
}
void logPosition(ChessPosition 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, ChessPosition pos) {
position = pos;
history.add(
ChessMove(
from: from ?? ChessCoordinate.none(),
to: to ?? ChessCoordinate.none(),
),
);
logPosition(position);
logHistory(history);
}
void resetToStartingPosition() {
history = ChessMoveHistory.empty(growable: true);
_instance = ChessPositionManager(position: _getStartingPosition());
}
static ChessPositionManager getInstance() {
return _instance;
}
static ChessPosition _getStartingPosition() {
ChessPosition 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;
}
}