From 7c5439a635e9394711e2add808a71e5eb2f3283b Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 19 Aug 2023 03:45:03 +0200 Subject: [PATCH] Display last played move. We now color the squares of the last move. This makes the state of the board clearer and shows whose turn it is. --- lib/chess/chess_board.dart | 13 ++++++-- lib/chess/chess_square.dart | 26 ++++++++------- lib/chess_bloc/chess_bloc.dart | 58 ++++++++++++++++++++++++---------- lib/pages/chess_game.dart | 2 +- lib/utils/chess_utils.dart | 29 +++++++++-------- pubspec.lock | 38 +++++++++++----------- 6 files changed, 103 insertions(+), 63 deletions(-) diff --git a/lib/chess/chess_board.dart b/lib/chess/chess_board.dart index 517a930..d8d556e 100644 --- a/lib/chess/chess_board.dart +++ b/lib/chess/chess_board.dart @@ -12,23 +12,30 @@ class ChessBoard extends StatelessWidget { const ChessBoard._({required this.bState, required this.squares}); - factory ChessBoard({required ChessBoardState bState}) { + factory ChessBoard({required ChessBoardState boardState}) { List squares = List.empty(growable: true); for (int i = 0; i < 64; i++) { var column = (i % 8) + 1; var row = (i ~/ 8) + 1; - final piece = bState.position[ChessCoordinate(column, row)]; + final piece = boardState.position[ChessCoordinate(column, row)]; + + bool squareWasPartOfLastMove = false; + if (boardState.lastMove.to == ChessCoordinate(column, row) || + boardState.lastMove.from == ChessCoordinate(column, row)) { + squareWasPartOfLastMove = true; + } squares.add( ChessSquare( ChessCoordinate(column, row), piece, + squareWasPartOfLastMove, ), ); } - return ChessBoard._(bState: bState, squares: squares); + return ChessBoard._(bState: boardState, squares: squares); } @override diff --git a/lib/chess/chess_square.dart b/lib/chess/chess_square.dart index 5b4046e..3ad360d 100644 --- a/lib/chess/chess_square.dart +++ b/lib/chess/chess_square.dart @@ -15,28 +15,32 @@ class ChessSquare extends StatelessWidget { final Color color; - const ChessSquare._( - {required this.coordinate, - required this.containedPiece, - required this.color}); + const ChessSquare._({ + required this.coordinate, + required this.containedPiece, + required this.color, + }); - factory ChessSquare(ChessCoordinate coord, ChessPiece? piece) { - Color lightSquares = Colors.brown.shade50; - Color darkSquares = Colors.brown.shade400; + factory ChessSquare( + ChessCoordinate coord, ChessPiece? piece, bool wasPartOfLastMove) { + Color lightSquaresColor = + wasPartOfLastMove ? Colors.green.shade200 : Colors.brown.shade50; + Color darkSquaresColor = + wasPartOfLastMove ? Colors.green.shade300 : Colors.brown.shade400; Color squareColor; if (coord.row % 2 == 0) { if (coord.column % 2 == 0) { - squareColor = darkSquares; + squareColor = darkSquaresColor; } else { - squareColor = lightSquares; + squareColor = lightSquaresColor; } } else { if (coord.column % 2 == 0) { - squareColor = lightSquares; + squareColor = lightSquaresColor; } else { - squareColor = darkSquares; + squareColor = darkSquaresColor; } } diff --git a/lib/chess_bloc/chess_bloc.dart b/lib/chess_bloc/chess_bloc.dart index 4861f53..7e8d532 100644 --- a/lib/chess_bloc/chess_bloc.dart +++ b/lib/chess_bloc/chess_bloc.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:mchess/api/websocket_message.dart'; @@ -6,7 +7,6 @@ import 'package:mchess/chess_bloc/chess_events.dart'; import 'package:mchess/chess_bloc/chess_position.dart'; import 'package:mchess/connection/ws_connection.dart'; import 'package:mchess/utils/chess_utils.dart'; -import 'dart:developer'; class ChessBloc extends Bloc { static final ChessBloc _instance = ChessBloc._internal(); @@ -37,26 +37,47 @@ class ChessBloc extends Bloc { void initBoard(InitBoard event, Emitter emit) { turnColor = ChessColor.white; ChessPositionManager.getInstance().resetToStartingPosition(); - emit(ChessBoardState(ChessColor.white, ChessColor.white, - ChessPositionManager.getInstance().currentPosition)); + emit( + ChessBoardState( + ChessColor.white, + ChessColor.white, + ChessPositionManager.getInstance().currentPosition, + ChessMove.none(), + ), + ); } void flipBoard(ColorDetermined event, Emitter emit) { log("My Color is $myColor"); myColor = event.myColor; - emit(ChessBoardState(event.myColor, state.newTurnColor, state.position)); + emit( + ChessBoardState( + event.myColor, + state.newTurnColor, + state.position, + ChessMove.none(), + ), + ); } void moveAndPositionHandler( ReceivedMove event, Emitter emit, ) { - ChessPositionManager.getInstance().recordMove(event.startSquare, event.endSquare, event.position); + ChessPositionManager.getInstance() + .recordMove(event.startSquare, event.endSquare, event.position); turnColor = state.newTurnColor == ChessColor.white ? ChessColor.black : ChessColor.white; - emit(ChessBoardState(state.bottomColor, turnColor, event.position)); + emit( + ChessBoardState( + state.bottomColor, + turnColor, + event.position, + ChessMove(from: event.startSquare, to: event.endSquare), + ), + ); } void ownMoveHandler(OwnPieceMoved event, Emitter emit) { @@ -84,6 +105,7 @@ class ChessBloc extends Bloc { state.bottomColor, turnColor, tempPosition, + move ), ); } @@ -108,28 +130,28 @@ class ChessBloc extends Bloc { void invalidMoveHandler( InvalidMovePlayed event, Emitter emit) { emit( - ChessBoardState( - state.bottomColor, - turnColor, - ChessPositionManager.getInstance().currentPosition, - ), + ChessBoardState(state.bottomColor, turnColor, + ChessPositionManager.getInstance().currentPosition, ChessMove.none()), ); } } class ChessBoardState { - late ChessColor bottomColor; + final ChessColor bottomColor; final ChessColor newTurnColor; final ChessPosition position; + final ChessMove lastMove; - ChessBoardState._(this.bottomColor, this.newTurnColor, this.position); + ChessBoardState._( + this.bottomColor, this.newTurnColor, this.position, this.lastMove); factory ChessBoardState( ChessColor bottomColor, ChessColor turnColor, - Map position, + ChessPosition position, + ChessMove lastMove, ) { - return ChessBoardState._(bottomColor, turnColor, position); + return ChessBoardState._(bottomColor, turnColor, position, lastMove); } factory ChessBoardState.init() { @@ -139,7 +161,11 @@ class ChessBoardState { ChessPositionManager.getInstance().resetToStartingPosition(); return ChessBoardState( - bottomColor, turnColor, ChessPositionManager.getInstance().currentPosition); + bottomColor, + turnColor, + ChessPositionManager.getInstance().currentPosition, + ChessMove.none(), + ); } void logPosition(Map pos) { diff --git a/lib/pages/chess_game.dart b/lib/pages/chess_game.dart index d48928e..2cef650 100644 --- a/lib/pages/chess_game.dart +++ b/lib/pages/chess_game.dart @@ -52,7 +52,7 @@ class _ChessGameState extends State { child: BlocBuilder( builder: (context, state) { return ChessBoard( - bState: state, + boardState: state, ); }, ), diff --git a/lib/utils/chess_utils.dart b/lib/utils/chess_utils.dart index ffc0a49..7d1916e 100644 --- a/lib/utils/chess_utils.dart +++ b/lib/utils/chess_utils.dart @@ -4,7 +4,6 @@ import 'package:mchess/api/move.dart'; import 'package:mchess/api/websocket_message.dart'; import 'package:quiver/core.dart'; - Map chessPiecesAssets = { ChessPieceAssetKey( pieceClass: ChessPieceClass.pawn, @@ -116,18 +115,18 @@ Map chessPiecesShortName = { }; Map 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), + '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 { @@ -241,6 +240,10 @@ class ChessMove { return ChessMove(from: start, to: end); } + factory ChessMove.none() { + return ChessMove(from: ChessCoordinate(0, 0), to: ChessCoordinate(0, 0)); + } + @override int get hashCode { return hash2(from, to); diff --git a/pubspec.lock b/pubspec.lock index 916a65a..7aa76cc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.17.2" crypto: dependency: transitive description: @@ -144,14 +144,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" - source: hosted - version: "0.6.7" lints: dependency: transitive description: @@ -172,18 +164,18 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: @@ -249,10 +241,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: @@ -289,10 +281,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.0" typed_data: dependency: transitive description: @@ -341,6 +333,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" + source: hosted + version: "0.1.4-beta" web_socket_channel: dependency: "direct main" description: @@ -358,5 +358,5 @@ packages: source: hosted version: "6.3.0" sdks: - dart: ">=3.0.0 <4.0.0" + dart: ">=3.1.0-185.0.dev <4.0.0" flutter: ">=3.7.0-0"