Marco
212a54612c
This adds an option to dragging-and-dropping which is slightly hard on smaller screens. Fix promotions when tapping and fix handling of subsequently tapping two pieces of your color Cancel tap if a drag is started (tapped square will not stay red in case a drag is started) Change url strategy back to the hashtag thing Change version Fix bug that would not allow a piece move if you tried to take an opponents piece. Fix the coloring of the last move after an invalid move was played. Upgrading deps
209 lines
5.6 KiB
Dart
209 lines
5.6 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);
|
|
}
|
|
|
|
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) {
|
|
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);
|
|
}
|
|
|
|
turnColor = event.turnColor;
|
|
|
|
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,
|
|
ChessPositionManager.getInstance().lastMove,
|
|
true,
|
|
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) {
|
|
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<ChessCoordinate, ChessPiece> pos) {
|
|
// for (int i = 0; i < 7; i++)
|
|
}
|
|
}
|