-
Notifications
You must be signed in to change notification settings - Fork 1
/
piece.rb
114 lines (103 loc) · 3.34 KB
/
piece.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
class Piece < ApplicationRecord
belongs_to :game
enum color: {white: 0, black: 1}
# req_x and req_y are coordinates/integers
def is_obstructed?(req_x, req_y)
if self.x == req_x # vertical
h = self.x
j = self.y
k = req_y
if self.y < req_y # up
return true if game.pieces.where("x = ? AND y > ? AND y < ?", h, j, k).present?
else # down
return true if game.pieces.where("x = ? AND y < ? AND y > ?", h, j, k).present?
end
elsif self.y == req_y # horizontal
h = self.y
j = self.x
k = req_x
if self.x < req_x # to right
return true if game.pieces.where("y = ? AND x > ? AND x < ?", h, j, k).present?
else # to left
return true if game.pieces.where("y = ? AND x < ? AND x > ?", h, j, k).present?
end
elsif (self.x - req_x).abs == (self.y - req_y).abs # diagonal
if self.x < req_x && self.y < req_y # x increasing, y increasing
i = 1
j = self.x
k = self.y
while i < (self.x - req_x).abs
j += 1
k += 1
return true if game.pieces.where("x = ? AND y = ?", j, k).present?
i += 1
end
elsif self.x > req_x && self.y < req_y # x decreasing, y increasing
i = 1
j = self.x
k = self.y
while i < (self.x - req_x).abs
j -= 1
k += 1
return true if game.pieces.where("x = ? AND y = ?", j, k).present?
i += 1
end
elsif self.x > req_x && self.y > req_y # x decreasing, y decreasing
i = 1
j = self.x
k = self.y
while i < (self.x - req_x).abs
j -= 1
k -= 1
return true if game.pieces.where("x = ? AND y = ?", j, k).present?
i += 1
end
else # x increasing, y decreasing
i = 1
j = self.x
k = self.y
while i < (self.x - req_x).abs
j += 1
k -= 1
return true if game.pieces.where("x = ? AND y = ?", j, k).present?
i += 1
end
end
elsif self.type == "Knight"
return false
else # invalid move
return "invalid move"
end
return false
end
def move_to!(req_x, req_y)
# return the 2nd piece (if it exists in the clicked cell)
blocking_piece = game.pieces.find_by("x = ? AND y = ?", req_x, req_y)
# if there is a 2nd piece,
if blocking_piece
# that is not the same color as the 1st piece,
if blocking_piece.color != self.color
# take the 2nd piece off the board and change its status to inactive
blocking_piece.update(x: 0, y: 0, active: false)
# move the 1st piece to the new spot
self.update(x: req_x, y: req_y)
end
elsif self.type == "King" && (req_x - self.x).abs == 2
self.castle!(req_x, req_y)
else
# if the clicked cell is empty then move the 1st piece there
self.update(x: req_x, y: req_y)
end
end
def same_team?(req_x, req_y)
blocking_piece = self.game.find_one_in_game(x:req_x,y:req_y)
#blocking_piece = game.pieces.find_by("x = ? AND y = ?", req_x, req_y)
return self.color == blocking_piece.color if blocking_piece
end
def valid_move?(req_x, req_y)
return false if is_obstructed?(req_x, req_y)
return false unless is_valid?(req_x, req_y)
return false if same_team?(req_x, req_y)
return true
end
end