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.
This commit is contained in:
Marco 2023-08-19 03:45:03 +02:00
parent 80fe378241
commit 7c5439a635
6 changed files with 103 additions and 63 deletions

View File

@ -12,23 +12,30 @@ class ChessBoard extends StatelessWidget {
const ChessBoard._({required this.bState, required this.squares}); const ChessBoard._({required this.bState, required this.squares});
factory ChessBoard({required ChessBoardState bState}) { factory ChessBoard({required ChessBoardState boardState}) {
List<ChessSquare> squares = List.empty(growable: true); List<ChessSquare> squares = List.empty(growable: true);
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
var column = (i % 8) + 1; var column = (i % 8) + 1;
var row = (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( squares.add(
ChessSquare( ChessSquare(
ChessCoordinate(column, row), ChessCoordinate(column, row),
piece, piece,
squareWasPartOfLastMove,
), ),
); );
} }
return ChessBoard._(bState: bState, squares: squares); return ChessBoard._(bState: boardState, squares: squares);
} }
@override @override

View File

@ -15,28 +15,32 @@ class ChessSquare extends StatelessWidget {
final Color color; final Color color;
const ChessSquare._( const ChessSquare._({
{required this.coordinate, required this.coordinate,
required this.containedPiece, required this.containedPiece,
required this.color}); required this.color,
});
factory ChessSquare(ChessCoordinate coord, ChessPiece? piece) { factory ChessSquare(
Color lightSquares = Colors.brown.shade50; ChessCoordinate coord, ChessPiece? piece, bool wasPartOfLastMove) {
Color darkSquares = Colors.brown.shade400; Color lightSquaresColor =
wasPartOfLastMove ? Colors.green.shade200 : Colors.brown.shade50;
Color darkSquaresColor =
wasPartOfLastMove ? Colors.green.shade300 : Colors.brown.shade400;
Color squareColor; Color squareColor;
if (coord.row % 2 == 0) { if (coord.row % 2 == 0) {
if (coord.column % 2 == 0) { if (coord.column % 2 == 0) {
squareColor = darkSquares; squareColor = darkSquaresColor;
} else { } else {
squareColor = lightSquares; squareColor = lightSquaresColor;
} }
} else { } else {
if (coord.column % 2 == 0) { if (coord.column % 2 == 0) {
squareColor = lightSquares; squareColor = lightSquaresColor;
} else { } else {
squareColor = darkSquares; squareColor = darkSquaresColor;
} }
} }

View File

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mchess/api/websocket_message.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/chess_bloc/chess_position.dart';
import 'package:mchess/connection/ws_connection.dart'; import 'package:mchess/connection/ws_connection.dart';
import 'package:mchess/utils/chess_utils.dart'; import 'package:mchess/utils/chess_utils.dart';
import 'dart:developer';
class ChessBloc extends Bloc<ChessEvent, ChessBoardState> { class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
static final ChessBloc _instance = ChessBloc._internal(); static final ChessBloc _instance = ChessBloc._internal();
@ -37,26 +37,47 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
void initBoard(InitBoard event, Emitter<ChessBoardState> emit) { void initBoard(InitBoard event, Emitter<ChessBoardState> emit) {
turnColor = ChessColor.white; turnColor = ChessColor.white;
ChessPositionManager.getInstance().resetToStartingPosition(); ChessPositionManager.getInstance().resetToStartingPosition();
emit(ChessBoardState(ChessColor.white, ChessColor.white, emit(
ChessPositionManager.getInstance().currentPosition)); ChessBoardState(
ChessColor.white,
ChessColor.white,
ChessPositionManager.getInstance().currentPosition,
ChessMove.none(),
),
);
} }
void flipBoard(ColorDetermined event, Emitter<ChessBoardState> emit) { void flipBoard(ColorDetermined event, Emitter<ChessBoardState> emit) {
log("My Color is $myColor"); log("My Color is $myColor");
myColor = event.myColor; myColor = event.myColor;
emit(ChessBoardState(event.myColor, state.newTurnColor, state.position)); emit(
ChessBoardState(
event.myColor,
state.newTurnColor,
state.position,
ChessMove.none(),
),
);
} }
void moveAndPositionHandler( void moveAndPositionHandler(
ReceivedMove event, ReceivedMove event,
Emitter<ChessBoardState> emit, Emitter<ChessBoardState> emit,
) { ) {
ChessPositionManager.getInstance().recordMove(event.startSquare, event.endSquare, event.position); ChessPositionManager.getInstance()
.recordMove(event.startSquare, event.endSquare, event.position);
turnColor = state.newTurnColor == ChessColor.white turnColor = state.newTurnColor == ChessColor.white
? ChessColor.black ? ChessColor.black
: ChessColor.white; : 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<ChessBoardState> emit) { void ownMoveHandler(OwnPieceMoved event, Emitter<ChessBoardState> emit) {
@ -84,6 +105,7 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
state.bottomColor, state.bottomColor,
turnColor, turnColor,
tempPosition, tempPosition,
move
), ),
); );
} }
@ -108,28 +130,28 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
void invalidMoveHandler( void invalidMoveHandler(
InvalidMovePlayed event, Emitter<ChessBoardState> emit) { InvalidMovePlayed event, Emitter<ChessBoardState> emit) {
emit( emit(
ChessBoardState( ChessBoardState(state.bottomColor, turnColor,
state.bottomColor, ChessPositionManager.getInstance().currentPosition, ChessMove.none()),
turnColor,
ChessPositionManager.getInstance().currentPosition,
),
); );
} }
} }
class ChessBoardState { class ChessBoardState {
late ChessColor bottomColor; final ChessColor bottomColor;
final ChessColor newTurnColor; final ChessColor newTurnColor;
final ChessPosition position; final ChessPosition position;
final ChessMove lastMove;
ChessBoardState._(this.bottomColor, this.newTurnColor, this.position); ChessBoardState._(
this.bottomColor, this.newTurnColor, this.position, this.lastMove);
factory ChessBoardState( factory ChessBoardState(
ChessColor bottomColor, ChessColor bottomColor,
ChessColor turnColor, ChessColor turnColor,
Map<ChessCoordinate, ChessPiece> position, ChessPosition position,
ChessMove lastMove,
) { ) {
return ChessBoardState._(bottomColor, turnColor, position); return ChessBoardState._(bottomColor, turnColor, position, lastMove);
} }
factory ChessBoardState.init() { factory ChessBoardState.init() {
@ -139,7 +161,11 @@ class ChessBoardState {
ChessPositionManager.getInstance().resetToStartingPosition(); ChessPositionManager.getInstance().resetToStartingPosition();
return ChessBoardState( return ChessBoardState(
bottomColor, turnColor, ChessPositionManager.getInstance().currentPosition); bottomColor,
turnColor,
ChessPositionManager.getInstance().currentPosition,
ChessMove.none(),
);
} }
void logPosition(Map<ChessCoordinate, ChessPiece> pos) { void logPosition(Map<ChessCoordinate, ChessPiece> pos) {

View File

@ -52,7 +52,7 @@ class _ChessGameState extends State<ChessGame> {
child: BlocBuilder<ChessBloc, ChessBoardState>( child: BlocBuilder<ChessBloc, ChessBoardState>(
builder: (context, state) { builder: (context, state) {
return ChessBoard( return ChessBoard(
bState: state, boardState: state,
); );
}, },
), ),

View File

@ -4,7 +4,6 @@ import 'package:mchess/api/move.dart';
import 'package:mchess/api/websocket_message.dart'; import 'package:mchess/api/websocket_message.dart';
import 'package:quiver/core.dart'; import 'package:quiver/core.dart';
Map<ChessPieceAssetKey, String> chessPiecesAssets = { Map<ChessPieceAssetKey, String> chessPiecesAssets = {
ChessPieceAssetKey( ChessPieceAssetKey(
pieceClass: ChessPieceClass.pawn, pieceClass: ChessPieceClass.pawn,
@ -241,6 +240,10 @@ class ChessMove {
return ChessMove(from: start, to: end); return ChessMove(from: start, to: end);
} }
factory ChessMove.none() {
return ChessMove(from: ChessCoordinate(0, 0), to: ChessCoordinate(0, 0));
}
@override @override
int get hashCode { int get hashCode {
return hash2(from, to); return hash2(from, to);

View File

@ -53,10 +53,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.1" version: "1.17.2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -144,14 +144,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.2"
js:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.7"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -172,18 +164,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.15" version: "0.12.16"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.0" version: "0.5.0"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -249,10 +241,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.10.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -289,10 +281,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.6.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -341,6 +333,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" 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: web_socket_channel:
dependency: "direct main" dependency: "direct main"
description: description:
@ -358,5 +358,5 @@ packages:
source: hosted source: hosted
version: "6.3.0" version: "6.3.0"
sdks: sdks:
dart: ">=3.0.0 <4.0.0" dart: ">=3.1.0-185.0.dev <4.0.0"
flutter: ">=3.7.0-0" flutter: ">=3.7.0-0"