Add game winner feature
This commit is contained in:
parent
eb2c38c9d3
commit
ab12e96879
@ -7,7 +7,6 @@ class Game < ActiveRecord::Base
|
|||||||
has_many :player_cards, through: :players
|
has_many :player_cards, through: :players
|
||||||
has_many :plays, through: :players
|
has_many :plays, through: :players
|
||||||
has_one :controlling_player
|
has_one :controlling_player
|
||||||
has_one :winner, :class_name => "Player", :primary_key => "winner_player_id"
|
|
||||||
belongs_to :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
|
||||||
@ -45,6 +44,14 @@ class Game < ActiveRecord::Base
|
|||||||
save
|
save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def winner
|
||||||
|
begin
|
||||||
|
self.players.find(self.winner_player_id)
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def validate_startable
|
def validate_startable
|
||||||
@player_count = players.count
|
@player_count = players.count
|
||||||
errors[:players] = 'Must be at least 2 players.' if @player_count < 2
|
errors[:players] = 'Must be at least 2 players.' if @player_count < 2
|
||||||
@ -159,10 +166,7 @@ class Game < ActiveRecord::Base
|
|||||||
|
|
||||||
def over?
|
def over?
|
||||||
return false unless self.started?
|
return false unless self.started?
|
||||||
@inventory_counts = []
|
@inventory_counts = self.players.map {|p| p.player_cards.count > 0 ? player.inventory.count : nil}
|
||||||
self.players.each do |player|
|
|
||||||
@inventory_counts << player.inventory.count
|
|
||||||
end
|
|
||||||
@inventory_counts.include? 0
|
@inventory_counts.include? 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -205,7 +205,7 @@ class Play < ActiveRecord::Base
|
|||||||
|
|
||||||
def contains_lowest_card?
|
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.first.value != self.game.lowest_card.value)
|
||||||
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}")
|
||||||
return false
|
return false
|
||||||
else
|
else
|
||||||
|
|||||||
@ -33,7 +33,7 @@ class User < ActiveRecord::Base
|
|||||||
@seats << table.seats.where(user_soft_token: self.soft_token)
|
@seats << table.seats.where(user_soft_token: self.soft_token)
|
||||||
end
|
end
|
||||||
@seats.flatten.each do |seat|
|
@seats.flatten.each do |seat|
|
||||||
seat.player.destroy
|
seat.try(:player).try(:destroy)
|
||||||
seat.user_id = nil
|
seat.user_id = nil
|
||||||
seat.player_id = nil
|
seat.player_id = nil
|
||||||
seat.user_soft_token = nil
|
seat.user_soft_token = nil
|
||||||
|
|||||||
@ -2,7 +2,7 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.feature "EndOfGames", type: :feature, js: true do
|
RSpec.feature "EndOfGames", type: :feature, js: true do
|
||||||
# Given I am in a started game
|
# Given I am in a started game
|
||||||
before do
|
before(:each) do
|
||||||
@game = setup_game
|
@game = setup_game
|
||||||
@game.reload
|
@game.reload
|
||||||
@player = @game.controlling_player
|
@player = @game.controlling_player
|
||||||
@ -13,26 +13,36 @@ RSpec.feature "EndOfGames", type: :feature, js: true do
|
|||||||
# And I play my last cards
|
# And I play my last cards
|
||||||
# Then I win the game
|
# Then I win the game
|
||||||
scenario 'I win the game' do
|
scenario 'I win the game' do
|
||||||
|
|
||||||
# Play lowest card
|
# Play lowest card
|
||||||
# Other players always pass
|
# Other players always pass
|
||||||
# Play next lowest card
|
# Play next lowest card
|
||||||
# Repeat until out of cards
|
# Repeat until out of cards
|
||||||
@player.inventory.each do |card|
|
while (@player.inventory.count > 0) do
|
||||||
|
card = @player.inventory.first
|
||||||
find_card(card).click
|
find_card(card).click
|
||||||
|
|
||||||
|
# Try to click the Play Hand button
|
||||||
|
# If this fails, reload the page
|
||||||
|
begin
|
||||||
click_button "Play Hand"
|
click_button "Play Hand"
|
||||||
sleep 1
|
|
||||||
visit current_url
|
visit current_url
|
||||||
@game.reload
|
@game.reload
|
||||||
@game.controlling_player_id = @player.id
|
rescue
|
||||||
@game.save
|
|
||||||
@game.reload
|
@game.reload
|
||||||
sleep 1
|
|
||||||
visit current_url
|
visit current_url
|
||||||
end
|
end
|
||||||
|
|
||||||
# Play my last card(s)
|
if @game.controlling_player_id != @player.id
|
||||||
|
# Simulate other players passing
|
||||||
|
@game.controlling_player_id = @player.id
|
||||||
|
@game.save
|
||||||
|
@game.reload
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# After I play my last card(s)
|
||||||
# Expect that I am the winner
|
# Expect that I am the winner
|
||||||
|
@game.reload
|
||||||
expect(@game.winner).to eq @player
|
expect(@game.winner).to eq @player
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,7 @@
|
|||||||
RSpec.describe Play, type: :model do
|
RSpec.describe Play, type: :model do
|
||||||
before(:all) do
|
before(:each) do
|
||||||
@game = setup_game
|
@game = setup_game
|
||||||
@play = @game.controlling_player.plays.new
|
@play = @game.controlling_player.plays.new(game_id: @game.id)
|
||||||
@play.game_id = @game.id
|
|
||||||
@play.save
|
|
||||||
end
|
|
||||||
|
|
||||||
after(:each) do
|
|
||||||
#reset game
|
|
||||||
@game.reload
|
|
||||||
@game.play_to_beat_id = nil
|
|
||||||
|
|
||||||
# reset play
|
|
||||||
@play.reload
|
|
||||||
@play.errors[:player_cards].clear
|
|
||||||
@play.game = @game
|
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { @play }
|
subject { @play }
|
||||||
@ -71,17 +58,22 @@ RSpec.describe Play, type: :model do
|
|||||||
describe 'wins?' do
|
describe 'wins?' do
|
||||||
context 'it does not beat the hand_to_beat' do
|
context 'it does not beat the hand_to_beat' do
|
||||||
it 'single' do
|
it 'single' do
|
||||||
|
# TODO: Refactor "lowest card first" to FactoryGirl.create :game, hand_to_beat: @cards
|
||||||
|
# First hand must contain lowest card
|
||||||
|
@cards_to_play = @play.player.player_cards.order(:value).first
|
||||||
|
@play.player_cards = [@cards_to_play]
|
||||||
|
@play.save
|
||||||
|
@game.reload
|
||||||
|
|
||||||
# Play a high single card
|
# Play a high single card
|
||||||
|
@play = @game.controlling_player.plays.new(game_id: @game.id)
|
||||||
@cards_to_play = @play.player.player_cards.order(:value).last
|
@cards_to_play = @play.player.player_cards.order(:value).last
|
||||||
@play.reload
|
@play.player_cards = [@cards_to_play]
|
||||||
@play.player_cards << @cards_to_play
|
|
||||||
@play.save
|
@play.save
|
||||||
@game.reload
|
@game.reload
|
||||||
|
|
||||||
# Try to play a losing card
|
# Try to play a losing card
|
||||||
@losing_play = Play.new
|
@losing_play = @game.controlling_player.plays.new(game_id: @game.id)
|
||||||
@losing_play.player = @game.players.where.not(id: @game.controlling_player_id).last
|
|
||||||
@losing_play.game = @game
|
|
||||||
@losing_play.player_cards << @losing_play.player.player_cards.order(:value).first
|
@losing_play.player_cards << @losing_play.player.player_cards.order(:value).first
|
||||||
expect(@losing_play.beats? @play).to eq(false)
|
expect(@losing_play.beats? @play).to eq(false)
|
||||||
expect(@losing_play.hand_valid?).to eq(false)
|
expect(@losing_play.hand_valid?).to eq(false)
|
||||||
@ -92,6 +84,12 @@ RSpec.describe Play, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'double' do
|
it 'double' do
|
||||||
|
# First hand must contain low card
|
||||||
|
@cards_to_play = @play.player.player_cards.order(:value).first
|
||||||
|
@play.player_cards = [@cards_to_play]
|
||||||
|
@play.save
|
||||||
|
@game.reload
|
||||||
|
|
||||||
@deck = Deck.new
|
@deck = Deck.new
|
||||||
@cards_to_beat = [
|
@cards_to_beat = [
|
||||||
@spade5 = PlayerCard.new(@deck.cards[8].instance_values),
|
@spade5 = PlayerCard.new(@deck.cards[8].instance_values),
|
||||||
@ -116,9 +114,7 @@ RSpec.describe Play, type: :model do
|
|||||||
expect(play.player_cards.length).to eq(2)
|
expect(play.player_cards.length).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
@play.reload
|
|
||||||
@game.reload
|
@game.reload
|
||||||
binding.pry unless !@play.valid?
|
|
||||||
|
|
||||||
expect(@play.valid?).to eq(false)
|
expect(@play.valid?).to eq(false)
|
||||||
expect(@play.beats? @play_to_beat).to eq(false)
|
expect(@play.beats? @play_to_beat).to eq(false)
|
||||||
@ -144,9 +140,7 @@ RSpec.describe Play, type: :model do
|
|||||||
@spade5 = PlayerCard.new(@deck.cards[8].instance_values)
|
@spade5 = PlayerCard.new(@deck.cards[8].instance_values)
|
||||||
]
|
]
|
||||||
|
|
||||||
@play.reload
|
|
||||||
@game.reload
|
@game.reload
|
||||||
binding.pry unless !@play.valid?
|
|
||||||
|
|
||||||
expect(@play.valid?).to eq(false)
|
expect(@play.valid?).to eq(false)
|
||||||
|
|
||||||
@ -161,6 +155,7 @@ RSpec.describe Play, type: :model do
|
|||||||
@play.save
|
@play.save
|
||||||
@game.reload
|
@game.reload
|
||||||
|
|
||||||
|
@play = @game.controlling_player.plays.new(game_id: @game.id)
|
||||||
# next player plays their lowest card and beats the previous play
|
# next player plays their lowest card and beats the previous play
|
||||||
@cards_to_play = @play.player.player_cards.order(:value).first
|
@cards_to_play = @play.player.player_cards.order(:value).first
|
||||||
@play.player_cards << @cards_to_play
|
@play.player_cards << @cards_to_play
|
||||||
@ -183,7 +178,8 @@ RSpec.describe Play, type: :model do
|
|||||||
@club3
|
@club3
|
||||||
]
|
]
|
||||||
|
|
||||||
@play.player_cards << @cards_to_beat
|
@play = @game.controlling_player.plays.new(game_id: @game.id)
|
||||||
|
@play.player_cards = @cards_to_beat
|
||||||
expect(@play.save).to be true
|
expect(@play.save).to be true
|
||||||
@game.reload
|
@game.reload
|
||||||
@game.controlling_player_id = @game.next_player_id
|
@game.controlling_player_id = @game.next_player_id
|
||||||
@ -288,16 +284,26 @@ RSpec.describe Play, type: :model do
|
|||||||
|
|
||||||
context 'when four cards are played' do
|
context 'when four cards are played' do
|
||||||
it 'valid bomb against a 2' do
|
it 'valid bomb against a 2' do
|
||||||
|
# TODO: Refactor "lowest card first" to FactoryGirl.create :game, hand_to_beat: @cards
|
||||||
|
# First hand must contain lowest card
|
||||||
|
@spade3 = @game.lowest_card
|
||||||
|
first_play = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: [@spade3])
|
||||||
|
first_play.save
|
||||||
|
@game.reload
|
||||||
|
|
||||||
|
# Setup play to beat
|
||||||
@heart2 = PlayerCard.new(rank: '2', suit: 'Heart', value: 52, player_id: @game.next_player_id)
|
@heart2 = PlayerCard.new(rank: '2', suit: 'Heart', value: 52, player_id: @game.next_player_id)
|
||||||
@play_to_beat = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: [@heart2])
|
@play_to_beat = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: [@heart2])
|
||||||
@play_to_beat.save
|
@play_to_beat.save
|
||||||
@game.play_to_beat_id = @play_to_beat.id
|
@game.reload
|
||||||
|
|
||||||
@spade3 = PlayerCard.new(value: 1, rank: "3", suit: "Spade")
|
@spade3 = PlayerCard.new(value: 1, rank: "3", suit: "Spade")
|
||||||
@club3 = PlayerCard.new(value: 2, rank: "3", suit: "Club")
|
@club3 = PlayerCard.new(value: 2, rank: "3", suit: "Club")
|
||||||
@diamond3 = PlayerCard.new(value: 3, rank: "3", suit: "Diamond")
|
@diamond3 = PlayerCard.new(value: 3, rank: "3", suit: "Diamond")
|
||||||
@heart3 = PlayerCard.new(value: 4, rank: "3", suit: "Heart")
|
@heart3 = PlayerCard.new(value: 4, rank: "3", suit: "Heart")
|
||||||
@cards_to_play = [@spade3, @club3, @diamond3, @heart3]
|
@cards_to_play = [@spade3, @club3, @diamond3, @heart3]
|
||||||
@play.player_cards << @cards_to_play
|
@play = @game.controlling_player.plays.new(game_id: @game.id)
|
||||||
|
@play.player_cards = @cards_to_play
|
||||||
expect(@play.hand_type).to eq('bomb')
|
expect(@play.hand_type).to eq('bomb')
|
||||||
expect(@play.valid?).to eq(true)
|
expect(@play.valid?).to eq(true)
|
||||||
end
|
end
|
||||||
@ -311,6 +317,7 @@ RSpec.describe Play, type: :model do
|
|||||||
@play_to_beat = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: @cards_to_beat)
|
@play_to_beat = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: @cards_to_beat)
|
||||||
@play_to_beat.save
|
@play_to_beat.save
|
||||||
@game.play_to_beat_id = @play_to_beat.id
|
@game.play_to_beat_id = @play_to_beat.id
|
||||||
|
@game.reload
|
||||||
|
|
||||||
# Setup the play
|
# Setup the play
|
||||||
@spade4 = PlayerCard.new(rank: "4", suit: "Spade", value: 5)
|
@spade4 = PlayerCard.new(rank: "4", suit: "Spade", value: 5)
|
||||||
@ -318,6 +325,7 @@ RSpec.describe Play, type: :model do
|
|||||||
@diamond4 = PlayerCard.new(rank: "4", suit: "Diamond", value: 7)
|
@diamond4 = PlayerCard.new(rank: "4", suit: "Diamond", value: 7)
|
||||||
@heart4 = PlayerCard.new(rank: "4", suit: "Heart", value: 8)
|
@heart4 = PlayerCard.new(rank: "4", suit: "Heart", value: 8)
|
||||||
@cards_to_play = [@spade4, @club4, @diamond4, @heart4]
|
@cards_to_play = [@spade4, @club4, @diamond4, @heart4]
|
||||||
|
@play = @game.controlling_player.plays.new(game_id: @game.id)
|
||||||
@play.player_cards = @cards_to_play
|
@play.player_cards = @cards_to_play
|
||||||
|
|
||||||
expect(@play.hand_type).to eq('bomb')
|
expect(@play.hand_type).to eq('bomb')
|
||||||
@ -326,16 +334,27 @@ RSpec.describe Play, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'invalid bomb against a greater bomb' do
|
it 'invalid bomb against a greater bomb' do
|
||||||
|
# Play lowest card first
|
||||||
|
@spade3 = @game.lowest_card
|
||||||
|
first_play = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: [@spade3])
|
||||||
|
first_play.save
|
||||||
|
@game.reload
|
||||||
|
|
||||||
|
# Create an Open Table, so every hand is valid.
|
||||||
|
@game.controlling_player_id = first_play.player_id
|
||||||
|
@game.save
|
||||||
|
#@game.reload
|
||||||
|
|
||||||
|
#
|
||||||
# Setup the play to beat
|
# Setup the play to beat
|
||||||
@spade4 = PlayerCard.new(rank: "4", suit: "Spade", value: 5)
|
@spade4 = PlayerCard.new(rank: "4", suit: "Spade", value: 5)
|
||||||
@club4 = PlayerCard.new(rank: "4", suit: "Club", value: 6)
|
@club4 = PlayerCard.new(rank: "4", suit: "Club", value: 6)
|
||||||
@diamond4 = PlayerCard.new(rank: "4", suit: "Diamond", value: 7)
|
@diamond4 = PlayerCard.new(rank: "4", suit: "Diamond", value: 7)
|
||||||
@heart4 = PlayerCard.new(rank: "4", suit: "Heart", value: 8)
|
@heart4 = PlayerCard.new(rank: "4", suit: "Heart", value: 8)
|
||||||
@cards_to_beat = [@spade4, @club4, @diamond4, @heart4]
|
@cards_to_beat = [@spade4, @club4, @diamond4, @heart4]
|
||||||
@play_to_beat = Play.new(game_id: @game.id, player_id: @game.next_player_id, player_cards: @cards_to_beat)
|
@play_to_beat = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: @cards_to_beat)
|
||||||
@play_to_beat.save
|
expect(@play_to_beat.save).to eq true
|
||||||
@game.play_to_beat_id = @play_to_beat.id
|
@game.reload
|
||||||
@play.reload
|
|
||||||
|
|
||||||
# Setup the play
|
# Setup the play
|
||||||
@spade3 = PlayerCard.new(rank: "3", suit: "Spade", value: 1)
|
@spade3 = PlayerCard.new(rank: "3", suit: "Spade", value: 1)
|
||||||
@ -343,9 +362,13 @@ RSpec.describe Play, type: :model do
|
|||||||
@diamond3 = PlayerCard.new(rank: "3", suit: "Diamond", value: 3)
|
@diamond3 = PlayerCard.new(rank: "3", suit: "Diamond", value: 3)
|
||||||
@heart3 = PlayerCard.new(rank: "3", suit: "Heart", value: 4)
|
@heart3 = PlayerCard.new(rank: "3", suit: "Heart", value: 4)
|
||||||
@cards_to_play = [@spade3, @club3, @diamond3, @heart3]
|
@cards_to_play = [@spade3, @club3, @diamond3, @heart3]
|
||||||
@play.player_cards = @cards_to_play
|
@play = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: @cards_to_beat)
|
||||||
|
|
||||||
expect(@play.hand_type).to eq('bomb')
|
expect(@play.hand_type).to eq('bomb')
|
||||||
|
#TODO: Refactor this test to only test the @play.beats? method
|
||||||
|
#TODO: Move other expectations to another test
|
||||||
|
#TODO: Test every validation of a play
|
||||||
|
#TODO: Refactor @play.valid? method
|
||||||
expect(@play.beats? @play_to_beat).to eq(false)
|
expect(@play.beats? @play_to_beat).to eq(false)
|
||||||
expect(@play.valid?).to eq(false)
|
expect(@play.valid?).to eq(false)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -11,5 +11,6 @@ if ENV['RAILS_ENV'] == 'staging'
|
|||||||
Capybara.app_host = asset_hosts[ENV['RAILS_ENV'].to_sym]
|
Capybara.app_host = asset_hosts[ENV['RAILS_ENV'].to_sym]
|
||||||
end
|
end
|
||||||
Capybara.asset_host = asset_hosts[ENV['RAILS_ENV'].to_sym]
|
Capybara.asset_host = asset_hosts[ENV['RAILS_ENV'].to_sym]
|
||||||
#Capybara.asset_host = 'http://localhost:3000'
|
|
||||||
Capybara.javascript_driver = :poltergeist # :selenium
|
Capybara.javascript_driver = :poltergeist
|
||||||
|
#Capybara.javascript_driver = :selenium
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user