chess_vwong 0.0.1
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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +4 -0
- data/bin/chess_vwong +21 -0
- data/chess_vwong.gemspec +24 -0
- data/example/example_game.rb +20 -0
- data/lib/chess_vwong/bishop.rb +22 -0
- data/lib/chess_vwong/board.rb +207 -0
- data/lib/chess_vwong/game.rb +73 -0
- data/lib/chess_vwong/king.rb +17 -0
- data/lib/chess_vwong/knight.rb +17 -0
- data/lib/chess_vwong/node.rb +9 -0
- data/lib/chess_vwong/pawn.rb +44 -0
- data/lib/chess_vwong/piece.rb +34 -0
- data/lib/chess_vwong/player.rb +12 -0
- data/lib/chess_vwong/preload.rb +65 -0
- data/lib/chess_vwong/queen.rb +28 -0
- data/lib/chess_vwong/rook.rb +22 -0
- data/lib/chess_vwong/version.rb +3 -0
- data/lib/chess_vwong.rb +23 -0
- data/spec/bishop_spec.rb +50 -0
- data/spec/board_spec.rb +293 -0
- data/spec/game_spec.rb +38 -0
- data/spec/king_spec.rb +51 -0
- data/spec/knight_spec.rb +73 -0
- data/spec/node_spec.rb +24 -0
- data/spec/pawn_spec.rb +112 -0
- data/spec/piece_spec.rb +53 -0
- data/spec/player_spec.rb +21 -0
- data/spec/queen_spec.rb +50 -0
- data/spec/rook_spec.rb +50 -0
- data/spec/spec_helper.rb +1 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0fef94857588ea8e0075792e5d00e17bdcb59027
|
4
|
+
data.tar.gz: 0ce26be57dff21eac0ccdcd316f7e1b57ca6d807
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2d7d20933510dbe53257fc26c64d49a6b7027a1464762b1d3d151914f952f2a45e83d4c41f9c53030b7861ccd277c26480f68401aaa12b299932475e2b98d45b
|
7
|
+
data.tar.gz: 3e8d19fac4928cad5b852093e61b8efdb8d6c7264f390c77659faf28eb2b51cbecebfce185cf89a31dd37143698cbe0d830c8001b35c072b871d313085a8e887
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Vincent Wong
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Chess
|
2
|
+
|
3
|
+
A barebones version of command-line Chess for 2 players.
|
4
|
+
|
5
|
+
TODO:
|
6
|
+
1. Alert Check/Mate
|
7
|
+
2. Castling & En-Passant Moves
|
8
|
+
|
9
|
+
##Gameplay
|
10
|
+
The game is played on a standard 8 by 8 board as show below.
|
11
|
+
|
12
|
+
A B C D E F G H
|
13
|
+
8 ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖
|
14
|
+
7 ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
|
15
|
+
6 _ _ _ _ _ _ _ _
|
16
|
+
5 _ _ _ _ _ _ _ _
|
17
|
+
4 _ _ _ _ _ _ _ _
|
18
|
+
3 _ _ _ _ _ _ _ _
|
19
|
+
2 ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
|
20
|
+
1 ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
|
21
|
+
|
22
|
+
A user will first be prompted to select a chess piece belonging to his/her color. Once a the chess piece has been chosen, he/she will then be prompted to select a space to move that chess piece.
|
23
|
+
|
24
|
+
To enter a command, simply type in the X and Y coordinate without any spaces or commas seperating the two, for example:
|
25
|
+
* A2
|
26
|
+
* H7
|
27
|
+
|
28
|
+
(Lowercases are also accepted)
|
29
|
+
|
30
|
+
If a command is invalid, the use will be alerted and prompted again until a valid command is entered.
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
## Installation
|
35
|
+
|
36
|
+
To install:
|
37
|
+
|
38
|
+
$ gem install chess_vwong
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
TODO: Write usage instructions here
|
43
|
+
|
44
|
+
## Contributing
|
45
|
+
|
46
|
+
1. Fork it ( https://github.com/[my-github-username]/chess_vwong/fork )
|
47
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
48
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
49
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
50
|
+
5. Create a new Pull Request
|
51
|
+
|
52
|
+
|
data/Rakefile
ADDED
data/bin/chess_vwong
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'chess_vwong'
|
3
|
+
|
4
|
+
puts "Welcome to Chess"
|
5
|
+
puts "Player 1, please Enter your name:"
|
6
|
+
name_1 = gets.chomp
|
7
|
+
puts "Player 2, please Enter your name:"
|
8
|
+
name_2 = gets.chomp
|
9
|
+
puts ""
|
10
|
+
|
11
|
+
puts "---------------------------"
|
12
|
+
puts "#{name_1} will be White"
|
13
|
+
puts "#{name_2} will be Black"
|
14
|
+
puts "---------------------------"
|
15
|
+
puts ""
|
16
|
+
puts "Let's begin!"
|
17
|
+
|
18
|
+
bob = ChessVwong::Player.new(name_1, "w")
|
19
|
+
peter = ChessVwong::Player.new(name_2, "b")
|
20
|
+
players = [bob, peter]
|
21
|
+
ChessVwong::Game.new(players).play
|
data/chess_vwong.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'chess_vwong/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "chess_vwong"
|
8
|
+
spec.version = ChessVwong::VERSION
|
9
|
+
spec.authors = ["Vincent Wong"]
|
10
|
+
spec.email = ["wingyu64@gmail.com"]
|
11
|
+
spec.summary = %q{2-player CLI Chess}
|
12
|
+
spec.description = %q{2-player CLI Chess}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = "chess_vwong"#spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative "../lib/chess_vwong.rb"
|
2
|
+
|
3
|
+
puts "Welcome to Chess"
|
4
|
+
puts "Player 1, please Enter your name:"
|
5
|
+
name_1 = gets.chomp
|
6
|
+
puts "Player 2, please Enter your name:"
|
7
|
+
name_2 = gets.chomp
|
8
|
+
puts ""
|
9
|
+
|
10
|
+
puts "---------------------------"
|
11
|
+
puts "#{name_1} will be White"
|
12
|
+
puts "#{name_2} will be Black"
|
13
|
+
puts "---------------------------"
|
14
|
+
puts ""
|
15
|
+
puts "Let's begin!"
|
16
|
+
|
17
|
+
bob = ChessVwong::Player.new(name_1, "w")
|
18
|
+
peter = ChessVwong::Player.new(name_2, "b")
|
19
|
+
players = [bob, peter]
|
20
|
+
ChessVwong::Game.new(players).play
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class Bishop < Piece
|
3
|
+
|
4
|
+
def character
|
5
|
+
color == "w" ? "\u{265D}" : "\u{2657}"
|
6
|
+
end
|
7
|
+
|
8
|
+
# Generate all possible Neighbouring Nodes
|
9
|
+
def generate_neighbours(current_space)
|
10
|
+
moves = []
|
11
|
+
(1..8).each {|i| moves << [i, i]}
|
12
|
+
(1..8).each {|i| moves << [i, -i]}
|
13
|
+
(1..8).each {|i| moves << [-i, i]}
|
14
|
+
(1..8).each {|i| moves << [-i, -i]}
|
15
|
+
moves.each do |move|
|
16
|
+
neigbour_helper(current_space, move[0], move[1])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class Board
|
3
|
+
attr_reader :grid
|
4
|
+
attr_accessor :chosen_piece, :node_path, :get_value
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@grid = default_grid
|
8
|
+
end
|
9
|
+
|
10
|
+
# Convert letter/number input into grid coordinates, if improper coordinates: empty array is returned
|
11
|
+
def process_input(input)
|
12
|
+
if input[0] =~ /[A-Za-z]/
|
13
|
+
grid_values = input.tr!("87654321", "12345678")
|
14
|
+
grid_values = input.upcase.tr!("ABCDEFGH", "12345678")
|
15
|
+
grid_values = grid_values.split("")
|
16
|
+
grid_values.map! {|i|i.to_i}
|
17
|
+
else
|
18
|
+
return []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get piece & generate neighbours, extra helper-methods required for Pawns due to unique nature
|
23
|
+
def get_piece(input=gets.chomp, player)
|
24
|
+
@get_value = process_input(input)
|
25
|
+
if get_value.count ==2
|
26
|
+
chosen_node = grid[get_value[1]][get_value[0]]
|
27
|
+
unless chosen_node.occupied.empty? || chosen_node.occupied.first.color != player.color
|
28
|
+
@chosen_piece = chosen_node.occupied.pop()
|
29
|
+
chosen_piece.instance_of?(Pawn) ? pawn_kill_helper(chosen_piece, get_value) : @chosen_piece.generate_neighbours(get_value)
|
30
|
+
return @chosen_piece
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sets piece if within neighbour range & valid, also checks if pawn can beome Queen
|
36
|
+
def set_piece(input=gets.chomp, player)
|
37
|
+
value = process_input(input)
|
38
|
+
if value.count ==2
|
39
|
+
chosen_node = grid[value[1]][value[0]]
|
40
|
+
if chosen_piece.neighbours.include?(value) && valid_path?(@get_value, value)
|
41
|
+
chosen_piece.current_space = value
|
42
|
+
chosen_node.occupied << chosen_piece
|
43
|
+
player.kill_list << chosen_node.occupied.shift() if chosen_node.occupied.count > 1
|
44
|
+
pawn_to_queen(chosen_piece, chosen_node) if chosen_piece.instance_of?(Pawn)
|
45
|
+
return chosen_node.occupied
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Print's out Board
|
51
|
+
def formatted_grid
|
52
|
+
grid.each do |row|
|
53
|
+
puts row.map { |node| node.occupied.empty? ? "_" : node.occupied.first.character}.join(" ")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
#Checks if path is valid
|
60
|
+
def valid_path?(start, dest)
|
61
|
+
#if End node is empty OR end_node is occupied with enemy_piece then check if path is clear
|
62
|
+
if grid[dest[1]][dest[0]].occupied.empty? || !grid[dest[1]][dest[0]].occupied.empty? && grid[dest[1]][dest[0]].occupied.first.color != chosen_piece.color
|
63
|
+
chosen_piece.instance_of?(Knight) ? true : clear_path?(start, dest)
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def scan_for_check
|
71
|
+
# execute it for selected piece that was most recently moves AND every king move
|
72
|
+
end
|
73
|
+
|
74
|
+
#Checks if path is clear [x,y] = grid[y][x]
|
75
|
+
def clear_path?(start, dest)
|
76
|
+
if (start[0] < dest[0] && start[1] > dest[1]) || (start[0] > dest[0] && start[1] < dest[1])
|
77
|
+
rising_path(start, dest)
|
78
|
+
elsif (start[0] < dest[0] && start[1] < dest[1]) || (start[0] > dest[0] && start[1] > dest[1])
|
79
|
+
falling_path(start, dest)
|
80
|
+
elsif start[1] != dest[1]
|
81
|
+
vertical_path(start, dest)
|
82
|
+
elsif start[0] != dest[0]
|
83
|
+
horizontal_path(start, dest)
|
84
|
+
end
|
85
|
+
return process_path
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
def vertical_path(start, dest)
|
91
|
+
@node_path = []
|
92
|
+
# DOWN
|
93
|
+
if start[1] < dest[1]
|
94
|
+
(start[1]...dest[1]).each do |i|
|
95
|
+
node_path << grid[i][start[0]]
|
96
|
+
end
|
97
|
+
# UP
|
98
|
+
elsif start[1] > dest[1]
|
99
|
+
start[1].step(dest[1]+1, -1) do |i|
|
100
|
+
node_path << grid[i][start[0]]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
node_path
|
104
|
+
end
|
105
|
+
|
106
|
+
def horizontal_path(start, dest)
|
107
|
+
@node_path = []
|
108
|
+
# RIGHT
|
109
|
+
if start[0] < dest[0]
|
110
|
+
(start[0]...dest[0]).each do |i|
|
111
|
+
node_path << grid[start[1]][i]
|
112
|
+
end
|
113
|
+
# LEFT
|
114
|
+
elsif start[0] > dest[0]
|
115
|
+
start[0].step(dest[0]+1, -1) do |i|
|
116
|
+
node_path << grid[start[1]][i]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
node_path
|
120
|
+
end
|
121
|
+
|
122
|
+
def rising_path(start, dest)
|
123
|
+
@node_path = []
|
124
|
+
i = 0
|
125
|
+
j = start[0]
|
126
|
+
#UP_RIGHT
|
127
|
+
if start[0] < dest[0] && start[1] > dest[1]
|
128
|
+
while j < dest[0]
|
129
|
+
node_path << grid[start[1] - i][start[0]+i]
|
130
|
+
i += 1
|
131
|
+
j += 1
|
132
|
+
end
|
133
|
+
#DOWN_LEFT
|
134
|
+
elsif start[0] > dest[0] && start[1] < dest[1]
|
135
|
+
while j > dest[0]
|
136
|
+
node_path << grid[start[1] + i][start[0]-i]
|
137
|
+
i += 1
|
138
|
+
j -= 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
node_path
|
142
|
+
end
|
143
|
+
|
144
|
+
def falling_path(start, dest)
|
145
|
+
@node_path = []
|
146
|
+
i = 0
|
147
|
+
j = start[0]
|
148
|
+
# DOWN_RIGHT
|
149
|
+
if start[0] < dest[0] && start[1] < dest[1]
|
150
|
+
while j < dest[0]
|
151
|
+
node_path << grid[start[1] + i][start[0]+i]
|
152
|
+
i += 1
|
153
|
+
j += 1
|
154
|
+
end
|
155
|
+
# UP_LEFT
|
156
|
+
elsif start[0] > dest[0] && start[1] > dest[1]
|
157
|
+
while j > dest[0]
|
158
|
+
node_path << grid[start[1]-i][start[0]-i]
|
159
|
+
i += 1
|
160
|
+
j -= 1
|
161
|
+
end
|
162
|
+
end
|
163
|
+
node_path
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
private
|
168
|
+
def default_grid
|
169
|
+
Array.new(9) { Array.new(9) { Node.new } }
|
170
|
+
end
|
171
|
+
|
172
|
+
# Goes through each node to see if it's Blocked
|
173
|
+
def process_path
|
174
|
+
node_path.each do |node|
|
175
|
+
unless node.occupied.empty?
|
176
|
+
return false
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# if Pawn is selected, nearby spaces analyzed if enemries are present, if so they have additional moves
|
182
|
+
def pawn_kill_helper(chosen_piece, get_value)
|
183
|
+
if chosen_piece.color == "w"
|
184
|
+
node1 = grid[get_value[1] - 1][get_value[0] - 1]
|
185
|
+
node2 = grid[get_value[1] - 1][get_value[0] + 1]
|
186
|
+
@chosen_piece.generate_neighbours(get_value, node1, node2)
|
187
|
+
else
|
188
|
+
node1 = grid[get_value[1] + 1][get_value[0] - 1]
|
189
|
+
node2 = grid[get_value[1] + 1][get_value[0] + 1]
|
190
|
+
@chosen_piece.generate_neighbours(get_value, node1, node2)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def pawn_to_queen(pawn, current_node)
|
195
|
+
if pawn.color == "w" && pawn.current_space[1] == 1
|
196
|
+
current_node.occupied.pop()
|
197
|
+
current_node.occupied << Queen.new(pawn.current_space, "w")
|
198
|
+
elsif pawn.color == "b" && pawn.current_space[1] == 8
|
199
|
+
current_node.occupied.pop()
|
200
|
+
current_node.occupied << Queen.new(pawn.current_space, "b")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class Game
|
3
|
+
attr_reader :current_player, :other_player
|
4
|
+
attr_reader :board
|
5
|
+
def initialize(players, board = Board.new)
|
6
|
+
@current_player = players[0]
|
7
|
+
@other_player = players[1]
|
8
|
+
@board = board
|
9
|
+
end
|
10
|
+
|
11
|
+
def switch_players
|
12
|
+
@current_player, @other_player = @other_player, @current_player
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
def game_over
|
18
|
+
return current_player if current_player.kill_list.last.instance_of?(King)
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def play
|
24
|
+
board.preload_pieces
|
25
|
+
while true
|
26
|
+
board.formatted_grid
|
27
|
+
puts ""
|
28
|
+
solicit_get_piece
|
29
|
+
puts ""
|
30
|
+
solicit_set_piece
|
31
|
+
if game_over
|
32
|
+
puts game_over_message
|
33
|
+
board.formatted_grid
|
34
|
+
return
|
35
|
+
else
|
36
|
+
switch_players
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def solicit_get_piece
|
44
|
+
loop do
|
45
|
+
puts "#{current_player.name}, Select a piece:"
|
46
|
+
if board.get_piece(current_player)
|
47
|
+
break
|
48
|
+
else
|
49
|
+
puts "Invalid Input!"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def solicit_set_piece
|
55
|
+
loop do
|
56
|
+
puts "#{current_player.name}, Select a destination:"
|
57
|
+
if board.set_piece(current_player)
|
58
|
+
break
|
59
|
+
else
|
60
|
+
puts "Invalid Move!"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def game_over_message
|
66
|
+
"#{current_player.name} wins!"
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class King < Piece
|
3
|
+
|
4
|
+
def character
|
5
|
+
color == "w" ? "\u{265A}" : "\u{2654}"
|
6
|
+
end
|
7
|
+
|
8
|
+
# Generate all possible Neighbouring Spaces
|
9
|
+
def generate_neighbours(current_space)
|
10
|
+
moves = [[ 1, 0], [-1, 0], [0, 1], [0, -1], [-1, 1], [1, -1], [1,1], [-1,-1]]
|
11
|
+
moves.each do |move|
|
12
|
+
neigbour_helper(current_space, move[0], move[1])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class Knight < Piece
|
3
|
+
|
4
|
+
def character
|
5
|
+
color == "w" ? "\u{265E}" : "\u{2658}"
|
6
|
+
end
|
7
|
+
|
8
|
+
# Generate all possible Neighbouring Spaces
|
9
|
+
def generate_neighbours(current_space)
|
10
|
+
moves = [[ 1, 2], [-1, 2], [ 1,-2], [-1,-2], [ 2, 1], [-2, 1], [ 2,-1], [-2,-1]]
|
11
|
+
moves.each do |move|
|
12
|
+
neigbour_helper(current_space, move[0], move[1])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class Pawn < Piece
|
3
|
+
|
4
|
+
def character
|
5
|
+
color == "w" ? "\u{265F}" : "\u{2659}"
|
6
|
+
end
|
7
|
+
|
8
|
+
# Generate all possible Neighbouring Spaces
|
9
|
+
def generate_neighbours(current_space, node1=nil, node2=nil)
|
10
|
+
color == "w" ? moves = [[0, -1]] : moves = [[0, 1]]
|
11
|
+
first_turn?(current_space, moves)
|
12
|
+
kill_move(node1, node2, moves)
|
13
|
+
moves.each do |move|
|
14
|
+
neigbour_helper(current_space, move[0], move[1])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# if there is a enemy piece nearby, then give option to attack
|
19
|
+
def kill_move(node1, node2, moves)
|
20
|
+
if color == "w"
|
21
|
+
moves << [-1,-1] if node1 &&!node1.occupied.empty? && node1.occupied.first.color == "b"
|
22
|
+
moves << [1,-1] if node2 && !node2.occupied.empty? && node2.occupied.first.color == "b"
|
23
|
+
else
|
24
|
+
moves << [-1,1] if node1 && !node1.occupied.empty? && node1.occupied.first.color == "w"
|
25
|
+
moves << [1,1] if node2 && !node2.occupied.empty? && node2.occupied.first.color == "w"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def first_turn?(current_space, moves)
|
33
|
+
if current_space[1] == 2 #Black
|
34
|
+
moves << [0,2]
|
35
|
+
elsif current_space[1] == 7 #White
|
36
|
+
moves << [0,-2]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class Piece
|
3
|
+
attr_reader :color
|
4
|
+
attr_accessor :neighbours, :current_space
|
5
|
+
def initialize(current_space, color)
|
6
|
+
@current_space = current_space
|
7
|
+
@color = color
|
8
|
+
@neighbours = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Ensuring the pieces can't go off board
|
12
|
+
def valid_space?(space)
|
13
|
+
true if space.all? {|coordinate| coordinate >= 1 && coordinate <9}
|
14
|
+
end
|
15
|
+
|
16
|
+
def character
|
17
|
+
return color
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Create 1 new Neighbouring space
|
23
|
+
def neigbour_helper(current_space, x, y)
|
24
|
+
new_x = current_space[0] + x
|
25
|
+
new_y = current_space[1] + y
|
26
|
+
neighbour = [new_x, new_y]
|
27
|
+
self.neighbours << neighbour if valid_space?(neighbour)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ChessVwong
|
2
|
+
class Board
|
3
|
+
# private
|
4
|
+
# White on the Bottom, Black on Top
|
5
|
+
def preload_pieces
|
6
|
+
white_pieces = [Rook.new([0,7], "w"), Knight.new([1,7], "w"), Bishop.new([2,7], "w"), Queen.new([3,7], "w"),
|
7
|
+
King.new([4,7], "w"), Bishop.new([5,7], "w"), Knight.new([6,7], "w"), Rook.new([7,7], "w")]
|
8
|
+
|
9
|
+
black_pieces = [Rook.new([0,0], "b"), Knight.new([1,0], "b"), Bishop.new([2,0], "b"), Queen.new([3,0], "b"),
|
10
|
+
King.new([4,0], "b"), Bishop.new([5,0], "b"), Knight.new([6,0], "b"), Rook.new([7,0], "b")]
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
#Load Coord-Displays
|
16
|
+
load_alphabet(grid[0])
|
17
|
+
load_num_coord
|
18
|
+
# Black Pawns
|
19
|
+
load_pawns(grid[2], "b")
|
20
|
+
#White Pawns
|
21
|
+
load_pawns(grid[7], "w")
|
22
|
+
# White Pieces
|
23
|
+
load_back_pieces(grid[1], black_pieces)
|
24
|
+
#Black Pieces
|
25
|
+
load_back_pieces(grid[8], white_pieces)
|
26
|
+
|
27
|
+
end
|
28
|
+
private
|
29
|
+
def load_pawns(row, color)
|
30
|
+
i = 0
|
31
|
+
row.each do |node|
|
32
|
+
node.occupied << Pawn.new([i,1],color)
|
33
|
+
i += 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_alphabet(row)
|
38
|
+
alphabet = ("A".."H").to_a
|
39
|
+
i = 0
|
40
|
+
while i < 8
|
41
|
+
row[i+1].occupied << Piece.new([0,0], alphabet[i])
|
42
|
+
i += 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_num_coord
|
47
|
+
i = 8
|
48
|
+
j=1
|
49
|
+
while i > 0
|
50
|
+
grid[j][0].occupied << Piece.new([0,0], i)
|
51
|
+
i -= 1
|
52
|
+
j += 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def load_back_pieces(row, pieces)
|
57
|
+
i = 0
|
58
|
+
while i < 8
|
59
|
+
row[i+1].occupied << pieces[i]
|
60
|
+
i += 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|