Skip to content

Commit 4563eee

Browse files
authored
Merge branch 'fairy-stockfish:master' into master
2 parents d632763 + 4d1d0cc commit 4563eee

File tree

8 files changed

+76
-17
lines changed

8 files changed

+76
-17
lines changed

.github/workflows/fairy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
run:
3737
working-directory: src
3838
steps:
39-
- uses: actions/checkout@v4
39+
- uses: actions/checkout@v5
4040
with:
4141
fetch-depth: 0
4242

.github/workflows/ffishjs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
node-version: [12.x]
2020

2121
steps:
22-
- uses: actions/checkout@v4
22+
- uses: actions/checkout@v5
2323
- name: Setup cache
2424
id: cache-system-libraries
2525
uses: actions/cache@v4
@@ -53,7 +53,7 @@ jobs:
5353
node-version: [12.x]
5454

5555
steps:
56-
- uses: actions/checkout@v4
56+
- uses: actions/checkout@v5
5757
- name: Setup cache
5858
id: cache-system-libraries
5959
uses: actions/cache@v4

.github/workflows/release.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
maximum-size: 16GB
2121
disk-root: "C:"
2222

23-
- uses: actions/checkout@v4
23+
- uses: actions/checkout@v5
2424

2525
- name: make
2626
run: cd src && make clean && make -j build COMP=mingw ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }}.exe && strip fairy-stockfish_${{ matrix.arch }}.exe
@@ -46,7 +46,7 @@ jobs:
4646
runs-on: ubuntu-24.04
4747

4848
steps:
49-
- uses: actions/checkout@v4
49+
- uses: actions/checkout@v5
5050

5151
- name: make
5252
run: cd src && make clean && make -j build COMP=gcc ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }} && strip fairy-stockfish_${{ matrix.arch }}
@@ -72,7 +72,7 @@ jobs:
7272
runs-on: macos-13
7373

7474
steps:
75-
- uses: actions/checkout@v4
75+
- uses: actions/checkout@v5
7676

7777
- name: make
7878
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }} && strip fairy-stockfish_${{ matrix.arch }}
@@ -97,7 +97,7 @@ jobs:
9797
runs-on: macos-14
9898

9999
steps:
100-
- uses: actions/checkout@v4
100+
- uses: actions/checkout@v5
101101

102102
- name: make
103103
run: cd src && make clean && make -j build COMP=clang ARCH=${{ matrix.arch }} EXE=fairy-stockfish_${{ matrix.arch }} && strip fairy-stockfish_${{ matrix.arch }}

.github/workflows/stockfish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
run:
4040
working-directory: src
4141
steps:
42-
- uses: actions/checkout@v4
42+
- uses: actions/checkout@v5
4343
with:
4444
fetch-depth: 0
4545

.github/workflows/wheels.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
os: [ubuntu-24.04, windows-2022, macos-13]
1818

1919
steps:
20-
- uses: actions/checkout@v4
20+
- uses: actions/checkout@v5
2121

2222
# Used to host cibuildwheel
2323
- uses: actions/setup-python@v5
@@ -43,7 +43,7 @@ jobs:
4343
name: Build source distribution
4444
runs-on: ubuntu-24.04
4545
steps:
46-
- uses: actions/checkout@v4
46+
- uses: actions/checkout@v5
4747
- uses: actions/setup-python@v5
4848
with:
4949
python-version: '3.9'

