terminal_chess 0.1.2 → 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 +4 -4
- data/Gemfile.lock +38 -0
- data/README.md +76 -52
- data/lib/board.rb +357 -0
- data/lib/local_chess_client.rb +45 -0
- data/lib/move.rb +97 -107
- data/lib/network_chess_client.rb +104 -0
- data/lib/printer.rb +129 -54
- data/lib/server.rb +65 -0
- data/lib/terminal_chess.rb +7 -26
- data/lib/terminal_chess/messages.rb +27 -0
- data/lib/terminal_chess/version.rb +1 -1
- data/terminal_chess.gemspec +5 -1
- data/test/test_terminal_chess.rb +240 -41
- metadata +65 -4
- data/lib/Board.rb +0 -266
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6a657c0e4f1a9d9e7f1d0c9ee0c62b009f33fdc
|
4
|
+
data.tar.gz: e691068c1d7e0ba8c9f0a6e2092a8ac32e4c562b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27347b75a56f10cb3969257fac8295d948ced1e6002f545fd539a1890d5853c46d11b287c4721d8ca4d1385938b58d562280542f76222ce9e0f351f29e0d7de6
|
7
|
+
data.tar.gz: 65ce2d89d403db4310bd179b635b36a0a1d84cfc4ae513826ff17de30e1427bb546a06db39203d8152754398d7053a5ebe8c60b94228e120a9ea085d1c2fbee7
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
terminal_chess (0.2.0)
|
5
|
+
colorize
|
6
|
+
em-websocket
|
7
|
+
eventmachine
|
8
|
+
faye-websocket
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
colorize (0.8.1)
|
14
|
+
em-websocket (0.5.1)
|
15
|
+
eventmachine (>= 0.12.9)
|
16
|
+
http_parser.rb (~> 0.6.0)
|
17
|
+
eventmachine (1.2.5)
|
18
|
+
faye-websocket (0.10.7)
|
19
|
+
eventmachine (>= 0.12.0)
|
20
|
+
websocket-driver (>= 0.5.1)
|
21
|
+
http_parser.rb (0.6.0)
|
22
|
+
minitest (5.8.4)
|
23
|
+
rake (10.5.0)
|
24
|
+
websocket-driver (0.7.0)
|
25
|
+
websocket-extensions (>= 0.1.0)
|
26
|
+
websocket-extensions (0.1.3)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
bundler (~> 1.7)
|
33
|
+
minitest
|
34
|
+
rake (~> 10.0)
|
35
|
+
terminal_chess!
|
36
|
+
|
37
|
+
BUNDLED WITH
|
38
|
+
1.16.0
|
data/README.md
CHANGED
@@ -1,63 +1,87 @@
|
|
1
1
|
Terminal-Chess
|
2
2
|
==============
|
3
3
|
|
4
|
-
A two-player chess game for the Terminal, written in Ruby
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
_A__ _B__ _C__ _D__ _E__ _F__ _G__ _H__
|
9
|
-
| || || || || || || || |
|
10
|
-
1 | || KN || BI || QU || KI || BI || KN || RO | 1
|
11
|
-
|____||____||____||____||____||____||____||____|
|
12
|
-
| || || || || || || || |
|
13
|
-
2 | || PA || PA || PA || PA || PA || PA || PA | 2
|
14
|
-
|____||____||____||____||____||____||____||____|
|
15
|
-
| || || || || || || || |
|
16
|
-
3 | || || || || RO || || || | 3
|
17
|
-
|____||____||____||____||____||____||____||____|
|
18
|
-
| || || || || || || || |
|
19
|
-
4 | PA || || || || || || || | 4
|
20
|
-
|____||____||____||____||____||____||____||____|
|
21
|
-
| || || || || || || || |
|
22
|
-
5 | PA || || || || || || || | 5
|
23
|
-
|____||____||____||____||____||____||____||____|
|
24
|
-
| || || || || || || || |
|
25
|
-
6 | || || || || || || || | 6
|
26
|
-
|____||____||____||____||____||____||____||____|
|
27
|
-
| || || || || || || || |
|
28
|
-
7 | || PA || PA || PA || PA || PA || PA || PA | 7
|
29
|
-
|____||____||____||____||____||____||____||____|
|
30
|
-
| || || || || || || || |
|
31
|
-
8 | RO || KN || BI || QU || KI || BI || KN || RO | 8
|
32
|
-
|____||____||____||____||____||____||____||____|
|
33
|
-
A B C D E F G H
|
34
|
-
|
35
|
-
Piece to Move: B8
|
36
|
-
Valid destinations: C6, A6
|
37
|
-
Location: c6
|
38
|
-
|
39
|
-
</pre>
|
40
|
-
|
41
|
-

