Add winner feature to games
This commit is contained in:
parent
c0d84b30ba
commit
eb2c38c9d3
@ -7,6 +7,7 @@ class Game < ActiveRecord::Base
|
||||
has_many :player_cards, through: :players
|
||||
has_many :plays, through: :players
|
||||
has_one :controlling_player
|
||||
has_one :winner, :class_name => "Player", :primary_key => "winner_player_id"
|
||||
belongs_to :play_to_beat
|
||||
accepts_nested_attributes_for :players
|
||||
#validates :title, presence: true
|
||||
|
||||
@ -7,9 +7,11 @@ class Play < ActiveRecord::Base
|
||||
validates :game, presence: true
|
||||
validates :player, presence: true
|
||||
validate :hand_valid?
|
||||
validate :player_has_control?
|
||||
|
||||
after_save :update_play_to_beat
|
||||
after_save :check_for_winner
|
||||
after_save :update_play_to_beat
|
||||
after_save :set_controlling_player
|
||||
|
||||
def check_for_winner
|
||||
if self.game.over?
|
||||
@ -30,8 +32,22 @@ class Play < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def set_controlling_player
|
||||
self.game.set_controlling_player 'next'
|
||||
self.game.save
|
||||
end
|
||||
|
||||
# Validation methods
|
||||
|
||||
def player_has_control?
|
||||
if self.player == self.game.controlling_player
|
||||
return true
|
||||
else
|
||||
errors.add(:player, "it's not your turn")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def hand_valid?
|
||||
return false if self.hand_type == nil
|
||||
# Gather the truths about the hand
|
||||
|
||||
@ -18,4 +18,17 @@ class Player < ActiveRecord::Base
|
||||
self.try(:user).try(:email) || "Guest#{self.soft_token[0..5]}"
|
||||
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'
|
||||
self.game.save
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -20,6 +20,10 @@ class User < ActiveRecord::Base
|
||||
self.email || "Guest#{self.soft_token[0..5]}"
|
||||
end
|
||||
|
||||
def sit_in(seat)
|
||||
seat.sit self
|
||||
end
|
||||
|
||||
def stand_from(table)
|
||||
@seats = []
|
||||
if self.id
|
||||
|
||||
43
spec/features/end_of_games_spec.rb
Normal file
43
spec/features/end_of_games_spec.rb
Normal file
@ -0,0 +1,43 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.feature "EndOfGames", type: :feature, js: true do
|
||||
# Given I am in a started game
|
||||
before do
|
||||
@game = setup_game
|
||||
@game.reload
|
||||
@player = @game.controlling_player
|
||||
signin(@player.user.email,'password')
|
||||
visit table_path @game.table
|
||||
end
|
||||
# And it is my turn
|
||||
# And I play my last cards
|
||||
# Then I win the game
|
||||
scenario 'I win the game' do
|
||||
|
||||
# Play lowest card
|
||||
# Other players always pass
|
||||
# Play next lowest card
|
||||
# Repeat until out of cards
|
||||
@player.inventory.each do |card|
|
||||
find_card(card).click
|
||||
click_button "Play Hand"
|
||||
sleep 1
|
||||
visit current_url
|
||||
@game.reload
|
||||
@game.controlling_player_id = @player.id
|
||||
@game.save
|
||||
@game.reload
|
||||
sleep 1
|
||||
visit current_url
|
||||
end
|
||||
|
||||
# Play my last card(s)
|
||||
# Expect that I am the winner
|
||||
expect(@game.winner).to eq @player
|
||||
end
|
||||
|
||||
describe 'I lose the game' do
|
||||
# Another player plays their last card(s)
|
||||
# Expect that they are the winner
|
||||
end
|
||||
end
|
||||
@ -11,14 +11,35 @@ RSpec.describe Game, type: :model do
|
||||
|
||||
it { should respond_to(:title) }
|
||||
it { should respond_to(:play_to_beat) }
|
||||
it { should respond_to(:winner) }
|
||||
|
||||
it '#title returns a string' do
|
||||
expect(@game.title).to match 'Test Game'
|
||||
end
|
||||
|
||||
it 'has a winner' do
|
||||
# Start the game
|
||||
@player1 = @user1.sit_in(@game.seats.first)
|
||||
@player2 = @user2.sit_in(@game.seats.last)
|
||||
@game.start
|
||||
|
||||
# controlling player plays all their cards
|
||||
@player = @game.controlling_player
|
||||
@player.inventory.each do |card|
|
||||
@player.play_hand [card]
|
||||
@game.reload
|
||||
while (@game.controlling_player != @player) do
|
||||
@game.controlling_player.pass
|
||||
@game.reload
|
||||
end
|
||||
end
|
||||
|
||||
expect(@game.winner).to eq @player
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
describe 'player_count' do
|
||||
context 'when there are between 2 and 4 players' do
|
||||
context 'when there are 2 to 4 players' do
|
||||
it 'is startable' do
|
||||
@game.add_player_from_user(@user1)
|
||||
@game.add_player_from_user(@user2)
|
||||
|
||||
@ -3,3 +3,6 @@ require 'rails_helper'
|
||||
RSpec.describe Player, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
|
||||
#TODO: Player can play_hand cards
|
||||
#TODO: Player can not play_hand if not game.controlling_player
|
||||
|
||||
@ -47,4 +47,6 @@ RSpec.configure do |config|
|
||||
# The different available types are documented in the features, such as in
|
||||
# https://relishapp.com/rspec/rspec-rails/docs
|
||||
config.infer_spec_type_from_file_location!
|
||||
|
||||
config.include GameHelpers
|
||||
end
|
||||
|
||||
@ -1,4 +1,52 @@
|
||||
module GameHelpers
|
||||
def setup_game
|
||||
# Default game has 4 players
|
||||
game = FactoryGirl.create :game
|
||||
user1 = FactoryGirl.create :user
|
||||
user2 = FactoryGirl.create :user
|
||||
user3 = FactoryGirl.create :user
|
||||
user4 = FactoryGirl.create :user
|
||||
game.seats[0].sit user1
|
||||
game.seats[1].sit user2
|
||||
game.seats[2].sit user3
|
||||
game.seats[3].sit user4
|
||||
game.start
|
||||
return game
|
||||
end
|
||||
|
||||
def setup_visitor_game
|
||||
# Default game has 3 players
|
||||
game = FactoryGirl.create :game
|
||||
|
||||
u = FactoryGirl.build :user
|
||||
game.seats[0].sit u
|
||||
|
||||
u = FactoryGirl.build :user
|
||||
game.seats[1].sit u
|
||||
|
||||
u = FactoryGirl.build :user
|
||||
game.seats[2].sit u
|
||||
|
||||
return game
|
||||
end
|
||||
|
||||
def find_card card
|
||||
find("[data-card-name='#{card.to_s}'] ~ img")
|
||||
end
|
||||
|
||||
def cards_to_beat
|
||||
@cards = find("#cards-to-beat")
|
||||
if @cards
|
||||
@cards = @cards.find_all('img')
|
||||
end
|
||||
@array = []
|
||||
@cards.map {|c| @array << c[:alt]}
|
||||
return @array.join " "
|
||||
end
|
||||
end
|
||||
|
||||
module Features
|
||||
#DEPRECATED Features module. Use top level GameHelpers
|
||||
module GameHelpers
|
||||
def setup_game
|
||||
# Default game has 4 players
|
||||
@ -47,6 +95,7 @@ module Features
|
||||
end
|
||||
end
|
||||
|
||||
# DEPRECATED Models module. Use top level GameHelpers
|
||||
# TODO: DRY up this repetition
|
||||
module Models
|
||||
module GameHelpers
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user