Another stash

This commit is contained in:
Jesse C. Fisher 2015-08-13 19:44:17 -07:00
parent 63ff0afb67
commit abffc4248d
4 changed files with 262 additions and 157 deletions

View File

@ -4,7 +4,7 @@ class Game < ActiveRecord::Base
has_many :users, through: :players has_many :users, through: :players
has_many :player_cards, through: :players has_many :player_cards, through: :players
has_many :plays, through: :players has_many :plays, through: :players
has_one :play_to_beat belongs_to :play_to_beat
accepts_nested_attributes_for :players accepts_nested_attributes_for :players
validates :title, presence: true validates :title, presence: true
@ -107,4 +107,8 @@ class Game < ActiveRecord::Base
def control_user def control_user
self.players.find(self.control_player_id).user self.players.find(self.control_player_id).user
end end
def hand_to_beat
self.play_to_beat.play.hand
end
end end

View File

@ -2,6 +2,7 @@ class Play < ActiveRecord::Base
belongs_to :game, foreign_key: 'game_id' belongs_to :game, foreign_key: 'game_id'
belongs_to :player, foreign_key: 'player_id' belongs_to :player, foreign_key: 'player_id'
has_many :player_cards, foreign_key: 'play_id' has_many :player_cards, foreign_key: 'play_id'
alias_attribute :hand, :player_cards
validates :game, presence: true validates :game, presence: true
validates :player, presence: true validates :player, presence: true
@ -15,26 +16,54 @@ class Play < ActiveRecord::Base
@pb.game = self.game @pb.game = self.game
@pb.play = self @pb.play = self
@pb.save @pb.save
self.game.play_to_beat = @pb
self.game.save!
end end
end end
# Validation methods # Validation methods
def hand_valid? def hand_valid?
@truths = []
if has_player_cards if has_player_cards
first_play?
# Open table / first play / no play to beat OR hand type matches OR play is back to the original active player @truths << !hand_type.empty?
self.game.play_to_beat == nil || self.hand_type == self.game.play_to_beat.play.hand_type || self.player == self.game.play_to_beat.player
end if first_play?
@truths << contains_lowest_card?
end end
# TODO: Recognize all valid hand types # Is there a hand_to_beat ?
if self.game.play_to_beat
# current player is not the player to beat
if (self.game.play_to_beat.try('play').player != self.player)
@truths << (self.hand_type == self.game.play_to_beat.hand_type)
# Compare this hand to the hand_to_beat,
@truths << (self.beats? self.game.play_to_beat)
end
end
end
return (!@truths.include? false)
end
# Check if the value of this hand is higher than the hand_to_beat
def beats?(play_to_beat)
@truth = self.high_card.value > play_to_beat.high_card.value
return @truth
end
def high_card
self.hand.order(:value).last
end
# TODO: Recognize face cards
def hand_type def hand_type
case self.player_cards.length case self.player_cards.length
when 1 when 1
@hand_type = 'single' @hand_type = 'single'
when 2 when 2
@hand_type = 'pair' @hand_type = 'double'
if (self.player_cards[0].rank != self.player_cards[1].rank) if (self.player_cards[0].rank != self.player_cards[1].rank)
errors.add(:player_cards, "Invalid pair. Rank must match.") errors.add(:player_cards, "Invalid pair. Rank must match.")
end end
@ -119,10 +148,19 @@ class Play < ActiveRecord::Base
def first_play? def first_play?
# First play of the game # First play of the game
if self.game.plays.empty? || ( self.game.plays.length == 1 && self.game.plays.first == self ) if self.game.plays.empty? || ( self.game.plays.length == 1 && self.game.plays.first == self )
true
else
false
end
end
def contains_lowest_card?
# Cards being played must include the lowest card # Cards being played must include the lowest card
if (self.player_cards.include? self.game.lowest_card) == false if (self.player_cards.include? self.game.lowest_card) == false
errors.add(:player_cards, "First hand must contain the lowest card: #{game.lowest_card.to_s}") errors.add(:player_cards, "First hand must contain the lowest card: #{game.lowest_card.to_s}")
end return false
else
return true
end end
end end

View File

