Add seat management fix new game button

This commit is contained in:
Jesse C. Fisher 2021-11-17 07:56:39 -08:00
parent 3a09b9bcff
commit 3d46e5b806
16 changed files with 161 additions and 46 deletions

View File

@ -1,5 +1,7 @@
class SeatsController < ApplicationController
before_action :set_seat, only: [:show, :edit, :update, :destroy, :sit, :stand, :add_bot, :remove_bot]
before_action :set_seat, only: [:show, :edit, :update, :destroy,
:sit, :stand, :add_bot, :remove_bot, :empty,
:remove_player]
respond_to :html, :json
@ -90,6 +92,16 @@ class SeatsController < ApplicationController
redirect_to @seat.table, notice: @message
end
def empty
@message = @seat.empty
redirect_to @seat.table, notice: @message
end
def remove_player
@message = @seat.remove_player
redirect_to @seat.table, notice: @message
end
private
# Use callbacks to share common setup or constraints between actions.
def set_seat

View File

@ -30,9 +30,16 @@ class TablesController < ApplicationController
# GET /tables/1
# GET /tables/1.json
def show
# TODO move this to the game.rb model
# Clear play to beat if play returns to owner
# TODO refactor to ensure play for 2nd and 3rd place
if @game.controlling_player.try("is_bot?")
flash[:notice] = "Bot is passes"
@game.controlling_player.pass
@game.save
@game.reload
end
# Clear play to beat if play returns to owner
if @game.play_to_beat.try(:player).try(:id) == @game.controlling_player_id
@game.play_to_beat_id = nil
@game.save
@ -41,7 +48,11 @@ class TablesController < ApplicationController
def new_game
@game = @table.add_game
@game.start
begin
@game.start
rescue
flash[:errors] = @game.errors
end
redirect_to @table
end

View File

@ -7,6 +7,7 @@ class Game < ActiveRecord::Base
has_many :player_cards, through: :players
has_many :plays, through: :players
belongs_to :play_to_beat
belongs_to :controlling_player, class_name: "Player", foreign_key: "controlling_player_id"
accepts_nested_attributes_for :players
#validates :title, presence: true
after_create :add_table
@ -79,6 +80,12 @@ class Game < ActiveRecord::Base
new_player = self.players.create(user: user, soft_token: user.soft_token)
end
def add_player_bot
# todo return if game is full
# return false unless self.joinable?(user)
new_player = self.players.create(is_bot: true)
end
def remove_player_from_user(user)
return false unless self.has_user? user
@ -116,7 +123,7 @@ class Game < ActiveRecord::Base
def full?
players.count >= 4
# players.count >= 4
end
def set_controlling_player(arg)
@ -132,7 +139,8 @@ class Game < ActiveRecord::Base
end
def joinable? user
!self.has_user?(user) && !self.full?
# !self.has_user?(user) && !self.full?
!self.full?
end
def player_ids_by_seat_order
@ -146,13 +154,6 @@ class Game < ActiveRecord::Base
player_ids_by_seat_order[(@controlling_player_index + 1) % self.player_ids_by_seat_order.length]
end
# The player whose turn it is
def controlling_player
if self.controlling_player_id
self.players.find_by_id(self.controlling_player_id)
end
end
# The user whose turn it is
def controlling_user
self.players.find(self.controlling_player_id).user
@ -182,8 +183,9 @@ private
self.table ||= Table.create current_game_id: self.id
self.seats = self.table.seats
self.seats.each do |seat|
if (seat.user_id || seat.user_soft_token)
new_player = self.players.create(user_id: seat.user_id, soft_token: seat.user_soft_token)
# if (seat.user_id || seat.user_soft_token)
if (seat.occupied?)
new_player = self.players.create(user_id: seat.user_id, soft_token: seat.user_soft_token, is_bot: seat.player.is_bot)
seat.player = new_player
seat.save
end

View File

@ -51,10 +51,15 @@ class Seat < ActiveRecord::Base
if self.player == nil
# add player to game
@bot_player = self.table.current_game.players.new(is_bot: true)
# @bot_player = self.table.current_game.add_player_from_user(current_user).id
self.player = @bot_player
self.player.save
self.save
return "Added Bot"
else
self.player.is_bot = true
self.player.save
return "Added Bot"
end
return "Failed to add Bot"
@ -75,6 +80,31 @@ class Seat < ActiveRecord::Base
end
end
def empty
self.player.user = nil
self.player.soft_token = nil
self.player.is_bot = false
self.player.save
self.user_id = nil
self.user_soft_token = nil
# self.player_id = nil
self.save
return "Successfully stood up."
end
def remove_player
if !self.player
return "No player to remove"
else
self.player.destroy
self.user_id = nil
self.user_soft_token = nil
# self.player_id = nil
self.save
return "Successfully removed player"
end
end
def occupied?
self.user_id.present? || self.user_soft_token.present? || self.try("player").try("is_bot?") == true
end

