terminal_chess 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: {}
|