chess 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/board.c +10 -1
- data/ext/chess.c +39 -0
- data/ext/chess.h +1 -0
- data/ext/game.c +1 -1
- data/ext/special.c +9 -9
- data/lib/chess/version.rb +1 -1
- data/test/test_move_generator.rb +29 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 144e0056d416422439a212c961f1a20f97899732
|
4
|
+
data.tar.gz: 8863ebc0662c3e8a9358df006302a41e2f4a1782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 859d042dbca0d119161bd0361dc9940dadc0e9de3b60e863ec9609425f6b8487f70bbd5821de98d67096c96cf46d6ada82ce59dba7a8e3963aba47fb3c0d29f0
|
7
|
+
data.tar.gz: 7466a2c6711067f3e90efb80ec5a7a64ca3c323cdd4d2ba087959ef93f04a54778fcd36d4cec537f962b9fc4d80aa726593febf857cf8588c791088ead57775c
|
data/ext/board.c
CHANGED
@@ -472,7 +472,9 @@ try_move (Board *board, int from, int to, char promote_in, Board *new_board, cha
|
|
472
472
|
return TRUE;
|
473
473
|
}
|
474
474
|
|
475
|
-
// Returns the short algebraic chess notation of the move from-to.
|
475
|
+
// Returns the short algebraic chess notation of the move from-to. Do not
|
476
|
+
// perform the check to add mate symbols like '+' or '#'. This check is done on
|
477
|
+
// `apply_move` method.
|
476
478
|
char*
|
477
479
|
get_notation (Board *board, int from, int to, int capture, int ep, char promotion, int check, int checkmate)
|
478
480
|
{
|
@@ -523,6 +525,13 @@ get_notation (Board *board, int from, int to, int capture, int ep, char promotio
|
|
523
525
|
}
|
524
526
|
}
|
525
527
|
}
|
528
|
+
// Swap file and rank disambiguating char if number is before the letter.
|
529
|
+
if (disc_file_added && disc_rank_added && notation[i-2] < notation[i-1])
|
530
|
+
{
|
531
|
+
int tmp = notation[i-2];
|
532
|
+
notation[i-2] = notation[i-1];
|
533
|
+
notation[i-1] = tmp;
|
534
|
+
}
|
526
535
|
}
|
527
536
|
}
|
528
537
|
if (capture || ep)
|
data/ext/chess.c
CHANGED
@@ -602,6 +602,44 @@ board_fullmove_number (VALUE self)
|
|
602
602
|
return INT2FIX (board->fullmove_number);
|
603
603
|
}
|
604
604
|
|
605
|
+
/*
|
606
|
+
* @overload generate_moves(square)
|
607
|
+
* Generate all legal moves for the piece in `square` position.
|
608
|
+
* @param [Integer,String] square The square of the {Board}. Can be an integer
|
609
|
+
* between 0 and 63 or a string like 'a2', 'c5'...
|
610
|
+
* @return [Array<String>] Returns all legal moves that the piece in `square`
|
611
|
+
* position can perform. The moves are in short algebraic chess notation
|
612
|
+
* format.
|
613
|
+
* @example
|
614
|
+
* :001 > g = Chess::Game.new
|
615
|
+
* => #<Chess::Game:0x007f88a529fa88>
|
616
|
+
* :002 > g.board.generate_moves('b1')
|
617
|
+
* => ["Na3", "Nc3"]
|
618
|
+
*/
|
619
|
+
VALUE
|
620
|
+
board_generate_moves (VALUE self, VALUE square)
|
621
|
+
{
|
622
|
+
Board *board;
|
623
|
+
Data_Get_Struct (self, Board, board);
|
624
|
+
int from;
|
625
|
+
if (TYPE (square) == T_STRING)
|
626
|
+
from = coord_to_square (StringValuePtr (square));
|
627
|
+
else
|
628
|
+
from = FIX2INT (square);
|
629
|
+
VALUE moves = rb_ary_new ();
|
630
|
+
Board new_board;
|
631
|
+
char *move_done;
|
632
|
+
char capture;
|
633
|
+
for (int i = 0; i < 64; i++)
|
634
|
+
if (pseudo_legal_move (board, from, i))
|
635
|
+
{
|
636
|
+
move_done = castling (board, castling_type (board, from, i), &new_board);
|
637
|
+
if (move_done || try_move (board, from, i, 'Q', &new_board, &move_done, &capture))
|
638
|
+
rb_ary_push (moves, rb_str_new2 (move_done));
|
639
|
+
}
|
640
|
+
return moves;
|
641
|
+
}
|
642
|
+
|
605
643
|
/*
|
606
644
|
* @overload to_fen
|
607
645
|
* Returns the FEN string of the board.
|
@@ -689,6 +727,7 @@ Init_chess ()
|
|
689
727
|
rb_define_method (board_klass, "active_color", board_active_color, 0);
|
690
728
|
rb_define_method (board_klass, "halfmove_clock", board_halfmove_clock, 0);
|
691
729
|
rb_define_method (board_klass, "fullmove_number", board_fullmove_number, 0);
|
730
|
+
rb_define_method (board_klass, "generate_moves", board_generate_moves, 1);
|
692
731
|
rb_define_method (board_klass, "to_fen", board_to_fen, 0);
|
693
732
|
rb_define_method (board_klass, "to_s", board_to_s, 0);
|
694
733
|
|
data/ext/chess.h
CHANGED
@@ -41,6 +41,7 @@ VALUE board_fifty_move_rule (VALUE self);
|
|
41
41
|
VALUE board_active_color (VALUE self);
|
42
42
|
VALUE board_halfmove_clock (VALUE self);
|
43
43
|
VALUE board_fullmove_number (VALUE self);
|
44
|
+
VALUE board_generate_moves (VALUE self, VALUE square);
|
44
45
|
VALUE board_to_fen (VALUE self);
|
45
46
|
VALUE board_to_s (VALUE self);
|
46
47
|
|
data/ext/game.c
CHANGED
data/ext/special.c
CHANGED
@@ -95,10 +95,10 @@ castling (Board *board, int castling_type, Board *new_board)
|
|
95
95
|
memcpy (new_board, board, sizeof (Board));
|
96
96
|
new_board->king[WHITE] ^= 0x50;
|
97
97
|
new_board->rooks[WHITE] ^= 0xa0;
|
98
|
-
new_board->placement[E1] = 0;
|
98
|
+
new_board->placement[E1] = '\0';
|
99
99
|
new_board->placement[F1] = 'R';
|
100
100
|
new_board->placement[G1] = 'K';
|
101
|
-
new_board->placement[H1] = 0;
|
101
|
+
new_board->placement[H1] = '\0';
|
102
102
|
new_board->castling ^= new_board->castling & 0x1100;
|
103
103
|
move = (char *) malloc (5);
|
104
104
|
strcpy (move, "O-O");
|
@@ -107,10 +107,10 @@ castling (Board *board, int castling_type, Board *new_board)
|
|
107
107
|
memcpy (new_board, board, sizeof (Board));
|
108
108
|
new_board->king[WHITE] ^= 0x14;
|
109
109
|
new_board->rooks[WHITE] ^= 0x09;
|
110
|
-
new_board->placement[E1] = 0;
|
110
|
+
new_board->placement[E1] = '\0';
|
111
111
|
new_board->placement[D1] = 'R';
|
112
112
|
new_board->placement[C1] = 'K';
|
113
|
-
new_board->placement[A1] = 0;
|
113
|
+
new_board->placement[A1] = '\0';
|
114
114
|
new_board->castling ^= new_board->castling & 0x1100;
|
115
115
|
move = (char *) malloc (7);
|
116
116
|
strcpy (move, "O-O-O");
|
@@ -119,10 +119,10 @@ castling (Board *board, int castling_type, Board *new_board)
|
|
119
119
|
memcpy (new_board, board, sizeof (Board));
|
120
120
|
new_board->king[BLACK] ^= 0x5000000000000000;
|
121
121
|
new_board->rooks[BLACK] ^= 0xa000000000000000;
|
122
|
-
new_board->placement[E8] = 0;
|
122
|
+
new_board->placement[E8] = '\0';
|
123
123
|
new_board->placement[F8] = 'r';
|
124
124
|
new_board->placement[G8] = 'k';
|
125
|
-
new_board->placement[H8] = 0;
|
125
|
+
new_board->placement[H8] = '\0';
|
126
126
|
new_board->castling ^= new_board->castling & 0x0011;
|
127
127
|
move = (char *) malloc (5);
|
128
128
|
strcpy (move, "O-O");
|
@@ -131,16 +131,16 @@ castling (Board *board, int castling_type, Board *new_board)
|
|
131
131
|
memcpy (new_board, board, sizeof (Board));
|
132
132
|
new_board->king[BLACK] ^= 0x1400000000000000;
|
133
133
|
new_board->rooks[BLACK] ^= 0x0900000000000000;
|
134
|
-
new_board->placement[E8] = 0;
|
134
|
+
new_board->placement[E8] = '\0';
|
135
135
|
new_board->placement[D8] = 'r';
|
136
136
|
new_board->placement[C8] = 'k';
|
137
|
-
new_board->placement[A8] = 0;
|
137
|
+
new_board->placement[A8] = '\0';
|
138
138
|
new_board->castling ^= new_board->castling & 0x0011;
|
139
139
|
move = (char *) malloc (7);
|
140
140
|
strcpy (move, "O-O-O");
|
141
141
|
break;
|
142
142
|
default:
|
143
|
-
return
|
143
|
+
return NULL;
|
144
144
|
}
|
145
145
|
set_occupied (new_board);
|
146
146
|
return move;
|
data/lib/chess/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ChessTest < Minitest::Test
|
4
|
+
|
5
|
+
GENS = {
|
6
|
+
'r2qk3/8/2n5/8/8/8/p2B4/4K2R w K - 0 1' => {'e1' => ['Kd1', 'Ke2', 'Kf2', 'Kf1', 'O-O']},
|
7
|
+
'r2qk3/8/2n5/8/8/8/p2B4/4K2R w - - 0 1' => {'e1' => ['Kd1', 'Ke2', 'Kf2', 'Kf1']},
|
8
|
+
'r2qk3/8/2n5/2b5/8/8/p2B4/4K2R w K - 0 1' => {'e1' => ['Kd1', 'Ke2', 'Kf1']},
|
9
|
+
'r2qk3/8/2n5/2b5/8/8/p2B4/4K2R b K - 0 1' => {'a2' => ['a1=Q']},
|
10
|
+
'r2qk3/8/2n1n3/2b5/8/8/p2B4/4K2R b K - 0 1' => {'e6' => ['Nf8', 'Ng7', 'Ng5', 'Nf4', 'Ned4', 'Nc7']},
|
11
|
+
'r2qk3/8/2n5/2b2pP1/8/8/3B4/4K2R w K f6 0 1' => {'g5' => ['gxf6ep', 'g6']},
|
12
|
+
'1B1k4/r3q3/2n1n3/2b2pP1/8/1n6/3B4/4K2R b K - 0 1' => {'c6' => ['Nxb8', 'Ne5', 'Ncd4', 'Nb4', 'Nca5']},
|
13
|
+
'1B1k4/r3q3/2n1n3/2b2pP1/8/8/2nB4/3K3R b - - 0 1' => {'c6' => ['Nxb8', 'Ne5', 'Nc6d4', 'N6b4', 'Na5']},
|
14
|
+
'1B1k4/r3q3/2n1n2P/2b5/5p2/3p1RP1/3B4/3K4 w - - 0 1' => {'f3' => ['Rxd3', 'Re3', 'Rxf4', 'Rf2', 'Rf1']},
|
15
|
+
'k7/1Q6/2P5/8/8/8/8/3K4 b - - 0 1' => {'a8' => []},
|
16
|
+
'k7/6P1/8/8/8/3r4/3Q4/3K4 w - - 0 1' => {'d2' => ['Qxd3']}
|
17
|
+
}
|
18
|
+
|
19
|
+
GENS.each do |fen, generators|
|
20
|
+
define_method("test_move_generator_#{fen}") do
|
21
|
+
game = Chess::Game.load_fen(fen)
|
22
|
+
generators.each do |from, moves|
|
23
|
+
result = game.board.generate_moves(from)
|
24
|
+
assert_equal moves.sort, result.sort
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chess
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Enrico Pilotto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -1315,6 +1315,7 @@ files:
|
|
1315
1315
|
- test/test_illegal_moves.rb
|
1316
1316
|
- test/test_insufficient_material.rb
|
1317
1317
|
- test/test_load_fen.rb
|
1318
|
+
- test/test_move_generator.rb
|
1318
1319
|
- test/test_particular_situations.rb
|
1319
1320
|
- test/test_pgn.rb
|
1320
1321
|
- test/test_pgn_collection.rb
|
@@ -2559,6 +2560,7 @@ test_files:
|
|
2559
2560
|
- test/test_illegal_moves.rb
|
2560
2561
|
- test/test_insufficient_material.rb
|
2561
2562
|
- test/test_load_fen.rb
|
2563
|
+
- test/test_move_generator.rb
|
2562
2564
|
- test/test_particular_situations.rb
|
2563
2565
|
- test/test_pgn.rb
|
2564
2566
|
- test/test_pgn_collection.rb
|