src/position.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,10 +1127,12 @@ bool Position::legal(Move m) const {
11271127
// Chess960 as they would be in standard chess.
11281128
kto = make_square(to > from ? castling_kingside_file() : castling_queenside_file(), castling_rank(us));
11291129
Direction step = kto > from ? EAST : WEST;
1130-
Square rto = kto - step;
1130+
Square rto = kto - (to > from ? EAST : WEST);
11311131
// Pseudo-royal king
11321132
if (st->pseudoRoyals & from)
1133-
for (Square s = from; s != kto; s += step)
1133+
// Loop over squares between the king and its final position
1134+
// Ensure to include the initial square if from == kto
1135+
for (Square s = from; from != kto ? s != kto : s == from; s += step)
11341136
if ( !(blast_on_capture() && (attacks_bb<KING>(s) & st->pseudoRoyals & pieces(~sideToMove)))
11351137
&& attackers_to(s, occupied, ~us))
11361138
return false;
@@ -1146,6 +1148,9 @@ bool Position::legal(Move m) const {
11461148
if (capture(m) && (var->petrifyOnCaptureTypes & type_of(moved_piece(m))) && (st->pseudoRoyals & from))
11471149
return false;
11481150
Bitboard pseudoRoyals = st->pseudoRoyals & pieces(sideToMove);
1151+
// Add dropped pseudo-royal
1152+
if (type_of(m) == DROP && (extinction_piece_types() & type_of(moved_piece(m))))
1153+
pseudoRoyals |= square_bb(to);
11491154
Bitboard pseudoRoyalsTheirs = st->pseudoRoyals & pieces(~sideToMove);
11501155
if (is_ok(from) && (pseudoRoyals & from))
11511156
pseudoRoyals ^= square_bb(from) ^ kto;

test.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@
120120
castlingKingPiece = k
121121
extinctionValue = loss
122122
extinctionPieceTypes = k
123+
124+
[coregaldrop:coregal]
125+
pieceDrops = true
126+
startFen = rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[Qq] w KQkq - 0 1
127+
128+
[cannonatomic:atomic]
129+
cannon = c
123130
"""
124131

125132
sf.load_variant_config(ini_text)
@@ -346,6 +353,11 @@ def test_legal_moves(self):
346353
result = sf.legal_moves("seirawan", fen, [])
347354
self.assertIn("c8g4h", result)
348355

356+
# Drop pseudo-royals into check
357+
result = sf.legal_moves("coregaldrop", sf.start_fen("coregaldrop"), [])
358+
self.assertIn("Q@a3", result)
359+
self.assertNotIn("Q@a6", result)
360+
349361
# In Cannon Shogi the FGC and FSC can also move one square diagonally and, besides,
350362
# move or capture two squares diagonally, by leaping an adjacent piece.
351363
fen = "lnsg1gsnl/1rc1kuab1/p1+A1p1p1p/3P5/6i2/6P2/P1P1P3P/1B1U1ICR1/LNSGKGSNL[] w - - 1 3"
@@ -397,7 +409,7 @@ def test_legal_moves(self):
397409
self.assertEqual(['d4c2', 'd4f3', 'd4b5', 'd4e6'], result)
398410

399411

400-
def test_short_castling(self):
412+
def test_castling(self):
401413
legals = ['f5f4', 'a7a6', 'b7b6', 'c7c6', 'd7d6', 'e7e6', 'i7i6', 'j7j6', 'a7a5', 'b7b5', 'c7c5', 'e7e5', 'i7i5', 'j7j5', 'b8a6', 'b8c6', 'h6g4', 'h6i4', 'h6j5', 'h6f7', 'h6g8', 'h6i8', 'd5a2', 'd5b3', 'd5f3', 'd5c4', 'd5e4', 'd5c6', 'd5e6', 'd5f7', 'd5g8', 'j8g8', 'j8h8', 'j8i8', 'e8f7', 'c8b6', 'c8d6', 'g6g2', 'g6g3', 'g6f4', 'g6g4', 'g6h4', 'g6e5', 'g6g5', 'g6i5', 'g6a6', 'g6b6', 'g6c6', 'g6d6', 'g6e6', 'g6f6', 'g6h8', 'f8f7', 'f8g8', 'f8i8']
402414
moves = ['b2b4', 'f7f5', 'c2c3', 'g8d5', 'a2a4', 'h8g6', 'f2f3', 'i8h6', 'h2h3']
403415
result = sf.legal_moves("capablanca", CAPA, moves)
@@ -417,6 +429,20 @@ def test_short_castling(self):
417429
result = sf.legal_moves("diana", "rbnk1r/pppbpp/3p2/5P/PPPPPB/RBNK1R w KQkq - 2 3", [])
418430
self.assertIn("d1f1", result)
419431

432+
# Atomic960 castling
433+
fen = "7k/8/8/8/8/8/2PP4/1RK4q w Q - 0 1"
434+
moves = sf.legal_moves("atomic", fen, [], True)
435+
# 'c1b1' is the castling move (king to rook square in 960 encoding) and must be illegal
436+
self.assertNotIn("c1b1", moves)
437+
# A normal king/commoner move like c1b2 should remain legal
438+
self.assertIn("c1b2", moves)
439+
440+
# Atomic960 anti-discovered check with cannon
441+
fen = "8/8/8/8/8/6k1/8/c5KR w K - 0 1"
442+
moves = sf.legal_moves("cannonatomic", fen, [], True)
443+
self.assertNotIn("g1h1", moves)
444+
self.assertIn("g1f1", moves)
445+
420446
# Check that in variants where castling rooks are not in the corner
421447
# the castling rook is nevertheless assigned correctly
422448
result = sf.legal_moves("shako", "c8c/ernbqkbnre/pppppppppp/10/10/10/10/PPPPPPPPPP/5K2RR/10 w Kkq - 0 1", [])

tests/regression.sh

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
11
#!/bin/bash
22
# regression test variant bench numbers
3-
# arguments: ./old_engine ./new_engine variant1 variant2 variant3 ...
3+
# arguments: ./old_engine ./new_engine "bench_args" [variant1 variant2 variant3 ...]
4+
# examples:
5+
# Pure bench: ./regression.sh ./old_engine ./new_engine "" chess xiangqi shogi
6+
# Perft bench: ./regression.sh ./old_engine ./new_engine "16 1 5 default perft" chess xiangqi shogi
7+
# Auto-detect common variants: ./regression.sh ./old_engine ./new_engine ""
48

59
echo "variant $1 $2"
6-
for var in "${@:3}"
10+
bench_args="$3"
11+
12+
# If no variants provided, extract them from UCI output
13+
if [ $# -eq 3 ]; then
14+
echo "No variants specified, extracting from UCI output..."
15+
16+
# Extract variants from first engine
17+
variants1=$(echo "uci" | $1 2>/dev/null | grep "option name UCI_Variant" | grep -o 'var [^[:space:]]*' | sed 's/var //' | sort)
18+
19+
# Extract variants from second engine
20+
variants2=$(echo "uci" | $2 2>/dev/null | grep "option name UCI_Variant" | grep -o 'var [^[:space:]]*' | sed 's/var //' | sort)
21+
22+
# Find intersection of variants (common to both engines)
23+
variants=$(comm -12 <(echo "$variants1") <(echo "$variants2"))
24+
25+
echo "Common variants found: $(echo $variants | wc -w)"
26+
27+
# Convert to array for processing
28+
variant_array=($variants)
29+
else
30+
# Use provided variants
31+
variant_array=("${@:4}")
32+
fi
33+
34+
for var in "${variant_array[@]}"
735
do
8-
ref=`$1 bench $var 2>&1 | grep "Nodes searched : " | awk '{print $4}'`
9-
signature=`$2 bench $var 2>&1 | grep "Nodes searched : " | awk '{print $4}'`
36+
ref=`$1 bench $var $bench_args 2>&1 | grep "Nodes searched : " | awk '{print $4}'`
37+
signature=`$2 bench $var $bench_args 2>&1 | grep "Nodes searched : " | awk '{print $4}'`
1038
if [ -z "$ref" ]; then
1139
echo "${var} none ${signature} <-- no reference"
1240
elif [ -z "$signature" ]; then

0 commit comments

Comments
 (0)