Lay foundation for promotions.

This commit is contained in:
Marco 2023-07-01 09:29:43 +02:00
parent 52540ec96c
commit 3bec7a84d8
9 changed files with 389 additions and 121 deletions

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mchess/chess_bloc/chess_bloc.dart'; import 'package:mchess/chess_bloc/chess_bloc.dart';
import 'package:mchess/chess_bloc/promotion_bloc.dart';
import 'package:mchess/connection_cubit/connection_cubit.dart'; import 'package:mchess/connection_cubit/connection_cubit.dart';
import 'package:mchess/utils/chess_router.dart'; import 'package:mchess/utils/chess_router.dart';
@ -9,17 +10,24 @@ class ChessApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return MultiBlocProvider(
create: (_) => ConnectionCubit.getInstance(), providers: [
child: BlocProvider( BlocProvider(
create: (_) => ChessBloc.getInstance(), create: (_) => ConnectionCubit.getInstance(),
child: MaterialApp.router(
theme: ThemeData.dark(
useMaterial3: true,
),
routerConfig: ChessAppRouter.getInstance().router,
title: 'mChess',
), ),
BlocProvider(
create: (context) => ChessBloc.getInstance(),
),
BlocProvider(
create: (context) => PromotionUiBloc.getInstance(),
)
],
child: MaterialApp.router(
theme: ThemeData.dark(
useMaterial3: true,
),
routerConfig: ChessAppRouter.getInstance().router,
title: 'mChess',
), ),
); );
} }

View File