@ -29,7 +29,8 @@
= "Me" if player.user == current_user = "Me" if player.user == current_user
// Show whose turn it is // Show whose turn it is
%strong= "My Turn " if @game.control_player == player - if @game.active_player_id
%strong= "My Turn " if @game.active_player == player
// Show the players' cards // Show the players' cards
- unless player.inventory.empty? - unless player.inventory.empty?
@ -46,6 +47,7 @@
- unless @game.status == nil - unless @game.status == nil
.table .table
- if @game.play_to_beat - if @game.play_to_beat
- if @game.play_to_beat.play
%h1 %h1
Hand to beat Hand to beat
- @game.play_to_beat.play.player_cards.each do |card| - @game.play_to_beat.play.player_cards.each do |card|

View File

@ -36,10 +36,72 @@ RSpec.describe Play, type: :model do
@play.player_cards << @cards_to_play @play.player_cards << @cards_to_play
@play.save @play.save
expect(@play.player_cards.include? @game.lowest_card).to eq true expect(@play.player_cards.include? @game.lowest_card).to eq true
expect(@game.play_to_beat.play).to eq subject #expect(@game.play_to_beat.play).to eq subject
expect(subject.valid?).to eq(true)
end end
end end
end end
describe 'wins?' do
context 'valid if it beats the hand_to_beat' do
it 'single' do
@play_to_beat = Play.new
@play_to_beat.player = @game.players.last
@play_to_beat.game = @game
@play_to_beat.player_cards << @play_to_beat.player.player_cards.order(:value).first
@play_to_beat.save
@cards_to_play = @play.player.player_cards.order(:value).last
@play.player_cards << @cards_to_play
@play.save
expect(@play.valid?).to eq(true)
expect(@play.errors[:player_cards]).to eq([])
end
it 'double' do
@deck = Deck.new
@cards_to_beat = [
@spade3 = PlayerCard.new(@deck.cards[0].instance_values),
@club3 = PlayerCard.new(@deck.cards[1].instance_values)
]
@play_to_beat = Play.new
@play_to_beat.player = @game.players.first
@play_to_beat.player_cards << @cards_to_beat
@play_to_beat.game = @game
@play_to_beat.save
@play.player_cards = [
@spade4 = PlayerCard.new(@deck.cards[4].instance_values),
@club4 = PlayerCard.new(@deck.cards[5].instance_values)
]
# Shared tests
[@play_to_beat,@play].each do |play|
expect(play.errors[:player_cards]).to eq([])
expect(play.valid?).to eq(true)
puts play
expect(play.player_cards.count).to eq(2)
expect(play.hand_type).to eq('double')
end
expect(@play.beats? @play_to_beat).to eq(true)
end
end
end
it 'becomes the new play_to_beat' do
expect(@game.play_to_beat).to eq(nil)
# Play the hand
@cards_to_play = @game.current_player.inventory[0]
@play.hand << @cards_to_play
@play.save
expect(@play.hand_valid?).to eq(true)
@game.reload
expect(@game.play_to_beat.play).to eq(@play)
end
end
describe 'hand_type' do describe 'hand_type' do
context 'when a single card is played' do context 'when a single card is played' do
@ -56,7 +118,7 @@ RSpec.describe Play, type: :model do
@club3 = PlayerCard.new(rank: "3", suit: "Club") @club3 = PlayerCard.new(rank: "3", suit: "Club")
@cards_to_play = [@spade3, @club3] @cards_to_play = [@spade3, @club3]
@play.player_cards << @cards_to_play @play.player_cards << @cards_to_play
expect(@play.hand_type).to eq('pair') expect(@play.hand_type).to eq('double')
expect(@play.errors[:player_cards]).to eq([]) expect(@play.errors[:player_cards]).to eq([])
end end
it 'invalid pair' do it 'invalid pair' do
@ -64,7 +126,7 @@ RSpec.describe Play, type: :model do
@club4 = PlayerCard.new(rank: "4", suit: "Club") @club4 = PlayerCard.new(rank: "4", suit: "Club")
@cards_to_play = [@spade3, @club4] @cards_to_play = [@spade3, @club4]
@play.player_cards << @cards_to_play @play.player_cards << @cards_to_play
expect(@play.hand_type).to eq('pair') expect(@play.hand_type).to eq('double')
expect(@play.errors[:player_cards]).to eq(['Invalid pair. Rank must match.']) expect(@play.errors[:player_cards]).to eq(['Invalid pair. Rank must match.'])
end end
end end
@ -193,4 +255,3 @@ RSpec.describe Play, type: :model do
end end
end end
end end
end