Add end of game status and winner
This commit is contained in:
parent
cbe99f180e
commit
a75631552f
18
README.md
18
README.md
@ -4,26 +4,22 @@ Thirteen Tien Len
|
||||
TODO
|
||||
----
|
||||
|
||||
hide play / pass buttons of other players
|
||||
- rename `current_player(_id)` to `controlling_player(_id)`
|
||||
|
||||
code end game "winner"
|
||||
- graphics
|
||||
|
||||
disable "pass" when not your turn same as "play hand" is disabled
|
||||
- Test `play_hand` of run including face cards
|
||||
|
||||
graphics
|
||||
|
||||
Test play_hand of run including face cards
|
||||
|
||||
BUG TODO: First player / lowest card holder should not be able to pass
|
||||
- BUG TODO: First player / lowest card holder should not be able to pass
|
||||
first play
|
||||
|
||||
Fix tests. They mostly pass when run individually. Explore if game_setup
|
||||
- Fix tests. They mostly pass when run individually. Explore if `game_setup`
|
||||
is causing a bleedover between scenarios
|
||||
|
||||
Bug: Players should not be able to pass outside of their turn.
|
||||
- Bug: Players should not be able to pass outside of their turn.
|
||||
Validate play: play.player == game.current_player
|
||||
|
||||
Replace publicly displayed emails with usernames
|
||||
- Replace publicly displayed emails with usernames
|
||||
|
||||
## Proposed Schema
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ var Game = React.createClass({
|
||||
return (
|
||||
<div>
|
||||
<div>Title: {this.state.data.title}</div>
|
||||
<div>Id: {this.props.id}</div>
|
||||
<div>Id: {this.state.data.id}</div>
|
||||
<div>Current Player: {this.state.data.current_player_id}</div>
|
||||
<div>Hand to beat: {this.state.data.play_to_beat_string}</div>
|
||||
<div className='player-list'>
|
||||
@ -99,7 +99,8 @@ var Game = React.createClass({
|
||||
game_id={this.props.id}
|
||||
players={this.state.data.players}
|
||||
onPlayHandSubmit={this.handlePlayHandSubmit}
|
||||
current_player_id={this.state.data.current_player_id} />
|
||||
current_player_id={this.state.data.current_player_id}
|
||||
current_user_id={this.state.data.current_user_id} />
|
||||
</div>
|
||||
<div>
|
||||
{/* TODO: If not joinable, show why. i.e. game full*/ }
|
||||
@ -108,8 +109,7 @@ var Game = React.createClass({
|
||||
{this.state.data.is_started ? null : <button onClick={this.handleStart} disabled={this.state.data.is_startable ? null : "disabled" }>Start</button>}
|
||||
</div>
|
||||
<div>
|
||||
{console.log('is startable?')}
|
||||
{console.log(this.state.data.is_startable)}
|
||||
{this.state.data.winner_player_id ? "Winner: " + this.state.data.winner_player_id : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -6,48 +6,22 @@ var Player = React.createClass({
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
<div>Id: {this.props.id}</div>
|
||||
<div style={{border: '1px solid', margin: '8px', padding: '8px'}}>
|
||||
<div>Player Id: {this.props.id}</div>
|
||||
<div>Email: {this.props.email}</div>
|
||||
<div>Inventory count: {this.props.inventory_count}</div>
|
||||
<div>
|
||||
<PlayerControls
|
||||
|
||||
{/* Show player controls if player is owned by current_user */}
|
||||
{this.props.user_id == this.props.current_user_id
|
||||
? (<PlayerControls
|
||||
key={this.props.id}
|
||||
onPlayHandSubmit={this.props.onPlayHandSubmit}
|
||||
game_id={this.props.game_id}
|
||||
player_id={this.props.id}
|
||||
inventory={this.props.inventory}
|
||||
current_player_id={this.props.current_player_id} />
|
||||
</div>
|
||||
current_player_id={this.props.current_player_id} /> )
|
||||
: null }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var PlayerList = React.createClass({
|
||||
propTypes: {
|
||||
players: React.PropTypes.array,
|
||||
game_id: React.PropTypes.number
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var playerList = this;
|
||||
var playerNodes = this.props.players.map(function (player) {
|
||||
return (
|
||||
<Player
|
||||
key={player.id}
|
||||
onPlayHandSubmit={playerList.props.onPlayHandSubmit}
|
||||
current_player_id={playerList.props.current_player_id}
|
||||
game_id={playerList.props.game_id} {...player} />
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
PlayerList:
|
||||
{playerNodes}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@ -34,6 +34,7 @@ var PlayerControls = React.createClass({
|
||||
name="commit">
|
||||
</input>
|
||||
<input id={"pass_hand_button_" + this.props.player_id}
|
||||
disabled={this.props.current_player_id == this.props.player_id ? null : 'disabled'}
|
||||
type="submit"
|
||||
onClick={this.handlePass}
|
||||
value="Pass"
|
||||
|
||||
29
app/assets/javascripts/components/player_list.js.jsx
Normal file
29
app/assets/javascripts/components/player_list.js.jsx
Normal file
@ -0,0 +1,29 @@
|
||||
var PlayerList = React.createClass({
|
||||
propTypes: {
|
||||
players: React.PropTypes.array,
|
||||
game_id: React.PropTypes.number
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var playerList = this;
|
||||
var playerNodes = this.props.players.map(function (player) {
|
||||
return (
|
||||
<Player
|
||||
key={player.id}
|
||||
onPlayHandSubmit={playerList.props.onPlayHandSubmit}
|
||||
current_player_id={playerList.props.current_player_id}
|
||||
current_user_id={playerList.props.current_user_id}
|
||||
user_id={player.user_id}
|
||||
game_id={playerList.props.game_id} {...player} />
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
PlayerList:
|
||||
{playerNodes}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
@ -119,4 +119,18 @@ class Game < ActiveRecord::Base
|
||||
def player_to_beat
|
||||
self.play_to_beat.try(:play).try(:player)
|
||||
end
|
||||
|
||||
def started?
|
||||
!self.status.nil?
|
||||
end
|
||||
|
||||
def over?
|
||||
return false unless self.started?
|
||||
@inventory_counts = []
|
||||
self.players.each do |player|
|
||||
@inventory_counts << player.inventory.count
|
||||
end
|
||||
@inventory_counts.include? 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -9,6 +9,15 @@ class Play < ActiveRecord::Base
|
||||
validate :hand_valid?
|
||||
|
||||
after_save :update_play_to_beat
|
||||
after_save :check_for_winner
|
||||
|
||||
def check_for_winner
|
||||
if self.game.over?
|
||||
self.game.winner_player_id = self.player.id
|
||||
self.game.status = "Player #{self.player.id} wins!"
|
||||
self.game.save
|
||||
end
|
||||
end
|
||||
|
||||
def update_play_to_beat
|
||||
if hand_valid?
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
= react_component 'Game', id: @game.id, url: "#{game_path @game}"
|
||||
= react_component 'Game', url: "#{game_path @game}"
|
||||
|
||||
-# TODO: Remove deprecated commented out code
|
||||
-#%p
|
||||
|
||||
@ -5,14 +5,18 @@ else
|
||||
json.play_to_beat_string @game.play_to_beat.try(:play).try(:to_s)
|
||||
end
|
||||
|
||||
json.winner_player_id @game.winner_player_id
|
||||
|
||||
json.is_joinable @game.joinable?(current_user)
|
||||
json.is_started !@game.status.nil?
|
||||
json.is_startable @game.startable?
|
||||
json.current_user_id current_user.id
|
||||
|
||||
json.players @game.players do |player|
|
||||
json.id player.id
|
||||
json.email player.user.email
|
||||
json.inventory_count player.inventory.count
|
||||
json.user_id player.user.id
|
||||
|
||||
if player.user == current_user
|
||||
json.inventory player.inventory
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
class AddWinnerPlayerIdToGame < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :games, :winner_player_id, :integer
|
||||
end
|
||||
end
|
||||
@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150810115450) do
|
||||
ActiveRecord::Schema.define(version: 20151107111235) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@ -23,6 +23,7 @@ ActiveRecord::Schema.define(version: 20150810115450) do
|
||||
t.string "status"
|
||||
t.integer "control_player_id"
|
||||
t.integer "play_to_beat_id"
|
||||
t.integer "winner_player_id"
|
||||
end
|
||||
|
||||
add_index "games", ["play_to_beat_id"], name: "index_games_on_play_to_beat_id", using: :btree
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
RSpec.describe Play, type: :model do
|
||||
before(:each) do
|
||||
before(:all) do
|
||||
@game = setup_game
|
||||
@play = @game.current_player.plays.new
|
||||
@play.game_id = @game.id
|
||||
@ -14,6 +14,7 @@ RSpec.describe Play, type: :model do
|
||||
# reset play
|
||||
@play.reload
|
||||
@play.errors[:player_cards].clear
|
||||
@play.game = @game
|
||||
end
|
||||
|
||||
subject { @play }
|
||||
@ -208,14 +209,14 @@ RSpec.describe Play, type: :model do
|
||||
end
|
||||
|
||||
it 'becomes the new play_to_beat' do
|
||||
expect(@game.play_to_beat).to eq(nil)
|
||||
expect(@play.game.play_to_beat).to eq(nil)
|
||||
# Play the hand
|
||||
@cards_to_play = @game.current_player.inventory[0]
|
||||
@cards_to_play = @play.player.inventory.first
|
||||
@play.hand << @cards_to_play
|
||||
|
||||
expect(@play.hand_valid?).to eq(true)
|
||||
@game.reload
|
||||
expect(@game.play_to_beat.play).to eq(@play)
|
||||
expect(@play.save)
|
||||
expect(@play.game.play_to_beat.play).to eq(@play)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user