computeLegalMoves function
List<LudoLegalMove>
computeLegalMoves(
- LudoGameState state,
- LudoDiceRules diceRules,
- int diceValue, {
- List<
LudoTeam> ? teams,
Computes all legal moves for the current player given diceValue.
Teams mode additions:
- A piece may land on a cell occupied by a teammate (friendly stack).
- A piece may NOT land on a safe cell occupied by ANY opponent (safe cell protection still applies).
- A piece MAY land on a non-safe cell occupied by opponents (triggering a capture).
teams — pass null for standard mode.
Implementation
List<LudoLegalMove> computeLegalMoves(
LudoGameState state,
LudoDiceRules diceRules,
int diceValue, {
List<LudoTeam>? teams,
}) {
final moves = <LudoLegalMove>[];
final playerIndex = state.currentPlayerIndex;
final myPieces = state.pieces.where((p) => p.playerIndex == playerIndex);
for (final piece in myPieces) {
if (piece.isFinished) continue;
if (piece.isHome) {
// Can only leave home on an allowed start value.
if (!diceRules.startAllowedValues.contains(diceValue)) continue;
// Starting cell — check it's not blocked by an opponent safe-stack.
if (_isBlockedByOpponent(
playerIndex: playerIndex,
trackPosition: 0,
pieces: state.pieces,
teams: teams,
)) {
continue;
}
moves.add(LudoLegalMove(
pieceId: piece.id,
playerIndex: playerIndex,
fromPosition: LudoPiece.home,
toPosition: 0,
));
continue;
}
// On-board piece — advance by diceValue.
final newPos = piece.trackPosition + diceValue;
// Cannot overshoot the finish.
if (newPos > LudoPiece.finished) continue;
// Cannot land on a cell blocked by an opponent on a safe cell.
if (newPos < LudoPiece.sharedPathSpan &&
_isBlockedByOpponent(
playerIndex: playerIndex,
trackPosition: newPos,
pieces: state.pieces,
teams: teams,
)) {
continue;
}
moves.add(LudoLegalMove(
pieceId: piece.id,
playerIndex: playerIndex,
fromPosition: piece.trackPosition,
toPosition: newPos,
));
}
return moves;
}