|
42
|
-
|
43
|
-
### Requirements
|
44
|
-
Requires the colorize Ruby gem (listed in .gemspec file)
|
45
|
-
```bash
|
46
|
-
$ sudo gem install colorize
|
47
|
-
```
|
4
|
+
A lightweight two-player chess game for the Terminal, written in Ruby
|
5
|
+
|
6
|
+

|
7
|
+
|
48
8
|
|
49
|
-
###
|
50
|
-
|
9
|
+
### Installing
|
10
|
+
|
11
|
+
The easiest way to use terminal_chess is to install it via the [Rubygem](https://rubygems.org/gems/terminal_chess). Note that the Gem is *way* out of date when compared to the repo
|
51
12
|
|
52
13
|
Otherwise, clone this repo directly and run:
|
53
|
-
|
14
|
+
|
15
|
+
```bash
|
16
|
+
# Download Repo
|
54
17
|
$ git clone git@github.com:at1as/Terminal-Chess.git
|
55
18
|
$ chmod +x lib/terminal_chess.rb
|
19
|
+
|
20
|
+
# Install Dependencies. Only dependency is the colorize gem
|
21
|
+
$ bundle install
|
22
|
+
```
|
23
|
+
|
24
|
+
### Running
|
25
|
+
|
26
|
+
#### Local Gameplay
|
27
|
+
|
28
|
+
In this mode, the game will launch in Terminal and allow the player to make moves for both sides of the board
|
29
|
+
|
30
|
+
```
|
31
|
+
# Run program in terminal
|
32
|
+
|
56
33
|
$ ruby lib/terminal_chess.rb
|
57
34
|
```
|
58
35
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
36
|
+
#### Multiplayer
|
37
|
+
|
38
|
+
Terminal Chess can connect to an opponent using websockets over ngrok. The requires first starting the server:
|
39
|
+
|
40
|
+
```
|
41
|
+
# The webserver must be running either on one of the players machines
|
42
|
+
# Or somewhere else. This will need to be running before either client can connect
|
43
|
+
$ lib/server.rb
|
44
|
+
|
45
|
+
# The host running the server will need to tunnel the connection through ngrok
|
46
|
+
# on the free plan the URL will change every time ngrok is launched
|
47
|
+
# therefor the `9cf13f35` component will need to be passed to the clients in order
|
48
|
+
# to connect
|
49
|
+
$ ngrok http 4567
|
50
|
+
=> http://9cf13f35.ngrok.io -> localhost:4567
|
51
|
+
```
|
52
|
+
|
53
|
+
And then the client can connect via the NGROK environment variable. if this environment variable is set, the client will attempt to start a session over the network. If the connection
|
54
|
+
|
55
|
+
```
|
56
|
+
# Replace the NGROK enviroment variable with whatever URL the ngrok server returned
|
57
|
+
$ NGROK=9cf13f5 ruby lib/terminal_chess.rb
|
58
|
+
|
59
|
+
# => [:message, "INFO: Awaiting second player..."]
|
60
|
+
```
|
61
|
+
|
62
|
+
And once the second client connects, game on!
|
63
|
+
|
64
|
+
```
|
65
|
+
$ NGROK=9cf13f5 ruby lib/terminal_chess.rb
|
66
|
+
|
67
|
+
# => [:message, "INFO: Connected to remote player"]
|
68
|
+
# => [:message, "SETUP: You are player 2"]
|
69
|
+
# => [:message, "INFO: Starting game!"]
|
70
|
+
```
|
71
|
+
|
72
|
+
Any subsequent clients that attempt to connect while the game is in session will have their connections dropped
|
73
|
+
|
74
|
+
### Testing:
|
75
|
+
|
76
|
+
```bash
|
77
|
+
$ bundle exec rake test --trace
|
78
|
+
```
|
79
|
+
|
80
|
+
### Notes
|
81
|
+
* Built and tested on macOS 10.11 with Ruby 2.4.0
|
82
|
+
* Neither player can currently be automated
|
83
|
+
|
84
|
+
### TODO:
|
85
|
+
* Update Gem to reflect the last two years' repo changes...
|
86
|
+
* Automate one of two players (note: tried this. Not easy to make it competent)
|
87
|
+
* Switch written Chess pieces to unicode characters (note: tried this. Didn't look great)
|
data/lib/board.rb
ADDED
@@ -0,0 +1,357 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
load 'printer.rb'
|
4
|
+
load 'move.rb'
|
5
|
+
load 'terminal_chess/messages.rb'
|
6
|
+
require 'colorize'
|
7
|
+
|
8
|
+
class Board
|
9
|
+
|
10
|
+
include Printer
|
11
|
+
include Move
|
12
|
+
|
13
|
+
attr_reader :piece_locations, :checkmate, :player_turn
|
14
|
+
attr_reader :taken_pieces
|
15
|
+
|
16
|
+
alias piece_manifest piece_locations
|
17
|
+
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@piece_locations_buffer = Hash.new
|
21
|
+
@piece_locations = Hash.new
|
22
|
+
@row_mappings = Hash[("A".."H").zip(1..8)]
|
23
|
+
@taken_pieces = Array.new
|
24
|
+
@player_turn = :black
|
25
|
+
@checkmate = false
|
26
|
+
|
27
|
+
setup_board
|
28
|
+
end
|
29
|
+
|
30
|
+
# Game logic
|
31
|
+
def move(p1, p2)
|
32
|
+
|
33
|
+
manifest = piece_manifest()
|
34
|
+
|
35
|
+
p1 = get_index_from_rowcol(p1.to_s)
|
36
|
+
p2 = get_index_from_rowcol(p2.to_s)
|
37
|
+
|
38
|
+
# Find valid positions and subtract king current position as nobody can directly take king piece
|
39
|
+
valid_positions = possible_moves(p1, manifest, true)
|
40
|
+
valid_positions -= king_positions
|
41
|
+
|
42
|
+
# If player is moving out of turn, display message
|
43
|
+
# `return p ...` is so we print value and return it from the function
|
44
|
+
# this is so the unit tests can get the value directly. There are better ways to do this
|
45
|
+
unless @player_turn == @piece_locations[p1][:color]
|
46
|
+
return p "It is #{@player_turn}'s turn. Please move a #{@player_turn} piece."
|
47
|
+
end
|
48
|
+
|
49
|
+
return p "Please select a valid destination." unless valid_positions.include?(p2)
|
50
|
+
|
51
|
+
create_board_after_piece_moved(p1, p2)
|
52
|
+
|
53
|
+
# If player is in check with the new proposed board, disallow the movement
|
54
|
+
if check?(@player_turn, @piece_locations_buffer)
|
55
|
+
return p "Please move #{@player_turn} king out of check to continue"
|
56
|
+
end
|
57
|
+
|
58
|
+
# At this point, the move appears to be valid
|
59
|
+
@taken_pieces << @piece_locations[p2] unless @piece_locations[p2][:type].nil?
|
60
|
+
|
61
|
+
# Check for Pawn Promotion (if pawn reaches end of the board, promote it)
|
62
|
+
if @piece_locations_buffer[p2][:type] == :pawn
|
63
|
+
if p2 < 9 && @piece_locations_buffer[p2][:color] == :red
|
64
|
+
promote(p2)
|
65
|
+
elsif p2 > 56 && @piece_locations_buffer[p2][:color] == :black
|
66
|
+
promote(p2)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Check for Castling - https://en.m.wikipedia.org/wiki/Castling
|
71
|
+
if @piece_locations_buffer[p2][:type] == :king && (p2 - p1).abs == 2
|
72
|
+
|
73
|
+
p2 < 9 ? y_offset = 0 : y_offset = 56
|
74
|
+
|
75
|
+
if p2 > p1
|
76
|
+
@piece_locations_buffer[6+y_offset] = @piece_locations_buffer[8+y_offset]
|
77
|
+
@piece_locations_buffer[8+y_offset] = {
|
78
|
+
:type => nil,
|
79
|
+
:number => nil,
|
80
|
+
:color => nil
|
81
|
+
}
|
82
|
+
else
|
83
|
+
@piece_locations_buffer[4+y_offset] = @piece_locations_buffer[1+y_offset]
|
84
|
+
@piece_locations_buffer[1+y_offset] = {
|
85
|
+
:type => nil,
|
86
|
+
:number => nil,
|
87
|
+
:color => nil
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
commit_board_piece_movement
|
93
|
+
|
94
|
+
if (winner = player_in_checkmate(@piece_locations))
|
95
|
+
return p Messages.black_winner if winner == :black
|
96
|
+
return p Messages.red_winner if winner == :red
|
97
|
+
end
|
98
|
+
|
99
|
+
return p Messages.piece_moved
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def commit_board_piece_movement
|
104
|
+
@piece_locations = @piece_locations_buffer
|
105
|
+
@player_turn = opposing_color(@player_turn)
|
106
|
+
display_board
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def create_board_after_piece_moved(p1, p2)
|
111
|
+
# Store state of board after proposed move in @piece_locations_buffer
|
112
|
+
@piece_locations_buffer = @piece_locations.clone
|
113
|
+
@piece_locations_buffer[p2] = @piece_locations_buffer[p1]
|
114
|
+
@piece_locations_buffer[p2][:moved] = true
|
115
|
+
@piece_locations_buffer[p1] = {
|
116
|
+
:type => nil,
|
117
|
+
:number => nil,
|
118
|
+
:color => nil
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
# Return the valid positions for piece at current_pos to move in readable format [A-H][1-8]
|
124
|
+
def valid_destinations(current_pos)
|
125
|
+
readable_positions = []
|
126
|
+
manifest = piece_manifest
|
127
|
+
p1 = get_index_from_rowcol(current_pos.to_s)
|
128
|
+
|
129
|
+
valid_positions = possible_moves(p1, manifest, true)
|
130
|
+
|
131
|
+
valid_positions.each do |pos|
|
132
|
+
grid_pos = get_rowcol_from_index(pos)
|
133
|
+
# Map first string character 1-8 to [A-H], for column, and then add second string character as [1-8]
|
134
|
+
readable_positions << (@row_mappings.key(grid_pos[0].to_i) + grid_pos[1].to_s)
|
135
|
+
end
|
136
|
+
|
137
|
+
readable_positions.sort
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# Search piece manifest for kings. Remove them from the list of positions returned
|
142
|
+
# from the Move module (so that players cannot take the "king" type piece)
|
143
|
+
def king_positions
|
144
|
+
king_locations = []
|
145
|
+
|
146
|
+
@piece_locations.each do |piece, details|
|
147
|
+
king_locations << piece if details.fetch(:type) == :king
|
148
|
+
end
|
149
|
+
|
150
|
+
king_locations
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
# Once a pawn reaches the end, this method is called to swap the pawn
|
155
|
+
# for another piece (from the list below)
|
156
|
+
def promote(p1)
|
157
|
+
puts "Promote to: [Q]ueen, [K]night, [R]ook, [B]ishop"
|
158
|
+
|
159
|
+
loop do
|
160
|
+
promo_piece = gets.chomp.downcase
|
161
|
+
|
162
|
+
if promo_piece == "q" || promo_piece == :queen
|
163
|
+
@piece_locations_buffer[p1][:type] = :queen
|
164
|
+
break
|
165
|
+
|
166
|
+
elsif promo_piece == "k" || promo_piece == :knight
|
167
|
+
@piece_locations_buffer[p1][:type] = :knight
|
168
|
+
break
|
169
|
+
|
170
|
+
elsif promo_piece == "r" || promo_piece == :rook
|
171
|
+
@piece_locations_buffer[p1][:type] = :rook
|
172
|
+
break
|
173
|
+
|
174
|
+
elsif promo_piece == "b" || promo_piece == :bishop
|
175
|
+
@piece_locations_buffer[p1][:type] = :bishop
|
176
|
+
break
|
177
|
+
|
178
|
+
else
|
179
|
+
puts "Please enter one of: [Q]ueen, [K]night, [R]ook, [B]ishop"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
private :promote
|
185
|
+
|
186
|
+
|
187
|
+
def player_in_checkmate(manifest = @piece_locations)
|
188
|
+
return :red if checkmate?(:black, manifest)
|
189
|
+
return :black if checkmate?(:red, manifest)
|
190
|
+
end
|
191
|
+
|
192
|
+
def checkmate?(color, manifest)
|
193
|
+
check?(color, manifest, recurse_for_checkmate=true) && @checkmate
|
194
|
+
end
|
195
|
+
|
196
|
+
# Return whether the player of a specified color has their king currently in check
|
197
|
+
# by checking the attack vectors of all the opponents players against the king location
|
198
|
+
# Also, check whether king currently in check, has all of their valid moves within
|
199
|
+
# their opponents attack vectors, and therefore are in checkmate (@checkmate)
|
200
|
+
def check?(color, proposed_manifest = @piece_locations, recurse_for_checkmate = false)
|
201
|
+
|
202
|
+
enemy_attack_vectors = {}
|
203
|
+
player_attack_vectors = {}
|
204
|
+
|
205
|
+
king_loc = []
|
206
|
+
enemy_color = opposing_color(color)
|
207
|
+
|
208
|
+
proposed_manifest.each do |piece, details|
|
209
|
+
|
210
|
+
if details[:color] == enemy_color
|
211
|
+
enemy_attack_vectors[piece] = possible_moves(piece, proposed_manifest)
|
212
|
+
|
213
|
+
elsif details[:color] == color
|
214
|
+
begin
|
215
|
+
player_attack_vectors[piece] = possible_moves(piece, proposed_manifest)
|
216
|
+
rescue
|
217
|
+
# TODO: Fix possible_moves() so it doesn't throw exceptions
|
218
|
+
# This happens because it is searching board for where pieces
|
219
|
+
# will be, as as a result some pieces are nil
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
king_loc = piece if details[:color] == color && details[:type] == :king
|
224
|
+
end
|
225
|
+
|
226
|
+
danger_vector = enemy_attack_vectors.values.flatten.uniq
|
227
|
+
defence_vector = player_attack_vectors.values.flatten.uniq
|
228
|
+
king_positions = possible_moves(king_loc, proposed_manifest)
|
229
|
+
|
230
|
+
# The King is in the attackable locations by the opposing player
|
231
|
+
return false unless danger_vector.include? king_loc
|
232
|
+
|
233
|
+
# If all the positions the king piece can move to is also attackable by the opposing player
|
234
|
+
if recurse_for_checkmate && ((king_positions - danger_vector).length == 0)
|
235
|
+
|
236
|
+
is_in_check = []
|
237
|
+
player_attack_vectors.each do |piece_index, piece_valid_moves|
|
238
|
+
piece_valid_moves.each do |possible_new_location|
|
239
|
+
|
240
|
+
# Check if board is still in check after piece moves to its new location
|
241
|
+
@new_piece_locations = @piece_locations.clone
|
242
|
+
@new_piece_locations[possible_new_location] = @new_piece_locations[piece_index]
|
243
|
+
@new_piece_locations[piece_index] = {
|
244
|
+
:type => nil,
|
245
|
+
:number => nil,
|
246
|
+
:color => nil
|
247
|
+
}
|
248
|
+
|
249
|
+
is_in_check << check?(color, @new_piece_locations)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
if is_in_check.include?(false)
|
254
|
+
return false
|
255
|
+
else
|
256
|
+
@checkmate = true
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
true
|
261
|
+
end
|
262
|
+
|
263
|
+
|
264
|
+
def opposing_color(player_color)
|
265
|
+
([:black, :red] - [player_color]).first
|
266
|
+
end
|
267
|
+
|
268
|
+
# Board spaces that are attackable by opposing pieces
|
269
|
+
# TODO: check? method should use this function
|
270
|
+
def attack_vectors(color = @player_turn, proposed_manifest = @piece_locations)
|
271
|
+
enemy_color = opposing_color(color)
|
272
|
+
kill_zone = Array.new
|
273
|
+
|
274
|
+
proposed_manifest.each do |piece, details|
|
275
|
+
kill_zone << possible_moves(piece, proposed_manifest) if details.fetch(:color) == enemy_color
|
276
|
+
end
|
277
|
+
|
278
|
+
kill_zone.flatten.uniq
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
# Reprint the board. Called after every valid piece move
|
283
|
+
def display_board
|
284
|
+
print_board @piece_locations
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
# Convert index [A-H][1-8] => (1 - 64)
|
289
|
+
def get_index_from_rowcol(row_col)
|
290
|
+
(row_col[1].to_i - 1) * 8 + @row_mappings.fetch(row_col[0]).to_i
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
# Convert index (1 - 64) => [A-H][1-8]
|
295
|
+
def get_rowcol_from_index(index)
|
296
|
+
letter = get_col_from_index(index)
|
297
|
+
number = get_row_from_index(index)
|
298
|
+
|
299
|
+
"#{letter}#{number}"
|
300
|
+
end
|
301
|
+
|
302
|
+
|
303
|
+
def setup_board
|
304
|
+
# Intial setup of board. Put pieces into the expected locations
|
305
|
+
setup_empty_tiles
|
306
|
+
place_player_pieces(:black)
|
307
|
+
place_player_pieces(:red)
|
308
|
+
end
|
309
|
+
|
310
|
+
|
311
|
+
def setup_empty_tiles
|
312
|
+
# Initialize chess board tiles without any pieces
|
313
|
+
(1..64).each do |tile_num|
|
314
|
+
@piece_locations[tile_num] = {
|
315
|
+
:type => nil,
|
316
|
+
:number => nil,
|
317
|
+
:color => nil
|
318
|
+
}
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
|
323
|
+
def place_player_pieces(color)
|
324
|
+
# Place pieces on chess board
|
325
|
+
place_first_row(color)
|
326
|
+
place_pawns(color)
|
327
|
+
end
|
328
|
+
|
329
|
+
|
330
|
+
def place_pawns(color)
|
331
|
+
offset = color == :black ? 8 : 48
|
332
|
+
|
333
|
+
(1..8).each do |piece_num|
|
334
|
+
@piece_locations[piece_num + offset] = {
|
335
|
+
:type => :pawn,
|
336
|
+
:number => piece_num,
|
337
|
+
:color => color,
|
338
|
+
:moved => false
|
339
|
+
}
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
def place_first_row(color)
|
345
|
+
row_offset = color == :black ? 0 : 56
|
346
|
+
|
347
|
+
@piece_locations[row_offset + 1] = {:type => :rook, :number => 1, :color => color, :moved => false}
|
348
|
+
@piece_locations[row_offset + 2] = {:type => :knight, :number => 1, :color => color, :moved => false}
|
349
|
+
@piece_locations[row_offset + 3] = {:type => :bishop, :number => 1, :color => color, :moved => false}
|
350
|
+
@piece_locations[row_offset + 4] = {:type => :queen, :number => 1, :color => color, :moved => false}
|
351
|
+
@piece_locations[row_offset + 5] = {:type => :king, :number => 1, :color => color, :moved => false}
|
352
|
+
@piece_locations[row_offset + 6] = {:type => :bishop, :number => 2, :color => color, :moved => false}
|
353
|
+
@piece_locations[row_offset + 7] = {:type => :knight, :number => 2, :color => color, :moved => false}
|
354
|
+
@piece_locations[row_offset + 8] = {:type => :rook, :number => 2, :color => color, :moved => false}
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|