View File

@ -3,18 +3,23 @@
.seat-controls
- if seat.occupied?
- if seat.player.is_bot?
= button_to remove_bot_seat_path(seat) do
-# = button_to remove_bot_seat_path(seat) do
- "- Bot"
- if seat.occupied_by? current_user
= button_to stand_seat_path(seat), :data => { :confirm => 'Are you sure you want to leave this seat?' } do
- "Stand"
- "Leave"
- else
= button_to empty_seat_path(seat), :data => { :confirm => 'Are you sure you want to empty this seat?' } do
- "Empty"
- else
= button_to sit_seat_path(seat) do
- "Sit"
= button_to add_bot_seat_path(seat) do
- "+ Bot"
- if seat.player
= button_to remove_player_seat_path(seat), :data => { :confirm => 'Are you sure you want to remove this player?' } do
- "Remove Player"
.player{id: "player-#{seat.player.id}", class: @game.controlling_player == seat.player ? "taking-turn" : "",
data: {soft_token: seat.player.soft_token} }
.user-name= seat.player.display_name

View File

@ -15,6 +15,9 @@
- if @game.winner_player_id || @game.nil?
= button_to 'New Game', new_game_table_path(@table)
-# - if @game && !@game.startable?
= button_to 'New Game', new_game_table_path(@table)
#game-component
- if @game.winner_player_id
%h1= @game.status

View File

@ -54,4 +54,5 @@ Rails.application.configure do
# Add Rack::LiveReload to the bottom of the middleware stack with the default options.
config.middleware.insert_after ActionDispatch::Static, Rack::LiveReload
BetterErrors::Middleware.allow_ip! '10.0.0.0/16'
end

View File

@ -3,6 +3,7 @@ Rails.application.routes.draw do
resources :tables do
member do
post 'new_game'
post 'end_game'
end
resources :seats do
member do
@ -23,6 +24,8 @@ Rails.application.routes.draw do
post 'stand'
post 'add_bot'
post 'remove_bot'
post 'empty'
post 'remove_player'
end
end

View File

@ -14,6 +14,7 @@ feature 'Add bot', type: :feature do
scenario 'visitor can add a bot if the seat is empty' do
@button = page.find_button('+ Bot', match: :first).click
expect(page).to have_content "BotPlayer"
end
scenario 'visitor can not add a bot if the seat is occupied by bot' do

View File

@ -0,0 +1,35 @@
# Feature: Bot takes turns
# As a player
# I want bots to take turns
# So I can play against the computer
feature 'Bot takes turn', type: :feature do
before(:each) do
@table = FactoryGirl.create :table
@game = @table.current_game
visit table_path @table
end
scenario 'bot player passes' do
@button = page.find_button('+ Bot', match: :first).click
expect(page).to have_content "BotPlayer"
@button = page.find_button('Sit', match: :first).click
click_button "Start"
click_button 'Pass'
expect(page).to have_content "Bot is passes"
end
scenario 'bot player plays single' do
@button = page.find_button('+ Bot', match: :first).click
expect(page).to have_content "BotPlayer"
@button = page.find_button('Sit', match: :first).click
click_button "Start"
@game = @table.current_game
if @game.controlling_player.soft_token == page.current_user.soft_token
@card_to_play = @game.controlling_player.inventory.first
find("[data-card-name='#{@card_to_play.to_s}']").click
click_button 'Play Hand'
end
expect(@game.play_to_beat.player.is_bot?).to eq true
expect(@game.play_to_beat.hand_type).to eq "single"
end
end

View File

@ -2,7 +2,7 @@ require 'rails_helper'
RSpec.feature "EndOfGames", type: :feature do
# Given I am in a started game
before(:each) do
before(:all) do
# If test is unable to click correct card, use wider window
# page.driver.browser.manage.window.resize_to(1640, 1090)
@game = setup_game
@ -10,11 +10,7 @@ RSpec.feature "EndOfGames", type: :feature do
@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
@ -41,11 +37,23 @@ RSpec.feature "EndOfGames", type: :feature do
@game.reload
end
end
end
# And it is my turn
# And I play my last cards
# Then I win the game
scenario 'I win the game' do
# After I play my last card(s)
# Expect that I am the winner
@game.reload
expect(@game.winner).to eq @player
click_button "New Game"
expect(page).to have_content "Game started"
end
scenario 'I start a new game at the same table' do
click_button "New Game"
expect(page).to have_content "Game started"
end
describe 'I lose the game' do

