chess 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72831c5ff5567709d9ce1e377c98d7867b35b611
4
- data.tar.gz: 0af6a358a253414ad636d9fec050eb1dd5ccfbc9
3
+ metadata.gz: 144e0056d416422439a212c961f1a20f97899732
4
+ data.tar.gz: 8863ebc0662c3e8a9358df006302a41e2f4a1782
5
5
  SHA512:
6
- metadata.gz: cf1c0fc216c2e2a76e978b96c4e668eed29d23eef23606280075b58d42a717b27d1fdfe50c1dae6961ffac71d4272ada39c6a3f8a8e2b69d5b16a33c24114abe
7
- data.tar.gz: 3544641ba2184d3965574c912472defad0e49020c650ae9f2a342683dddd02b81ced292156c3828d987b6001f5e8993a252c4950bc56bd965de827d5f858e03e
6
+ metadata.gz: 859d042dbca0d119161bd0361dc9940dadc0e9de3b60e863ec9609425f6b8487f70bbd5821de98d67096c96cf46d6ada82ce59dba7a8e3963aba47fb3c0d29f0
7
+ data.tar.gz: 7466a2c6711067f3e90efb80ec5a7a64ca3c323cdd4d2ba087959ef93f04a54778fcd36d4cec537f962b9fc4d80aa726593febf857cf8588c791088ead57775c
@@ -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)
@@ -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
 
@@ -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
@@ -67,7 +67,7 @@ current_move (Game *g)
67
67
  {
68
68
  if (g->current > 0)
69
69
  return g->moves[g->current-1];
70
- return 0;
70
+ return NULL;
71
71
  }
72
72
 
73
73
  // Returns the last move done in coordinate format.
@@ -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 0;
143
+ return NULL;
144
144
  }
145
145
  set_occupied (new_board);
146
146
  return move;
@@ -1,5 +1,5 @@
1
1
  # The Chess library module.
2
2
  module Chess
3
3
  # The library version.
4
- VERSION = '0.1.4'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -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.1.4
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-16 00:00:00.000000000 Z
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