2023-06-02 21:28:40 +00:00
|
|
|
import 'dart:convert';
|
2023-08-19 01:45:03 +00:00
|
|
|
import 'dart:developer';
|
2023-06-02 21:28:40 +00:00
|
|
|
|
2022-11-13 00:03:09 +00:00
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
2023-06-08 15:14:50 +00:00
|
|
|
import 'package:mchess/api/websocket_message.dart';
|
2022-11-13 13:27:00 +00:00
|
|
|
import 'package:mchess/chess_bloc/chess_events.dart';
|
2023-01-30 21:39:13 +00:00
|
|
|
import 'package:mchess/chess_bloc/chess_position.dart';
|
|
|
|
import 'package:mchess/connection/ws_connection.dart';
|
2022-12-25 15:16:23 +00:00
|
|
|
import 'package:mchess/utils/chess_utils.dart';
|
2022-11-13 00:03:09 +00:00
|
|
|
|
|
|
|
class ChessBloc extends Bloc<ChessEvent, ChessBoardState> {
|
|
|
|
static final ChessBloc _instance = ChessBloc._internal();
|
2023-01-30 21:39:13 +00:00
|
|
|
static ChessColor turnColor = ChessColor.white;
|
2023-07-01 07:29:43 +00:00
|
|
|
static ChessColor? myColor = ChessColor.white;
|
2022-12-21 22:14:53 +00:00
|
|
|
|
|
|
|
static ChessColor? getSidesColor() {
|
|
|
|
return myColor;
|
|
|
|
}
|
2022-11-13 00:03:09 +00:00
|
|
|
|
|
|
|
ChessBloc._internal() : super(ChessBoardState.init()) {
|
2022-12-18 00:04:08 +00:00
|
|
|
on<InitBoard>(initBoard);
|
|
|
|
on<ColorDetermined>(flipBoard);
|
2023-12-09 19:34:52 +00:00
|
|
|
on<ReceivedBoardState>(moveAndPositionHandler);
|
2023-01-30 21:39:13 +00:00
|
|
|
on<OwnPieceMoved>(ownMoveHandler);
|
2023-07-03 17:41:12 +00:00
|
|
|
on<OwnPromotionPlayed>(ownPromotionHandler);
|
2023-06-28 10:37:59 +00:00
|
|
|
on<InvalidMovePlayed>(invalidMoveHandler);
|
2023-12-09 19:34:52 +00:00
|
|
|
on<BoardStatusReceived>(boardStatusHandler);
|
2022-11-13 00:03:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
factory ChessBloc.getInstance() {
|
|
|
|
return ChessBloc();
|
|
|
|
}
|
|
|
|
|
|
|
|
factory ChessBloc() {
|
|
|
|
return _instance;
|
|
|
|
}
|
|
|
|
|
2022-12-18 00:04:08 +00:00
|
|
|
void initBoard(InitBoard event, Emitter<ChessBoardState> emit) {
|
2023-07-11 20:29:55 +00:00
|
|
|
turnColor = ChessColor.white;
|
2023-08-14 22:39:10 +00:00
|
|
|
ChessPositionManager.getInstance().resetToStartingPosition();
|
2023-08-19 01:45:03 +00:00
|
|
|
emit(
|
|
|
|
ChessBoardState(
|
|
|
|
ChessColor.white,
|
|
|
|
ChessColor.white,
|
|
|
|
ChessPositionManager.getInstance().currentPosition,
|
|
|
|
ChessMove.none(),
|
2023-08-25 10:28:58 +00:00
|
|
|
false,
|
2023-09-04 19:39:51 +00:00
|
|
|
ChessCoordinate.none(),
|
2023-08-19 01:45:03 +00:00
|
|
|
),
|
|
|
|
);
|
2022-12-18 00:04:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void flipBoard(ColorDetermined event, Emitter<ChessBoardState> emit) {
|
2022-12-21 22:14:53 +00:00
|
|
|
log("My Color is $myColor");
|
|
|
|
myColor = event.myColor;
|
2023-08-19 01:45:03 +00:00
|
|
|
emit(
|
|
|
|
ChessBoardState(
|
|
|
|
event.myColor,
|
|
|
|
state.newTurnColor,
|
|
|
|
state.position,
|
|
|
|
ChessMove.none(),
|
2023-08-25 10:28:58 +00:00
|
|
|
false,
|
2023-09-04 19:39:51 +00:00
|
|
|
ChessCoordinate.none(),
|
2023-08-19 01:45:03 +00:00
|
|
|
),
|
|
|
|
);
|
2022-12-18 00:04:08 +00:00
|
|
|
}
|
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
void moveAndPositionHandler(
|
2023-12-09 19:34:52 +00:00
|
|
|
ReceivedBoardState event, Emitter<ChessBoardState> emit) {
|
2023-07-05 22:12:03 +00:00
|
|
|
turnColor = state.newTurnColor == ChessColor.white
|
|
|
|
? ChessColor.black
|
|
|
|
: ChessColor.white;
|
|
|
|
|
2023-12-09 19:34:52 +00:00
|
|
|
ChessMove? move;
|
|
|
|
if (event.startSquare != null && event.endSquare != null) {
|
|
|
|
move = ChessMove(from: event.startSquare!, to: event.endSquare!);
|
|
|
|
ChessPositionManager.getInstance()
|
|
|
|
.recordMove(event.startSquare, event.endSquare, event.position);
|
|
|
|
}
|
|
|
|
|
2023-08-19 01:45:03 +00:00
|
|
|
emit(
|
|
|
|
ChessBoardState(
|
|
|
|
state.bottomColor,
|
|
|
|
turnColor,
|
|
|
|
event.position,
|
2023-12-09 19:34:52 +00:00
|
|
|
move,
|
2023-08-25 10:28:58 +00:00
|
|
|
true,
|
2023-09-04 19:39:51 +00:00
|
|
|
event.squareInCheck,
|
2023-08-19 01:45:03 +00:00
|
|
|
),
|
|
|
|
);
|
2023-07-03 17:41:12 +00:00
|
|
|
}
|
|
|
|
|
2023-01-30 21:39:13 +00:00
|
|
|
void ownMoveHandler(OwnPieceMoved event, Emitter<ChessBoardState> emit) {
|
2023-06-08 18:23:00 +00:00
|
|
|
log('ownMoveHandler()');
|
2023-07-03 17:41:12 +00:00
|
|
|
var apiMove =
|
|
|
|
ChessMove(from: event.startSquare, to: event.endSquare).toApiMove();
|
2023-06-28 10:37:59 +00:00
|
|
|
var apiMessage = ApiWebsocketMessage(
|
2023-08-14 15:04:25 +00:00
|
|
|
type: MessageType.move,
|
|
|
|
move: apiMove,
|
2023-12-09 19:34:52 +00:00
|
|
|
turnColor: null,
|
2023-08-14 15:04:25 +00:00
|
|
|
reason: null,
|
|
|
|
position: null,
|
2023-09-04 19:39:51 +00:00
|
|
|
squareInCheck: null,
|
2023-12-09 19:34:52 +00:00
|
|
|
playerColor: null,
|
2023-08-14 15:04:25 +00:00
|
|
|
);
|
2023-06-08 15:10:48 +00:00
|
|
|
|
2023-06-28 10:37:59 +00:00
|
|
|
ServerConnection.getInstance().send(jsonEncode(apiMessage));
|
2023-06-08 15:10:48 +00:00
|
|
|
|
2023-06-29 23:49:18 +00:00
|
|
|
//Temporary chess position until server responds with acknowledgement
|
2023-06-28 10:37:59 +00:00
|
|
|
var move = ChessMove.fromApiMove(apiMove);
|
2023-08-14 22:39:10 +00:00
|
|
|
var tempPosition = ChessPositionManager.getInstance().copyOfCurrentPosition;
|
2023-06-28 10:37:59 +00:00
|
|
|
tempPosition[move.to] = tempPosition[move.from] ?? const ChessPiece.none();
|
|
|
|
tempPosition[move.from] = const ChessPiece.none();
|
2023-06-08 15:10:48 +00:00
|
|
|
|
|
|
|
emit(
|
2023-09-04 19:39:51 +00:00
|
|
|
ChessBoardState(state.bottomColor, turnColor, tempPosition, move, false,
|
|
|
|
ChessCoordinate.none()),
|
2023-06-08 15:10:48 +00:00
|
|
|
);
|
2023-01-30 21:39:13 +00:00
|
|
|
}
|
2023-06-28 10:37:59 +00:00
|
|
|
|
2023-07-03 17:41:12 +00:00
|
|
|
void ownPromotionHandler(
|
|
|
|
OwnPromotionPlayed event, Emitter<ChessBoardState> emit) {
|
|
|
|
var apiMove = event.move.toApiMove();
|
|
|
|
var shorNameForPiece = chessPiecesShortName[
|
2023-08-12 09:43:51 +00:00
|
|
|
ChessPieceAssetKey(pieceClass: event.pieceClass, color: myColor!)]!;
|
2023-07-03 17:41:12 +00:00
|
|
|
apiMove.promotionToPiece = shorNameForPiece;
|
|
|
|
var message = ApiWebsocketMessage(
|
|
|
|
type: MessageType.move,
|
|
|
|
move: apiMove,
|
2023-12-09 19:34:52 +00:00
|
|
|
turnColor: null,
|
2023-07-03 17:41:12 +00:00
|
|
|
reason: null,
|
2023-08-14 15:04:25 +00:00
|
|
|
position: null,
|
2023-09-04 19:39:51 +00:00
|
|
|
squareInCheck: null,
|
2023-12-09 19:34:52 +00:00
|
|
|
playerColor: null,
|
2023-07-03 17:41:12 +00:00
|
|
|
);
|
|
|
|
log(jsonEncode(message));
|
|
|
|
ServerConnection.getInstance().send(jsonEncode(message));
|
|
|
|
}
|
|
|
|
|
2023-06-28 10:37:59 +00:00
|
|
|
void invalidMoveHandler(
|
|
|
|
InvalidMovePlayed event, Emitter<ChessBoardState> emit) {
|
2023-07-01 07:29:43 +00:00
|
|
|
emit(
|
2023-09-04 19:39:51 +00:00
|
|
|
ChessBoardState(
|
|
|
|
state.bottomColor,
|
|
|
|
turnColor,
|
|
|
|
ChessPositionManager.getInstance().currentPosition,
|
|
|
|
ChessMove.none(),
|
|
|
|
false,
|
|
|
|
event.squareInCheck,
|
|
|
|
),
|
2023-07-01 07:29:43 +00:00
|
|
|
);
|
2023-06-28 10:37:59 +00:00
|
|
|
}
|
2023-12-09 19:34:52 +00:00
|
|
|
|
|
|
|
void boardStatusHandler(
|
|
|
|
BoardStatusReceived event, Emitter<ChessBoardState> emit) {
|
|
|
|
emit(
|
|
|
|
ChessBoardState(
|
|
|
|
event.myColor,
|
|
|
|
event.whoseTurn,
|
|
|
|
event.pos,
|
|
|
|
ChessMove.none(),
|
|
|
|
false,
|
|
|
|
ChessCoordinate.none(),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2022-11-13 00:03:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class ChessBoardState {
|
2023-08-19 01:45:03 +00:00
|
|
|
final ChessColor bottomColor;
|
2022-12-18 00:04:08 +00:00
|
|
|
final ChessColor newTurnColor;
|
2023-08-14 22:39:10 +00:00
|
|
|
final ChessPosition position;
|
2023-08-19 01:45:03 +00:00
|
|
|
final ChessMove lastMove;
|
2023-09-04 19:39:51 +00:00
|
|
|
final bool positionAckdByServer;
|
|
|
|
final ChessCoordinate squareInCheck;
|
2022-11-13 00:03:09 +00:00
|
|
|
|
2023-08-19 01:45:03 +00:00
|
|
|
ChessBoardState._(
|
2023-09-04 19:39:51 +00:00
|
|
|
this.bottomColor,
|
|
|
|
this.newTurnColor,
|
|
|
|
this.position,
|
|
|
|
this.lastMove,
|
|
|
|
this.positionAckdByServer,
|
|
|
|
this.squareInCheck,
|
|
|
|
);
|
2022-11-13 01:42:10 +00:00
|
|
|
|
|
|
|
factory ChessBoardState(
|
2022-12-18 00:04:08 +00:00
|
|
|
ChessColor bottomColor,
|
2022-11-13 01:42:10 +00:00
|
|
|
ChessColor turnColor,
|
2023-08-19 01:45:03 +00:00
|
|
|
ChessPosition position,
|
2023-12-09 19:34:52 +00:00
|
|
|
ChessMove? lastMove,
|
2023-08-25 10:28:58 +00:00
|
|
|
bool positionAckd,
|
2023-09-04 19:39:51 +00:00
|
|
|
ChessCoordinate squareInCheck,
|
2022-11-13 01:42:10 +00:00
|
|
|
) {
|
2023-12-09 19:34:52 +00:00
|
|
|
return ChessBoardState._(bottomColor, turnColor, position,
|
|
|
|
lastMove ?? ChessMove.none(), positionAckd, squareInCheck);
|
2022-11-13 01:42:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
factory ChessBoardState.init() {
|
2022-12-18 00:04:08 +00:00
|
|
|
ChessColor bottomColor = ChessColor.white;
|
2022-11-13 01:42:10 +00:00
|
|
|
ChessColor turnColor = ChessColor.white;
|
|
|
|
|
2023-08-14 22:39:10 +00:00
|
|
|
ChessPositionManager.getInstance().resetToStartingPosition();
|
2023-06-08 18:23:00 +00:00
|
|
|
|
|
|
|
return ChessBoardState(
|
2023-08-19 01:45:03 +00:00
|
|
|
bottomColor,
|
|
|
|
turnColor,
|
|
|
|
ChessPositionManager.getInstance().currentPosition,
|
|
|
|
ChessMove.none(),
|
2023-08-25 10:28:58 +00:00
|
|
|
false,
|
2023-09-04 19:39:51 +00:00
|
|
|
ChessCoordinate.none(),
|
2023-08-19 01:45:03 +00:00
|
|
|
);
|
2022-11-13 01:42:10 +00:00
|
|
|
}
|
2022-12-18 22:43:06 +00:00
|
|
|
|
|
|
|
void logPosition(Map<ChessCoordinate, ChessPiece> pos) {
|
|
|
|
// for (int i = 0; i < 7; i++)
|
|
|
|
}
|
2022-11-13 00:03:09 +00:00
|
|
|
}
|