Use position to build board
Now the client considers the position sent by the server to build the position on the board.
This commit is contained in:
parent
a281d2acfa
commit
c213d9b1f3
@ -22,12 +22,15 @@ class ApiWebsocketMessage {
|
||||
final ApiMove? move;
|
||||
final ApiColor? color;
|
||||
final String? reason;
|
||||
final String? position;
|
||||
|
||||
ApiWebsocketMessage(
|
||||
{required this.type,
|
||||
required this.move,
|
||||
required this.color,
|
||||
required this.reason});
|
||||
ApiWebsocketMessage({
|
||||
required this.type,
|
||||
required this.move,
|
||||
required this.color,
|
||||
required this.reason,
|
||||
required this.position,
|
||||
});
|
||||
|
||||
factory ApiWebsocketMessage.fromJson(Map<String, dynamic> json) {
|
||||
final type = MessageType.fromJson(json['messageType']);
|
||||
@ -35,17 +38,21 @@ class ApiWebsocketMessage {
|
||||
switch (type) {
|
||||
case MessageType.colorDetermined:
|
||||
ret = ApiWebsocketMessage(
|
||||
type: type,
|
||||
move: null,
|
||||
color: ApiColor.fromJson(json['color']),
|
||||
reason: null);
|
||||
type: type,
|
||||
move: null,
|
||||
color: ApiColor.fromJson(json['color']),
|
||||
reason: null,
|
||||
position: null,
|
||||
);
|
||||
break;
|
||||
case MessageType.move:
|
||||
ret = ApiWebsocketMessage(
|
||||
type: type,
|
||||
move: ApiMove.fromJson(json['move']),
|
||||
color: null,
|
||||
reason: null);
|
||||
type: type,
|
||||
move: ApiMove.fromJson(json['move']),
|
||||
color: null,
|
||||
reason: null,
|
||||
position: json['position'],
|
||||
);
|
||||
break;
|
||||
case MessageType.invalidMove:
|
||||
ret = ApiWebsocketMessage(
|
||||
@ -53,6 +60,7 @@ class ApiWebsocketMessage {
|
||||
move: ApiMove.fromJson(json['move']),
|
||||
color: null,
|
||||
reason: json['reason'],
|
||||
position: null,
|
||||
);
|
||||
}
|
||||
return ret;
|
||||
|
@ -21,7 +21,7 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
||||
on<InitBoard>(initBoard);
|
||||
on<ColorDetermined>(flipBoard);
|
||||
on<ReceivedMove>(moveHandler);
|
||||
on<ReceivedPromotion>(promotionHandler);
|
||||
on<ReceivedPosition>(positionHandler);
|
||||
on<OwnPieceMoved>(ownMoveHandler);
|
||||
on<OwnPromotionPlayed>(ownPromotionHandler);
|
||||
on<InvalidMovePlayed>(invalidMoveHandler);
|
||||
@ -49,96 +49,18 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
||||
}
|
||||
|
||||
void moveHandler(ReceivedMove event, Emitter<ChessBoardState> emit) {
|
||||
log('opponentMoveHandler()');
|
||||
|
||||
var move = ChessMove(from: event.startSquare, to: event.endSquare);
|
||||
bool wasEnPassant = move.wasEnPassant();
|
||||
bool wasCastling = move.wasCastling();
|
||||
|
||||
var oldPosition = ChessPosition.getInstance().copyOfCurrentPosition;
|
||||
ChessPosition.getInstance().recordMove(event.startSquare, event.endSquare);
|
||||
var newPosition = ChessPosition.getInstance().currentPosition;
|
||||
|
||||
if (wasEnPassant) {
|
||||
if (turnColor == ChessColor.white) {
|
||||
newPosition[ChessCoordinate(
|
||||
event.endSquare.column, event.endSquare.row - 1)] =
|
||||
const ChessPiece.none();
|
||||
} else {
|
||||
newPosition[ChessCoordinate(
|
||||
event.endSquare.column, event.endSquare.row + 1)] =
|
||||
const ChessPiece.none();
|
||||
}
|
||||
} else if (wasCastling) {
|
||||
ChessPiece rookToMove;
|
||||
ChessPiece kingToMove;
|
||||
if (move.to.column == 7) {
|
||||
rookToMove = oldPosition[ChessCoordinate(8, move.to.row)]!;
|
||||
newPosition[ChessCoordinate(6, move.to.row)] = rookToMove;
|
||||
newPosition[ChessCoordinate(8, move.to.row)] = const ChessPiece.none();
|
||||
|
||||
kingToMove = oldPosition[ChessCoordinate(5, move.to.row)]!;
|
||||
newPosition[ChessCoordinate(7, move.to.row)] = kingToMove;
|
||||
newPosition[ChessCoordinate(5, move.to.row)] = const ChessPiece.none();
|
||||
}
|
||||
if (move.to.column == 3) {
|
||||
rookToMove = oldPosition[ChessCoordinate(1, move.to.row)]!;
|
||||
newPosition[ChessCoordinate(4, move.to.row)] = rookToMove;
|
||||
newPosition[ChessCoordinate(1, move.to.row)] = const ChessPiece.none();
|
||||
|
||||
kingToMove = oldPosition[ChessCoordinate(5, move.to.row)]!;
|
||||
newPosition[ChessCoordinate(3, move.to.row)] = kingToMove;
|
||||
newPosition[ChessCoordinate(5, move.to.row)] = const ChessPiece.none();
|
||||
}
|
||||
}
|
||||
|
||||
turnColor = state.newTurnColor == ChessColor.white
|
||||
? ChessColor.black
|
||||
: ChessColor.white;
|
||||
|
||||
emit(
|
||||
ChessBoardState(
|
||||
state.bottomColor,
|
||||
turnColor,
|
||||
newPosition,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void promotionHandler(
|
||||
ReceivedPromotion event,
|
||||
void positionHandler(
|
||||
ReceivedPosition event,
|
||||
Emitter<ChessBoardState> emit,
|
||||
) {
|
||||
var pieceAtStartSquare = ChessPosition.getInstance().getPieceAt(
|
||||
ChessCoordinate(event.startSquare.column, event.startSquare.row));
|
||||
if (pieceAtStartSquare == null) {
|
||||
log('received a promotion but start square was empty');
|
||||
return;
|
||||
}
|
||||
|
||||
ChessPieceClass pieceClass = ChessPieceClass.none;
|
||||
for (var piece in chessPiecesShortName.entries) {
|
||||
if (piece.value == event.piece) {
|
||||
pieceClass = piece.key.pieceClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var newPosition = ChessPosition.getInstance().currentPosition;
|
||||
newPosition[
|
||||
ChessCoordinate(event.startSquare.column, event.startSquare.row)] =
|
||||
const ChessPiece.none();
|
||||
newPosition[ChessCoordinate(event.endSquare.column, event.endSquare.row)] =
|
||||
ChessPiece(pieceClass, pieceAtStartSquare.color);
|
||||
|
||||
turnColor = state.newTurnColor == ChessColor.white
|
||||
? ChessColor.black
|
||||
: ChessColor.white;
|
||||
|
||||
emit(ChessBoardState(
|
||||
state.bottomColor,
|
||||
turnColor,
|
||||
newPosition,
|
||||
));
|
||||
emit(ChessBoardState(state.bottomColor, turnColor, event.position));
|
||||
}
|
||||
|
||||
void ownMoveHandler(OwnPieceMoved event, Emitter<ChessBoardState> emit) {
|
||||
@ -146,7 +68,12 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
||||
var apiMove =
|
||||
ChessMove(from: event.startSquare, to: event.endSquare).toApiMove();
|
||||
var apiMessage = ApiWebsocketMessage(
|
||||
type: MessageType.move, move: apiMove, color: null, reason: null);
|
||||
type: MessageType.move,
|
||||
move: apiMove,
|
||||
color: null,
|
||||
reason: null,
|
||||
position: null,
|
||||
);
|
||||
|
||||
ServerConnection.getInstance().send(jsonEncode(apiMessage));
|
||||
|
||||
@ -176,6 +103,7 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
||||
move: apiMove,
|
||||
color: null,
|
||||
reason: null,
|
||||
position: null,
|
||||
);
|
||||
log(jsonEncode(message));
|
||||
ServerConnection.getInstance().send(jsonEncode(message));
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:mchess/chess_bloc/chess_position.dart';
|
||||
import 'package:mchess/utils/chess_utils.dart';
|
||||
|
||||
abstract class ChessEvent {}
|
||||
@ -9,15 +10,10 @@ class ReceivedMove extends ChessEvent {
|
||||
ReceivedMove({required this.startSquare, required this.endSquare});
|
||||
}
|
||||
|
||||
class ReceivedPromotion extends ChessEvent {
|
||||
final ChessCoordinate startSquare;
|
||||
final ChessCoordinate endSquare;
|
||||
final String piece;
|
||||
class ReceivedPosition extends ChessEvent {
|
||||
final ChessPositionType position;
|
||||
|
||||
ReceivedPromotion(
|
||||
{required this.startSquare,
|
||||
required this.endSquare,
|
||||
required this.piece});
|
||||
ReceivedPosition({required this.position});
|
||||
}
|
||||
|
||||
class OwnPieceMoved extends ChessEvent {
|
||||
|
@ -1,31 +1,96 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:mchess/utils/chess_utils.dart';
|
||||
|
||||
typedef ChessPositionType = Map<ChessCoordinate, ChessPiece>;
|
||||
typedef ChessMoveHistory = List<ChessMove>;
|
||||
typedef ChessPositionType = Map<ChessCoordinate, ChessPiece>;
|
||||
|
||||
class ChessPosition {
|
||||
static ChessPosition _instance = ChessPosition._internal();
|
||||
static ChessMoveHistory history = ChessMoveHistory.empty(growable: true);
|
||||
final ChessPositionType position;
|
||||
|
||||
static ChessPosition getInstance() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
ChessPosition({required this.position});
|
||||
|
||||
factory ChessPosition._internal() {
|
||||
return ChessPosition(position: _getStartingPosition());
|
||||
}
|
||||
|
||||
ChessPositionType get currentPosition => position;
|
||||
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<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(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 = {};
|
||||
|
||||
@ -72,48 +137,4 @@ class ChessPosition {
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
ChessPiece? getPieceAt(ChessCoordinate coordinate) {
|
||||
return position[ChessCoordinate(coordinate.column, coordinate.row)];
|
||||
}
|
||||
|
||||
void resetToStartingPosition() {
|
||||
history = ChessMoveHistory.empty(growable: true);
|
||||
_instance = ChessPosition(position: _getStartingPosition());
|
||||
}
|
||||
|
||||
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 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 logHistory(ChessMoveHistory hist) {
|
||||
for (var element in hist) {
|
||||
log('${element.from.toAlphabetical()} -> ${element.to.toAlphabetical()}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import 'package:mchess/api/websocket_message.dart';
|
||||
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
||||
import 'package:mchess/chess_bloc/chess_events.dart';
|
||||
import 'package:mchess/api/register.dart';
|
||||
import 'package:mchess/chess_bloc/chess_position.dart';
|
||||
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
||||
import 'package:mchess/utils/chess_utils.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
@ -86,15 +87,13 @@ class ServerConnection {
|
||||
void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) {
|
||||
var move = ChessMove.fromApiMove(apiMessage.move!);
|
||||
|
||||
if (apiMessage.move?.promotionToPiece?.isNotEmpty ?? false) {
|
||||
ChessBloc.getInstance().add(ReceivedPromotion(
|
||||
startSquare: move.from,
|
||||
endSquare: move.to,
|
||||
piece: apiMessage.move!.promotionToPiece!));
|
||||
} else {
|
||||
ChessBloc.getInstance()
|
||||
.add(ReceivedMove(startSquare: move.from, endSquare: move.to));
|
||||
if (apiMessage.position != null) {
|
||||
ChessBloc.getInstance().add(ReceivedPosition(
|
||||
position:
|
||||
ChessPosition.getInstance().fromPGNString(apiMessage.position!)));
|
||||
}
|
||||
ChessBloc.getInstance()
|
||||
.add(ReceivedMove(startSquare: move.from, endSquare: move.to));
|
||||
}
|
||||
|
||||
void handleInvalidMoveMessage(ApiWebsocketMessage apiMessage) {
|
||||
|
@ -13,25 +13,6 @@ class LobbySelector extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
//We deactivate random lobbies for now.
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// context.push('/prepareRandom');
|
||||
// },
|
||||
// child: const Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// Icon(Icons.question_mark),
|
||||
// SizedBox(
|
||||
// width: 10,
|
||||
// ),
|
||||
// Text('Random')
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(
|
||||
// height: 25,
|
||||
// ),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
_dialogBuilder(context);
|
||||
@ -43,7 +24,7 @@ class LobbySelector extends StatelessWidget {
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text('Private')
|
||||
Text('Private game')
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -4,57 +4,6 @@ import 'package:mchess/api/move.dart';
|
||||
import 'package:mchess/api/websocket_message.dart';
|
||||
import 'package:quiver/core.dart';
|
||||
|
||||
import '../chess_bloc/chess_position.dart';
|
||||
|
||||
enum ChessPieceClass {
|
||||
none,
|
||||
pawn,
|
||||
bishop,
|
||||
knight,
|
||||
rook,
|
||||
queen,
|
||||
king,
|
||||
}
|
||||
|
||||
class ChessPieceAssetKey {
|
||||
final ChessPieceClass pieceClass;
|
||||
final ChessColor color;
|
||||
|
||||
ChessPieceAssetKey({required this.pieceClass, required this.color});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return (other is ChessPieceAssetKey &&
|
||||
(pieceClass == other.pieceClass) &&
|
||||
(color == other.color));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hash2(pieceClass, color);
|
||||
}
|
||||
}
|
||||
|
||||
enum ChessColor {
|
||||
black,
|
||||
white;
|
||||
|
||||
static ChessColor fromApiColor(ApiColor color) {
|
||||
if (color == ApiColor.black) {
|
||||
return black;
|
||||
} else {
|
||||
return white;
|
||||
}
|
||||
}
|
||||
|
||||
ChessColor getOpposite() {
|
||||
if (name == 'black') {
|
||||
return white;
|
||||
} else {
|
||||
return black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<ChessPieceAssetKey, String> chessPiecesAssets = {
|
||||
ChessPieceAssetKey(
|
||||
@ -166,12 +115,56 @@ Map<ChessPieceAssetKey, String> chessPiecesShortName = {
|
||||
): '-',
|
||||
};
|
||||
|
||||
Map<String, ChessPiece> pieceFromShortname = {
|
||||
'P': ChessPiece(ChessPieceClass.pawn, ChessColor.white),
|
||||
'R': ChessPiece(ChessPieceClass.rook, ChessColor.white),
|
||||
'N': ChessPiece(ChessPieceClass.knight, ChessColor.white),
|
||||
'B': ChessPiece(ChessPieceClass.bishop, ChessColor.white),
|
||||
'K': ChessPiece(ChessPieceClass.king, ChessColor.white),
|
||||
'Q': ChessPiece(ChessPieceClass.queen, ChessColor.white),
|
||||
'p': ChessPiece(ChessPieceClass.pawn, ChessColor.black),
|
||||
'r': ChessPiece(ChessPieceClass.rook, ChessColor.black),
|
||||
'n': ChessPiece(ChessPieceClass.knight, ChessColor.black),
|
||||
'b': ChessPiece(ChessPieceClass.bishop, ChessColor.black),
|
||||
'k': ChessPiece(ChessPieceClass.king, ChessColor.black),
|
||||
'q': ChessPiece(ChessPieceClass.queen, ChessColor.black),
|
||||
};
|
||||
|
||||
enum ChessColor {
|
||||
black,
|
||||
white;
|
||||
|
||||
ChessColor getOpposite() {
|
||||
if (name == 'black') {
|
||||
return white;
|
||||
} else {
|
||||
return black;
|
||||
}
|
||||
}
|
||||
|
||||
static ChessColor fromApiColor(ApiColor color) {
|
||||
if (color == ApiColor.black) {
|
||||
return black;
|
||||
} else {
|
||||
return white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChessCoordinate {
|
||||
final int column;
|
||||
final int row;
|
||||
|
||||
ChessCoordinate(this.column, this.row);
|
||||
|
||||
ChessCoordinate.copyFrom(ChessCoordinate original)
|
||||
: column = original.column,
|
||||
row = original.row;
|
||||
|
||||
factory ChessCoordinate.fromApiCoordinate(ApiCoordinate apiCoordinate) {
|
||||
return ChessCoordinate(apiCoordinate.col, apiCoordinate.row);
|
||||
}
|
||||
|
||||
factory ChessCoordinate.fromString(String coordString) {
|
||||
var column = int.parse(coordString[0]);
|
||||
var row = int.parse(coordString[1]);
|
||||
@ -179,38 +172,16 @@ class ChessCoordinate {
|
||||
return ChessCoordinate(column, row);
|
||||
}
|
||||
|
||||
factory ChessCoordinate.fromApiCoordinate(ApiCoordinate apiCoordinate) {
|
||||
return ChessCoordinate(apiCoordinate.col, apiCoordinate.row);
|
||||
}
|
||||
|
||||
ApiCoordinate toApiCoordinate() {
|
||||
return ApiCoordinate(col: column, row: row);
|
||||
}
|
||||
|
||||
ChessCoordinate.copyFrom(ChessCoordinate original)
|
||||
: column = original.column,
|
||||
row = original.row;
|
||||
|
||||
static String columnIntToColumnString(int col) {
|
||||
String colStr;
|
||||
|
||||
colStr = String.fromCharCode(col + 96);
|
||||
|
||||
return colStr;
|
||||
}
|
||||
|
||||
static int columnStringToColumnInt(String col) {
|
||||
int colInt;
|
||||
colInt = col.codeUnitAt(0) - 96;
|
||||
return colInt;
|
||||
@override
|
||||
int get hashCode {
|
||||
return hash2(column, row);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
String rowStr = row.toString();
|
||||
String colStr = column.toString();
|
||||
|
||||
return '$colStr$rowStr';
|
||||
operator ==(other) {
|
||||
return other is ChessCoordinate &&
|
||||
other.column == column &&
|
||||
other.row == row;
|
||||
}
|
||||
|
||||
String toAlphabetical() {
|
||||
@ -230,16 +201,61 @@ class ChessCoordinate {
|
||||
return '$colStr$rowStr';
|
||||
}
|
||||
|
||||
ApiCoordinate toApiCoordinate() {
|
||||
return ApiCoordinate(col: column, row: row);
|
||||
}
|
||||
|
||||
@override
|
||||
operator ==(other) {
|
||||
return other is ChessCoordinate &&
|
||||
other.column == column &&
|
||||
other.row == row;
|
||||
String toString() {
|
||||
String rowStr = row.toString();
|
||||
String colStr = column.toString();
|
||||
|
||||
return '$colStr$rowStr';
|
||||
}
|
||||
|
||||
static String columnIntToColumnString(int col) {
|
||||
String colStr;
|
||||
|
||||
colStr = String.fromCharCode(col + 96);
|
||||
|
||||
return colStr;
|
||||
}
|
||||
|
||||
static int columnStringToColumnInt(String col) {
|
||||
int colInt;
|
||||
colInt = col.codeUnitAt(0) - 96;
|
||||
return colInt;
|
||||
}
|
||||
}
|
||||
|
||||
class ChessMove {
|
||||
ChessCoordinate from;
|
||||
ChessCoordinate to;
|
||||
|
||||
ChessMove({required this.from, required this.to});
|
||||
|
||||
factory ChessMove.fromApiMove(ApiMove apiMove) {
|
||||
final start = ChessCoordinate.fromApiCoordinate(apiMove.startSquare);
|
||||
final end = ChessCoordinate.fromApiCoordinate(apiMove.endSquare);
|
||||
|
||||
return ChessMove(from: start, to: end);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hash2(column, row);
|
||||
return hash2(from, to);
|
||||
}
|
||||
|
||||
@override
|
||||
operator ==(other) {
|
||||
return other is ChessMove && other.from == from && other.to == to;
|
||||
}
|
||||
|
||||
ApiMove toApiMove() {
|
||||
var toSquare = to.toApiCoordinate();
|
||||
var fromSquare = from.toApiCoordinate();
|
||||
return ApiMove(
|
||||
startSquare: fromSquare, endSquare: toSquare, promotionToPiece: null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,9 +265,6 @@ class ChessPiece extends StatelessWidget {
|
||||
final String shortName;
|
||||
final Widget? pieceImage;
|
||||
|
||||
const ChessPiece._(
|
||||
this.pieceClass, this.color, this.pieceImage, this.shortName);
|
||||
|
||||
factory ChessPiece(ChessPieceClass pieceClass, ChessColor color) {
|
||||
Widget? pieceImage;
|
||||
String pieceAssetUrl = chessPiecesAssets[
|
||||
@ -269,6 +282,9 @@ class ChessPiece extends StatelessWidget {
|
||||
pieceImage = null,
|
||||
shortName = "-";
|
||||
|
||||
const ChessPiece._(
|
||||
this.pieceClass, this.color, this.pieceImage, this.shortName);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
@ -277,58 +293,33 @@ class ChessPiece extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class ChessMove {
|
||||
ChessCoordinate from;
|
||||
ChessCoordinate to;
|
||||
class ChessPieceAssetKey {
|
||||
final ChessPieceClass pieceClass;
|
||||
final ChessColor color;
|
||||
|
||||
ChessMove({required this.from, required this.to});
|
||||
|
||||
factory ChessMove.fromApiMove(ApiMove apiMove) {
|
||||
final start = ChessCoordinate.fromApiCoordinate(apiMove.startSquare);
|
||||
final end = ChessCoordinate.fromApiCoordinate(apiMove.endSquare);
|
||||
|
||||
return ChessMove(from: start, to: end);
|
||||
}
|
||||
|
||||
ApiMove toApiMove() {
|
||||
var toSquare = to.toApiCoordinate();
|
||||
var fromSquare = from.toApiCoordinate();
|
||||
return ApiMove(
|
||||
startSquare: fromSquare, endSquare: toSquare, promotionToPiece: null);
|
||||
}
|
||||
|
||||
@override
|
||||
operator ==(other) {
|
||||
return other is ChessMove && other.from == from && other.to == to;
|
||||
}
|
||||
ChessPieceAssetKey({required this.pieceClass, required this.color});
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hash2(from, to);
|
||||
return hash2(pieceClass, color);
|
||||
}
|
||||
|
||||
bool wasEnPassant() {
|
||||
var pieceMoved = ChessPosition.getInstance().getPieceAt(from);
|
||||
var pieceAtEndSquare = ChessPosition.getInstance().getPieceAt(to);
|
||||
if (pieceMoved != null &&
|
||||
pieceMoved.pieceClass == ChessPieceClass.pawn &&
|
||||
pieceAtEndSquare == null &&
|
||||
from.column != to.column) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return (other is ChessPieceAssetKey &&
|
||||
(pieceClass == other.pieceClass) &&
|
||||
(color == other.color));
|
||||
}
|
||||
}
|
||||
|
||||
bool wasCastling() {
|
||||
var pieceMoved = ChessPosition.getInstance().getPieceAt(from);
|
||||
if (pieceMoved != null && pieceMoved.pieceClass == ChessPieceClass.king) {
|
||||
var colDiff = (from.column - to.column).abs();
|
||||
if (colDiff == 2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
enum ChessPieceClass {
|
||||
none,
|
||||
pawn,
|
||||
bishop,
|
||||
knight,
|
||||
rook,
|
||||
queen,
|
||||
king,
|
||||
}
|
||||
|
||||
class PieceDragged {
|
||||
|
Loading…
Reference in New Issue
Block a user