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);
|
||
|
}
|
||
|
}
|