Make promotions work.

This commit is contained in:
Marco 2023-07-03 19:41:12 +02:00
parent 0f27fc6b4e
commit a5befed62c
16 changed files with 292 additions and 138 deletions

View File

@ -1,21 +1,30 @@
class ApiMove { class ApiMove {
final ApiCoordinate startSquare; final ApiCoordinate startSquare;
final ApiCoordinate endSquare; final ApiCoordinate endSquare;
String? promotionToPiece;
const ApiMove({ ApiMove({
required this.startSquare, required this.startSquare,
required this.endSquare, required this.endSquare,
this.promotionToPiece,
}); });
factory ApiMove.fromJson(Map<String, dynamic> json) { factory ApiMove.fromJson(Map<String, dynamic> json) {
final startSquare = ApiCoordinate.fromJson(json['startSquare']); final startSquare = ApiCoordinate.fromJson(json['startSquare']);
final endSquare = ApiCoordinate.fromJson(json['endSquare']); final endSquare = ApiCoordinate.fromJson(json['endSquare']);
final promotionToPiece = json['promotionToPiece'];
return ApiMove(startSquare: startSquare, endSquare: endSquare); return ApiMove(
startSquare: startSquare,
endSquare: endSquare,
promotionToPiece: promotionToPiece);
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() => {
{'startSquare': startSquare, 'endSquare': endSquare}; 'startSquare': startSquare,
'endSquare': endSquare,
'promotionToPiece': promotionToPiece
};
} }
class ApiCoordinate { class ApiCoordinate {

View File

@ -58,6 +58,9 @@ class ApiWebsocketMessage {
return ret; return ret;
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() => {
{'messageType': type, 'move': move, 'color': color}; 'messageType': type,
'move': move,
'color': color,
};
} }

View File

@ -19,7 +19,7 @@ class ChessApp extends StatelessWidget {
create: (context) => ChessBloc.getInstance(), create: (context) => ChessBloc.getInstance(),
), ),
BlocProvider( BlocProvider(
create: (context) => PromotionUiBloc.getInstance(), create: (context) => PromotionBloc.getInstance(),
) )
], ],
child: MaterialApp.router( child: MaterialApp.router(

View File

@ -66,18 +66,20 @@ class ChessSquare extends StatelessWidget {
} }
return true; return true;
}, },
onAccept: (move) { onAccept: (pieceDragged) {
// Replace the dummy value with the actual target of the move. // Replace the dummy value with the actual target of the move.
move.toSquare = coordinate; pieceDragged.toSquare = coordinate;
if (isPromotionMove(move)) { if (isPromotionMove(pieceDragged)) {
PromotionUiBloc.getInstance().add(PawnMovedToPromotionField( var move = ChessMove(
endSquare: move.toSquare, colorMoved: ChessBloc.myColor!)); from: pieceDragged.fromSquare, to: pieceDragged.toSquare);
} else if (coordinate != move.fromSquare) { PromotionBloc.getInstance().add(PawnMovedToPromotionField(
move: move, colorMoved: ChessBloc.myColor!));
} else if (coordinate != pieceDragged.fromSquare) {
ChessBloc.getInstance().add(OwnPieceMoved( ChessBloc.getInstance().add(OwnPieceMoved(
startSquare: move.fromSquare, startSquare: pieceDragged.fromSquare,
endSquare: move.toSquare, endSquare: pieceDragged.toSquare,
piece: containedPiece!)); piece: pieceDragged.movedPiece!));
} }
}, },
builder: (context, candidateData, rejectedData) { builder: (context, candidateData, rejectedData) {

View File

@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mchess/api/move.dart';
import 'package:mchess/api/websocket_message.dart'; import 'package:mchess/api/websocket_message.dart';
import 'package:mchess/chess_bloc/chess_events.dart'; import 'package:mchess/chess_bloc/chess_events.dart';
import 'package:mchess/chess_bloc/chess_position.dart'; import 'package:mchess/chess_bloc/chess_position.dart';
@ -22,7 +21,9 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
on<InitBoard>(initBoard); on<InitBoard>(initBoard);
on<ColorDetermined>(flipBoard); on<ColorDetermined>(flipBoard);
on<ReceivedMove>(moveHandler); on<ReceivedMove>(moveHandler);
on<ReceivedPromotion>(promotionHandler);
on<OwnPieceMoved>(ownMoveHandler); on<OwnPieceMoved>(ownMoveHandler);
on<OwnPromotionPlayed>(ownPromotionHandler);
on<InvalidMovePlayed>(invalidMoveHandler); on<InvalidMovePlayed>(invalidMoveHandler);
} }
@ -64,14 +65,40 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
); );
} }
void promotionHandler(
ReceivedPromotion event, Emitter<ChessBoardState> emit) {
var pieceAtStartSquare = ChessPosition.getInstance().getPieceAt(
ChessCoordinate(event.startSquare.column, event.startSquare.row));
if (pieceAtStartSquare == null) {
log('received a promotion but piece on start square was empty');
return;
}
ChessPieceClass pieceClass = ChessPieceClass.none;
for (var piece in chessPiecesShortName.entries) {
if (piece.value.toLowerCase() == 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);
emit(ChessBoardState(
state.bottomColor,
turnColor,
newPosition,
));
}
void ownMoveHandler(OwnPieceMoved event, Emitter<ChessBoardState> emit) { void ownMoveHandler(OwnPieceMoved event, Emitter<ChessBoardState> emit) {
log('ownMoveHandler()'); log('ownMoveHandler()');
var apiMove =
var start = ApiCoordinate( ChessMove(from: event.startSquare, to: event.endSquare).toApiMove();
col: event.startSquare.column, row: event.startSquare.row);
var end =
ApiCoordinate(col: event.endSquare.column, row: event.endSquare.row);
var apiMove = ApiMove(startSquare: start, endSquare: end);
var apiMessage = ApiWebsocketMessage( var apiMessage = ApiWebsocketMessage(
type: MessageType.move, move: apiMove, color: null, reason: null); type: MessageType.move, move: apiMove, color: null, reason: null);
@ -92,6 +119,23 @@ class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
); );
} }
void ownPromotionHandler(
OwnPromotionPlayed event, Emitter<ChessBoardState> emit) {
var apiMove = event.move.toApiMove();
var shorNameForPiece = chessPiecesShortName[
ChessPieceAssetKey(pieceClass: event.pieceClass, color: myColor!)]!
.toLowerCase();
apiMove.promotionToPiece = shorNameForPiece;
var message = ApiWebsocketMessage(
type: MessageType.move,
move: apiMove,
color: null,
reason: null,
);
log(jsonEncode(message));
ServerConnection.getInstance().send(jsonEncode(message));
}
void invalidMoveHandler( void invalidMoveHandler(
InvalidMovePlayed event, Emitter<ChessBoardState> emit) { InvalidMovePlayed event, Emitter<ChessBoardState> emit) {
emit( emit(

View File

@ -9,6 +9,17 @@ class ReceivedMove extends ChessEvent {
ReceivedMove({required this.startSquare, required this.endSquare}); ReceivedMove({required this.startSquare, required this.endSquare});
} }
class ReceivedPromotion extends ChessEvent {
final ChessCoordinate startSquare;
final ChessCoordinate endSquare;
final String piece;
ReceivedPromotion(
{required this.startSquare,
required this.endSquare,
required this.piece});
}
class OwnPieceMoved extends ChessEvent { class OwnPieceMoved extends ChessEvent {
final ChessCoordinate startSquare; final ChessCoordinate startSquare;
final ChessCoordinate endSquare; final ChessCoordinate endSquare;
@ -20,6 +31,13 @@ class OwnPieceMoved extends ChessEvent {
required this.piece}); required this.piece});
} }
class OwnPromotionPlayed extends ChessEvent {
final ChessPieceClass pieceClass;
final ChessMove move;
OwnPromotionPlayed({required this.pieceClass, required this.move});
}
class InitBoard extends ChessEvent { class InitBoard extends ChessEvent {
InitBoard(); InitBoard();
} }

