terminal_chess 0.1.1 → 0.1.2
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/Rakefile +1 -1
- data/lib/Board.rb +4 -11
- data/lib/move.rb +2 -3
- data/lib/printer.rb +2 -2
- data/lib/terminal_chess.rb +9 -7
- data/lib/terminal_chess/version.rb +1 -1
- data/terminal_chess.gemspec +1 -1
- data/test/test_terminal_chess.rb +265 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34fa5a38bd74510d2289f5fec7141397fb691f5f
|
4
|
+
data.tar.gz: f01641e3e28dbb1e3965a42a2a3da40078442d0c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9b484ad6b6058cf21c2f0feda9d35bd41285ddea65d7d1926bcfde9ccf10d77d2c0f9d1239d7bf62f1d6a0b37eb13fc7c5a24a893ebbb1c4c90636b2c9dcb40
|
7
|
+
data.tar.gz: cb690106cc38935ac5528639d222e81d237367584b4c075abe848742ea11645fa35644334d6e38d98863bf1b79d6f63c344da344766aeff44f747b081427a003
|
data/Rakefile
CHANGED
data/lib/Board.rb
CHANGED
@@ -76,18 +76,11 @@ class Board
|
|
76
76
|
@@player_turn = (["black", "red"] - [@@player_turn]).first
|
77
77
|
board_refresh
|
78
78
|
else
|
79
|
-
|
79
|
+
p "Please move #{@@player_turn} king out of check to continue"
|
80
80
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
else
|
86
|
-
puts "It is #{@@player_turn}'s turn. Please move a #{@@player_turn} piece."
|
87
|
-
end
|
88
|
-
else
|
89
|
-
puts "Checkmate! Game Over."
|
90
|
-
end
|
81
|
+
else p "Please select a valid destination." end
|
82
|
+
else p "It is #{@@player_turn}'s turn. Please move a #{@@player_turn} piece." end
|
83
|
+
else p "Checkmate! Game Over." end
|
91
84
|
end
|
92
85
|
|
93
86
|
# Return the valid positions for piece at current_pos to move in readable format [A-H][1-8]
|
data/lib/move.rb
CHANGED
@@ -167,7 +167,6 @@ module MOVE
|
|
167
167
|
if unoccupied?(next_pos)
|
168
168
|
valid << next_pos
|
169
169
|
else
|
170
|
-
#puts "PC #{piece_color(next_pos)} #{enemy_color}" #INCOMEPSDFJDSLFJDKLFJDASKLF
|
171
170
|
if piece_color(next_pos) == @@enemy_color
|
172
171
|
valid << next_pos
|
173
172
|
end
|
@@ -279,11 +278,11 @@ module MOVE
|
|
279
278
|
def castle(index)
|
280
279
|
valid = []
|
281
280
|
dangerous_tiles = attack_vectors
|
282
|
-
|
281
|
+
|
283
282
|
# Valid positions for a King to be in order to castle
|
284
283
|
if index == 5 || index == 61
|
285
284
|
# Empty space between a King and a Rook
|
286
|
-
if unoccupied?(index - 1) && unoccupied?(index - 2) && unoccupied?(index - 3) && @@pieces[index - 4]["moved"] == false
|
285
|
+
if unoccupied?(index - 1) && unoccupied?(index - 2) && unoccupied?(index - 3) && @@pieces[index - 4]["moved"] == false
|
287
286
|
# Ensure king does not move through check or into check
|
288
287
|
if !dangerous_tiles.include?(index - 1) && !dangerous_tiles.include?(index - 2)
|
289
288
|
# King's castle position
|
data/lib/printer.rb
CHANGED
data/lib/terminal_chess.rb
CHANGED
@@ -8,23 +8,25 @@ require_relative "move.rb"
|
|
8
8
|
require_relative "board.rb"
|
9
9
|
|
10
10
|
# Setup
|
11
|
-
|
11
|
+
board = Board.new;
|
12
|
+
board.setup_board;
|
13
|
+
board.board_refresh
|
12
14
|
|
13
15
|
# Gameplay
|
14
|
-
|
15
|
-
|
16
|
-
print "\nPiece to Move [#{
|
16
|
+
loop do
|
17
|
+
|
18
|
+
print "\nPiece to Move [#{board.player_turn.capitalize}]: "
|
17
19
|
from = gets.chomp.upcase
|
18
20
|
|
19
21
|
begin
|
20
|
-
print "Valid destinations: #{
|
22
|
+
print "Valid destinations: #{board.valid_destinations(from).join(", ")}"
|
21
23
|
|
22
24
|
print "\nLocation: "
|
23
25
|
to = gets.chomp.upcase
|
24
|
-
|
26
|
+
board.move(from, to)
|
25
27
|
|
26
28
|
rescue Exception => e
|
27
|
-
puts "Invalid selection"
|
29
|
+
puts "Invalid selection #{e if !ENV["DEV"].nil?}"
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
data/terminal_chess.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.description = "Two player chess game through the terminal"
|
12
12
|
s.authors = ["Jason Willems"]
|
13
13
|
s.email = 'hello@jasonwillems.com'
|
14
|
-
s.homepage = 'https://github.com/
|
14
|
+
s.homepage = 'https://github.com/at1as/Terminal-Chess'
|
15
15
|
s.license = 'MIT'
|
16
16
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
@@ -0,0 +1,265 @@
|
|
1
|
+
#require 'test/unit'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require "./lib/terminal_chess/version"
|
4
|
+
require "printer.rb"
|
5
|
+
require "move.rb"
|
6
|
+
require "board.rb"
|
7
|
+
|
8
|
+
class MyIO
|
9
|
+
def gets
|
10
|
+
"Q\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class TestBoard < MiniTest::Unit::TestCase
|
15
|
+
|
16
|
+
def setup
|
17
|
+
|
18
|
+
@columns = %w[A B C D E F G H]
|
19
|
+
@invalid_msg = "Invalid selection"
|
20
|
+
@red_turn_msg = "It is red's turn. Please move a red piece."
|
21
|
+
@black_turn_msg = "It is black's turn. Please move a black piece."
|
22
|
+
@red_in_check = "Please move red king out of check to continue"
|
23
|
+
@black_in_check = "Please move black king out of check to continue"
|
24
|
+
|
25
|
+
@board = Board.new
|
26
|
+
@board.setup_board
|
27
|
+
@board.board_refresh
|
28
|
+
|
29
|
+
def valid_piece_movement(from)
|
30
|
+
@board.valid_destinations(from)
|
31
|
+
end
|
32
|
+
|
33
|
+
def move_piece(from, to)
|
34
|
+
@board.move(from, to)
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_board
|
38
|
+
@board.piece_manifest
|
39
|
+
end
|
40
|
+
|
41
|
+
def piece_quantity(piece)
|
42
|
+
all_tiles = get_board
|
43
|
+
count = 0
|
44
|
+
all_tiles.each do |num, details|
|
45
|
+
count += 1 if details.fetch("type") == piece
|
46
|
+
end
|
47
|
+
count
|
48
|
+
end
|
49
|
+
|
50
|
+
def tile_empty(lowerbound, upperbound)
|
51
|
+
all_tiles = get_board
|
52
|
+
empty = true
|
53
|
+
all_tiles.each do |num, details|
|
54
|
+
if num >= lowerbound && num <= upperbound
|
55
|
+
empty = empty && details.fetch("type") == " "
|
56
|
+
end
|
57
|
+
end
|
58
|
+
empty
|
59
|
+
end
|
60
|
+
|
61
|
+
def type_on_tile(index)
|
62
|
+
all_tiles = get_board
|
63
|
+
all_tiles.each do |num, details|
|
64
|
+
return details.fetch("type") if num == index
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
## Tests
|
71
|
+
def version_exists
|
72
|
+
assert_instance_of(String, TerminalChess::VERSION, "Version string not present")
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def test_red_cannot_move_out_of_turn
|
77
|
+
assert_equal(@black_turn_msg, @board.move("C7", "C5"))
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_turn_does_not_change_after_invalid_move
|
81
|
+
move_piece("H2", "H9") # Error moving black pawn
|
82
|
+
assert_equal(false, tile_empty(16, 16))
|
83
|
+
move_piece("H2", "H3")
|
84
|
+
assert_equal(true, tile_empty(16, 16))
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_unmoved_pawns_can_move_one_space
|
88
|
+
assert_equal(piece_quantity("pawn"), 16)
|
89
|
+
@columns.each do |c|
|
90
|
+
move_piece("#{c}2", "#{c}3")
|
91
|
+
move_piece("#{c}7", "#{c}6")
|
92
|
+
end
|
93
|
+
assert_equal(16, piece_quantity("pawn"), "There are no longer 16 pawns on the board")
|
94
|
+
assert_equal(true, tile_empty(9,16), "Tiles 9 - 16 are still occupied")
|
95
|
+
assert_equal(true, tile_empty(49, 56), "Tiles 49 - 58 are still occupied")
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_unmoved_pawns_can_move_two_spaces
|
99
|
+
assert_equal(piece_quantity("pawn"), 16)
|
100
|
+
@columns.each do |c|
|
101
|
+
move_piece("#{c}2", "#{c}4")
|
102
|
+
move_piece("#{c}7", "#{c}5")
|
103
|
+
end
|
104
|
+
assert_equal(16, piece_quantity("pawn"), "There are no longer 16 pawns on the board")
|
105
|
+
assert_equal(true, tile_empty(9, 24), "Tiles 9 - 24 are still occupied")
|
106
|
+
assert_equal(true, tile_empty(41, 56), "Tiles 41 - 56 are still occupied")
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_pawns_only_attack_diagonal
|
110
|
+
move_piece("B2", "B4")
|
111
|
+
move_piece("G7", "G5")
|
112
|
+
move_piece("B4", "B5")
|
113
|
+
move_piece("G5", "G4")
|
114
|
+
move_piece("B5", "B6")
|
115
|
+
move_piece("G4", "G3")
|
116
|
+
assert_equal(["A7", "C7"], valid_piece_movement("B6"), "black pawn should only attack diagonally")
|
117
|
+
assert_equal(["F2", "H2"], valid_piece_movement("G3"), "red pawn should only attack diagonally")
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_king_cannot_castle_through_check_to_right
|
121
|
+
move_piece("G2", "G4") # black pawn
|
122
|
+
move_piece("A7", "A5") # red pawn
|
123
|
+
move_piece("F1", "H3") # black bishop
|
124
|
+
move_piece("A8", "A6") # red rook
|
125
|
+
move_piece("G1", "F3") # black knight
|
126
|
+
move_piece("A6", "G6") # red rook
|
127
|
+
move_piece("G4", "G5") # black pawn
|
128
|
+
move_piece("G6", "G5") # red rook
|
129
|
+
assert_equal(["F1"], valid_piece_movement("E1"), "King should only be allowed to move right one tile")
|
130
|
+
move_piece("A2", "A3") # black pawn
|
131
|
+
move_piece("G5", "G2") # red rook
|
132
|
+
move_piece("A3", "A4") # black pawn
|
133
|
+
move_piece("G2", "F2") # red rook
|
134
|
+
assert_equal(@black_in_check, move_piece("E1", "F1"), "King should not be allowed to move into check")
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_king_cannot_castle_through_check_to_left
|
138
|
+
move_piece("B1", "A3") # black knight
|
139
|
+
move_piece("A7", "A5") # red pawn
|
140
|
+
move_piece("D2", "D4") # black pawn
|
141
|
+
move_piece("A8", "A6") # red rook
|
142
|
+
move_piece("C1", "F4") # black bishop
|
143
|
+
move_piece("A6", "B6") # red rook
|
144
|
+
move_piece("D1", "D2") # black queen
|
145
|
+
move_piece("B6", "B2") # black pawn
|
146
|
+
assert_equal(["C1", "D1"], valid_piece_movement("E1"), "King should only be allowed to move left one or two tiles")
|
147
|
+
move_piece("F4", "G5") # black bishop
|
148
|
+
move_piece("B2", "C2") # red rook
|
149
|
+
assert_equal(["D1"], valid_piece_movement("E1"), "King should only be allowed to move left one tile (or it's traversing check)")
|
150
|
+
move_piece("G5", "H5") # black bishop
|
151
|
+
move_piece("C2", "D2") # red rook
|
152
|
+
assert_equal(["D1"], valid_piece_movement("E1"), "King should only be allowed to move left one tile (or it's traversing check)")
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_king_can_castle_to_right
|
156
|
+
move_piece("G2", "G4") # black pawn
|
157
|
+
move_piece("A7", "A5") # red pawn
|
158
|
+
move_piece("F1", "H3") # black bishop
|
159
|
+
move_piece("A8", "A6") # red rook
|
160
|
+
move_piece("G1", "F3") # black knight
|
161
|
+
move_piece("A5", "A4") # red pawn
|
162
|
+
assert_equal(["F1", "G1"], valid_piece_movement("E1"), "King should be allowed to move right one or two tiles")
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_king_can_castle_to_left
|
166
|
+
move_piece("B1", "A3") # Error moving black pawn
|
167
|
+
move_piece("A7", "A6") # Error moving black pawn
|
168
|
+
move_piece("D2", "D4") # Error moving black pawn
|
169
|
+
move_piece("B7", "B6") # Error moving black pawn
|
170
|
+
move_piece("C1", "F4") # Error moving black pawn
|
171
|
+
move_piece("C7", "C6") # Error moving black pawn
|
172
|
+
move_piece("D1", "D2") # Error moving black pawn
|
173
|
+
move_piece("D7", "D6") # Error moving black pawn
|
174
|
+
assert_equal(["C1", "D1"], valid_piece_movement("E1"), "King should be allowed to move left one or two tiles")
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_king_can_kill_check_attacker
|
178
|
+
move_piece("A2", "A3") # Error moving black pawn
|
179
|
+
move_piece("A7", "A5") # Error moving red pawn
|
180
|
+
move_piece("A3", "A4") # Error moving black pawn
|
181
|
+
move_piece("A8", "A6") # Error moving red rook
|
182
|
+
move_piece("B2", "B3") # Error moving black pawn
|
183
|
+
move_piece("A6", "E6") # Error moving red rook
|
184
|
+
move_piece("B3", "B4") # Error moving black pawn
|
185
|
+
move_piece("E6", "E2") # Error moving red rook
|
186
|
+
assert_equal(@black_in_check, move_piece("B4", "B5"))
|
187
|
+
assert_equal(false, tile_empty(5, 5))
|
188
|
+
move_piece("E1", "E2") # Error moving black king
|
189
|
+
assert_equal(true, tile_empty(5, 5))
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_non_king_can_kill_check_attacker
|
193
|
+
move_piece("A2", "A3") # black pawn
|
194
|
+
move_piece("A7", "A5") # red pawn
|
195
|
+
move_piece("A3", "A4") # black pawn
|
196
|
+
move_piece("A8", "A6") # red rook
|
197
|
+
move_piece("B2", "B3") # black pawn
|
198
|
+
move_piece("A6", "E6") # red rook
|
199
|
+
move_piece("B3", "B4") # black pawn
|
200
|
+
move_piece("E6", "E2") # red rook
|
201
|
+
assert_equal(@black_in_check, move_piece("B4", "B5"))
|
202
|
+
assert_equal(false, tile_empty(4, 4))
|
203
|
+
move_piece("D1", "E2")
|
204
|
+
assert_equal(true, tile_empty(4, 4))
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_king_can_move_out_of_check
|
208
|
+
move_piece("G2", "G3") # black knight
|
209
|
+
move_piece("A7", "A5") # red pawn
|
210
|
+
move_piece("F1", "H3") # black pawn
|
211
|
+
move_piece("A8", "A6") # red rook
|
212
|
+
move_piece("G3", "G4") # black pawn
|
213
|
+
move_piece("A6", "E6") # red rook
|
214
|
+
move_piece("G4", "G5") # black pawn
|
215
|
+
move_piece("E6", "E2") # red rook
|
216
|
+
assert_equal(@black_in_check, move_piece("G5", "G6"))
|
217
|
+
assert_equal(false, tile_empty(4, 4))
|
218
|
+
move_piece("E1", "F1")
|
219
|
+
assert_equal(true, tile_empty(5,5))
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_pawn_can_be_promoted
|
223
|
+
move_piece("A2", "A4")
|
224
|
+
move_piece("H7", "H6")
|
225
|
+
move_piece("A4", "A5")
|
226
|
+
move_piece("H6", "H5")
|
227
|
+
move_piece("A5", "A6")
|
228
|
+
move_piece("H5", "H4")
|
229
|
+
move_piece("A6", "B7")
|
230
|
+
move_piece("H4", "H3")
|
231
|
+
$stdin = MyIO.new
|
232
|
+
move_piece("B7", "C8")
|
233
|
+
assert_equal("queen", type_on_tile(59))
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_pawn_cannot_be_promoted_out_of_turn
|
237
|
+
move_piece("A2", "A4")
|
238
|
+
move_piece("H7", "H6")
|
239
|
+
move_piece("A4", "A5")
|
240
|
+
move_piece("H6", "H5")
|
241
|
+
move_piece("A5", "A6")
|
242
|
+
move_piece("H5", "H4")
|
243
|
+
move_piece("A6", "B7")
|
244
|
+
$stdin = MyIO.new
|
245
|
+
assert_equal(@red_turn_msg, move_piece("B7", "C8"))
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_pawn_cannot_be_promoted_while_check
|
249
|
+
move_piece("A2", "A4")
|
250
|
+
move_piece("H7", "H5")
|
251
|
+
move_piece("A4", "A5")
|
252
|
+
move_piece("H8", "H6")
|
253
|
+
move_piece("A5", "A6")
|
254
|
+
move_piece("H6", "E6")
|
255
|
+
move_piece("A6", "B7")
|
256
|
+
move_piece("E6", "E2")
|
257
|
+
assert_equal(@black_in_check, move_piece("B7", "C8"))
|
258
|
+
assert_equal("pawn", type_on_tile(50))
|
259
|
+
assert_equal("bishop", type_on_tile(59))
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_invalid_moves_not_accepted
|
263
|
+
# TODO
|
264
|
+
end
|
265
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terminal_chess
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Willems
|
@@ -70,7 +70,8 @@ files:
|
|
70
70
|
- lib/terminal_chess.rb
|
71
71
|
- lib/terminal_chess/version.rb
|
72
72
|
- terminal_chess.gemspec
|
73
|
-
|
73
|
+
- test/test_terminal_chess.rb
|
74
|
+
homepage: https://github.com/at1as/Terminal-Chess
|
74
75
|
licenses:
|
75
76
|
- MIT
|
76
77
|
metadata: {}
|