New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Queen - Piece specific move logic code #38

Merged
merged 12 commits into from Jan 12, 2015
View
@@ -93,7 +93,9 @@ def is_move_obstructed?(piece_id, new_x, new_y)
# line away from current piece
x_diff = current_piece.x_coord - new_x
y_diff = current_piece.y_coord - new_y
unless (x_diff == y_diff) || (x_diff == 0) || (y_diff == 0)
if !(((x_diff == y_diff) || (x_diff == 0) || (y_diff == 0)))
# Raise a BIG exception
return nil
end
@@ -102,6 +104,7 @@ def is_move_obstructed?(piece_id, new_x, new_y)
places_between = [ [new_x, new_y] ]
back_to_start = false
current_coordinates = [current_piece.x_coord, current_piece.y_coord]
until back_to_start
if new_x > current_piece.x_coord
new_x = new_x - 1
@@ -118,19 +121,32 @@ def is_move_obstructed?(piece_id, new_x, new_y)
if current_coordinates == [new_x, new_y]
back_to_start = true
else
places_between << [new_x, new_y]
if x_diff == y_diff
places_between << [new_x, new_y]
elsif x_diff == 0
places_between << [current_piece.x_coord, new_y]
else
places_between << [new_x, current_piece.y_coord]
end
end
end
# get coordinates for all game pieces
pieces = self.pieces.to_a
#puts pieces.inspect
all_piece_coordinates = pieces.map { |p| [p.x_coord, p.y_coord] }
# check if any current game pieces overlap with
# the coordinates between target and current piece position
obstruction = false
all_piece_coordinates.each do |piece_coordinates|
if places_between.include? piece_coordinates
all_piece_coordinates.each do |piece_coordinates|
is_current_piece = current_coordinates == piece_coordinates
is_destination_piece = piece_coordinates == [new_x, new_y]
if x_diff == 0 && y_diff == 0
obstruction = true
end
if places_between.include?(piece_coordinates) && !is_current_piece && !is_destination_piece
obstruction = true
break
end
View
@@ -13,7 +13,7 @@ def is_move_allowed?(new_x, new_y)
# and vice versa
return !self.game.is_move_obstructed?(self.id, new_x, new_y)
else
return nil
return false
end
end
View
@@ -1,7 +1,7 @@
class Piece < ActiveRecord::Base
belongs_to :game
def move_piece!(x_coord, y_coord)
def move_piece!(x_coord, y_coord)
captured = self.game.pieces.where(:x_coord => x_coord, :y_coord => y_coord).first
if captured.present? && self.color != captured.color
captured.update_attributes(:x_coord => nil, :y_coord => nil)
@@ -11,7 +11,7 @@ def move_piece!(x_coord, y_coord)
else
self.update_attributes({:x_coord => x_coord, :y_coord => y_coord})
end
return true
return true
end
# ========================================================
View
@@ -1,16 +1,50 @@
class Queen < Piece
def is_move_allowed?(new_x, new_y)
# return a boolean (true if move is valid, else false)
# most pieces have two steps:
# (1) is the target move allowed by the game piece logic?
# (2) is there an obstruction in the way? the game model
#  has a function that checks this:
#  is_move_obstructed?(piece_id, new_x, new_y)
# check whether suggested move obeys game logic

This comment has been minimized.

@kenmazaika

kenmazaika Jan 8, 2015

Contributor

Same note about the copy/pasted/sameness of this code. Probably want to move this into the piece model (see my comment to nan)

@kenmazaika

kenmazaika Jan 8, 2015

Contributor

Same note about the copy/pasted/sameness of this code. Probably want to move this into the piece model (see my comment to nan)

This comment has been minimized.

@brantwellman

brantwellman Jan 9, 2015

Contributor

I've opened up an Issue so that this can be dealt with separately in a separate pull request for all of the Piece_type models.

@brantwellman

brantwellman Jan 9, 2015

Contributor

I've opened up an Issue so that this can be dealt with separately in a separate pull request for all of the Piece_type models.

