chess 0.4.0 → 0.5.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
  SHA256:
3
- metadata.gz: 70707b1702323bd7382d8b5c33f4215df8e4cc03456aca37f3c3007c0ca325c4
4
- data.tar.gz: dce9ac8cd70a77c5f5ff615f468a58dff050e1ed0da806b1682dcfa407c80754
3
+ metadata.gz: 566d4eef7efcdc8a6240d1899c7fc4b909a9972e579b0f912d268c766f3f1a59
4
+ data.tar.gz: 72c276541f51226dd146c16c341dcb7becd3b944b05c64d1ab1eb00eacf1ac28
5
5
  SHA512:
6
- metadata.gz: c1cfbb10d79c883d5cdfacf01ca079075f7520053e323e6ff030e4882f1d9112aad465b2b47eb5995a9f48150ef332d6b9ee7e05f8218bf97636b965d0a4c463
7
- data.tar.gz: 3a81d782a5e9bc63b611bbf6d1305bdd9c848233ee87f83e72e66738a69a5a8365aebbe5a22893cc41da51c4945fb997848aa9f972a61b1ee19f3198e6def9ab
6
+ metadata.gz: 2a619775af9cc2bdc2d1b9907c8928f353456f85a6bb27d5af7761a5df01827c331a2d5222bd9baa60d8afe765b6b96162eb636d3a5a863225b75c53735d4b2b
7
+ data.tar.gz: d7ddfd431a188264b3abe420cad013ed3e3410633ef7936a33795665beaca8334d23472b05a3ec692c30b5923ab35535a538a34cc64509fa77c91eeece5a6d8f
@@ -18,11 +18,11 @@ jobs:
18
18
  runs-on: ubuntu-latest
19
19
  strategy:
20
20
  matrix:
21
- ruby-version: ['2.7', '3.0', '3.1', '3.2', '3.3']
21
+ ruby-version: ['3.4', '4.0']
22
22
 
23
23
  steps:
24
24
  - name: Checkout repository
25
- uses: actions/checkout@v4
25
+ uses: actions/checkout@v6
26
26
  - name: Set up Ruby
27
27
  uses: ruby/setup-ruby@v1
28
28
  with:
@@ -35,8 +35,11 @@ jobs:
35
35
  make
36
36
  - name: Run tests
37
37
  run: bundle exec rake test
38
- env:
39
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
38
+ - name: Upload coverage to Codecov
39
+ uses: codecov/codecov-action@v5
40
+ with:
41
+ token: ${{ secrets.CODECOV_TOKEN }}
42
+ fail_ci_if_error: true
40
43
 
41
44
  rubocop:
42
45
  runs-on: ubuntu-latest
@@ -47,7 +50,7 @@ jobs:
47
50
  - name: Set up Ruby
48
51
  uses: ruby/setup-ruby@v1
49
52
  with:
50
- ruby-version: '3.3'
53
+ ruby-version: '3.4'
51
54
  bundler-cache: true
52
55
  - name: Run Rubocop
53
56
  run: bundle exec rubocop
data/.gitignore CHANGED
@@ -5,7 +5,7 @@
5
5
  .yardoc/
6
6
  coverage/
7
7
  ext/chess/Makefile