View File

@ -168,11 +168,12 @@ feature 'Play a hand', type: :feature do
# Given I am the active player
# When I pass
# Then I see an successful pass message
scenario 'active player can pass', js: true do
# scenario 'active player can pass', js: true do
scenario 'active player can pass' do
@current_user = @game.controlling_player
accept_confirm do
# accept_confirm do
click_button 'Pass'
end
# end
# click_button "pass_hand_button_#{@player.id}"
## TODO: Flash messages
expect(page).to have_content 'Successfully passed.'

View File

@ -28,7 +28,7 @@ feature 'Seats', :devise do
@button = page.find_button('Sit', match: :first)
@button.click
expect(page).to have_content "Guest"
@buttons = page.find_all('button', text: 'Stand')
@buttons = page.find_all('button', text: 'Leave')
expect(@buttons.length).to eq 1
end
@ -62,13 +62,14 @@ feature 'Seats', :devise do
find_all(:button, "Sit")
end
scenario 'visitor can leave the current game', js: true do
# scenario 'visitor can leave the current game', js: true do
scenario 'seated visitor can leave the current game' do
click_button 'Sit', match: :first
expect(page).to have_content 'Guest'
expect(page.text.scan('Guest').count).to eq 1
accept_confirm do
click_button 'Stand', match: :first
end
# accept_confirm do
click_button 'Leave', match: :first
# end
expect(page.find('.seat.position-1')).to have_content 'Sit'
expect(sit_buttons.length).to eq 4
expect(page.text.scan('Guest').count).to eq 0
@ -95,13 +96,14 @@ feature 'Seats', :devise do
expect(page.text.scan(@user.email).count).to eq 1
end
scenario 'user can leave the current game', js: true do
# scenario 'user can leave the current game', js: true do
scenario 'user can leave the current game' do
click_button 'Sit', match: :first
expect(page).to have_content @user.email
expect(page.text.scan(@user.email).count).to eq 1
accept_confirm do
click_button 'Stand', match: :first
end
# accept_confirm do
click_button 'Leave', match: :first
# end
expect(page.text.scan(@user.email).count).to eq 0
end

View File

@ -21,13 +21,14 @@ feature 'Table show', :devise do
expect(page.text.scan('Guest').count).to eq 1
end
scenario 'visitor can leave the current game', js: true do
# scenario 'visitor can leave the current game', js: true do
scenario 'visitor can leave the current game' do
click_button 'Sit', match: :first
expect(page).to have_content "Guest"
expect(page.text.scan('Guest').count).to eq 1
accept_confirm do
# accept_confirm do
click_button 'Stand', match: :first
end
# end
expect(page.find('.seat.position-1')).to have_content "Sit"
expect(page.text.scan('Guest').count).to eq 0
end
@ -56,14 +57,15 @@ feature 'Table show', :devise do
expect(page.text.scan(@user.email).count).to eq 1
end
scenario 'user can leave the current game', js: true do
# scenario 'user can leave the current game', js: true do
scenario 'user can leave the current game' do
expect(page).to have_content "Sit"
click_button 'Sit', match: :first
expect(page).to have_content @user.email
expect(page.text.scan(@user.email).count).to eq 1
accept_confirm do
# accept_confirm do
click_button 'Stand', match: :first
end
# end
expect(page.find('.seat.position-1')).to have_content "Sit"
expect(page.text.scan(@user.email).count).to eq 0
end

View File

@ -17,7 +17,8 @@ feature 'Navigation links', :devise do
# Given I am a visitor
# When I click a navigation link
# Then I see the proper web page
scenario 'follow navigation links', js: :true do
# scenario 'follow navigation links', js: :true do
scenario 'follow navigation links' do
visit root_path
@links = {
'Play Now': '"/tables/1"',
@ -26,9 +27,6 @@ feature 'Navigation links', :devise do
}
@links.each do |link|
click_link link[0]
#TODO: Remove race condition
sleep 4
page.save_screenshot
expect(page.current_path).to eq(eval(link[1]))
visit root_path
end

View File

@ -4,6 +4,7 @@ require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!
`trash tmp/capybara/*`
require 'capybara-screenshot/rspec'
# Requires supporting ruby files with custom matchers and macros, etc, in