chess 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +44 -0
- data/Rakefile +6 -7
- data/chess.gemspec +1 -1
- data/ext/bitboard.c +24 -0
- data/ext/board.c +78 -24
- data/ext/board.h +4 -2
- data/ext/chess.c +216 -196
- data/ext/chess.h +1 -0
- data/ext/common.c +10 -0
- data/ext/game.c +33 -16
- data/ext/special.c +14 -11
- data/ext/special.h +1 -2
- data/lib/chess/exceptions.rb +7 -10
- data/lib/chess/game.rb +66 -50
- data/lib/chess/gnuchess.rb +19 -25
- data/lib/chess/pgn.rb +49 -9
- data/lib/chess/utf8_notation.rb +11 -9
- data/lib/chess/version.rb +1 -1
- data/test/pgn_collection/illegal/0001.pgn +18 -0
- data/test/pgn_collection/illegal/0002.pgn +17 -0
- data/test/pgn_collection/illegal/0003.pgn +13 -0
- data/test/pgn_collection/illegal/0004.pgn +15 -0
- data/test/pgn_collection/illegal/0005.pgn +16 -0
- data/test/pgn_collection/invalid/0001.pgn +20 -0
- data/test/pgn_collection/invalid/0002.pgn +16 -0
- data/test/pgn_collection/invalid/0003.pgn +13 -0
- data/test/pgn_collection/invalid/0004.pgn +15 -0
- data/test/pgn_collection/valid/0001.pgn +6 -7
- data/test/pgn_collection/valid/0002.pgn +8 -9
- data/test/pgn_collection/valid/0005.pgn +7 -8
- data/test/pgn_collection/valid/0009.pgn +14 -15
- data/test/pgn_collection/valid/0010.pgn +6 -7
- data/test/pgn_collection/valid/0011.pgn +5 -6
- data/test/pgn_collection/valid/0012.pgn +0 -1
- data/test/pgn_collection/valid/0013.pgn +5 -6
- data/test/pgn_collection/valid/0014.pgn +6 -7
- data/test/pgn_collection/valid/0020.pgn +6 -7
- data/test/pgn_collection/valid/0021.pgn +15 -16
- data/test/pgn_collection/valid/0971.pgn +22 -14
- data/test/test_big_pgn_collection.rb +12 -5
- data/test/test_helper.rb +1 -1
- data/test/test_illegal_moves.rb +14 -0
- data/test/test_insufficient_material.rb +13 -1
- data/test/test_particular_situations.rb +14 -0
- data/test/test_pgn.rb +24 -0
- data/test/test_pgn_collection.rb +1 -4
- metadata +30 -63
- data/README.rdoc +0 -44
- data/doc/Chess.html +0 -112
- data/doc/Chess/BadNotationError.html +0 -107
- data/doc/Chess/Board.html +0 -700
- data/doc/Chess/CGame.html +0 -1004
- data/doc/Chess/Game.html +0 -684
- data/doc/Chess/Gnuchess.html +0 -215
- data/doc/Chess/IllegalMoveError.html +0 -105
- data/doc/Chess/InvalidFenFormatError.html +0 -105
- data/doc/Chess/InvalidPgnFormatError.html +0 -105
- data/doc/Chess/Pgn.html +0 -309
- data/doc/Chess/UTF8Notation.html +0 -174
- data/doc/README_rdoc.html +0 -143
- data/doc/created.rid +0 -15
- data/doc/css/fonts.css +0 -167
- data/doc/css/rdoc.css +0 -590
- data/doc/fonts/Lato-Light.ttf +0 -0
- data/doc/fonts/Lato-LightItalic.ttf +0 -0
- data/doc/fonts/Lato-Regular.ttf +0 -0
- data/doc/fonts/Lato-RegularItalic.ttf +0 -0
- data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +0 -160
- data/doc/js/darkfish.js +0 -161
- data/doc/js/jquery.js +0 -4
- data/doc/js/navigation.js +0 -142
- data/doc/js/navigation.js.gz +0 -0
- data/doc/js/search.js +0 -109
- data/doc/js/search_index.js +0 -1
- data/doc/js/search_index.js.gz +0 -0
- data/doc/js/searcher.js +0 -229
- data/doc/js/searcher.js.gz +0 -0
- data/doc/table_of_contents.html +0 -331
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72831c5ff5567709d9ce1e377c98d7867b35b611
|
4
|
+
data.tar.gz: 0af6a358a253414ad636d9fec050eb1dd5ccfbc9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf1c0fc216c2e2a76e978b96c4e668eed29d23eef23606280075b58d42a717b27d1fdfe50c1dae6961ffac71d4272ada39c6a3f8a8e2b69d5b16a33c24114abe
|
7
|
+
data.tar.gz: 3544641ba2184d3965574c912472defad0e49020c650ae9f2a342683dddd02b81ced292156c3828d987b6001f5e8993a252c4950bc56bd965de827d5f858e03e
|
data/.gitignore
CHANGED
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Chess
|
2
|
+
|
3
|
+
A fast Ruby library to play chess with Ruby. This library is quite fast
|
4
|
+
because rappresent the game situations with bitboards. In addition, the move
|
5
|
+
generator is written in C as a Ruby extension.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
* Ruby 1.9 or higher
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
gem install chess
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
require 'chess'
|
18
|
+
g = Chess::Game.new
|
19
|
+
until g.over?
|
20
|
+
begin
|
21
|
+
print "Give me a #{g.active_player} move: "
|
22
|
+
input = gets.chop
|
23
|
+
break if input == 'quit'
|
24
|
+
g << input
|
25
|
+
puts g
|
26
|
+
puts g.moves.last
|
27
|
+
rescue Chess::IllegalMoveError => e
|
28
|
+
puts 'Illegal move!'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
puts g.status
|
32
|
+
|
33
|
+
**Documentation** is available [here](http://pioz.github.com/chess).
|
34
|
+
|
35
|
+
## Questions or problems?
|
36
|
+
|
37
|
+
If you have any issues please add an [issue on
|
38
|
+
GitHub](https://github.com/pioz/chess/issues) or fork the project and send a
|
39
|
+
pull request.
|
40
|
+
|
41
|
+
## Copyright
|
42
|
+
|
43
|
+
Copyright (c) 2017 [Enrico Pilotto (@pioz)](https://github.com/pioz). See
|
44
|
+
[LICENSE](https://github.com/pioz/chess/blob/master/LICENSE) for details.
|
data/Rakefile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
|
3
|
-
require '
|
4
|
-
Rake::
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
rd.generator = 'darkfish'
|
3
|
+
require 'yard'
|
4
|
+
YARD::Rake::YardocTask.new do |t|
|
5
|
+
t.files = ['lib/**/*.rb', 'ext/*.c']
|
6
|
+
t.options << '-rREADME.md'
|
7
|
+
t.options << '--title=Chess'
|
8
|
+
t.options << '-mmarkdown'
|
10
9
|
end
|
11
10
|
|
12
11
|
require 'rake/testtask'
|
data/chess.gemspec
CHANGED
@@ -24,5 +24,5 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_development_dependency 'bundler', '~> 1.14'
|
25
25
|
s.add_development_dependency 'rake', '~> 12.0'
|
26
26
|
s.add_development_dependency 'minitest', '~> 5.10'
|
27
|
-
s.add_development_dependency '
|
27
|
+
s.add_development_dependency 'yard', '~> 0.9'
|
28
28
|
end
|
data/ext/bitboard.c
CHANGED
@@ -73,12 +73,15 @@ const bboard AVOID_WRAP[8] =
|
|
73
73
|
};
|
74
74
|
|
75
75
|
// Bitboard getters
|
76
|
+
|
77
|
+
// Given file and rank returns the square (0..63).
|
76
78
|
int
|
77
79
|
square (int file, int rank)
|
78
80
|
{
|
79
81
|
return 8 * rank + file;
|
80
82
|
}
|
81
83
|
|
84
|
+
// Given a bitboard returns the first square (0..63) with a piece.
|
82
85
|
int
|
83
86
|
square2 (bboard b)
|
84
87
|
{
|
@@ -91,6 +94,7 @@ square2 (bboard b)
|
|
91
94
|
return pos;
|
92
95
|
}
|
93
96
|
|
97
|
+
// Returns the array and its size (n) with pieces in the bitboard.
|
94
98
|
void
|
95
99
|
squares (bboard b, int *array, int *n)
|
96
100
|
{
|
@@ -103,29 +107,36 @@ squares (bboard b, int *array, int *n)
|
|
103
107
|
}
|
104
108
|
}
|
105
109
|
|
110
|
+
// Given a square returns the corresponding file.
|
106
111
|
int
|
107
112
|
file (int square)
|
108
113
|
{
|
109
114
|
return square & 7;
|
110
115
|
}
|
111
116
|
|
117
|
+
// Given a square returns the corresponding rank.
|
112
118
|
int rank (int square)
|
113
119
|
{
|
114
120
|
return square >> 3;
|
115
121
|
}
|
116
122
|
|
123
|
+
// Given a bitboard and a square (0..63) returns a bitboard copy with square set
|
124
|
+
// to 1.
|
117
125
|
bboard
|
118
126
|
get (bboard b, int square)
|
119
127
|
{
|
120
128
|
return b & (1ULL << square);
|
121
129
|
}
|
122
130
|
|
131
|
+
// Given a bitboard, a file and a rank returns a bitboard copy with square set
|
132
|
+
// to 1.
|
123
133
|
bboard
|
124
134
|
get2 (bboard b, int file, int rank)
|
125
135
|
{
|
126
136
|
return b & (1ULL << (8 * rank + file));
|
127
137
|
}
|
128
138
|
|
139
|
+
// Print the bitboard.
|
129
140
|
void
|
130
141
|
print_bitboard (bboard b)
|
131
142
|
{
|
@@ -139,24 +150,28 @@ print_bitboard (bboard b)
|
|
139
150
|
|
140
151
|
// Bitboard manipulations
|
141
152
|
|
153
|
+
// Returns true if the bitboard has only one bit equals to 1.
|
142
154
|
bboard
|
143
155
|
has_only_one_one (bboard b)
|
144
156
|
{
|
145
157
|
return b && !(b & (b-1));
|
146
158
|
}
|
147
159
|
|
160
|
+
// Returns true if the bitboard has only bits equals to 1 in the white squares.
|
148
161
|
bboard
|
149
162
|
only_white_squares (bboard b)
|
150
163
|
{
|
151
164
|
return !((b ^ WHITE_SQUARES) & b);
|
152
165
|
}
|
153
166
|
|
167
|
+
// Returns true if the bitboard has only bits equals to 1 in the black squares.
|
154
168
|
bboard
|
155
169
|
only_black_squares (bboard b)
|
156
170
|
{
|
157
171
|
return !((b ^ BLACK_SQUARES) & b);
|
158
172
|
}
|
159
173
|
|
174
|
+
// Returns the horizontally mirrored bitboard.
|
160
175
|
bboard
|
161
176
|
mirror_horizontal (bboard b)
|
162
177
|
{
|
@@ -169,6 +184,7 @@ mirror_horizontal (bboard b)
|
|
169
184
|
return b;
|
170
185
|
}
|
171
186
|
|
187
|
+
// Returns the vertically mirrored bitboard.
|
172
188
|
bboard
|
173
189
|
mirror_vertical (bboard b)
|
174
190
|
{
|
@@ -180,6 +196,7 @@ mirror_vertical (bboard b)
|
|
180
196
|
return b;
|
181
197
|
}
|
182
198
|
|
199
|
+
// Returns the left rotated bitboard.
|
183
200
|
bboard
|
184
201
|
rotate_left (bboard b, int s)
|
185
202
|
{
|
@@ -188,6 +205,7 @@ rotate_left (bboard b, int s)
|
|
188
205
|
return s > 0 ? b << s : b >> -s;
|
189
206
|
}
|
190
207
|
|
208
|
+
// Returns the right rotated bitboard.
|
191
209
|
bboard
|
192
210
|
rotate_right (bboard b, int s)
|
193
211
|
{
|
@@ -196,6 +214,8 @@ rotate_right (bboard b, int s)
|
|
196
214
|
return s > 0 ? b >> s : b << -s;
|
197
215
|
}
|
198
216
|
|
217
|
+
// Given a generator, a propagator and a direction returns the bitboard with
|
218
|
+
// occluded squares setted to 1.
|
199
219
|
bboard
|
200
220
|
occluded_fill (bboard gen, bboard pro, int dir)
|
201
221
|
{
|
@@ -209,12 +229,14 @@ occluded_fill (bboard gen, bboard pro, int dir)
|
|
209
229
|
return gen;
|
210
230
|
}
|
211
231
|
|
232
|
+
// Returns the shifted bitboard.
|
212
233
|
bboard
|
213
234
|
shift_one (bboard b, int dir)
|
214
235
|
{
|
215
236
|
return rotate_left (b, DIR[dir]) & AVOID_WRAP[dir];
|
216
237
|
}
|
217
238
|
|
239
|
+
// Returns the bitboard with sliding attacks.
|
218
240
|
bboard
|
219
241
|
sliding_attacks (bboard slider, bboard propagator, int dir)
|
220
242
|
{
|
@@ -223,6 +245,7 @@ sliding_attacks (bboard slider, bboard propagator, int dir)
|
|
223
245
|
}
|
224
246
|
|
225
247
|
// Pre-calculators
|
248
|
+
|
226
249
|
void
|
227
250
|
precalculate_xray_attack_white_pawn (bboard xray[64])
|
228
251
|
{
|
@@ -281,6 +304,7 @@ precalculate_all_xray ()
|
|
281
304
|
}
|
282
305
|
|
283
306
|
// XRay generators
|
307
|
+
|
284
308
|
bboard
|
285
309
|
xray_white_pawn (bboard occupied_square, int square)
|
286
310
|
{
|
data/ext/board.c
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
#include "board.h"
|
9
9
|
|
10
|
+
// Initialize the board
|
10
11
|
void
|
11
12
|
init_board (Board *board)
|
12
13
|
{
|
@@ -32,6 +33,7 @@ init_board (Board *board)
|
|
32
33
|
set_occupied (board);
|
33
34
|
}
|
34
35
|
|
36
|
+
// Set helpers bitboards (white pieces, black pieces, occupied squares).
|
35
37
|
void
|
36
38
|
set_occupied (Board *board)
|
37
39
|
{
|
@@ -50,6 +52,7 @@ set_occupied (Board *board)
|
|
50
52
|
board->occupied = board->pieces[WHITE] | board->pieces[BLACK];
|
51
53
|
}
|
52
54
|
|
55
|
+
// Board to string.
|
53
56
|
char*
|
54
57
|
print_board (Board *board)
|
55
58
|
{
|
@@ -72,6 +75,7 @@ print_board (Board *board)
|
|
72
75
|
return s;
|
73
76
|
}
|
74
77
|
|
78
|
+
// Given a square returns its color (white is 0, black is 1).
|
75
79
|
int
|
76
80
|
get_color (Board *board, int square)
|
77
81
|
{
|
@@ -85,6 +89,7 @@ get_color (Board *board, int square)
|
|
85
89
|
return -1;
|
86
90
|
}
|
87
91
|
|
92
|
+
// Given a piece returns the piece's bitboard.
|
88
93
|
bboard*
|
89
94
|
get_piece_bitboard (Board *board, char piece)
|
90
95
|
{
|
@@ -107,12 +112,15 @@ get_piece_bitboard (Board *board, char piece)
|
|
107
112
|
}
|
108
113
|
}
|
109
114
|
|
115
|
+
// Given a square (0..63) retuns the piece's bitboard in that square.
|
110
116
|
bboard*
|
111
117
|
get_bitboard (Board *board, int square)
|
112
118
|
{
|
113
119
|
return get_piece_bitboard (board, board->placement[square]);
|
114
120
|
}
|
115
121
|
|
122
|
+
// Returns the bitboard with the xray that start from square. If only_attack use
|
123
|
+
// only pawns attack squares.
|
116
124
|
bboard
|
117
125
|
xray (Board *board, int from, bool only_attack)
|
118
126
|
{
|
@@ -140,7 +148,8 @@ xray (Board *board, int from, bool only_attack)
|
|
140
148
|
}
|
141
149
|
}
|
142
150
|
|
143
|
-
|
151
|
+
|
152
|
+
// Returns the bitboard with all the xray that start from the color pieces.
|
144
153
|
bboard
|
145
154
|
all_xray (Board *board, int color, bool only_attack)
|
146
155
|
{
|
@@ -155,13 +164,15 @@ all_xray (Board *board, int color, bool only_attack)
|
|
155
164
|
return x;
|
156
165
|
}
|
157
166
|
|
158
|
-
//
|
167
|
+
// Returns the bitboard with all the xray that start from the color pieces with
|
168
|
+
// friend squares removed.
|
159
169
|
bboard
|
160
|
-
|
170
|
+
all_xray_without_friends (Board *board, int color, bool only_attack)
|
161
171
|
{
|
162
172
|
return all_xray (board, color, only_attack) & ~board->pieces[color];
|
163
173
|
}
|
164
174
|
|
175
|
+
// Returns a new board with the piece in square position removed.
|
165
176
|
void
|
166
177
|
remove_piece (Board *board, int square, Board *new_board)
|
167
178
|
{
|
@@ -174,7 +185,8 @@ remove_piece (Board *board, int square, Board *new_board)
|
|
174
185
|
}
|
175
186
|
}
|
176
187
|
|
177
|
-
//
|
188
|
+
// Returns the squares of the same pieces of color and its size that can capture
|
189
|
+
// the square. If piece_filter consider only that kind of pieces.
|
178
190
|
int
|
179
191
|
same_pieces_that_can_capture_a_square (Board *board, int color, int square, int *pieces, char piece_filter)
|
180
192
|
{
|
@@ -195,13 +207,15 @@ same_pieces_that_can_capture_a_square (Board *board, int color, int square, int
|
|
195
207
|
return index;
|
196
208
|
}
|
197
209
|
|
210
|
+
// Returns true if square can be captured from color pieces.
|
198
211
|
bool
|
199
212
|
capture (Board *board, int color, int square)
|
200
213
|
{
|
201
|
-
return
|
214
|
+
return all_xray_without_friends (board, color, FALSE) & (1ULL << square) ? TRUE : FALSE;
|
202
215
|
}
|
203
216
|
|
204
|
-
//
|
217
|
+
// Returns true if there is a piece that can capture the square without put its
|
218
|
+
// king in check.
|
205
219
|
bool
|
206
220
|
pieces_can_safe_capture (Board *board, int color, int square)
|
207
221
|
{
|
@@ -209,20 +223,22 @@ pieces_can_safe_capture (Board *board, int color, int square)
|
|
209
223
|
return same_pieces_that_can_capture_a_square (board, color, square, pieces, 0) > 0;
|
210
224
|
}
|
211
225
|
|
226
|
+
// Returns true if the king color is in check.
|
212
227
|
bool
|
213
228
|
king_in_check (Board *board, int color)
|
214
229
|
{
|
215
|
-
return
|
230
|
+
return all_xray_without_friends (board, !color, TRUE) & board->king[color] ? TRUE : FALSE;
|
216
231
|
}
|
217
232
|
|
218
|
-
// Assumes that king is in
|
233
|
+
// Returns true if the king color is in check. Assumes that the king is in
|
234
|
+
// check.
|
219
235
|
bool
|
220
236
|
king_in_checkmate (Board *board, int color)
|
221
237
|
{
|
222
238
|
int king_square = square2 (board->king[color]);
|
223
239
|
bboard king = xray_king (king_square) & ~board->pieces[color];
|
224
240
|
Board board_without_king;
|
225
|
-
remove_piece (board, king_square, &board_without_king); // King
|
241
|
+
remove_piece (board, king_square, &board_without_king); // King can't be auto-shielded xray
|
226
242
|
bboard attackers = all_xray (&board_without_king, !color, TRUE);
|
227
243
|
// If king can move return false
|
228
244
|
if (king & ~attackers)
|
@@ -237,7 +253,8 @@ king_in_checkmate (Board *board, int color)
|
|
237
253
|
if (pieces_can_safe_capture (board, color, attacker))
|
238
254
|
return FALSE;
|
239
255
|
// Test if there is an en passant capture
|
240
|
-
if (
|
256
|
+
if (have_en_passant (board, attacker + 1, board->en_passant) ||
|
257
|
+
have_en_passant (board, attacker - 1, board->en_passant))
|
241
258
|
return FALSE;
|
242
259
|
// Test if attack can be shielded
|
243
260
|
bboard slide = EMPTY_BOARD;
|
@@ -249,7 +266,7 @@ king_in_checkmate (Board *board, int color)
|
|
249
266
|
break;
|
250
267
|
}
|
251
268
|
bboard attack = xray (board, attacker, TRUE) & slide;
|
252
|
-
bboard defend =
|
269
|
+
bboard defend = all_xray_without_friends (board, color, FALSE);
|
253
270
|
bboard shield = attack & defend;
|
254
271
|
if (shield)
|
255
272
|
{
|
@@ -263,6 +280,7 @@ king_in_checkmate (Board *board, int color)
|
|
263
280
|
return TRUE;
|
264
281
|
}
|
265
282
|
|
283
|
+
// Returns true if the color pieces are in stale.
|
266
284
|
bool
|
267
285
|
stalemate (Board *board, int color)
|
268
286
|
{
|
@@ -285,6 +303,7 @@ stalemate (Board *board, int color)
|
|
285
303
|
return TRUE;
|
286
304
|
}
|
287
305
|
|
306
|
+
// Returns true if there are insufficient material to make a checkmate.
|
288
307
|
bool
|
289
308
|
insufficient_material (Board *board)
|
290
309
|
{
|
@@ -310,15 +329,40 @@ insufficient_material (Board *board)
|
|
310
329
|
|| (only_black_squares(board->bishops[WHITE]) && only_black_squares(board->bishops[BLACK])))
|
311
330
|
return TRUE;
|
312
331
|
}
|
332
|
+
// TODO more bishops on same color square
|
313
333
|
return FALSE;
|
314
334
|
}
|
315
335
|
|
336
|
+
// Returns true if on the board there are only the two kings.
|
337
|
+
bool
|
338
|
+
only_kings (Board *board)
|
339
|
+
{
|
340
|
+
return !board->pawns[WHITE] && !board->pawns[BLACK] &&
|
341
|
+
!board->rooks[WHITE] && !board->rooks[BLACK] &&
|
342
|
+
!board->knights[WHITE] && !board->knights[BLACK] &&
|
343
|
+
!board->bishops[WHITE] && !board->bishops[BLACK] &&
|
344
|
+
!board->queens[WHITE] && !board->queens[BLACK];
|
345
|
+
}
|
346
|
+
|
347
|
+
// Returns true if fifty move rule is available.
|
316
348
|
bool
|
317
349
|
fifty_move_rule (Board *board)
|
318
350
|
{
|
319
351
|
return board->halfmove_clock >= 50;
|
320
352
|
}
|
321
353
|
|
354
|
+
// Returns true if the move from-to can not promote the pawn.
|
355
|
+
bool
|
356
|
+
invalid_promotion (Board *board, int from, int to)
|
357
|
+
{
|
358
|
+
if (toupper (board->placement[from]) != 'P')
|
359
|
+
return TRUE;
|
360
|
+
if ((board->active_color ? 0xffffffffffffff00 : 0x00ffffffffffffff) & (1ULL << to))
|
361
|
+
return TRUE;
|
362
|
+
return FALSE;
|
363
|
+
}
|
364
|
+
|
365
|
+
// Returns true if the move from-to is pseudo legal.
|
322
366
|
bool
|
323
367
|
pseudo_legal_move (Board *board, int from, int to)
|
324
368
|
{
|
@@ -336,7 +380,9 @@ pseudo_legal_move (Board *board, int from, int to)
|
|
336
380
|
return x & (1ULL << to) ? TRUE : FALSE;
|
337
381
|
}
|
338
382
|
|
339
|
-
|
383
|
+
// Returns true if the move piece-dis-to is legal. Returns also [from, to]
|
384
|
+
// coordinate (0..63). Pseudo legal move check included.
|
385
|
+
bool
|
340
386
|
get_coord (Board *board, char piece, const char *disambiguating, const char *to_coord, char promote_in, int *from, int *to)
|
341
387
|
{
|
342
388
|
int count = 0;
|
@@ -355,10 +401,10 @@ get_coord (Board *board, char piece, const char *disambiguating, const char *to_
|
|
355
401
|
{
|
356
402
|
file = square_to_file (i);
|
357
403
|
rank = square_to_rank (i);
|
358
|
-
if (!
|
359
|
-
|
360
|
-
|
361
|
-
|
404
|
+
if (!disambiguating
|
405
|
+
|| disambiguating[0] == file
|
406
|
+
|| disambiguating[0] == rank
|
407
|
+
|| (disambiguating[0] == file && disambiguating[1] == rank))
|
362
408
|
{
|
363
409
|
Board new_board;
|
364
410
|
if (try_move (board, i, *to, promote_in, &new_board, 0, 0))
|
@@ -371,14 +417,23 @@ get_coord (Board *board, char piece, const char *disambiguating, const char *to_
|
|
371
417
|
}
|
372
418
|
}
|
373
419
|
if (count != 1)
|
374
|
-
|
420
|
+
{
|
421
|
+
*from = *to = 0;
|
422
|
+
return FALSE;
|
423
|
+
}
|
375
424
|
// For compatibility: if pawn capture a file disambiguating is required
|
376
|
-
|
377
|
-
|
425
|
+
if (piece == 'P' && !disambiguating && square_to_file (*from) != square_to_file (*to))
|
426
|
+
{
|
378
427
|
*from = *to = 0;
|
428
|
+
return FALSE;
|
429
|
+
}
|
430
|
+
return TRUE;
|
379
431
|
}
|
380
432
|
|
381
|
-
//
|
433
|
+
// Returns true if the move from-to can be performed. Returns also the short
|
434
|
+
// algebraic chess notation of the move and the captured piece if occured.
|
435
|
+
// Assume that the move is pseudo legal. Do not consider castling, this is
|
436
|
+
// handled separately.
|
382
437
|
bool
|
383
438
|
try_move (Board *board, int from, int to, char promote_in, Board *new_board, char **move_done, char *capture)
|
384
439
|
{
|
@@ -403,10 +458,7 @@ try_move (Board *board, int from, int to, char promote_in, Board *new_board, cha
|
|
403
458
|
new_board->placement[from] = 0;
|
404
459
|
// Promotion check
|
405
460
|
if (require_a_promotion (new_board))
|
406
|
-
|
407
|
-
if (!promote (new_board, to, promote_in))
|
408
|
-
return FALSE;
|
409
|
-
}
|
461
|
+
promote (new_board, to, promote_in);
|
410
462
|
else
|
411
463
|
promote_in = 0;
|
412
464
|
// Set occupied pieces in new board
|
@@ -420,6 +472,7 @@ try_move (Board *board, int from, int to, char promote_in, Board *new_board, cha
|
|
420
472
|
return TRUE;
|
421
473
|
}
|
422
474
|
|
475
|
+
// Returns the short algebraic chess notation of the move from-to.
|
423
476
|
char*
|
424
477
|
get_notation (Board *board, int from, int to, int capture, int ep, char promotion, int check, int checkmate)
|
425
478
|
{
|
@@ -506,6 +559,7 @@ get_notation (Board *board, int from, int to, int capture, int ep, char promotio
|
|
506
559
|
return notation;
|
507
560
|
}
|
508
561
|
|
562
|
+
// Returns the fen string that rappresent the board.
|
509
563
|
char*
|
510
564
|
to_fen (Board *board)
|
511
565
|
{
|