import 'dart:convert'; import 'dart:developer'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:mchess/api/websocket_message.dart'; 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'; class ChessBloc extends Bloc { static final ChessBloc _instance = ChessBloc._internal(); static ChessColor turnColor = ChessColor.white; static ChessColor myColor = ChessColor.white; static ChessColor getMyColor() { return myColor; } ChessBloc._internal() : super(ChessBoardState.init()) { on(initBoard); on(flipBoard); on(moveAndPositionHandler); on(ownMoveHandler); on(ownPromotionHandler); on(invalidMoveHandler); } factory ChessBloc.getInstance() { return ChessBloc(); } factory ChessBloc() { return _instance; } void initBoard(InitBoard event, Emitter emit) { turnColor = ChessColor.white; ChessPositionManager.getInstance().resetToStartingPosition(); emit( ChessBoardState( ChessColor.white, ChessColor.white, ChessPositionManager.getInstance().currentPosition, ChessMove.none(), false, ChessCoordinate.none(), ), ); } void flipBoard(ColorDetermined event, Emitter emit) { log("My Color is $myColor"); myColor = event.playerColor; emit( ChessBoardState( event.playerColor, state.newTurnColor, state.position, ChessMove.none(), false, ChessCoordinate.none(), ), ); } void moveAndPositionHandler( ReceivedBoardState event, Emitter emit) { ChessMove? move; if (event.startSquare != ChessCoordinate.none() && event.endSquare != ChessCoordinate.none()) { move = ChessMove(from: event.startSquare!, to: event.endSquare!); ChessPositionManager.getInstance() .recordMove(event.startSquare, event.endSquare, event.position); } myColor = event.playerColor; turnColor = event.turnColor; emit( ChessBoardState( myColor, event.turnColor, event.position, move, true, event.squareInCheck, ), ); } void ownMoveHandler(OwnPieceMoved event, Emitter emit) { log('ownMoveHandler()'); var apiMove = ChessMove(from: event.startSquare, to: event.endSquare).toApiMove(); var apiMessage = ApiWebsocketMessage( type: MessageType.move, move: apiMove, turnColor: null, reason: null, position: null, squareInCheck: null, playerColor: null, ); ServerConnection.getInstance().send(jsonEncode(apiMessage)); //Temporary chess position until server responds with acknowledgement var move = ChessMove.fromApiMove(apiMove); var tempPosition = ChessPositionManager.getInstance().copyOfCurrentPosition; tempPosition[move.to] = tempPosition[move.from] ?? const ChessPiece.none(); tempPosition[move.from] = const ChessPiece.none(); emit( ChessBoardState( state.bottomColor, turnColor, tempPosition, ChessPositionManager.getInstance().lastMove, true, ChessCoordinate.none(), ), ); } void ownPromotionHandler( OwnPromotionPlayed event, Emitter emit) { var apiMove = event.move.toApiMove(); var shorNameForPiece = chessPiecesShortName[ ChessPieceAssetKey(pieceClass: event.pieceClass, color: myColor)]!; apiMove.promotionToPiece = shorNameForPiece; var message = ApiWebsocketMessage( type: MessageType.move, move: apiMove, turnColor: null, reason: null, position: null, squareInCheck: null, playerColor: null, ); log(jsonEncode(message)); ServerConnection.getInstance().send(jsonEncode(message)); } void invalidMoveHandler( InvalidMovePlayed event, Emitter emit) { var move = ChessPositionManager.getInstance().lastMove; emit( ChessBoardState( state.bottomColor, turnColor, ChessPositionManager.getInstance().currentPosition, move, true, event.squareInCheck, ), ); } } class ChessBoardState { final ChessColor bottomColor; final ChessColor newTurnColor; final ChessPosition position; final ChessMove lastMove; final bool colorLastMove; final ChessCoordinate squareInCheck; ChessBoardState._( this.bottomColor, this.newTurnColor, this.position, this.lastMove, this.colorLastMove, this.squareInCheck, ); factory ChessBoardState( ChessColor bottomColor, ChessColor turnColor, ChessPosition position, ChessMove? lastMove, bool positionAckd, ChessCoordinate squareInCheck, ) { return ChessBoardState._(bottomColor, turnColor, position, lastMove ?? ChessMove.none(), positionAckd, squareInCheck); } factory ChessBoardState.init() { ChessColor bottomColor = ChessColor.white; ChessColor turnColor = ChessColor.white; ChessPositionManager.getInstance().resetToStartingPosition(); return ChessBoardState( bottomColor, turnColor, ChessPositionManager.getInstance().currentPosition, ChessMove.none(), false, ChessCoordinate.none(), ); } void logPosition(Map pos) { // for (int i = 0; i < 7; i++) } }