Marco
1cb5ffb82b
This is another step to allow reconnecting after connection loss or browser closing. When the game is left with the X button on the bottom right, we will close the websocket connection, to let the server know, that we are gone. The server still has issues that prevent this from working flawlessly.
218 lines
5.8 KiB
Dart
218 lines
5.8 KiB
Dart
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<ChessEvent, ChessBoardState> {
|
|
static final ChessBloc _instance = ChessBloc._internal();
|
|
static ChessColor turnColor = ChessColor.white;
|
|
static ChessColor? myColor = ChessColor.white;
|
|
|
|
static ChessColor? getSidesColor() {
|
|
return myColor;
|
|
}
|
|
|
|
ChessBloc._internal() : super(ChessBoardState.init()) {
|
|
on<InitBoard>(initBoard);
|
|
on<ColorDetermined>(flipBoard);
|
|
on<ReceivedBoardState>(moveAndPositionHandler);
|
|
on<OwnPieceMoved>(ownMoveHandler);
|
|
on<OwnPromotionPlayed>(ownPromotionHandler);
|
|
on<InvalidMovePlayed>(invalidMoveHandler);
|
|
on<BoardStatusReceived>(boardStatusHandler);
|
|
}
|
|
|
|
factory ChessBloc.getInstance() {
|
|
return ChessBloc();
|
|
}
|
|
|
|
factory ChessBloc() {
|
|
return _instance;
|
|
}
|
|
|
|
void initBoard(InitBoard event, Emitter<ChessBoardState> 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<ChessBoardState> emit) {
|
|
log("My Color is $myColor");
|
|
myColor = event.myColor;
|
|
emit(
|
|
ChessBoardState(
|
|
event.myColor,
|
|
state.newTurnColor,
|
|
state.position,
|
|
ChessMove.none(),
|
|
false,
|
|
ChessCoordinate.none(),
|
|
),
|
|
);
|
|
}
|
|
|
|
void moveAndPositionHandler(
|
|
ReceivedBoardState event, Emitter<ChessBoardState> emit) {
|
|
turnColor = state.newTurnColor == ChessColor.white
|
|
? ChessColor.black
|
|
: ChessColor.white;
|
|
|
|
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);
|
|
}
|
|
|
|
emit(
|
|
ChessBoardState(
|
|
state.bottomColor,
|
|
turnColor,
|
|
event.position,
|
|
move,
|
|
true,
|
|
event.squareInCheck,
|
|
),
|
|
);
|
|
}
|
|
|
|
void ownMoveHandler(OwnPieceMoved event, Emitter<ChessBoardState> 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, move, false,
|
|
ChessCoordinate.none()),
|
|
);
|
|
}
|
|
|
|
void ownPromotionHandler(
|
|
OwnPromotionPlayed event, Emitter<ChessBoardState> 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<ChessBoardState> emit) {
|
|
emit(
|
|
ChessBoardState(
|
|
state.bottomColor,
|
|
turnColor,
|
|
ChessPositionManager.getInstance().currentPosition,
|
|
ChessMove.none(),
|
|
false,
|
|
event.squareInCheck,
|
|
),
|
|
);
|
|
}
|
|
|
|
void boardStatusHandler(
|
|
BoardStatusReceived event, Emitter<ChessBoardState> emit) {
|
|
emit(
|
|
ChessBoardState(
|
|
event.myColor,
|
|
event.whoseTurn,
|
|
event.pos,
|
|
ChessMove.none(),
|
|
false,
|
|
ChessCoordinate.none(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class ChessBoardState {
|
|
final ChessColor bottomColor;
|
|
final ChessColor newTurnColor;
|
|
final ChessPosition position;
|
|
final ChessMove lastMove;
|
|
final bool positionAckdByServer;
|
|
final ChessCoordinate squareInCheck;
|
|
|
|
ChessBoardState._(
|
|
this.bottomColor,
|
|
this.newTurnColor,
|
|
this.position,
|
|
this.lastMove,
|
|
this.positionAckdByServer,
|
|
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<ChessCoordinate, ChessPiece> pos) {
|
|
// for (int i = 0; i < 7; i++)
|
|
}
|
|
}
|