fix: promotions and board rotation
This commit is contained in:
parent
a2a6ea7bc3
commit
c58753cfd3
3 changed files with 100 additions and 40 deletions
|
@ -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;
|
||||||
|
|
|
@ -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<_>>()
|
||||||
|
|
18
src/game.rs
18
src/game.rs
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue