terminal_chess 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminal_chess
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Willems
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-03 00:00:00.000000000 Z
11
+ date: 2017-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -24,6 +24,48 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: em-websocket
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: eventmachine
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faye-websocket
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: bundler
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +94,20 @@ dependencies:
52
94
  - - "~>"
53
95
  - !ruby/object:Gem::Version
54
96
  version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
55
111
  description: Two player chess game through the terminal
56
112
  email: hello@jasonwillems.com
57
113
  executables:
@@ -60,14 +116,19 @@ extensions: []
60
116
  extra_rdoc_files: []
61
117
  files:
62
118
  - Gemfile
119
+ - Gemfile.lock
63
120
  - LICENSE
64
121
  - README.md
65
122
  - Rakefile
66
123
  - bin/terminal_chess
67
- - lib/Board.rb
124
+ - lib/board.rb
125
+ - lib/local_chess_client.rb
68
126
  - lib/move.rb
127
+ - lib/network_chess_client.rb
69
128
  - lib/printer.rb
129
+ - lib/server.rb
70
130
  - lib/terminal_chess.rb
131
+ - lib/terminal_chess/messages.rb
71
132
  - lib/terminal_chess/version.rb
72
133
  - terminal_chess.gemspec
73
134
  - test/test_terminal_chess.rb
@@ -91,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
152
  version: '0'
92
153
  requirements: []
93
154
  rubyforge_project:
94
- rubygems_version: 2.2.2
155
+ rubygems_version: 2.6.8
95
156
  signing_key:
96
157
  specification_version: 4
97
158
  summary: Chess game playable via the terminal
@@ -1,266 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- load 'printer.rb'
4
- load 'move.rb'
5
- require 'colorize'
6
-
7
- class Board
8
-
9
- include PRINTER
10
- include MOVE
11
-
12
- def initialize
13
- @@piece_locations = Hash.new
14
- @@piece_locations_buffer = Hash.new
15
- @@row_mappings = Hash[("A".."H").zip(1..8)]
16
- @@taken_pieces = []
17
- @@player_turn = "black"
18
- @@checkmate = false
19
- end
20
-
21
-
22
- # Game logic
23
- def move(p1, p2)
24
- manifest = piece_manifest
25
- p1 = get_index_from_rowcol(p1.to_s)
26
- p2 = get_index_from_rowcol(p2.to_s)
27
- valid_positions = possible_moves(p1, manifest, true)
28
-
29
- ##Subtract king current position from valid positions
30
- valid_positions -= king_positions
31
-
32
- # Allow piece movements, unless in checkmate
33
- if !@@checkmate
34
- # Ensure player is moving in turn
35
- if @@player_turn == @@piece_locations[p1]["color"]
36
-
37
- @@piece_locations_buffer = @@piece_locations.clone
38
-
39
- # Chosen destination is within the list of valid destinations
40
- if ([p2] - valid_positions).empty?
41
-
42
- @@piece_locations_buffer[p2] = @@piece_locations_buffer[p1]
43
- @@piece_locations_buffer[p2]["moved"] = true
44
- @@piece_locations_buffer[p1] = {"type" => " ", "number" => nil, "color" => nil}
45
-
46
- # If the current player is not in check at the end of the turn, allow them to proceed
47
- if !check?(@@player_turn, @@piece_locations_buffer)
48
-
49
- @@taken_pieces << @@piece_locations[p2] if !@@piece_locations[p2]["number"].nil?
50
-
51
- # Check for Pawn Promotion (if pawn reaches end of the board, promote it)
52
- if @@piece_locations_buffer[p2]["type"] == "pawn"
53
- if p2 < 9 && @@piece_locations_buffer[p2]["color"] == "red"
54
- promote(p2)
55
- elsif p2 > 56 && @@piece_locations_buffer[p2]["color"] == "black"
56
- promote(p2)
57
- end
58
- end
59
-
60
- # Check for Castling
61
- if @@piece_locations_buffer[p2]["type"] == "king" && (p2 - p1).abs == 2
62
-
63
- p2 < 9 ? y_offset = 0 : y_offset = 56
64
-
65
- if p2 > p1
66
- @@piece_locations_buffer[6+y_offset] = @@piece_locations_buffer[8+y_offset]
67
- @@piece_locations_buffer[8+y_offset] = {"type" => " ", "number" => nil, "color" => nil}
68
- else
69
- @@piece_locations_buffer[4+y_offset] = @@piece_locations_buffer[1+y_offset]
70
- @@piece_locations_buffer[1+y_offset] = {"type" => " ", "number" => nil, "color" => nil}
71
- end
72
- end
73
-
74
- # Clean Up
75
- @@piece_locations = @@piece_locations_buffer
76
- @@player_turn = (["black", "red"] - [@@player_turn]).first
77
- board_refresh
78
- else
79
- p "Please move #{@@player_turn} king out of check to continue"
80
- 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
84
- end
85
-
86
- # Return the valid positions for piece at current_pos to move in readable format [A-H][1-8]
87
- def valid_destinations(current_pos)
88
- readable_positions = []
89
- manifest = piece_manifest
90
- p1 = get_index_from_rowcol(current_pos.to_s)
91
-
92
- valid_positions = possible_moves(p1, manifest, true)
93
- valid_positions.each do |pos|
94
- grid_pos = get_rowcol_from_index(pos)
95
- # Map first string character 1-8 to [A-H], for column, and then add second string character as [1-8]
96
- readable_positions << (@@row_mappings.key(grid_pos[0].to_i) + grid_pos[1].to_s)
97
- end
98
- return readable_positions.sort
99
- end
100
-
101
- # Search piece manifest for kings. Remove them from the list of positions returned
102
- # from the MOVE module (so that players cannot take the "king" type piece)
103
- def king_positions
104
- king_locations = []
105
- @@piece_locations.each do |piece, details|
106
- if details["type"] == "king"
107
- king_locations << piece
108
- end
109
- end
110
- return king_locations
111
- end
112
-
113
-
114
- # Once a pawn reaches the end, this method is called to swap the pawn
115
- # for another piece (from the list below)
116
- def promote(p1)
117
- puts "Promote to: [Q]ueen, [K]night, [R]ook, [B]ishop"
118
- while true
119
- promo_piece = gets.chomp.downcase
120
- if promo_piece == "q" || promo_piece == "queen"
121
- @@piece_locations_buffer[p1]["type"] = "queen"
122
- break
123
- elsif promo_piece == "k" || promo_piece == "knight"
124
- @@piece_locations_buffer[p1]["type"] = "knight"
125
- break
126
- elsif promo_piece == "r" || promo_piece == "rook"
127
- @@piece_locations_buffer[p1]["type"] = "rook"
128
- break
129
- elsif promo_piece == "b" || promo_piece == "bishop"
130
- @@piece_locations_buffer[p1]["type"] = "bishop"
131
- break
132
- else
133
- puts "Please enter one of: [Q]ueen, [K]night, [R]ook, [B]ishop"
134
- end
135
- end
136
- end
137
-
138
- private :promote
139
-
140
- # Return whether the player of a specified color has their king currently in check
141
- # by checking the attack vectors of all the opponents players, versus the king location
142
- # Also, check whether king currently in check, has all of their valid moves within
143
- # their opponents attack vectors, and therefore are in checkmate (@@checkmate)
144
- def check?(color, proposed_manifest = @@piece_locations)
145
- path, king_loc = [], []
146
- enemy_color = (["black", "red"] - ["#{color}"]).first
147
-
148
- proposed_manifest.each do |piece, details|
149
- if details["color"] == enemy_color
150
- path << possible_moves(piece, proposed_manifest)
151
- end
152
- if details["color"] == color && details["type"] == "king"
153
- king_loc = piece
154
- end
155
- end
156
-
157
- danger_vector = path.flatten.uniq
158
- king_positions = possible_moves(king_loc, proposed_manifest)
159
-
160
- # If the King is in the attackable locations for the opposing player
161
- if danger_vector.include? king_loc
162
- # If all the positions the can move to is also attackable by the opposing player
163
- if (king_positions - danger_vector).length != 0
164
- # This is flawed. It verified whether the king could move out check
165
- # There are two other cases: whether a piece can remove the enemy
166
- # And whether the enemy's attack vector can be blocked
167
- #@@checkmate = true
168
- end
169
- return true
170
- # Piece not in check
171
- else
172
- return false
173
- end
174
- end
175
-
176
-
177
- # Board spaces that are attackable by opposing pieces
178
- # TODO: check? method should use this function
179
- def attack_vectors(color = @@player_turn, proposed_manifest = @@piece_locations)
180
- enemy_color = (["black", "red"] - ["#{color}"]).first
181
- kill_zone = []
182
-
183
- proposed_manifest.each do |piece, details|
184
- if details["color"] == enemy_color
185
- kill_zone << possible_moves(piece, proposed_manifest)
186
- end
187
- end
188
-
189
- kill_zone.flatten.uniq
190
- end
191
-
192
-
193
- # Reprint the board. Called after every valid piece move
194
- def board_refresh
195
- print_board(@@piece_locations)
196
- end
197
-
198
-
199
- # Convert index [A-H][1-8] => (1 - 64)
200
- def get_index_from_rowcol(row_col)
201
- offset = @@row_mappings[row_col[0]].to_i
202
- multiplier = row_col[1].to_i - 1
203
- return multiplier * 8 + offset
204
- end
205
-
206
-
207
- # Convert index (1 - 64) => [A-H][1-8]
208
- def get_rowcol_from_index(index)
209
- letter = get_col_from_index(index)
210
- number = get_row_from_index(index)
211
- "#{letter}#{number}"
212
- end
213
-
214
-
215
- # Intial setup of board. Put pieces into the expected locations
216
- def setup_board
217
- (1..64).each do |location|
218
- @@piece_locations[location] = {"type" => " ", "number" => nil, "color" => nil}
219
- end
220
-
221
- # Black Pieces
222
- @@piece_locations[1] = {"type" => "rook", "number" => 1, "color" => "black", "moved" => false}
223
- @@piece_locations[2] = {"type" => "knight", "number" => 1, "color" => "black", "moved" => false}
224
- @@piece_locations[3] = {"type" => "bishop", "number" => 1, "color" => "black", "moved" => false}
225
- @@piece_locations[4] = {"type" => "queen", "number" => 1, "color" => "black", "moved" => false}
226
- @@piece_locations[5] = {"type" => "king", "number" => 1, "color" => "black", "moved" => false}
227
- @@piece_locations[6] = {"type" => "bishop", "number" => 2, "color" => "black", "moved" => false}
228
- @@piece_locations[7] = {"type" => "knight", "number" => 2, "color" => "black", "moved" => false}
229
- @@piece_locations[8] = {"type" => "rook", "number" => 2, "color" => "black", "moved" => false}
230
- (1..8).each do |col|
231
- @@piece_locations[col + 8] = {"type" => "pawn", "number" => col, "color" => "black", "moved" => false}
232
- end
233
-
234
- # White Pieces
235
- @@piece_locations[57] = {"type" => "rook", "number" => 1, "color" => "red", "moved" => false}
236
- @@piece_locations[58] = {"type" => "knight", "number" => 1, "color" => "red", "moved" => false}
237
- @@piece_locations[59] = {"type" => "bishop", "number" => 1, "color" => "red", "moved" => false}
238
- @@piece_locations[60] = {"type" => "queen", "number" => 1, "color" => "red", "moved" => false}
239
- @@piece_locations[61] = {"type" => "king", "number" => 1, "color" => "red", "moved" => false}
240
- @@piece_locations[62] = {"type" => "bishop", "number" => 2, "color" => "red", "moved" => false}
241
- @@piece_locations[63] = {"type" => "knight", "number" => 2, "color" => "red", "moved" => false}
242
- @@piece_locations[64] = {"type" => "rook", "number" => 2, "color" => "red", "moved" => false}
243
- (1..8).each do |col|
244
- @@piece_locations[col + 48] = {"type" => "pawn", "number" => col, "color" => "red", "moved" => false}
245
- end
246
- end
247
-
248
-
249
- def piece_manifest
250
- return @@piece_locations
251
- end
252
-
253
- # Not currently used
254
- def taken_pieces
255
- return @@taken_pieces
256
- end
257
-
258
- def checkmate?
259
- return @@checkmate
260
- end
261
-
262
- def player_turn
263
- return @@player_turn
264
- end
265
-
266
- end