Skip to content

Commit 18e18cc

Browse files
committed
Split classes into own files.
1 parent 9bb0bd2 commit 18e18cc

13 files changed

+352
-338
lines changed

bishop.rb

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
require_relative 'sliding_piece'
2+
3+
class Bishop < SlidingPiece
4+
def move_dirs
5+
[DELTAS[:nw], DELTAS[:ne], DELTAS[:sw], DELTAS[:se]]
6+
end
7+
8+
def to_s
9+
@color == :b ? "\u{265d}" : "\u{2657}"
10+
end
11+
end

chess.rb

+2-338
Original file line numberDiff line numberDiff line change
@@ -1,325 +1,5 @@
1-
# encoding: utf-8
2-
3-
def vector_sum(vectors)
4-
result = [0,0]
5-
vectors.each do |vec|
6-
result[0] += vec[0]
7-
result[1] += vec[1]
8-
end
9-
result
10-
end
11-
12-
class Piece
13-
attr_reader :color
14-
attr_accessor :pos
15-
# row, col
16-
DELTAS = { nw: [-1, -1], n: [-1, 0], ne: [-1, 1],
17-
w: [0, -1], e: [0, 1],
18-
sw: [1, -1], s: [1, 0], se: [1, 1] }
19-
20-
def initialize(pos, board, color)
21-
@pos = pos
22-
@board = board
23-
@color = color
24-
end
25-
26-
def move_within_boundaries?(pos)
27-
row, col = pos
28-
row.between?(0, @board.height - 1) && col.between?(0, @board.width - 1)
29-
end
30-
31-
def valid_moves
32-
moves.select { |move| valid_move?(move) }
33-
end
34-
35-
def valid_move?(target)
36-
duped_board = @board.dup
37-
duped_board.move!(@pos, target)
38-
!duped_board.in_check?(self.color)
39-
end
40-
end
41-
42-
class SlidingPiece < Piece
43-
def moves
44-
moves = []
45-
move_dirs.each do |dir|
46-
current_pos = @pos
47-
loop do
48-
next_move = vector_sum([current_pos, dir])
49-
break unless move_within_boundaries?(next_move)
50-
break if !@board[next_move].nil? && @board[next_move].color == self.color
51-
moves << next_move
52-
break unless @board[next_move].nil? #change .empty? to whatever call
53-
54-
current_pos = next_move
55-
end
56-
end
57-
58-
moves
59-
end
60-
end
61-
62-
class SteppingPiece < Piece
63-
def moves
64-
moves = []
65-
move_dirs.each do |dir|
66-
next_move = vector_sum([pos, dir])
67-
next unless move_within_boundaries?(next_move)
68-
next if !@board[next_move].nil? && @board[next_move].color == self.color
69-
moves << next_move
70-
end
71-
72-
moves
73-
end
74-
end
75-
76-
class Pawn < Piece
77-
def move_dirs
78-
case @color
79-
when :w
80-
[DELTAS[:n], DELTAS[:ne], DELTAS[:nw]]
81-
when :b
82-
[DELTAS[:s], DELTAS[:se], DELTAS[:sw]]
83-
end
84-
end
85-
86-
def moves
87-
moves = []
88-
dirs = move_dirs
89-
90-
advance = vector_sum([@pos, dirs[0]])
91-
if @board[advance].nil?
92-
moves << advance
93-
unless moved?
94-
advance = vector_sum([advance, dirs[0]])
95-
moves << advance if @board[advance].nil?
96-
end
97-
end
98-
99-
2.times do |i|
100-
advance = vector_sum([@pos, dirs[i + 1]])
101-
unless @board[advance].nil? || @board[advance].color == self.color
102-
moves << advance
103-
end
104-
end
105-
106-
moves.select { |move| move_within_boundaries?(move) }
107-
end
108-
109-
def to_s
110-
@color == :b ? "\u{265f}" : "\u{2659}"
111-
end
112-
113-
def moved?
114-
case @color
115-
when :w
116-
@pos.first != @board.height - 2
117-
when :b
118-
@pos.first != 1
119-
end
120-
end
121-
122-
end
123-
124-
class Bishop < SlidingPiece
125-
def move_dirs
126-
[DELTAS[:nw], DELTAS[:ne], DELTAS[:sw], DELTAS[:se]]
127-
end
128-
129-
def to_s
130-
@color == :b ? "\u{265d}" : "\u{2657}"
131-
end
132-
end
133-
134-
class Rook < SlidingPiece
135-
def move_dirs
136-
[DELTAS[:n], DELTAS[:e], DELTAS[:s], DELTAS[:w]]
137-
end
138-
139-
def to_s
140-
@color == :b ? "\u{265c}" : "\u{2656}"
141-
end
142-
end
143-
144-
class Queen < SlidingPiece
145-
def move_dirs
146-
DELTAS.values
147-
end
148-
149-
def to_s
150-
@color == :b ? "\u{265b}" : "\u{2655}"
151-
end
152-
end
153-
154-
class Knight < SteppingPiece
155-
def move_dirs
156-
[
157-
[DELTAS[:n]] * 2 + [DELTAS[:e]],
158-
[DELTAS[:n]] * 2 + [DELTAS[:w]],
159-
[DELTAS[:s]] * 2 + [DELTAS[:e]],
160-
[DELTAS[:s]] * 2 + [DELTAS[:w]],
161-
[DELTAS[:e]] * 2 + [DELTAS[:n]],
162-
[DELTAS[:w]] * 2 + [DELTAS[:n]],
163-
[DELTAS[:e]] * 2 + [DELTAS[:s]],
164-
[DELTAS[:w]] * 2 + [DELTAS[:s]],
165-
].map { |vec| vector_sum(vec) }
166-
end
167-
168-
def to_s
169-
@color == :b ? "\u{265e}" : "\u{2658}"
170-
end
171-
end
172-
173-
class King < SteppingPiece
174-
def move_dirs
175-
DELTAS.values
176-
end
177-
178-
def to_s
179-
@color == :b ? "\u{265a}" : "\u{2654}"
180-
end
181-
end
182-
183-
class Board
184-
def initialize
185-
@board = Array.new(8) { Array.new(8) }
186-
place_pieces
187-
end
188-
189-
def height
190-
@board.count
191-
end
192-
193-
def width
194-
@board[0].count
195-
end
196-
197-
def [](pos)
198-
row, col = pos
199-
@board[row][col]
200-
end
201-
202-
def []=(pos, value)
203-
row, col = pos
204-
@board[row][col] = value
205-
end
206-
207-
def place_pieces
208-
place_piece_row(0, :b)
209-
place_pawn_row(1, :b)
210-
place_pawn_row(6, :w)
211-
place_piece_row(7, :w)
212-
end
213-
214-
def place_pawn_row(row, color)
215-
@board[row].each_with_index do |spot, i|
216-
@board[row][i] = Pawn.new([row, i], self, color)
217-
end
218-
219-
nil
220-
end
221-
222-
def place_piece_row(row, color)
223-
starting_row = [Rook, Knight, Bishop, Queen, King, Bishop, Knight, Rook]
224-
@board[row].each_with_index do |spot, i|
225-
@board[row][i] = starting_row[i].new([row, i], self, color)
226-
end
227-
228-
nil
229-
end
230-
231-
def display
232-
puts ''
233-
puts ' ' + ('a'..'h').to_a.join(' ')
234-
@board.each_with_index do |row, index|
235-
print " #{8 - index} "
236-
row.each do |piece|
237-
print (piece.nil? ? ' ' : piece.to_s) + ' '
238-
end
239-
print "#{8 - index}"
240-
puts
241-
end
242-
puts ' ' + ('a'..'h').to_a.join(' ')
243-
puts ' '
244-
245-
nil
246-
end
247-
248-
def find_king(color)
249-
@board.flatten.each do |piece|
250-
if piece.class == King && piece.color == color
251-
return piece.pos
252-
end
253-
end
254-
255-
nil
256-
end
257-
258-
def in_check?(color)
259-
king_pos = find_king(color)
260-
@board.flatten.compact.each do |piece|
261-
next if piece.color == color
262-
return true if piece.moves.include?(king_pos)
263-
end
264-
265-
false
266-
end
267-
268-
def move!(start, end_pos)
269-
piece = self[start]
270-
# changes piece.pos to end_pos
271-
piece.pos = end_pos
272-
273-
# changes Board positions
274-
self[start], self[end_pos] = nil, piece
275-
276-
nil
277-
end
278-
279-
def move(start, end_pos)
280-
# finds piece at start position
281-
piece = self[start]
282-
if piece.nil?
283-
raise "No piece at start position."
284-
end
285-
286-
# checks piece.moves for end_pos
287-
unless piece.moves.include?(end_pos)
288-
raise "Can't move to that position."
289-
end
290-
291-
unless piece.valid_moves.include?(end_pos)
292-
raise "Move will leave you in check."
293-
end
294-
295-
piece.pos = end_pos
296-
self[start], self[end_pos] = nil, piece
297-
298-
nil
299-
end
300-
301-
def checkmate?(color)
302-
pieces = @board.flatten.compact.select { |piece| piece.color == color }
303-
pieces.all? { |piece| piece.valid_moves.empty? }
304-
end
305-
306-
def dup
307-
duped_board = Board.new #Array.new(8) { Array.new(8) }
308-
@board.each_with_index do |row, row_index|
309-
row.each_with_index do |piece, col_index|
310-
pos = [row_index, col_index]
311-
if piece.nil?
312-
duped_board[pos] = nil
313-
else
314-
duped_board[pos] = piece.class.new(pos, duped_board, piece.color)
315-
end
316-
end
317-
end
318-
319-
duped_board
320-
end
321-
322-
end
1+
require_relative 'chess_board'
2+
require_relative 'human_player'
3233

3244
class Game
3255
def initialize(white, black)
@@ -379,22 +59,6 @@ def make_move(color, start, target)
37959

38060
end
38161

382-
class HumanPlayer
383-
def play_turn
384-
print "Input start, target positions: "
385-
move_string = gets.chomp
386-
start, target = move_string.scan(/\D\d/)
387-
388-
[parse(start), parse(target)]
389-
end
390-
391-
def parse(pos_string)
392-
letters, numbers = ('a'..'h').to_a, (1..8).to_a.reverse
393-
394-
[numbers.index(pos_string[1].to_i), letters.index(pos_string[0])]
395-
end
396-
end
397-
39862
if __FILE__ == $PROGRAM_NAME
39963
player1 = HumanPlayer.new
40064
player2 = HumanPlayer.new

0 commit comments

Comments
 (0)