8
- ext/chess/*.bundle
8
+ ext/chess/*.bundle*
9
9
  ext/chess/*.o
10
10
  lib/chess/chess.bundle
11
11
  main.rb
data/.rubocop.yml CHANGED
@@ -1,11 +1,11 @@
1
- require:
1
+ plugins:
2
2
  - rubocop-minitest
3
3
  - rubocop-performance
4
4
  - rubocop-rake
5
5
 
6
6
  AllCops:
7
7
  NewCops: enable
8
- TargetRubyVersion: 2.5
8
+ TargetRubyVersion: 3.4
9
9
 
10
10
  Layout/LineLength:
11
11
  Enabled: false
data/Gemfile CHANGED
@@ -4,7 +4,6 @@ source 'http://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'bundler'
7
- gem 'codecov'
8
7
  gem 'debug'
9
8
  gem 'minitest'
10
9
  gem 'rake'
@@ -13,4 +12,5 @@ gem 'rubocop-minitest'
13
12
  gem 'rubocop-performance'
14
13
  gem 'rubocop-rake'
15
14
  gem 'simplecov'
15
+ gem 'simplecov-cobertura'
16
16
  gem 'yard', '>= 0.9.20'
data/Gemfile.lock CHANGED
@@ -1,83 +1,102 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- chess (0.4.0)
4
+ chess (0.5.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
8
  specs:
9
- ast (2.4.2)
10
- codecov (0.6.0)
11
- simplecov (>= 0.15, < 0.22)
12
- debug (1.9.2)
9
+ ast (2.4.3)
10
+ date (3.5.1)
11
+ debug (1.11.1)
13
12
  irb (~> 1.10)
14
13
  reline (>= 0.3.8)
15
14
  docile (1.4.1)
16
- io-console (0.7.2)
17
- irb (1.14.0)
15
+ drb (2.2.3)
16
+ erb (6.0.2)
17
+ io-console (0.8.2)
18
+ irb (1.17.0)
19
+ pp (>= 0.6.0)
20
+ prism (>= 1.3.0)
18
21
  rdoc (>= 4.0.0)
19
22
  reline (>= 0.4.2)
20
- json (2.7.2)
21
- language_server-protocol (3.17.0.3)
22
- minitest (5.25.1)
23
- parallel (1.26.3)
24
- parser (3.3.4.2)
23
+ json (2.19.3)
24
+ language_server-protocol (3.17.0.5)
25
+ lint_roller (1.1.0)
26
+ minitest (6.0.3)
27
+ drb (~> 2.0)
28
+ prism (~> 1.5)
29
+ parallel (1.28.0)
30
+ parser (3.3.11.1)
25
31
  ast (~> 2.4.1)
26
32
  racc
27
- psych (5.1.2)
33
+ pp (0.6.3)
34
+ prettyprint
35
+ prettyprint (0.2.0)
36
+ prism (1.9.0)
37
+ psych (5.3.1)
38
+ date
28
39
  stringio
29
40
  racc (1.8.1)
30
41
  rainbow (3.1.1)
31
- rake (13.2.1)
32
- rdoc (6.7.0)
42
+ rake (13.3.1)
43
+ rdoc (7.2.0)
44
+ erb
33
45
  psych (>= 4.0.0)
34
- regexp_parser (2.9.2)
35
- reline (0.5.9)
46
+ tsort
47
+ regexp_parser (2.12.0)
48
+ reline (0.6.3)
36
49
  io-console (~> 0.5)
37
- rexml (3.3.6)
38
- strscan
39
- rubocop (1.65.1)
50
+ rexml (3.4.4)
51
+ rubocop (1.86.0)
40
52
  json (~> 2.3)
41
- language_server-protocol (>= 3.17.0)
53
+ language_server-protocol (~> 3.17.0.2)
54
+ lint_roller (~> 1.1.0)
42
55
  parallel (~> 1.10)
43
56
  parser (>= 3.3.0.2)
44
57
  rainbow (>= 2.2.2, < 4.0)
45
- regexp_parser (>= 2.4, < 3.0)
46
- rexml (>= 3.2.5, < 4.0)
47
- rubocop-ast (>= 1.31.1, < 2.0)
58
+ regexp_parser (>= 2.9.3, < 3.0)
59
+ rubocop-ast (>= 1.49.0, < 2.0)
48
60
  ruby-progressbar (~> 1.7)
49
- unicode-display_width (>= 2.4.0, < 3.0)
50
- rubocop-ast (1.32.1)
51
- parser (>= 3.3.1.0)
52
- rubocop-minitest (0.35.1)
53
- rubocop (>= 1.61, < 2.0)
54
- rubocop-ast (>= 1.31.1, < 2.0)
55
- rubocop-performance (1.21.1)
56
- rubocop (>= 1.48.1, < 2.0)
57
- rubocop-ast (>= 1.31.1, < 2.0)
58
- rubocop-rake (0.6.0)
59
- rubocop (~> 1.0)
61
+ unicode-display_width (>= 2.4.0, < 4.0)
62
+ rubocop-ast (1.49.1)
63
+ parser (>= 3.3.7.2)
64
+ prism (~> 1.7)
65
+ rubocop-minitest (0.39.1)
66
+ lint_roller (~> 1.1)
67
+ rubocop (>= 1.75.0, < 2.0)
68
+ rubocop-ast (>= 1.38.0, < 2.0)
69
+ rubocop-performance (1.26.1)
70
+ lint_roller (~> 1.1)
71
+ rubocop (>= 1.75.0, < 2.0)
72
+ rubocop-ast (>= 1.47.1, < 2.0)
73
+ rubocop-rake (0.7.1)
74
+ lint_roller (~> 1.1)
75
+ rubocop (>= 1.72.1)
60
76
  ruby-progressbar (1.13.0)
61
- simplecov (0.21.2)
77
+ simplecov (0.22.0)
62
78
  docile (~> 1.1)
63
79
  simplecov-html (~> 0.11)
64
80
  simplecov_json_formatter (~> 0.1)
65
- simplecov-html (0.12.3)
81
+ simplecov-cobertura (3.1.0)
82
+ rexml
83
+ simplecov (~> 0.19)
84
+ simplecov-html (0.13.2)
66
85
  simplecov_json_formatter (0.1.4)
67
- stringio (3.1.1)
68
- strscan (3.1.0)
69
- unicode-display_width (2.5.0)
70
- yard (0.9.36)
86
+ stringio (3.2.0)
87
+ tsort (0.2.0)
88
+ unicode-display_width (3.2.0)
89
+ unicode-emoji (~> 4.1)
90
+ unicode-emoji (4.2.0)
91
+ yard (0.9.38)
71
92
 
72
93
  PLATFORMS
94
+ arm64-darwin-24
73
95
  ruby
74
- x86_64-darwin-18
75
- x86_64-darwin-19
76
96
 
77
97
  DEPENDENCIES
78
98
  bundler
79
99
  chess!
80
- codecov
81
100
  debug
82
101
  minitest
83
102
  rake
@@ -86,7 +105,51 @@ DEPENDENCIES
86
105
  rubocop-performance
87
106
  rubocop-rake
88
107
  simplecov
108
+ simplecov-cobertura
89
109
  yard (>= 0.9.20)
90
110
 
111
+ CHECKSUMS
112
+ ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
113
+ chess (0.5.0)
114
+ date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
115
+ debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6
116
+ docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
117
+ drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
118
+ erb (6.0.2) sha256=9fe6264d44f79422c87490a1558479bd0e7dad4dd0e317656e67ea3077b5242b
119
+ io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
120
+ irb (1.17.0) sha256=168c4ddb93d8a361a045c41d92b2952c7a118fa73f23fe14e55609eb7a863aae
121
+ json (2.19.3) sha256=289b0bb53052a1fa8c34ab33cc750b659ba14a5c45f3fcf4b18762dc67c78646
122
+ language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
123
+ lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
124
+ minitest (6.0.3) sha256=88ac8a1de36c00692420e7cb3cc11a0773bbcb126aee1c249f320160a7d11411
125
+ parallel (1.28.0) sha256=33e6de1484baf2524792d178b0913fc8eb94c628d6cfe45599ad4458c638c970
126
+ parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54
127
+ pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
128
+ prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
129
+ prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
130
+ psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
131
+ racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
132
+ rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
133
+ rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
134
+ rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192
135
+ regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
136
+ reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
137
+ rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
138
+ rubocop (1.86.0) sha256=4ff1186fe16ebe9baff5e7aad66bb0ad4cabf5cdcd419f773146dbba2565d186
139
+ rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
140
+ rubocop-minitest (0.39.1) sha256=998398d6da4026d297f0f9bf709a1eac5f2b6947c24431f94af08138510cf7ed
141
+ rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
142
+ rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
143
+ ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
144
+ simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
145
+ simplecov-cobertura (3.1.0) sha256=6d7f38aa32c965ca2174b2e5bd88cb17138eaf629518854976ac50e628925dc5
146
+ simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
147
+ simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
148
+ stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
149
+ tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
150
+ unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
151
+ unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
152
+ yard (0.9.38) sha256=721fb82afb10532aa49860655f6cc2eaa7130889df291b052e1e6b268283010f
153
+
91
154
  BUNDLED WITH
92
- 2.3.8
155
+ 4.0.9
data/README.md CHANGED
@@ -7,7 +7,7 @@ A fast Ruby gem to play chess with Ruby. This library is quite fast because mana
7
7
 
8
8
  ## Requirements
9
9
 
10
- - Ruby 2.5 or higher
10
+ - Ruby 3.4 or higher
11
11
 
12
12
  ## Installation
13
13
 
data/chess.gemspec CHANGED
@@ -17,5 +17,5 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.metadata['rubygems_mfa_required'] = 'true'
19
19
 
20
- s.required_ruby_version = '>= 2.5'
20
+ s.required_ruby_version = '>= 3.4'
21
21
  end
data/ext/chess/board.c CHANGED
@@ -573,7 +573,7 @@ char*
573
573
  to_fen (Board *board)
574
574
  {
575
575
  // 1. Placement
576
- char placement[65];
576
+ char placement[72]; // 8 * 8 + 7 (slash separators) + 1 (null terminator)
577
577
  int cur = 0;
578
578
  char p, pp = '-';
579
579
  for (int i = 7; i >= 0; i--)
@@ -633,7 +633,7 @@ to_fen (Board *board)
633
633
  // > board->fullmove_number
634
634
 
635
635
  // join all in fen string
636
- char *fen = (char *) malloc (80);
636
+ char *fen = (char *) malloc (104); // Max size: 71 placement + 1 space + 1 active + 1 space + 4 castling + 1 space + 2 ep + 1 space + 10 halfmove + 1 space + 10 fullmove + 1 NUL = 104.
637
637
  sprintf (fen, "%s %c %s %s %d %d", placement, active_color, castling, ep, board->halfmove_clock, board->fullmove_number);
638
638
 
639
639
  free (castling);
data/ext/chess/game.c CHANGED
@@ -83,6 +83,7 @@ current_coord_move (Game *g)
83
83
  bool
84
84
  apply_move (Game *g, int from, int to, char promote_in)
85
85
  {
86
+ if (g->current >= BUFFER_SIZE) return FALSE;
86
87
  if (g->result != IN_PROGRESS && g->result != DRAW) return FALSE;
87
88
  Board *board = current_board (g);
88
89
  if (promote_in && invalid_promotion (board, from, to)) return FALSE;
@@ -151,11 +152,11 @@ threefold_repetition (Game *g)
151
152
  {
152
153
  if (g->current < 6) // Minimum moves to get a threefold repetition
153
154
  return FALSE;
154
- char placement[65];
155
+ char placement[72]; // 8 * 8 + 7 (slash separators) + 1 (null terminator)
155
156
  char turn;
156
157
  char *fen, *castling, *ep;
157
158
  char* s[g->current + 1];
158
- s[0] = (char *) malloc (80);
159
+ s[0] = (char *) malloc (104); // Max size: 71 placement + 1 space + 1 active + 1 space + 4 castling + 1 space + 2 ep + 1 space + 10 halfmove + 1 space + 10 fullmove + 1 NUL = 104.
159
160
  strcpy (s[0], "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -");
160
161
  bool found = FALSE;
161
162
  int i, j;
@@ -165,7 +166,7 @@ threefold_repetition (Game *g)
165
166
  for (j = 0; fen[j] != ' '; j++)
166
167
  placement[j] = fen[j];
167
168
  placement[j] = '\0';
168
- s[i+1] = (char *) malloc (80);
169
+ s[i+1] = (char *) malloc (104);
169
170
  turn = g->boards[i]->active_color ? 'b' : 'w';
170
171
  castling = castling_to_s (g->boards[i]->castling);
171
172
  ep = en_passant_to_s (g->boards[i]->en_passant);
@@ -330,6 +331,12 @@ set_fen (Game *g, const char *fen)
330
331
  pch = strtok (NULL, " /");
331
332
  }
332
333
  set_occupied (board);
334
+ if (g->current >= BUFFER_SIZE)
335
+ {
336
+ free (board);
337
+ free (s);
338
+ return;
339
+ }
333
340
  g->boards[g->current] = board;
334
341
  g->moves[g->current] = (char *) malloc (11);
335
342
  g->coord_moves[g->current] = (char *) malloc (11);
data/lib/chess/game.rb CHANGED
@@ -190,9 +190,9 @@ module Chess
190
190
  end
191
191
  end
192
192
 
193
- MOVE_REGEXP = /^([RNBQK])?([a-h]|[1-8]|[a-h][1-8])?(?:x)?([a-h][1-8])(?:=?([RrNnBbQq]))?(?:ep)?(?:\+|\#)?$/.freeze
194
- SHORT_CASTLING_REGEXP = /^([0O])-([0O])([+#])?$/.freeze
195
- LONG_CASTLING_REGEXP = /^([0O])-([0O])-([0O])([+#])?$/.freeze
193
+ MOVE_REGEXP = /^([RNBQK])?([a-h]|[1-8]|[a-h][1-8])?(?:x)?([a-h][1-8])(?:=?([RrNnBbQq]))?(?:ep)?(?:\+|\#)?$/
194
+ SHORT_CASTLING_REGEXP = /^([0O])-([0O])([+#])?$/
195
+ LONG_CASTLING_REGEXP = /^([0O])-([0O])-([0O])([+#])?$/
196
196
  private_constant :MOVE_REGEXP
197
197
  private_constant :SHORT_CASTLING_REGEXP
198
198
  private_constant :LONG_CASTLING_REGEXP
data/lib/chess/pgn.rb CHANGED
@@ -60,16 +60,16 @@ module Chess
60
60
  # @raise [InvalidPgnFormatError]
61
61
  # @raise [IllegalMoveError]
62
62
  def load_from_string(str, check_moves: false)
63
- str.gsub!(/\{.*?\}/, '') # remove comments
63
+ fen = str.gsub(/\{.*?\}/, '') # remove comments
64
64
  TAGS.each do |t|
65
- instance_variable_set(:"@#{t}", str.match(/^\[#{t.capitalize} ".*"\]\s?$/).to_s.strip[t.size + 3..-3])
65
+ instance_variable_set(:"@#{t}", fen.match(/^\[#{t.capitalize} ".*"\]\s?$/).to_s.strip[(t.size + 3)..-3])
66
66
  end
67
67
  @result = '1/2-1/2' if @result == '1/2'
68
- game_index = str.index(/^1\./)
68
+ game_index = fen.index(/^1\./)
69
69
  raise Chess::InvalidPgnFormatError.new if game_index.nil?
70
70
 
71
- game = str[game_index..-1].strip
72
- @moves = game.tr("\n", ' ').split(/\d+\./).collect(&:strip)[1..-1].map(&:split).flatten
71
+ game = fen[game_index..].strip
72
+ @moves = game.tr("\n", ' ').split(/\d+\./).collect(&:strip)[1..].map(&:split).flatten
73
73
  @moves.delete_at(@moves.size - 1) if @moves.last.match?(/(0-1)|(1-0)|(1\/2)|(1\/2-1\/2)|(\*)/)
74
74
  @moves.each do |m|
75
75
  raise Chess::InvalidPgnFormatError.new if m !~ MOVE_REGEXP && m !~ SHORT_CASTLING_REGEXP && m !~ LONG_CASTLING_REGEXP
@@ -80,19 +80,20 @@ module Chess
80
80
 
81
81
  # PGN to string.
82
82
  def to_s
83
- s = ''
83
+ s = []
84
84
  TAGS.each do |t|
85
85
  tag = instance_variable_defined?(:"@#{t}") ? instance_variable_get(:"@#{t}") : ''
86
86
  s << "[#{t.capitalize} \"#{tag}\"]\n"
87
87
  end
88
88
  s << "\n"
89
- m = ''
89
+ m = []
90
90
  @moves.each_with_index do |move, i|
91
91
  m << "#{(i / 2) + 1}. " if i.even?
92
92
  m << "#{move} "
93
93
  end
94
94
  m << @result unless @result.nil?
95
- s << m.gsub(/(.{1,78})(?: +|$)\n?|(.{78})/, "\\1\\2\n")
95
+ s << m.join.gsub(/(.{1,78})(?: +|$)\n?|(.{78})/, "\\1\\2\n")
96
+ return s.join
96
97
  end
97
98
 
98
99
  # Write PGN to file.
data/lib/chess/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # The Chess library module.
2
2
  module Chess
3
3
  # The library version.
4
- VERSION = '0.4.0'.freeze
4
+ VERSION = '0.5.0'.freeze
5
5
  end
data/mise.toml ADDED
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ ruby = "3.4.2"
data/test/test_helper.rb CHANGED
@@ -1,11 +1,9 @@
1
1
  require 'simplecov'
2
+ require 'simplecov-cobertura'
3
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter if ENV['CI']
2
4
  SimpleCov.start do
3
5
  add_filter 'lib/chess/gnuchess.rb'
4
6
  end
5
- if ENV['CODECOV_TOKEN']
6
- require 'codecov'
7
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
8
- end
9
7
 
10
8
  require 'chess'
11
9
  require 'debug'
@@ -48,6 +48,42 @@ class ChessTest < Minitest::Test
48
48
  assert_equal '2b1kbnr/rpq1pp1p/2n3p1/8/3Q4/2P5/PP3PPP/RN1K1BNR b k - 1 9', g.board.to_fen
49
49
  end
50
50
 
51
+ def test_fen_long_placement_no_overflow
52
+ # Issue #35: placement strings >= 65 chars caused a stack buffer overflow
53
+ g = Chess::Game.load_fen('r2q1rk1/1pp2pp1/p1np1n1p/2b1p3/2B1P1b1/P1NP1N2/1PP1QPPP/R1B1R1K1 w - - 2 10')
54
+ g.move('h2h3')
55
+
56
+ assert_equal 'r2q1rk1/1pp2pp1/p1np1n1p/2b1p3/2B1P1b1/P1NP1N1P/1PP1QPP1/R1B1R1K1 b - - 0 10', g.board.to_fen
57
+ end
58
+
59
+ def test_fen_long_placement_threefold_repetition
60
+ # Issue #35: threefold_repetition? calls to_fen internally, exercising
61
+ # the placement buffer in game.c with a long placement string.
62
+ # Note: 3 full cycles (12 half-moves) needed because the FEN-loaded board
63
+ # stores en_passant differently from move-generated boards.
64
+ g = Chess::Game.load_fen('r2q1rk1/1pp2pp1/p1np1n1p/2b1p3/2B1P1b1/P1NP1N1P/1PP1QPP1/R1B1R1K1 b - - 0 10')
65
+ 3.times do
66
+ g.move('Qd7')
67
+ g.move('Qe3')
68
+ g.move('Qd8')
69
+ g.move('Qe2')
70
+ end
71
+
72
+ assert g.threefold_repetition?
73
+ end
74
+
75
+ def test_fen_max_length_fills_malloc_buffer
76
+ # Exercises the malloc(104) boundary in to_fen: 71 placement + 1 space +
77
+ # 1 active + 1 space + 4 castling + 1 space + 2 ep + 1 space +
78
+ # 10 halfmove + 1 space + 10 fullmove = 103 chars + NUL = 104 bytes.
79
+ fen = 'rnbqkbnr/pppppppp/nnnnnnnn/bbbbbbbb/BBBBBBBB/NNNNNNNN/PPPPPPPP/RNBQKBNR b KQkq e3 2147483647 2147483647'
80
+ g = Chess::Game.load_fen(fen)
81
+ result = g.board.to_fen
82
+
83
+ assert_equal fen, result
84
+ assert_equal 103, result.length
85
+ end
86
+
51
87
  def test_fen_castling_to
52
88
  g = Chess::Game.load_fen('2b1kbnr/rpq1pp1p/2n3p1/8/3Q4/2P5/PP3PPP/RN2KBNR w KQk - 0 9')
53
89
  g.move('Qh8')
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chess
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Enrico Pilotto
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-08-30 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: A fast chess library that use bitboards to play chess with Ruby.
14
13
  email:
@@ -74,6 +73,7 @@ files:
74
73
  - lib/chess/pgn.rb
75
74
  - lib/chess/utf8_notation.rb
76
75
  - lib/chess/version.rb
76
+ - mise.toml
77
77
  - test/pgn_collection/checkmate/black_won/0001.pgn
78
78
  - test/pgn_collection/checkmate/black_won/0002.pgn
79
79
  - test/pgn_collection/checkmate/black_won/0003.pgn
@@ -1302,7 +1302,6 @@ licenses:
1302
1302
  - LGPLv3
1303
1303
  metadata:
1304
1304
  rubygems_mfa_required: 'true'
1305
- post_install_message:
1306
1305
  rdoc_options: []
1307
1306
  require_paths:
1308
1307
  - lib
@@ -1310,15 +1309,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
1310
1309
  requirements:
1311
1310
  - - ">="
1312
1311
  - !ruby/object:Gem::Version
1313
- version: '2.5'
1312
+ version: '3.4'
1314
1313
  required_rubygems_version: !ruby/object:Gem::Requirement
1315
1314
  requirements:
1316
1315
  - - ">="
1317
1316
  - !ruby/object:Gem::Version
1318
1317
  version: '0'
1319
1318
  requirements: []
1320
- rubygems_version: 3.5.11
1321
- signing_key:
1319
+ rubygems_version: 3.7.2
1322
1320
  specification_version: 4
1323
1321
  summary: A fast chess library to play chess with Ruby.
1324
1322
  test_files: []