View File

@ -30,51 +30,61 @@ 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(ChessPieceClass.pawn, ChessColor.black);
// pos[ChessCoordinate(i, 2)] = pos[ChessCoordinate(i, 2)] =
// ChessPiece(ChessPieceName.whitePawn, ChessColor.white); ChessPiece(ChessPieceClass.pawn, ChessColor.white);
} }
pos[ChessCoordinate(1, 7)] = pos[ChessCoordinate(1, 7)] =
ChessPiece(ChessPieceClass.pawn, ChessColor.white); ChessPiece(ChessPieceClass.pawn, ChessColor.white);
pos[ChessCoordinate(2, 7)] =
ChessPiece(ChessPieceClass.pawn, ChessColor.white);
pos[ChessCoordinate(8, 4)] =
ChessPiece(ChessPieceClass.king, ChessColor.white);
pos[ChessCoordinate(8, 6)] =
ChessPiece(ChessPieceClass.king, ChessColor.black);
// pos[ChessCoordinate(1, 8)] = pos[ChessCoordinate(1, 8)] =
// ChessPiece(ChessPieceName.blackRook, ChessColor.black); ChessPiece(ChessPieceClass.rook, ChessColor.black);
// pos[ChessCoordinate(2, 8)] = pos[ChessCoordinate(2, 8)] =
// ChessPiece(ChessPieceName.blackKnight, ChessColor.black); ChessPiece(ChessPieceClass.knight, ChessColor.black);
// pos[ChessCoordinate(3, 8)] = pos[ChessCoordinate(3, 8)] =
// ChessPiece(ChessPieceName.blackBishop, ChessColor.black); ChessPiece(ChessPieceClass.bishop, ChessColor.black);
// pos[ChessCoordinate(4, 8)] = pos[ChessCoordinate(4, 8)] =
// ChessPiece(ChessPieceName.blackQueen, ChessColor.black); ChessPiece(ChessPieceClass.queen, ChessColor.black);
// pos[ChessCoordinate(5, 8)] = pos[ChessCoordinate(5, 8)] =
// ChessPiece(ChessPieceName.blackKing, ChessColor.black); ChessPiece(ChessPieceClass.king, ChessColor.black);
// pos[ChessCoordinate(6, 8)] = pos[ChessCoordinate(6, 8)] =
// ChessPiece(ChessPieceName.blackBishop, ChessColor.black); ChessPiece(ChessPieceClass.bishop, ChessColor.black);
// pos[ChessCoordinate(7, 8)] = pos[ChessCoordinate(7, 8)] =
// ChessPiece(ChessPieceName.blackKnight, ChessColor.black); ChessPiece(ChessPieceClass.knight, ChessColor.black);
// pos[ChessCoordinate(8, 8)] = pos[ChessCoordinate(8, 8)] =
// ChessPiece(ChessPieceName.blackRook, ChessColor.black); ChessPiece(ChessPieceClass.rook, ChessColor.black);
// pos[ChessCoordinate(1, 1)] = pos[ChessCoordinate(1, 1)] =
// ChessPiece(ChessPieceName.whiteRook, ChessColor.white); ChessPiece(ChessPieceClass.rook, ChessColor.white);
// pos[ChessCoordinate(2, 1)] = pos[ChessCoordinate(2, 1)] =
// ChessPiece(ChessPieceName.whiteKnight, ChessColor.white); ChessPiece(ChessPieceClass.knight, ChessColor.white);
// pos[ChessCoordinate(3, 1)] = pos[ChessCoordinate(3, 1)] =
// ChessPiece(ChessPieceName.whiteBishop, ChessColor.white); ChessPiece(ChessPieceClass.bishop, ChessColor.white);
// pos[ChessCoordinate(4, 1)] = pos[ChessCoordinate(4, 1)] =
// ChessPiece(ChessPieceName.whiteQueen, ChessColor.white); ChessPiece(ChessPieceClass.queen, ChessColor.white);
// pos[ChessCoordinate(5, 1)] = pos[ChessCoordinate(5, 1)] =
// ChessPiece(ChessPieceName.whiteKing, ChessColor.white); ChessPiece(ChessPieceClass.king, ChessColor.white);
// pos[ChessCoordinate(6, 1)] = pos[ChessCoordinate(6, 1)] =
// ChessPiece(ChessPieceName.whiteBishop, ChessColor.white); ChessPiece(ChessPieceClass.bishop, ChessColor.white);
// pos[ChessCoordinate(7, 1)] = pos[ChessCoordinate(7, 1)] =
// ChessPiece(ChessPieceName.whiteKnight, ChessColor.white); ChessPiece(ChessPieceClass.knight, ChessColor.white);
// pos[ChessCoordinate(8, 1)] = pos[ChessCoordinate(8, 1)] =
// ChessPiece(ChessPieceName.whiteRook, ChessColor.white); ChessPiece(ChessPieceClass.rook, ChessColor.white);
return pos; return pos;
} }
ChessPiece? getPieceAt(ChessCoordinate coordinate) {
return position[ChessCoordinate(coordinate.column, coordinate.row)];
}
void resetToStartingPosition() { void resetToStartingPosition() {
history = ChessMoveHistory.empty(growable: true); history = ChessMoveHistory.empty(growable: true);
_instance = ChessPosition(position: _getStartingPosition()); _instance = ChessPosition(position: _getStartingPosition());

View File

@ -1,26 +1,40 @@
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_events.dart';
import 'package:mchess/utils/chess_utils.dart'; import 'package:mchess/utils/chess_utils.dart';
class PromotionUiBloc extends Bloc<PromotionEvent, PromotionUiState> { class PromotionBloc extends Bloc<PromotionEvent, PromotionState> {
static final PromotionUiBloc _instance = PromotionUiBloc._internal(); static final PromotionBloc _instance = PromotionBloc._internal();
static late ChessMove move;
PromotionUiBloc._internal() : super(PromotionUiState.init()) { PromotionBloc._internal() : super(PromotionState.init()) {
on<PawnMovedToPromotionField>(promotionMoveHandler); on<PawnMovedToPromotionField>(promotionMoveHandler);
on<PieceChosen>(pieceChosenHandler);
} }
void promotionMoveHandler( void promotionMoveHandler(
PawnMovedToPromotionField event, PawnMovedToPromotionField event,
Emitter<PromotionUiState> emit, Emitter<PromotionState> emit,
) { ) {
emit(PromotionUiState( move = event.move;
emit(PromotionState(
showPromotionDialog: true, colorMoved: event.colorMoved)); showPromotionDialog: true, colorMoved: event.colorMoved));
} }
factory PromotionUiBloc.getInstance() { void pieceChosenHandler(
return PromotionUiBloc(); PieceChosen event,
Emitter<PromotionState> emit,
) {
ChessBloc.getInstance()
.add(OwnPromotionPlayed(pieceClass: event.pieceClass, move: move));
emit(PromotionState(showPromotionDialog: false, colorMoved: event.color));
} }
factory PromotionUiBloc() { factory PromotionBloc.getInstance() {
return PromotionBloc();
}
factory PromotionBloc() {
return _instance; return _instance;
} }
} }
@ -28,22 +42,27 @@ class PromotionUiBloc extends Bloc<PromotionEvent, PromotionUiState> {
abstract class PromotionEvent {} abstract class PromotionEvent {}
class PawnMovedToPromotionField extends PromotionEvent { class PawnMovedToPromotionField extends PromotionEvent {
final ChessCoordinate endSquare; final ChessMove move;
final ChessColor colorMoved; final ChessColor colorMoved;
PawnMovedToPromotionField( PawnMovedToPromotionField({required this.move, required this.colorMoved});
{required this.endSquare, required this.colorMoved});
} }
class PromotionUiState { class PieceChosen extends PromotionEvent {
final ChessPieceClass pieceClass;
final ChessColor color;
PieceChosen({required this.pieceClass, required this.color});
}
class PromotionState {
final bool showPromotionDialog; final bool showPromotionDialog;
final ChessColor colorMoved; final ChessColor colorMoved;
PromotionUiState( PromotionState({required this.showPromotionDialog, required this.colorMoved});
{required this.showPromotionDialog, required this.colorMoved});
factory PromotionUiState.init() { factory PromotionState.init() {
return PromotionUiState( return PromotionState(
showPromotionDialog: false, colorMoved: ChessColor.white); showPromotionDialog: false, colorMoved: ChessColor.white);
} }
} }

View File

@ -77,15 +77,24 @@ class ServerConnection {
} }
void handleIncomingColorDeterminedMessage(ApiWebsocketMessage apiMessage) { void handleIncomingColorDeterminedMessage(ApiWebsocketMessage apiMessage) {
ConnectionCubit.getInstance().opponentConnected();
ChessBloc.getInstance().add(InitBoard());
ChessBloc.getInstance().add( ChessBloc.getInstance().add(
ColorDetermined(myColor: ChessColor.fromApiColor(apiMessage.color!))); ColorDetermined(myColor: ChessColor.fromApiColor(apiMessage.color!)));
ConnectionCubit.getInstance().opponentConnected();
} }
void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) { void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) {
var move = ChessMove.fromApiMove(apiMessage.move!); var move = ChessMove.fromApiMove(apiMessage.move!);
ChessBloc.getInstance()
.add(ReceivedMove(startSquare: move.from, endSquare: move.to)); 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));
}
} }
void handleInvalidMoveMessage(ApiWebsocketMessage apiMessage) { void handleInvalidMoveMessage(ApiWebsocketMessage apiMessage) {

View File

@ -43,7 +43,7 @@ class _ChessGameState extends State<ChessGame> {
if (kDebugMode) const ServerLogWidget(textColor: Colors.white), if (kDebugMode) const ServerLogWidget(textColor: Colors.white),
Container( Container(
margin: const EdgeInsets.all(20), margin: const EdgeInsets.all(20),
child: BlocListener<PromotionUiBloc, PromotionUiState>( child: BlocListener<PromotionBloc, PromotionState>(
listener: (context, state) { listener: (context, state) {
if (state.showPromotionDialog) { if (state.showPromotionDialog) {
promotionDialogBuilder(context, state.colorMoved); promotionDialogBuilder(context, state.colorMoved);

View File

@ -27,8 +27,6 @@ class _HostGameWidgetState extends State<HostGameWidget> {
@override @override
void initState() { void initState() {
ChessBloc.getInstance().add(InitBoard());
registerResponse = hostPrivateGame(); registerResponse = hostPrivateGame();
connectToWebsocket(registerResponse); connectToWebsocket(registerResponse);
@ -130,7 +128,7 @@ class _HostGameWidgetState extends State<HostGameWidget> {
Future.delayed(const Duration(seconds: 2), () { Future.delayed(const Duration(seconds: 2), () {
ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(snackBar); ScaffoldMessenger.of(context).showSnackBar(snackBar);
context.pop(); context.push('/'); // We go back to the lobby selector
}); });
return null; return null;
} }

View File

@ -100,7 +100,7 @@ class _JoinGameWidgetState extends State<JoinGameWidget> {
Future.delayed(const Duration(seconds: 2), () { Future.delayed(const Duration(seconds: 2), () {
ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).clearSnackBars();
ScaffoldMessenger.of(context).showSnackBar(snackBar); ScaffoldMessenger.of(context).showSnackBar(snackBar);
context.pop(); context.push('/'); // We go back to lobby selector
}); });
return null; return null;
} }

View File

@ -13,24 +13,25 @@ class LobbySelector extends StatelessWidget {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
ElevatedButton( //We deactivate random lobbies for now.
onPressed: () { // ElevatedButton(
context.push('/prepareRandom'); // onPressed: () {
}, // context.push('/prepareRandom');
child: const Row( // },
mainAxisSize: MainAxisSize.min, // child: const Row(
children: [ // mainAxisSize: MainAxisSize.min,
Icon(Icons.question_mark), // children: [
SizedBox( // Icon(Icons.question_mark),
width: 10, // SizedBox(
), // width: 10,
Text('Random') // ),
], // Text('Random')
), // ],
), // ),
const SizedBox( // ),
height: 25, // const SizedBox(
), // height: 25,
// ),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
_dialogBuilder(context); _dialogBuilder(context);

View File

@ -24,12 +24,8 @@ class _PrepareRandomGameWidgetState extends State<PrepareRandomGameWidget> {
@override @override
void initState() { void initState() {
ChessBloc.getInstance().add(InitBoard());
randomGameResponse = registerForRandomGame(); randomGameResponse = registerForRandomGame();
goToGameWhenResponseIsHere(randomGameResponse as Future<PlayerInfo?>); goToGameWhenResponseIsHere(randomGameResponse as Future<PlayerInfo?>);
super.initState(); super.initState();
} }

View File

@ -44,6 +44,14 @@ enum ChessColor {
return white; return white;
} }
} }
ChessColor getOpposite() {
if (name == 'black') {
return white;
} else {
return black;
}
}
} }
Map<ChessPieceAssetKey, String> chessPiecesAssets = { Map<ChessPieceAssetKey, String> chessPiecesAssets = {
@ -173,6 +181,10 @@ class ChessCoordinate {
return ChessCoordinate(apiCoordinate.col, apiCoordinate.row); return ChessCoordinate(apiCoordinate.col, apiCoordinate.row);
} }
ApiCoordinate toApiCoordinate() {
return ApiCoordinate(col: column, row: row);
}
ChessCoordinate.copyFrom(ChessCoordinate original) ChessCoordinate.copyFrom(ChessCoordinate original)
: column = original.column, : column = original.column,
row = original.row; row = original.row;
@ -276,6 +288,13 @@ class ChessMove {
return ChessMove(from: start, to: end); 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 @override
operator ==(other) { operator ==(other) {
return other is ChessMove && other.from == from && other.to == to; return other is ChessMove && other.from == from && other.to == to;

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:mchess/chess_bloc/promotion_bloc.dart';
import 'package:mchess/utils/chess_utils.dart'; import 'package:mchess/utils/chess_utils.dart';
class PromotionDialog extends StatelessWidget { class PromotionDialog extends StatelessWidget {
@ -8,40 +10,64 @@ class PromotionDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( double windowWidth = MediaQuery.of(context).size.width;
child: Column(children: [ double windowHeight = MediaQuery.of(context).size.height;
Expanded( double iconSize;
flex: 1,
child: Row( if (windowWidth < windowHeight) {
children: [ iconSize = 0.15 * windowWidth;
ElevatedButton( } else {
onPressed: () {}, iconSize = 0.15 * windowHeight;
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey( }
pieceClass: ChessPieceClass.queen, color: sideColor)]!),
), return Dialog(
ElevatedButton( child: Row(
onPressed: () {}, mainAxisSize: MainAxisSize.min,
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey( mainAxisAlignment: MainAxisAlignment.spaceEvenly,
pieceClass: ChessPieceClass.rook, color: sideColor)]!), children: [
), IconButton(
ElevatedButton( onPressed: () {
onPressed: () {}, pieceChosen(ChessPieceClass.queen);
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey( context.pop();
pieceClass: ChessPieceClass.knight, color: sideColor)]!), },
), icon: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
ElevatedButton( pieceClass: ChessPieceClass.queen, color: sideColor)]!),
onPressed: () {}, iconSize: 200,
child: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.bishop, color: sideColor)]!),
)
],
), ),
), IconButton(
const Expanded( onPressed: () {
flex: 3, pieceChosen(ChessPieceClass.rook);
child: ColoredBox(color: Colors.red), context.pop();
) },
]), icon: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.rook, color: sideColor)]!),
iconSize: 100,
),
IconButton(
onPressed: () {
pieceChosen(ChessPieceClass.knight);
context.pop();
},
icon: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.knight, color: sideColor)]!),
iconSize: 10,
),
IconButton(
onPressed: () {
pieceChosen(ChessPieceClass.bishop);
context.pop();
},
icon: SvgPicture.asset(chessPiecesAssets[ChessPieceAssetKey(
pieceClass: ChessPieceClass.bishop, color: sideColor)]!),
iconSize: iconSize,
)
],
),
); );
} }
void pieceChosen(ChessPieceClass pieceClass) {
PromotionBloc.getInstance()
.add(PieceChosen(pieceClass: pieceClass, color: sideColor));
}
} }