@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mchess/chess_bloc/chess_bloc.dart'; import 'package:mchess/chess_bloc/chess_bloc.dart';
import 'package:mchess/chess_bloc/promotion_bloc.dart';
import '../chess_bloc/chess_events.dart'; import '../chess_bloc/chess_events.dart';
import '../utils/chess_utils.dart'; import '../utils/chess_utils.dart';
@ -58,7 +59,7 @@ class ChessSquare extends StatelessWidget {
draggableFdbSize = 0.15 * windowHeight; draggableFdbSize = 0.15 * windowHeight;
} }
return DragTarget<PieceMovedFrom>( return DragTarget<PieceDragged>(
onWillAccept: (move) { onWillAccept: (move) {
if (move?.fromSquare == coordinate) { if (move?.fromSquare == coordinate) {
return false; return false;
@ -66,9 +67,17 @@ class ChessSquare extends StatelessWidget {
return true; return true;
}, },
onAccept: (move) { onAccept: (move) {
if (coordinate != move.fromSquare) { // Replace the dummy value with the actual target of the move.
move.toSquare = coordinate;
if (isPromotionMove(move)) {
PromotionUiBloc.getInstance().add(PawnMovedToPromotionField(
endSquare: move.toSquare, colorMoved: ChessBloc.myColor!));
} else if (coordinate != move.fromSquare) {
ChessBloc.getInstance().add(OwnPieceMoved( ChessBloc.getInstance().add(OwnPieceMoved(
startSquare: move.fromSquare, endSquare: coordinate)); startSquare: move.fromSquare,
endSquare: move.toSquare,
piece: containedPiece!));
} }
}, },
builder: (context, candidateData, rejectedData) { builder: (context, candidateData, rejectedData) {
@ -79,9 +88,9 @@ class ChessSquare extends StatelessWidget {
color: color, color: color,
width: ChessSquare.pieceWidth, width: ChessSquare.pieceWidth,
height: ChessSquare.pieceWidth, height: ChessSquare.pieceWidth,
child: Draggable<PieceMovedFrom>( child: Draggable<PieceDragged>(
/* We create the move with the startSquare == endSquare. The receiving widget will give the correct value to end square. */ /* We create the move with the startSquare == endSquare. The receiving widget will give the correct value to end square. */
data: PieceMovedFrom(coordinate, containedPiece), data: PieceDragged(coordinate, coordinate, containedPiece),
maxSimultaneousDrags: maxDrags, maxSimultaneousDrags: maxDrags,
feedback: FractionalTranslation( feedback: FractionalTranslation(
translation: const Offset(-0.5, -0.75), translation: const Offset(-0.5, -0.75),
@ -100,4 +109,28 @@ class ChessSquare extends StatelessWidget {
}, },
); );
} }
bool isPromotionMove(PieceDragged move) {
bool isPromotion = false;
if (move.movedPiece!.pieceClass != ChessPieceClass.pawn) {
return isPromotion;
}
switch (ChessBloc.myColor) {
case ChessColor.black:
if (move.toSquare.row == 1) {
isPromotion = true;
}
break;
case ChessColor.white:
if (move.toSquare.row == 8) {
isPromotion = true;
}
break;
case null:
break;
}
return isPromotion;
}
} }

View File

@ -12,7 +12,7 @@ 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();
static ChessColor turnColor = ChessColor.white; static ChessColor turnColor = ChessColor.white;
static ChessColor? myColor; static ChessColor? myColor = ChessColor.white;
static ChessColor? getSidesColor() { static ChessColor? getSidesColor() {
return myColor; return myColor;
@ -94,8 +94,13 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
void invalidMoveHandler( void invalidMoveHandler(
InvalidMovePlayed event, Emitter<ChessBoardState> emit) { InvalidMovePlayed event, Emitter<ChessBoardState> emit) {
emit(ChessBoardState(state.bottomColor, turnColor, emit(
ChessPosition.getInstance().currentPosition)); ChessBoardState(
state.bottomColor,
turnColor,
ChessPosition.getInstance().currentPosition,
),
);
} }
} }

View File

@ -12,8 +12,12 @@ class ReceivedMove extends ChessEvent {
class OwnPieceMoved extends ChessEvent { class OwnPieceMoved extends ChessEvent {
final ChessCoordinate startSquare; final ChessCoordinate startSquare;
final ChessCoordinate endSquare; final ChessCoordinate endSquare;
final ChessPiece piece;
OwnPieceMoved({required this.startSquare, required this.endSquare}); OwnPieceMoved(
{required this.startSquare,
required this.endSquare,
required this.piece});
} }
class InitBoard extends ChessEvent { class InitBoard extends ChessEvent {

View File

@ -30,45 +30,47 @@ class ChessPosition {
ChessPositionType pos = {}; ChessPositionType pos = {};
for (int i = 1; i <= 8; i++) { for (int i = 1; i <= 8; i++) {
pos[ChessCoordinate(i, 7)] = // pos[ChessCoordinate(i, 7)] =
ChessPiece(ChessPieceName.blackPawn, ChessColor.black); // ChessPiece(ChessPieceName.blackPawn, ChessColor.black);
pos[ChessCoordinate(i, 2)] = // pos[ChessCoordinate(i, 2)] =
ChessPiece(ChessPieceName.whitePawn, ChessColor.white); // ChessPiece(ChessPieceName.whitePawn, ChessColor.white);
} }
pos[ChessCoordinate(1, 7)] =
ChessPiece(ChessPieceClass.pawn, ChessColor.white);
pos[ChessCoordinate(1, 8)] = // pos[ChessCoordinate(1, 8)] =
ChessPiece(ChessPieceName.blackRook, ChessColor.black); // ChessPiece(ChessPieceName.blackRook, ChessColor.black);
pos[ChessCoordinate(2, 8)] = // pos[ChessCoordinate(2, 8)] =
ChessPiece(ChessPieceName.blackKnight, ChessColor.black); // ChessPiece(ChessPieceName.blackKnight, ChessColor.black);
pos[ChessCoordinate(3, 8)] = // pos[ChessCoordinate(3, 8)] =
ChessPiece(ChessPieceName.blackBishop, ChessColor.black); // ChessPiece(ChessPieceName.blackBishop, ChessColor.black);
pos[ChessCoordinate(4, 8)] = // pos[ChessCoordinate(4, 8)] =
ChessPiece(ChessPieceName.blackQueen, ChessColor.black); // ChessPiece(ChessPieceName.blackQueen, ChessColor.black);
pos[ChessCoordinate(5, 8)] = // pos[ChessCoordinate(5, 8)] =
ChessPiece(ChessPieceName.blackKing, ChessColor.black); // ChessPiece(ChessPieceName.blackKing, ChessColor.black);
pos[ChessCoordinate(6, 8)] = // pos[ChessCoordinate(6, 8)] =
ChessPiece(ChessPieceName.blackBishop, ChessColor.black); // ChessPiece(ChessPieceName.blackBishop, ChessColor.black);
pos[ChessCoordinate(7, 8)] = // pos[ChessCoordinate(7, 8)] =
ChessPiece(ChessPieceName.blackKnight, ChessColor.black); // ChessPiece(ChessPieceName.blackKnight, ChessColor.black);
pos[ChessCoordinate(8, 8)] = // pos[ChessCoordinate(8, 8)] =
ChessPiece(ChessPieceName.blackRook, ChessColor.black); // ChessPiece(ChessPieceName.blackRook, ChessColor.black);
pos[ChessCoordinate(1, 1)] = // pos[ChessCoordinate(1, 1)] =
ChessPiece(ChessPieceName.whiteRook, ChessColor.white); // ChessPiece(ChessPieceName.whiteRook, ChessColor.white);
pos[ChessCoordinate(2, 1)] = // pos[ChessCoordinate(2, 1)] =
ChessPiece(ChessPieceName.whiteKnight, ChessColor.white); // ChessPiece(ChessPieceName.whiteKnight, ChessColor.white);
pos[ChessCoordinate(3, 1)] = // pos[ChessCoordinate(3, 1)] =
ChessPiece(ChessPieceName.whiteBishop, ChessColor.white); // ChessPiece(ChessPieceName.whiteBishop, ChessColor.white);
pos[ChessCoordinate(4, 1)] = // pos[ChessCoordinate(4, 1)] =
ChessPiece(ChessPieceName.whiteQueen, ChessColor.white); // ChessPiece(ChessPieceName.whiteQueen, ChessColor.white);
pos[ChessCoordinate(5, 1)] = // pos[ChessCoordinate(5, 1)] =
ChessPiece(ChessPieceName.whiteKing, ChessColor.white); // ChessPiece(ChessPieceName.whiteKing, ChessColor.white);
pos[ChessCoordinate(6, 1)] = // pos[ChessCoordinate(6, 1)] =
ChessPiece(ChessPieceName.whiteBishop, ChessColor.white); // ChessPiece(ChessPieceName.whiteBishop, ChessColor.white);
pos[ChessCoordinate(7, 1)] = // pos[ChessCoordinate(7, 1)] =
ChessPiece(ChessPieceName.whiteKnight, ChessColor.white); // ChessPiece(ChessPieceName.whiteKnight, ChessColor.white);
pos[ChessCoordinate(8, 1)] = // pos[ChessCoordinate(8, 1)] =
ChessPiece(ChessPieceName.whiteRook, ChessColor.white); // ChessPiece(ChessPieceName.whiteRook, ChessColor.white);
return pos; return pos;
} }

View File

@ -0,0 +1,49 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mchess/utils/chess_utils.dart';
class PromotionUiBloc extends Bloc<PromotionEvent, PromotionUiState> {
static final PromotionUiBloc _instance = PromotionUiBloc._internal();
PromotionUiBloc._internal() : super(PromotionUiState.init()) {
on<PawnMovedToPromotionField>(promotionMoveHandler);
}
void promotionMoveHandler(
PawnMovedToPromotionField event,
Emitter<PromotionUiState> emit,
) {
emit(PromotionUiState(
showPromotionDialog: true, colorMoved: event.colorMoved));
}
factory PromotionUiBloc.getInstance() {
return PromotionUiBloc();
}
factory PromotionUiBloc() {
return _instance;
}
}
abstract class PromotionEvent {}
class PawnMovedToPromotionField extends PromotionEvent {
final ChessCoordinate endSquare;
final ChessColor colorMoved;
PawnMovedToPromotionField(
{required this.endSquare, required this.colorMoved});
}
class PromotionUiState {
final bool showPromotionDialog;
final ChessColor colorMoved;
PromotionUiState(
{required this.showPromotionDialog, required this.colorMoved});
factory PromotionUiState.init() {
return PromotionUiState(
showPromotionDialog: false, colorMoved: ChessColor.white);
}
}

View File

@ -6,6 +6,9 @@ import 'package:mchess/chess_bloc/chess_bloc.dart';
import 'package:mchess/chess/chess_board.dart'; import 'package:mchess/chess/chess_board.dart';
import 'package:mchess/chess/turn_indicator_widget.dart'; import 'package:mchess/chess/turn_indicator_widget.dart';
import 'package:mchess/chess_bloc/promotion_bloc.dart';
import 'package:mchess/utils/chess_utils.dart';
import 'package:mchess/utils/widgets/promotion_dialog.dart';
import 'package:mchess/utils/widgets/server_log_widget.dart'; import 'package:mchess/utils/widgets/server_log_widget.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -32,23 +35,32 @@ class _ChessGameState extends State<ChessGame> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: FittedBox( body: Center(
fit: BoxFit.contain, child: FittedBox(
child: Column( fit: BoxFit.contain,
children: [ child: Column(
if (kDebugMode) const ServerLogWidget(textColor: Colors.white), children: [
Container( if (kDebugMode) const ServerLogWidget(textColor: Colors.white),
margin: const EdgeInsets.all(20), Container(
child: BlocBuilder<ChessBloc, ChessBoardState>( margin: const EdgeInsets.all(20),
builder: (context, state) { child: BlocListener<PromotionUiBloc, PromotionUiState>(
return ChessBoard( listener: (context, state) {
bState: state, if (state.showPromotionDialog) {
); promotionDialogBuilder(context, state.colorMoved);
}, }
},
child: BlocBuilder<ChessBloc, ChessBoardState>(
builder: (context, state) {
return ChessBoard(
bState: state,
);
},
),
),
), ),
), if (kDebugMode) const TurnIndicator(),
if (kDebugMode) const TurnIndicator(), ],
], ),
), ),
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
@ -59,6 +71,18 @@ class _ChessGameState extends State<ChessGame> {
), ),
); );
} }
Future<void> promotionDialogBuilder(BuildContext context, ChessColor color) {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return PromotionDialog(
sideColor: color,
);
},
);
}
} }
class ChessGameArguments { class ChessGameArguments {

View File

@ -1,23 +1,38 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:mchess/api/move.dart'; 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';
enum ChessPieceName { enum ChessPieceClass {
none, none,
whitePawn, pawn,
whiteBishop, bishop,
whiteKnight, knight,
whiteRook, rook,
whiteQueen, queen,
whiteKing, king,
blackPawn, }
blackBishop,
blackKnight, class ChessPieceAssetKey {
blackRook, final ChessPieceClass pieceClass;
blackQueen, final ChessColor color;
blackKing,
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 { enum ChessColor {
@ -33,36 +48,114 @@ enum ChessColor {
} }
} }
Map<ChessPieceName, String> chessPiecesAssets = { Map<ChessPieceAssetKey, String> chessPiecesAssets = {
ChessPieceName.whitePawn: 'assets/pieces/white/pawn.svg', ChessPieceAssetKey(
ChessPieceName.whiteBishop: 'assets/pieces/white/bishop.svg', pieceClass: ChessPieceClass.pawn,
ChessPieceName.whiteKnight: 'assets/pieces/white/knight.svg', color: ChessColor.white,
ChessPieceName.whiteRook: 'assets/pieces/white/rook.svg', ): 'assets/pieces/white/pawn.svg',
ChessPieceName.whiteQueen: 'assets/pieces/white/queen.svg', ChessPieceAssetKey(
ChessPieceName.whiteKing: 'assets/pieces/white/king.svg', pieceClass: ChessPieceClass.bishop,
ChessPieceName.blackPawn: 'assets/pieces/black/pawn.svg', color: ChessColor.white,
ChessPieceName.blackBishop: 'assets/pieces/black/bishop.svg', ): 'assets/pieces/white/bishop.svg',
ChessPieceName.blackKnight: 'assets/pieces/black/knight.svg', ChessPieceAssetKey(
ChessPieceName.blackRook: 'assets/pieces/black/rook.svg', pieceClass: ChessPieceClass.knight,
ChessPieceName.blackQueen: 'assets/pieces/black/queen.svg', color: ChessColor.white,
ChessPieceName.blackKing: 'assets/pieces/black/king.svg', ): 'assets/pieces/white/knight.svg',
ChessPieceName.none: 'assets/empty.svg', ChessPieceAssetKey(
pieceClass: ChessPieceClass.rook,
color: ChessColor.white,
): 'assets/pieces/white/rook.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.queen,
color: ChessColor.white,
): 'assets/pieces/white/queen.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.king,
color: ChessColor.white,
): 'assets/pieces/white/king.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.pawn,
color: ChessColor.black,
): 'assets/pieces/black/pawn.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.bishop,
color: ChessColor.black,
): 'assets/pieces/black/bishop.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.knight,
color: ChessColor.black,
): 'assets/pieces/black/knight.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.rook,
color: ChessColor.black,
): 'assets/pieces/black/rook.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.queen,
color: ChessColor.black,
): 'assets/pieces/black/queen.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.king,
color: ChessColor.black,
): 'assets/pieces/black/king.svg',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.none,
color: ChessColor.black,
): 'assets/empty.svg',
}; };
Map<ChessPieceName, String> chessPiecesShortName = { Map<ChessPieceAssetKey, String> chessPiecesShortName = {
ChessPieceName.whitePawn: 'P', ChessPieceAssetKey(
ChessPieceName.whiteBishop: 'B', pieceClass: ChessPieceClass.pawn,
ChessPieceName.whiteKnight: 'N', color: ChessColor.white,
ChessPieceName.whiteRook: 'R', ): 'P',
ChessPieceName.whiteQueen: 'Q', ChessPieceAssetKey(
ChessPieceName.whiteKing: 'K', pieceClass: ChessPieceClass.bishop,
ChessPieceName.blackPawn: 'p', color: ChessColor.white,
ChessPieceName.blackBishop: 'b', ): 'B',
ChessPieceName.blackKnight: 'n', ChessPieceAssetKey(
ChessPieceName.blackRook: 'r', pieceClass: ChessPieceClass.knight,
ChessPieceName.blackQueen: 'q', color: ChessColor.white,
ChessPieceName.blackKing: 'k', ): 'N',
ChessPieceName.none: 'X', ChessPieceAssetKey(
pieceClass: ChessPieceClass.rook,
color: ChessColor.white,
): 'R',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.queen,
color: ChessColor.white,
): 'Q',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.king,
color: ChessColor.white,
): 'K',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.pawn,
color: ChessColor.black,
): 'p',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.bishop,
color: ChessColor.black,
): 'b',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.knight,
color: ChessColor.black,
): 'n',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.rook,
color: ChessColor.black,
): 'r',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.queen,
color: ChessColor.black,
): 'q',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.king,
color: ChessColor.black,
): 'k',
ChessPieceAssetKey(
pieceClass: ChessPieceClass.none,
color: ChessColor.black,
): '-',
}; };
class ChessCoordinate { class ChessCoordinate {
@ -140,24 +233,26 @@ class ChessCoordinate {
class ChessPiece extends StatelessWidget { class ChessPiece extends StatelessWidget {
final ChessColor color; final ChessColor color;
final ChessPieceName pieceName; final ChessPieceClass pieceClass;
final String shortName; final String shortName;
final Widget? pieceImage; final Widget? pieceImage;
const ChessPiece._( const ChessPiece._(
this.pieceName, this.color, this.pieceImage, this.shortName); this.pieceClass, this.color, this.pieceImage, this.shortName);
factory ChessPiece(ChessPieceName name, ChessColor color) { factory ChessPiece(ChessPieceClass pieceClass, ChessColor color) {
Widget? pieceImage; Widget? pieceImage;
String pieceAssetUrl = chessPiecesAssets[name]!; String pieceAssetUrl = chessPiecesAssets[
String shortName = chessPiecesShortName[name]!; ChessPieceAssetKey(pieceClass: pieceClass, color: color)]!;
String shortName = chessPiecesShortName[
ChessPieceAssetKey(pieceClass: pieceClass, color: color)]!;
pieceImage = SvgPicture.asset(pieceAssetUrl); pieceImage = SvgPicture.asset(pieceAssetUrl);
return ChessPiece._(name, color, pieceImage, shortName); return ChessPiece._(pieceClass, color, pieceImage, shortName);
} }
const ChessPiece.none({super.key}) const ChessPiece.none({super.key})
: pieceName = ChessPieceName.none, : pieceClass = ChessPieceClass.none,
color = ChessColor.white, color = ChessColor.white,
pieceImage = null, pieceImage = null,
shortName = "-"; shortName = "-";
@ -194,9 +289,10 @@ class ChessMove {
} }
} }
class PieceMovedFrom { class PieceDragged {
ChessCoordinate fromSquare; ChessCoordinate fromSquare;
ChessCoordinate toSquare;
ChessPiece? movedPiece; ChessPiece? movedPiece;
PieceMovedFrom(this.fromSquare, this.movedPiece); PieceDragged(this.fromSquare, this.toSquare, this.movedPiece);
} }

View File

@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mchess/utils/chess_utils.dart';
class PromotionDialog extends StatelessWidget {
final ChessColor sideColor;
const PromotionDialog({required this.sideColor, super.key});
@override
Widget build(BuildContext context) {
return Card(
child: Column(children: [
Expanded(
flex: 1,
child: Row(
children: [
ElevatedButton(
onPressed: () {},
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.queen, color: sideColor)]!),
),
ElevatedButton(
onPressed: () {},
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.rook, color: sideColor)]!),
),
ElevatedButton(
onPressed: () {},
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.knight, color: sideColor)]!),
),
ElevatedButton(
onPressed: () {},
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.bishop, color: sideColor)]!),
)
],
),
),
const Expanded(
flex: 3,
child: ColoredBox(color: Colors.red),
)
]),
);
}
}