require_relative input_controller
require_relative ../models/game_board
# ===========================================
# =====DONT modify the following code=======
# ===========================================
PLAYER_ONE = 1
PLAYER_TWO = 2
RANDOM_ATTACK_SIZE = 35
# GameController responsible for the game logic
# Reads files by calling input_controller and take
class GameController
def initialize(players)
@players = players
@game_board = nil, nil
@attacks = [], []
end
# setup and start the game
def start_game
@game_board = load_ships(@players.game_board_1, PLAYER_ONE), load_ships(@players.game_board_2, PLAYER_TWO)
@attacks = load_attacks(@players.attack_1, PLAYER_ONE), load_attacks(@players.attack_2, PLAYER_TWO)
puts
play_game
end
# load the GameBoard for the player # (calls input_controller function)
def load_ships(game_board_file, player_number)
player_game_board = read_ships_file(game_board_file)
unless player_game_board
raise Input Error
Error loading Player #{player_number}s ships file. +
Make sure the ship file provided exists and the format is correct (i.e, 5 ships per player).
end
player_game_board
end
# load the attack strategy file for the player #
# Creates random attack moves if file is not provided.
def load_attacks(attack_file, player)
if attack_file.nil?
puts No attack file found for Player #{player}. Using random generator instead.
return generate_random_attacks RANDOM_ATTACK_SIZE
end
attacks = read_attacks_file(attack_file)
unless attacks
raise Input Error
Error reading Player #{player}s attack file. +
Make sure the attack strategy file provided exists and the format is correct.
end
attacks
end
# take turns and perform attacks
def play_game
winner = -1
if @attacks[0].empty? || @attacks[1].empty?
raise Each player must have AT LEAST one attack position. +
Player-#{@attacks[0].empty? ? 1 : 2} has 0 attacks.
end
while true
winner = take_turn_check_winner PLAYER_ONE
break if winner != -1
winner = take_turn_check_winner PLAYER_TWO
break if winner != -1
end
#print end of game message
msg = * 2
puts
#{msg}
Yoo-hoooo!
Player #{winner} has won the game!
#{msg}
puts #{= * 20}
Player-1 GameBoard
puts @game_board[PLAYER_ONE 1]
puts #{= * 20}
Player-2 GameBoard
puts @game_board[PLAYER_TWO 1]
end
# player takes turn and performs attack.
# checks for winner and return the winner number if there is one.
# If no winner, returns -1
def take_turn_check_winner(player)
other_player = player == PLAYER_ONE ? PLAYER_TWO : PLAYER_ONE
# skip invalid attacks
did_attack = false
until did_attack
did_attack = perform_attack_on(player, other_player)
end
# if one player ran out of attack moves, stop the game and announce the winner
if player == PLAYER_TWO
unless has_valid_attack?(PLAYER_ONE) && has_valid_attack?(PLAYER_TWO)
p_success =@game_board[other_player 1].num_successful_attacks
other_p_success =@game_board[player 1].num_successful_attacks
puts Game result:
P#{other_player} success: #{other_p_success}, P#{player} success: #{p_success}
if p_success > other_p_success
return player
else
return other_player
end
end
end
if @game_board[other_player 1].all_sunk?
p_success =@game_board[other_player 1].num_successful_attacks
other_p_success =@game_board[player 1].num_successful_attacks
puts Game result:
P#{player} success: #{p_success},P#{other_player} success: #{other_p_success}
puts All player #{other_player} ships sunk!
return player
end
-1
end
# Perform a single attack from
def perform_attack_on(player, other_player)
player_attack_strategy = @attacks[player 1]
# player attacks other player
result = @game_board[other_player 1].attack_pos(player_attack_strategy.shift)
result != nil
end
# generate a list of random attack positions
def generate_random_attacks(size)
attacks = []
rng = Random.new
for _ in 0size
attacks.append Position.new(rng.rand(1..@game_board[0].max_row), rng.rand(1..@game_board[0].max_column))
end
attacks
end
def has_valid_attack?(player)
player_attack_strategy = @attacks[player 1]
player_attack_strategy.each do |position|
return true if position_valid? position
end
false
end
def position_valid?(position)
is_valid = Proc.new { |x, max| x <= max && x >= 1 }
is_valid.call(position.row, @game_board[0].max_row) && is_valid.call(position.column, @game_board[0].max_column)
end
end
Reviews
There are no reviews yet.