move_logic_is_valid = false
if legit_moves.include? [new_x, new_y]
move_logic_is_valid = true
end
# if the destination location obeys the game rules, then check for obstructions
if move_logic_is_valid
# if is_move_obstructed returns true, then return 'false' for main function,
# and vice versa
return !self.game.is_move_obstructed?(self.id, new_x, new_y)
else
return false
end
end
def legit_moves
# return an array of squares that the piece can move to
x_init = self.x_coord
y_init = self.y_coord
tiles = [1, 2, 3, 4, 5, 6, 7]
moves = []
tiles.each do |x|
(x_init + x > 7)? x_move1 = nil : x_move1 = x_init + x
(x_init - x < 0)? x_move2 = nil : x_move2 = x_init - x
(y_init + x > 7)? y_move1 = nil : y_move1 = y_init + x
(y_init - x < 0)? y_move2 = nil : y_move2 = y_init - x
move1 = [x_move1, y_init]
move2 = [x_move2, y_init]
move3 = [x_init, y_move1]
move4 = [x_init, y_move2]
move5 = [x_move1, y_move1]
move6 = [x_move2, y_move1]
move7 = [x_move1, y_move2]
move8 = [x_move2, y_move2]
moves.push(move1, move2, move3, move4, move5, move6, move7, move8)
end
moves.delete_if {|moves| moves.include?(nil)}
return moves
end
def self.get_image(color)
View
@@ -2,16 +2,47 @@ class Rook < Piece
def is_move_allowed?(new_x, new_y)
# return a boolean (true if move is valid, else false)
# most pieces have two steps:
# (1) is the target move allowed by the game piece logic?
# (2) is there an obstruction in the way? the game model
#  has a function that checks this:
#  is_move_obstructed?(piece_id, new_x, new_y)
# is the target move allowed by the game piece logic?
move_logic_is_valid = false
if legit_moves.include? [new_x, new_y]
move_logic_is_valid = true
end
# is there an obstruction in the way? the game model
if move_logic_is_valid
# if is_move_obstructed returns true, then return false for method
return !self.game.is_move_obstructed?(self.id, new_x, new_y)
else
return false
end
end
def legit_moves
# return an array of squares that the piece can move to
end
def legit_moves
x_init = self.x_coord
y_init = self.y_coord
tiles = [1, 2, 3, 4, 5, 6, 7]
moves = []
tiles.each do |x|
(x_init + x > 7)? x_move1 = nil : x_move1 = x_init + x
(x_init - x < 0)? x_move2 = nil : x_move2 = x_init - x
(y_init + x > 7)? y_move1 = nil : y_move1 = y_init + x
(y_init - x < 0)? y_move2 = nil : y_move2 = y_init - x
move1 = [x_move1, y_init]
move2 = [x_move2, y_init]
move3 = [x_init, y_move1]
move4 = [x_init, y_move2]
moves.push(move1, move2, move3, move4)
end
moves.delete_if {|moves| moves.include?(nil)}
return moves
end
def self.get_image(color)
if color == "white"
@@ -21,4 +52,5 @@ def self.get_image(color)
end
end
end
end
View
@@ -21,9 +21,17 @@
game
end
factory :queen do
x_coord "2"
y_coord "2"
color "white"
game
end
factory :knight do
x_coord "3"
y_coord "4"
color "white"
game
end
@@ -34,6 +42,13 @@
game
end
factory :rook do
x_coord "3"
y_coord "6"
color "black"
game
end
factory :king do
x_coord "4"
y_coord "0"
View
@@ -5,7 +5,10 @@ class GameTest < ActiveSupport::TestCase
test "check obstruction logic" do
game = FactoryGirl.create(:game)
piece_to_move = FactoryGirl.create(:pawn, :game_id => game.id, :x_coord => 3, :y_coord => 4, :color => "white")
piece_to_move2 = FactoryGirl.create(:rook, :game_id => game.id, :x_coord => 2, :y_coord => 6, :color => "black")
different_piece = FactoryGirl.create(:pawn, :game_id => game.id, :x_coord => 3, :y_coord => 5, :color => "white")
another_piece = FactoryGirl.create(:pawn, :game_id => game.id, :x_coord => 3, :y_coord => 7, :color => "white")
additional_piece = FactoryGirl.create(:rook, :game_id => game.id, :x_coord => 3, :y_coord => 6, :color => "black")
actual = game.is_move_obstructed?(piece_to_move.id,3, 5)
assert actual, "There should be an obstruction detected on target tile"
@@ -21,6 +24,16 @@ class GameTest < ActiveSupport::TestCase
actual = game.is_move_obstructed?(piece_to_move.id,6, 6)
assert_nil actual, "Should return nil if destination tile is not on horiz/vert/diagonal line from piece tile"
actual = game.is_move_obstructed?(piece_to_move2.id, 5, 6)
assert actual, "Rook simulation should fail due to obstruction"
actual = game.is_move_obstructed?(piece_to_move2, 4, 8)
assert actual, "Bishop simulation should fail due to obstruction"
actual = game.is_move_obstructed?(piece_to_move2, 2, 6)
assert actual, "Piece can not move to the tile it already occupies"
end
test "check obstruction and move validity logic combined" do
@@ -39,16 +52,31 @@ class GameTest < ActiveSupport::TestCase
assert actual, "Move is valid and there is no obstruction detected on target tile"
end
test "check obstruction logic shows obstruction only up/down or only across - not both" do
game = FactoryGirl.create(:game)
piece_to_move = FactoryGirl.create(:rook, :game_id => game.id, :x_coord => 3, :y_coord => 3, :color => "white")
different_piece = FactoryGirl.create(:pawn, :game_id => game.id, :x_coord => 4, :y_coord => 3, :color => "white")
piece_to_move2 = FactoryGirl.create(:queen, :game_id => game.id, :x_coord => 5, :y_coord => 5, :color => "white")
another_piece = FactoryGirl.create(:pawn, :game_id => game.id, :x_coord => 5, :y_coord => 6, :color => "white")
actual = game.is_move_obstructed?(piece_to_move.id, 3, 4)
assert_not actual, "Piece moving up is showing obstruction to the right"
actual = game.is_move_obstructed?(piece_to_move.id, 6, 5)
assert_not actual, "Piece moving to the right is showing obstruction up"
end
test "check turn logic" do
game = FactoryGirl.create(:game)
actual = game.player_turn
assert_equal "white", actual, "Player at start of game should be white"
game.next_player
actual = game.player_turn
assert_equal "black", actual, "Player after first turn should be black"
game.next_player
actual = game.player_turn
assert_equal "black", actual, "Player after first turn should be black"
assert_equal "white", game.get_player_color(game.user.id), "First player (user) should be white"
assert_equal "black", game.get_player_color(game.opponent.id), "Second player (opponent) should be black"
assert_equal "white", game.get_player_color(game.user.id), "First player (user) should be white"
assert_equal "black", game.get_player_color(game.opponent.id), "Second player (opponent) should be black"
end
end
View
@@ -75,6 +75,54 @@ class PieceTest < ActiveSupport::TestCase
end
test "check queen moves are legit" do
piece = FactoryGirl.create(:queen, :x_coord => 2, :y_coord => 2, :color => "white")
actual = piece.is_move_allowed?(4, 2)
assert actual, "Queen moves horizontally to the right"
actual = piece.is_move_allowed?(2, 4)
assert actual, "Queen moves up the board"
actual = piece.is_move_allowed?(3, 3)
assert actual, "Queen moves diagonally up and to the right"
actual = piece.is_move_allowed?(2, 8)
assert_not actual, "Queen can not move up off the board"
actual = piece.is_move_allowed?(-1, 2)
assert_not actual, "Queen can not move horizontally off the board to the left"
piece_obstruction = FactoryGirl.create(:pawn, :x_coord => 2, :y_coord => 3, :color => "white", :game => piece.game)
piece.reload
actual = piece.is_move_allowed?(2, 4)
assert ! actual, "There should be an obstruction preventing the piece to move"
end
test "check rook moves are legit" do
piece = FactoryGirl.create(:rook, :x_coord => 0, :y_coord => 0, :color => "white")
actual = piece.is_move_allowed?(0, 2)
assert actual
actual = piece.is_move_allowed?(2, 0)
assert actual
actual = piece.is_move_allowed?(2, 2)
assert_not actual
actual = piece.is_move_allowed?(0, 8)
assert_not actual
actual = piece.is_move_allowed?(8, 0)
assert_not actual
piece_obstruction = FactoryGirl.create(:pawn, :x_coord => 0, :y_coord => 1, :color => "white")
actual = piece.is_move_allowed?(0, 2)
assert actual, "There should be an obstruction preventing the piece to move"
end
test "check knight moves are legit" do
piece = FactoryGirl.create(:knight, :x_coord => 3, :y_coord => 4)
ProTip! Use n and p to navigate between commits in a pull request.