mchess-client/lib/chess/chess_square.dart

147 lines
4.3 KiB
Dart
Raw Normal View History

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
2022-11-13 02:42:30 +00:00
import 'package:mchess/chess_bloc/chess_bloc.dart';
2023-07-01 07:29:43 +00:00
import 'package:mchess/chess_bloc/promotion_bloc.dart';
import '../chess_bloc/chess_events.dart';
2022-12-25 15:16:23 +00:00
import '../utils/chess_utils.dart';
class ChessSquare extends StatelessWidget {
final ChessCoordinate coordinate;
final ChessPiece? containedPiece;
static const double pieceWidth = 200;
static const double pieceHeight = 200;
final Color color;
const ChessSquare._({
required this.coordinate,
required this.containedPiece,
required this.color,
});
factory ChessSquare(
ChessCoordinate coord, ChessPiece? piece, bool wasPartOfLastMove) {
Color lightSquaresColor =
wasPartOfLastMove ? Colors.green.shade200 : Colors.brown.shade50;
Color darkSquaresColor =
wasPartOfLastMove ? Colors.green.shade300 : Colors.brown.shade400;
Color squareColor;
if (coord.row % 2 == 0) {
if (coord.column % 2 == 0) {
squareColor = darkSquaresColor;
} else {
squareColor = lightSquaresColor;
}
} else {
if (coord.column % 2 == 0) {
squareColor = lightSquaresColor;
} else {
squareColor = darkSquaresColor;
}
}
return ChessSquare._(
coordinate: coord,
containedPiece: piece,
color: squareColor,
);
}
@override
Widget build(BuildContext context) {
double windowWidth = MediaQuery.of(context).size.width;
double windowHeight = MediaQuery.of(context).size.height;
double draggableFdbSize;
if (windowWidth < windowHeight) {
draggableFdbSize = 0.15 * windowWidth;
} else {
draggableFdbSize = 0.15 * windowHeight;
}
2023-07-01 07:29:43 +00:00
return DragTarget<PieceDragged>(
onWillAccept: (move) {
if (move?.fromSquare == coordinate) {
return false;
}
return true;
},
2023-07-03 17:41:12 +00:00
onAccept: (pieceDragged) {
2023-07-01 07:29:43 +00:00
// Replace the dummy value with the actual target of the move.
2023-07-03 17:41:12 +00:00
pieceDragged.toSquare = coordinate;
2023-07-01 07:29:43 +00:00
2023-07-03 17:41:12 +00:00
if (isPromotionMove(pieceDragged)) {
var move = ChessMove(
from: pieceDragged.fromSquare, to: pieceDragged.toSquare);
PromotionBloc.getInstance().add(PawnMovedToPromotionField(
move: move, colorMoved: ChessBloc.myColor!));
} else if (coordinate != pieceDragged.fromSquare) {
ChessBloc.getInstance().add(OwnPieceMoved(
2023-07-03 17:41:12 +00:00
startSquare: pieceDragged.fromSquare,
endSquare: pieceDragged.toSquare,
piece: pieceDragged.movedPiece!));
}
},
builder: (context, candidateData, rejectedData) {
var maxDrags = kDebugMode
? 1
: ((ChessBloc.turnColor == ChessBloc.myColor) &&
(containedPiece?.color == ChessBloc.turnColor)
? 1
: 0);
return Container(
color: color,
width: ChessSquare.pieceWidth,
height: ChessSquare.pieceWidth,
2023-07-01 07:29:43 +00:00
child: Draggable<PieceDragged>(
/* We create the move with the startSquare == endSquare. The receiving widget will give the correct value to end square. */
2023-07-01 07:29:43 +00:00
data: PieceDragged(coordinate, coordinate, containedPiece),
maxSimultaneousDrags: maxDrags,
feedback: FractionalTranslation(
translation: const Offset(-0.5, -0.75),
child: SizedBox(
height: draggableFdbSize,
width: draggableFdbSize,
child: containedPiece),
),
childWhenDragging: Container(),
dragAnchorStrategy: pointerDragAnchorStrategy,
child: containedPiece ?? Container(),
onDragCompleted: () {},
onDragStarted: () {},
),
);
},
);
}
2023-07-01 07:29:43 +00:00
bool isPromotionMove(PieceDragged move) {
bool isPromotion = false;
if (move.movedPiece!.pieceClass != ChessPieceClass.pawn) {
return isPromotion;
}
switch (ChessBloc.myColor) {
case ChessColor.black:
if (move.toSquare.row == 1) {
isPromotion = true;
}
break;
case ChessColor.white:
if (move.toSquare.row == 8) {
isPromotion = true;
}
break;
case null:
break;
}
return isPromotion;
}
}