Marco
2a4da9a1af
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.
110 lines
3.0 KiB
Dart
110 lines
3.0 KiB
Dart
import 'dart:developer';
|
|
|
|
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/chess_bloc/promotion_bloc.dart';
|
|
import 'package:mchess/utils/chess_utils.dart';
|
|
|
|
class TapBloc extends Bloc<TapEvent, TapState> {
|
|
static final TapBloc _instance = TapBloc._internal();
|
|
|
|
static TapBloc getInstance() {
|
|
return _instance;
|
|
}
|
|
|
|
factory TapBloc() {
|
|
return _instance;
|
|
}
|
|
|
|
TapBloc._internal() : super(TapState.init()) {
|
|
on<SquareTappedEvent>(handleTap);
|
|
on<CancelTapEvent>(cancelTap);
|
|
}
|
|
|
|
void handleTap(SquareTappedEvent event, Emitter<TapState> emit) {
|
|
ChessCoordinate? firstTappedSquare, secondTappedSquare;
|
|
ChessPiece? piece;
|
|
|
|
if (ChessBloc.myColor != ChessBloc.turnColor) return;
|
|
|
|
if (state.firstSquareTapped == null) {
|
|
//first tap
|
|
if (event.pieceOnSquare == null) return;
|
|
if (event.pieceOnSquare != null &&
|
|
ChessBloc.myColor != event.pieceOnSquare!.color) return;
|
|
firstTappedSquare = event.tapped;
|
|
piece = event.pieceOnSquare;
|
|
} else {
|
|
//second tap
|
|
if (event.pieceOnSquare?.color == ChessBloc.myColor) {
|
|
emit(TapState(
|
|
firstSquareTapped: event.tapped,
|
|
pieceOnFirstTappedSquare: event.pieceOnSquare,
|
|
secondSquareTapped: null));
|
|
return;
|
|
}
|
|
secondTappedSquare = event.tapped;
|
|
}
|
|
|
|
if (state.firstSquareTapped != null &&
|
|
state.firstSquareTapped != event.tapped) {
|
|
if (isPromotionMove(
|
|
state.pieceOnFirstTappedSquare!.pieceClass,
|
|
ChessBloc.myColor!,
|
|
event.tapped,
|
|
)) {
|
|
PromotionBloc().add(PawnMovedToPromotionField(
|
|
move: ChessMove(from: state.firstSquareTapped!, to: event.tapped),
|
|
colorMoved: ChessBloc.myColor!));
|
|
emit(TapState.init());
|
|
return;
|
|
} else {
|
|
ChessBloc().add(OwnPieceMoved(
|
|
startSquare: state.firstSquareTapped!, endSquare: event.tapped));
|
|
emit(TapState.init());
|
|
return;
|
|
}
|
|
}
|
|
log("handleTap() in TapBloc is called");
|
|
emit(TapState(
|
|
firstSquareTapped: firstTappedSquare,
|
|
pieceOnFirstTappedSquare: piece,
|
|
secondSquareTapped: secondTappedSquare));
|
|
}
|
|
|
|
void cancelTap(CancelTapEvent event, Emitter<TapState> emit) {
|
|
emit(TapState.init());
|
|
}
|
|
}
|
|
|
|
abstract class TapEvent {}
|
|
|
|
class SquareTappedEvent extends TapEvent {
|
|
ChessCoordinate tapped;
|
|
ChessPiece? pieceOnSquare;
|
|
|
|
SquareTappedEvent({required this.tapped, required this.pieceOnSquare});
|
|
}
|
|
|
|
class CancelTapEvent extends TapEvent {}
|
|
|
|
class TapState {
|
|
ChessCoordinate? firstSquareTapped;
|
|
ChessPiece? pieceOnFirstTappedSquare;
|
|
|
|
ChessCoordinate? secondSquareTapped;
|
|
|
|
TapState(
|
|
{required this.firstSquareTapped,
|
|
required this.pieceOnFirstTappedSquare,
|
|
required this.secondSquareTapped});
|
|
|
|
factory TapState.init() {
|
|
return TapState(
|
|
firstSquareTapped: null,
|
|
pieceOnFirstTappedSquare: null,
|
|
secondSquareTapped: null);
|
|
}
|
|
}
|