113 lines
3.3 KiB
Ruby
113 lines
3.3 KiB
Ruby
# Associates users to games
|
|
class Player < ActiveRecord::Base
|
|
belongs_to :game
|
|
belongs_to :user
|
|
|
|
has_many :player_cards
|
|
has_many :plays
|
|
|
|
#TODO: Note: soft_user is not associated with a user
|
|
#validates :user, presence: true
|
|
validates :game, presence: true
|
|
|
|
def principal
|
|
stp = SoftTokenPrincipal.where(soft_token: self.soft_token).first_or_initialize
|
|
if stp.principal.nil?
|
|
#TODO use principal
|
|
`dfx identity use anonymous`
|
|
if `dfx identity use #{soft_token}; echo $?`.to_i == 255
|
|
`dfx identity new #{soft_token} --disable-encryption`
|
|
`dfx identity use #{soft_token}`
|
|
@principal = `dfx identity get-principal`
|
|
`dfx identity use anonymous`
|
|
stp.principal = @principal
|
|
stp.save
|
|
end
|
|
end
|
|
return stp.principal
|
|
end
|
|
|
|
def inventory
|
|
player_cards.where(play_id: nil).order(:value)
|
|
end
|
|
|
|
def display_name
|
|
return user.email.split("@")[0] if self.user
|
|
return "BotPlayer" if self.is_bot?
|
|
return ("Guest" + self.soft_token)[0..9] if self.soft_token
|
|
return "Empty"
|
|
end
|
|
|
|
def play_hand(cards)
|
|
self.plays.create(game_id: self.game.id, player_cards: cards)
|
|
end
|
|
|
|
def pass
|
|
#TODO: Create a Play instead of modifying the controlling player directly
|
|
# Then you won't need this return/fail validation
|
|
return false unless self.game.controlling_player == self
|
|
|
|
self.game.set_controlling_player 'next'
|
|
# Clear play to beat if play returns to owner
|
|
if self.game.play_to_beat.try(:player).try(:id) == self.game.controlling_player_id
|
|
self.game.play_to_beat_id = nil
|
|
end
|
|
self.game.save
|
|
end
|
|
|
|
def runs
|
|
@runs = self.inventory.chunk_while {|i, j| i.rank.to_i+1 == j.rank.to_i }
|
|
end
|
|
|
|
def triple_runs
|
|
@triple_runs = self.runs.map{|r| r.length > 2 ? r : nil}.compact
|
|
end
|
|
|
|
def auto_play
|
|
# TODO not sure this return clause works
|
|
return false unless self.game.controlling_player == self
|
|
|
|
# If first play of game, play lowest card
|
|
if self.game.plays.empty?
|
|
@cards_to_play = [self.inventory[0]]
|
|
return self.play_hand @cards_to_play
|
|
end
|
|
|
|
# If open table
|
|
if !self.game.play_to_beat
|
|
@cards_to_play = self.inventory[0..0]
|
|
else
|
|
@cards_to_beat = self.game.play_to_beat.play.player_cards
|
|
case self.game.play_to_beat.play.hand_type
|
|
when "single"
|
|
@cards_to_play = self.inventory.where("value > #{@cards_to_beat.min.value}")[0..0]
|
|
when "double"
|
|
@doubles = self.inventory.group_by {|card| card.rank}.map{|c| c if c[1].length > 1}.compact
|
|
if @doubles.present?
|
|
if @doubles[0][1][0..1].max.value > @cards_to_beat.max.value
|
|
@cards_to_play = @doubles[0][1][0..1]
|
|
end
|
|
end
|
|
when "triple run"
|
|
@runs = self.inventory.chunk_while {|i, j| i.rank.to_i+1 == j.rank.to_i }
|
|
@triple_runs = @runs.map{|r| r.length > 2 ? r : nil}.compact
|
|
if @triple_runs.present?
|
|
@cards_to_play = @triple_runs[0][0..2]
|
|
end
|
|
end
|
|
end
|
|
|
|
if @cards_to_play.present?
|
|
if @cards_to_beat.present?
|
|
if (@cards_to_play.max_by{|c| c.value}.value > @cards_to_beat.max_by{|c| c.value}.value)
|
|
return self.play_hand @cards_to_play
|
|
end
|
|
else
|
|
return self.play_hand @cards_to_play
|
|
end
|
|
end
|
|
self.pass
|
|
end
|
|
|
|
end
|