chess_validator 0.2.19 → 0.2.23
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 +4 -4
- data/lib/board_logic.rb +6 -2
- data/lib/engine.rb +4 -0
- data/lib/move_logic.rb +115 -12
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d61b299ea0d6ec07579ccb0b6d34ec50a7d5835960ae866469f653c4f7d43d06
|
4
|
+
data.tar.gz: cbc0f79075fa4f497b2ac8128864acab023da94a74e68efcfe87ff0c4d4950b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 952a4c3df07b35e8ef83ee10e72b5488c6cb57a4c09f2e3b1d56de1a37a2024545d7d682812b7497fa6884994453616933437872ac4db47554afec12586c97e5
|
7
|
+
data.tar.gz: d86e7337b4e0616b7dc8bf67aef635e87ddec04fe96d4a395ccfc118c45255f1edade66acc98e42c9a6d6672c2e04247ef712e1a6e576e999156b08eca7dd627
|
data/lib/board_logic.rb
CHANGED
@@ -3,9 +3,13 @@ require 'piece'
|
|
3
3
|
module ChessValidator
|
4
4
|
class BoardLogic
|
5
5
|
def self.build_board(fen)
|
6
|
+
build_board_from_string(fen.board_string)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.build_board_from_string(board_string)
|
6
10
|
board = {}
|
7
11
|
square_index = 1
|
8
|
-
|
12
|
+
board_string.chars.each do |char|
|
9
13
|
if empty_square?(char)
|
10
14
|
square_index += char.to_i
|
11
15
|
elsif char != '/'
|
@@ -23,7 +27,7 @@ module ChessValidator
|
|
23
27
|
notation += handle_castle(previous_fen.castling, piece, board)
|
24
28
|
notation += handle_en_passant(piece, move)
|
25
29
|
notation += handle_half_move_clock(previous_fen, piece.piece_type, captured)
|
26
|
-
notation += piece.color == 'b' ? previous_fen.fullmove.
|
30
|
+
notation += piece.color == 'b' ? previous_fen.fullmove&.next.to_s : previous_fen.fullmove.to_s
|
27
31
|
notation
|
28
32
|
end
|
29
33
|
|
data/lib/engine.rb
CHANGED
data/lib/move_logic.rb
CHANGED
@@ -4,19 +4,79 @@ require 'pgn'
|
|
4
4
|
module ChessValidator
|
5
5
|
class MoveLogic
|
6
6
|
class << self
|
7
|
+
MAX_CACHE_SIZE = 1000
|
8
|
+
|
7
9
|
def next_moves(fen)
|
8
|
-
|
10
|
+
fen_notation = fen.to_s
|
11
|
+
return next_moves_for[fen_notation] if next_moves_for[fen_notation]
|
12
|
+
|
13
|
+
board = get_board(fen.to_s)
|
9
14
|
pieces = []
|
15
|
+
|
10
16
|
board.values.each do |piece|
|
11
17
|
if piece.color == fen.active
|
12
18
|
load_move_data(board, piece, fen)
|
13
19
|
pieces << piece if piece.valid_moves.size > 0
|
14
20
|
end
|
15
21
|
end
|
22
|
+
next_moves_for[fen_notation] = pieces
|
16
23
|
|
17
24
|
pieces
|
18
25
|
end
|
19
26
|
|
27
|
+
def boards
|
28
|
+
if @boards.nil? || @boards.size > MAX_CACHE_SIZE
|
29
|
+
@boards = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
@boards
|
33
|
+
end
|
34
|
+
|
35
|
+
def next_moves_for
|
36
|
+
if @next_moves_for.nil? || @next_moves_for.size > MAX_CACHE_SIZE
|
37
|
+
@next_moves_for = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
@next_moves_for
|
41
|
+
end
|
42
|
+
|
43
|
+
def occupied_square_sets
|
44
|
+
if @occupied_square_sets.nil? || @occupied_square_sets.size > MAX_CACHE_SIZE
|
45
|
+
@occupied_square_sets = {}
|
46
|
+
end
|
47
|
+
|
48
|
+
@occupied_square_sets
|
49
|
+
end
|
50
|
+
|
51
|
+
def defended_sets
|
52
|
+
if @defended_sets.nil? || @defended_sets.size > MAX_CACHE_SIZE
|
53
|
+
@defended_sets = {}
|
54
|
+
end
|
55
|
+
|
56
|
+
@defended_sets
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_board(fen_string)
|
60
|
+
return boards[fen_string] if boards[fen_string]
|
61
|
+
|
62
|
+
board = BoardLogic.build_board_from_string(fen_string.split.first)
|
63
|
+
boards[fen_string] = board
|
64
|
+
board
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def get_occupied_spaces(fen_string)
|
69
|
+
return occupied_square_sets[fen_string] if occupied_square_sets[fen_string]
|
70
|
+
board = get_board(fen_string)
|
71
|
+
|
72
|
+
occupied_spaces = []
|
73
|
+
board.values.each { |p| occupied_spaces << p.position }
|
74
|
+
|
75
|
+
occupied_square_sets[fen_string] = occupied_spaces
|
76
|
+
occupied_spaces
|
77
|
+
end
|
78
|
+
|
79
|
+
|
20
80
|
def load_move_data(board, piece, fen)
|
21
81
|
moves_for_piece(piece).each do |move|
|
22
82
|
if valid_move?(piece, board, move, fen)
|
@@ -41,14 +101,13 @@ module ChessValidator
|
|
41
101
|
end
|
42
102
|
|
43
103
|
def valid_move?(piece, board, move, fen)
|
44
|
-
occupied_spaces = []
|
45
|
-
board.values.each { |p| occupied_spaces << p.position }
|
46
104
|
case piece.piece_type.downcase
|
47
105
|
when 'k'
|
48
|
-
handle_king(piece, board, move, fen,
|
106
|
+
handle_king(piece, board, move, fen) && valid_destination?(piece, board, move)
|
49
107
|
when 'p'
|
50
108
|
handle_pawn(piece, board, move, fen)
|
51
109
|
else
|
110
|
+
occupied_spaces = get_occupied_spaces(fen.to_s)
|
52
111
|
valid_move_path?(piece, move, occupied_spaces) &&
|
53
112
|
valid_destination?(piece, board, move) &&
|
54
113
|
king_will_be_safe?(piece, board, move)
|
@@ -112,10 +171,9 @@ module ChessValidator
|
|
112
171
|
end
|
113
172
|
|
114
173
|
def make_move(piece, move, fen_notation)
|
115
|
-
|
116
|
-
board = BoardLogic.build_board(fen)
|
174
|
+
board = get_board(fen_notation)
|
117
175
|
new_board = with_next_move(piece, board, move)
|
118
|
-
|
176
|
+
fen = PGN::FEN.new(fen_notation)
|
119
177
|
BoardLogic.to_fen_notation(new_board, fen, piece, move, board[INDEX_KEY[move]])
|
120
178
|
end
|
121
179
|
|
@@ -135,16 +193,16 @@ module ChessValidator
|
|
135
193
|
end
|
136
194
|
|
137
195
|
def find_king_and_spaces(board, color)
|
138
|
-
occupied_spaces = []
|
139
196
|
king = nil
|
140
|
-
board.values.
|
197
|
+
occupied_spaces = board.values.map do |p|
|
141
198
|
king = p if p.piece_type.downcase == 'k' && p.color == color
|
142
|
-
|
199
|
+
p.position
|
143
200
|
end
|
201
|
+
|
144
202
|
[king, occupied_spaces]
|
145
203
|
end
|
146
204
|
|
147
|
-
def handle_king(king, board, move, fen
|
205
|
+
def handle_king(king, board, move, fen)
|
148
206
|
if (king.position[0].ord - move[0].ord).abs == 2
|
149
207
|
empty_b_square = true
|
150
208
|
if move[0] == 'c'
|
@@ -155,6 +213,8 @@ module ChessValidator
|
|
155
213
|
castle_code = 'k'
|
156
214
|
between = 'f' + move[1]
|
157
215
|
end
|
216
|
+
occupied_spaces = get_occupied_spaces(fen.to_s)
|
217
|
+
|
158
218
|
(fen.castling.include?(castle_code) && king.color == 'b' || fen.castling.include?(castle_code.upcase) && king.color == 'w') &&
|
159
219
|
king_is_safe?(king.color, board, king.position, occupied_spaces) &&
|
160
220
|
king_is_safe?(king.color, board, between, occupied_spaces) &&
|
@@ -162,7 +222,7 @@ module ChessValidator
|
|
162
222
|
board.values.none? { |piece| [between, move].include?(piece.position) } &&
|
163
223
|
empty_b_square
|
164
224
|
else
|
165
|
-
|
225
|
+
king_will_be_safe?(king, board, move)
|
166
226
|
end
|
167
227
|
end
|
168
228
|
|
@@ -271,6 +331,49 @@ module ChessValidator
|
|
271
331
|
!(move_path & occupied_spaces).empty?
|
272
332
|
end
|
273
333
|
|
334
|
+
def can_defend?(piece, board, position, fen)
|
335
|
+
case piece.piece_type.downcase
|
336
|
+
when 'k'
|
337
|
+
handle_king(piece, board, position, fen)
|
338
|
+
when 'p'
|
339
|
+
if piece.position[0] != position[0]
|
340
|
+
target_piece = find_piece(board, position)
|
341
|
+
valid = (target_piece && target_piece.color != piece.color) || position == fen.en_passant
|
342
|
+
valid && king_will_be_safe?(piece, board, position)
|
343
|
+
end
|
344
|
+
else
|
345
|
+
occupied_spaces = get_occupied_spaces(fen.to_s)
|
346
|
+
valid_move_path?(piece, position, occupied_spaces) && king_will_be_safe?(piece, board, position)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def defended_pieces_by_square(fen_notation)
|
351
|
+
return defended_sets[fen_notation] if defended_sets[fen_notation]
|
352
|
+
|
353
|
+
board = get_board(fen_notation)
|
354
|
+
|
355
|
+
fen = PGN::FEN.new(fen_notation)
|
356
|
+
space_index = {}
|
357
|
+
|
358
|
+
pieces = board.values.map do |piece|
|
359
|
+
space_index[piece.position] = piece.piece_type + piece.color
|
360
|
+
piece
|
361
|
+
end
|
362
|
+
|
363
|
+
defended = Hash.new([])
|
364
|
+
|
365
|
+
pieces.each do |piece|
|
366
|
+
moves_for_piece(piece).each do |move|
|
367
|
+
if space_index[move] && space_index[move][-1] == piece.color && can_defend?(piece, board, move, fen)
|
368
|
+
defended[move] += [piece]
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
defended_sets[fen_notation] = defended
|
374
|
+
defended
|
375
|
+
end
|
376
|
+
|
274
377
|
def moves_for_piece(piece)
|
275
378
|
case piece.piece_type.downcase
|
276
379
|
when 'r'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chess_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Ellison
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Documentation: https://github.com/chadellison/chess_validator'
|
14
14
|
email: chad.ellison0123@gmail.com
|
@@ -27,7 +27,7 @@ homepage: https://rubygems.org/search?utf8=%E2%9C%93&query=chess_validator
|
|
27
27
|
licenses:
|
28
28
|
- MIT
|
29
29
|
metadata: {}
|
30
|
-
post_install_message:
|
30
|
+
post_install_message:
|
31
31
|
rdoc_options: []
|
32
32
|
require_paths:
|
33
33
|
- lib
|
@@ -42,8 +42,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: '0'
|
44
44
|
requirements: []
|
45
|
-
rubygems_version: 3.
|
46
|
-
signing_key:
|
45
|
+
rubygems_version: 3.2.3
|
46
|
+
signing_key:
|
47
47
|
specification_version: 4
|
48
48
|
summary: A chess move validator
|
49
49
|
test_files: []
|