fix: promotions and board rotation

This commit is contained in:
Ashhhleyyy 2022-11-02 13:18:18 +00:00
parent a2a6ea7bc3
commit c58753cfd3
Signed by: ash
GPG key ID: 83B789081A0878FB
3 changed files with 100 additions and 40 deletions

View file

@ -1,11 +1,13 @@
import { Accessor, Component, createSignal, For, Show } from "solid-js"; import { Accessor, Component, createSignal, For, Show } from "solid-js";
import { Board as BoardData, Coordinate, Move, PieceType } from "../events"; import { Board as BoardData, Coordinate, Move, PieceType, Side } from "../events";
import './Board.css'; import './Board.css';
import Button, { ButtonContainer } from "./Button";
interface Props { interface Props {
board: Accessor<BoardData>; board: Accessor<BoardData>;
moves: Accessor<Move[]>; moves: Accessor<Move[]>;
makeMove: (move: Move) => void; makeMove: (move: Move) => void;
side: Side;
} }
const PIECE_CHARS: Record<PieceType, string> = { const PIECE_CHARS: Record<PieceType, string> = {
@ -19,6 +21,7 @@ const PIECE_CHARS: Record<PieceType, string> = {
const Board: Component<Props> = (props) => { const Board: Component<Props> = (props) => {
const [selectedSquare, setSelectedSquare] = createSignal<number | null>(null); const [selectedSquare, setSelectedSquare] = createSignal<number | null>(null);
const [promotionMove, setPromotionMove] = createSignal<Move | null>(null);
const validMoves = () => { const validMoves = () => {
const selected = selectedSquare(); const selected = selectedSquare();
@ -29,8 +32,18 @@ const Board: Component<Props> = (props) => {
} }
}; };
return <div class="board"> const board = () => {
{props.board().map((piece, i) => { if (props.side === 'white') {
return props.board().slice().reverse();
} else {
return props.board();
}
};
return <>
<div class="board">
{board().map((piece, i_) => {
const i = props.side === 'white' ? 63 - i_ : i_;
const coord: Coordinate = { const coord: Coordinate = {
rank: Math.floor(i / 8), rank: Math.floor(i / 8),
file: i % 8, file: i % 8,
@ -40,7 +53,8 @@ const Board: Component<Props> = (props) => {
const targetMove = () => validMoves().find(move => move.to.rank === coord.rank && move.to.file === coord.file); const targetMove = () => validMoves().find(move => move.to.rank === coord.rank && move.to.file === coord.file);
const isTarget = () => targetMove() !== undefined; const isTarget = () => targetMove() !== undefined;
return <div classList={{ return <>
<div classList={{
square: true, square: true,
light: isLight(), light: isLight(),
dark: !isLight(), dark: !isLight(),
@ -56,9 +70,15 @@ const Board: Component<Props> = (props) => {
} }
} else { } else {
const target = targetMove(); const target = targetMove();
if (target && !target.promotions) { console.log(target);
if (target) {
if (target.promotions) {
setPromotionMove(target);
} else {
props.makeMove(target); props.makeMove(target);
setSelectedSquare(null); setSelectedSquare(null);
setPromotionMove(null);
}
} }
} }
}}> }}>
@ -66,8 +86,26 @@ const Board: Component<Props> = (props) => {
<Show when={isTarget()}><div class="borderTarget" /></Show> <Show when={isTarget()}><div class="borderTarget" /></Show>
<Show when={piece !== null}>{PIECE_CHARS[piece!.ty]}</Show> <Show when={piece !== null}>{PIECE_CHARS[piece!.ty]}</Show>
</div> </div>
</>
})} })}
</div> </div>
<Show when={promotionMove() !== null}>
<ButtonContainer>
<For each={promotionMove()?.promotions!}>
{(promotion, i) => <Button onClick={() => {
props.makeMove({
...promotionMove()!,
promotions: [promotion],
});
setSelectedSquare(null);
setPromotionMove(null);
}}>
{promotion.ty}
</Button>}
</For>
</ButtonContainer>
</Show>
</>
} }
export default Board; export default Board;

View file

@ -400,7 +400,13 @@ pub fn generate_legal(board: &Board) -> Vec<Move> {
return false; return false;
} }
} }
let test_board = mv.make(board); let test_board = if mv.promotions.is_some() {
let mut fake_move = mv.clone();
fake_move.promotions = None;
fake_move.make(board)
} else {
mv.make(board)
};
!*test_board.calc_check_state().get(board.to_move) !*test_board.calc_check_state().get(board.to_move)
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()

View file

@ -110,7 +110,23 @@ impl Handler<IncomingEvent> for ChessGame {
return; return;
} }
let legal_moves = generate_legal(&self.board); let legal_moves = generate_legal(&self.board);
if legal_moves.contains(&mv) { let legal = if let Some(promotions) = &mv.promotions {
if promotions.len() == 1 {
legal_moves.iter().any(|m| {
m.from == mv.from
&& m.to == mv.to
&& m.set_en_passant == mv.set_en_passant
&& m.other == mv.other
&& matches!(&m.promotions, Some(p) if p.contains(&promotions[0]))
})
} else {
tracing::warn!(?incoming_event.side, ?mv, "cannot promote to more than one piece");
false
}
} else {
legal_moves.contains(&mv)
};
if legal {
self.board = mv.make(&self.board); self.board = mv.make(&self.board);
self.broadcast_new_board(); self.broadcast_new_board();
self.send_possible_moves(); self.send_possible_moves();