123 lines
2.7 KiB
Ruby

# The game class
class Game < ActiveRecord::Base
has_many :players, dependent: :destroy
has_many :users, through: :players
has_many :player_cards, through: :players
has_many :plays, through: :players
belongs_to :play_to_beat
accepts_nested_attributes_for :players
validates :title, presence: true
# TODO: Simplify to a single attribute
alias_attribute :current_player_id, :control_player_id
alias_attribute :active_player_id, :control_player_id
alias_attribute :active_player, :control_player
def start
validate_startable
return false unless startable?
# Start the game
self.status = 'Game Started'
# Create a deck
d = Deck.new
# Shuffle the deck
d.cards.shuffle!
# Deal the cards
players.each do |player|
13.times do
card = d.cards.shift
player.player_cards.new(card.instance_values)
end
player.save
end
# Set status to first turn
# Player with the lowest card
self.status = 'First Play at: ' + self.lowest_card.player.user.email
self.control_player_id = self.lowest_card.player.id
save
end
def current_player
self.players.find_by(id: control_player_id)
end
def validate_startable
@player_count = players.count
errors[:players] = 'Must be at least 2 players.' if @player_count < 2
errors[:players] = 'Must be less than 5 players.' if @player_count > 4
errors[:status] = 'Game already started...' if self.status.nil? == false
errors[:player_cards] = 'Cards already dealt...' unless player_cards.empty?
fail StandardError, errors if errors.count > 0
return true
end
def current_hand
return nil
end
def startable?
begin
self.validate_startable
rescue
return false
end
end
def lowest_card
self.player_cards.order(:value).first
end
def add_player_from_user(user)
return false unless can_accomodate(user)
self.players.create(user: user)
end
def can_accomodate(user)
!(already_has?(user) || full?)
end
def already_has?(user)
users.include?(user)
end
def full?
players.count >= 4
end
def set_active_player(arg)
case arg
when 'next'
self.active_player_id = self.next_player_id
end
end
def joinable? user
!self.users.include?(user) && !self.full?
end
def next_player_id
player_ids[(player_ids.index(current_player_id) + 1 ) % player_ids.length]
end
# The player whose turn it is
def control_player
self.players.find(self.control_player_id)
end
# The user whose turn it is
def control_user
self.players.find(self.control_player_id).user
end
def hand_to_beat
self.play_to_beat.try(:play).try(:hand)
end
def player_to_beat
self.play_to_beat.try(:play).try(:player)
end
end