From a75631552f80f0dd5dd07520abd679644f632d5b Mon Sep 17 00:00:00 2001 From: "Jesse C. Fisher" Date: Sat, 7 Nov 2015 18:05:11 -0800 Subject: [PATCH] Add end of game status and winner --- README.md | 20 ++++----- app/assets/javascripts/components/game.js.jsx | 8 ++-- .../javascripts/components/player.js.jsx | 42 ++++--------------- .../components/player_controls.js.jsx | 1 + .../javascripts/components/player_list.js.jsx | 29 +++++++++++++ app/models/game.rb | 14 +++++++ app/models/play.rb | 9 ++++ app/views/games/show.html.haml | 2 +- app/views/games/show.json.jbuilder | 4 ++ ...1107111235_add_winner_player_id_to_game.rb | 5 +++ db/schema.rb | 3 +- spec/models/play_spec.rb | 11 ++--- 12 files changed, 91 insertions(+), 57 deletions(-) create mode 100644 app/assets/javascripts/components/player_list.js.jsx create mode 100644 db/migrate/20151107111235_add_winner_player_id_to_game.rb diff --git a/README.md b/README.md index b1b52ab6..3316c347 100644 --- a/README.md +++ b/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 -is causing a bleedover between scenarios +- 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 diff --git a/app/assets/javascripts/components/game.js.jsx b/app/assets/javascripts/components/game.js.jsx index 151ec420..8b8624b4 100644 --- a/app/assets/javascripts/components/game.js.jsx +++ b/app/assets/javascripts/components/game.js.jsx @@ -91,7 +91,7 @@ var Game = React.createClass({ return (
Title: {this.state.data.title}
-
Id: {this.props.id}
+
Id: {this.state.data.id}
Current Player: {this.state.data.current_player_id}
Hand to beat: {this.state.data.play_to_beat_string}
@@ -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} />
{/* TODO: If not joinable, show why. i.e. game full*/ } @@ -108,8 +109,7 @@ var Game = React.createClass({ {this.state.data.is_started ? null : }
- {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}
); diff --git a/app/assets/javascripts/components/player.js.jsx b/app/assets/javascripts/components/player.js.jsx index 556bff18..a35d69ff 100644 --- a/app/assets/javascripts/components/player.js.jsx +++ b/app/assets/javascripts/components/player.js.jsx @@ -6,48 +6,22 @@ var Player = React.createClass({ render: function() { return ( -
-
Id: {this.props.id}
+
+
Player Id: {this.props.id}
Email: {this.props.email}
Inventory count: {this.props.inventory_count}
-
- -
+ current_player_id={this.props.current_player_id} /> ) + : null }
); } }); - -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 ( - - ); - }); - - return ( -
- PlayerList: - {playerNodes} -
- ); - } - -}); diff --git a/app/assets/javascripts/components/player_controls.js.jsx b/app/assets/javascripts/components/player_controls.js.jsx index d5db7137..e9fbe96d 100644 --- a/app/assets/javascripts/components/player_controls.js.jsx +++ b/app/assets/javascripts/components/player_controls.js.jsx @@ -34,6 +34,7 @@ var PlayerControls = React.createClass({ name="commit"> + ); + }); + + return ( +
+ PlayerList: + {playerNodes} +
+ ); + } + +}); diff --git a/app/models/game.rb b/app/models/game.rb index 06d30910..bec05158 100644 --- a/app/models/game.rb +++ b/app/models/game.rb @@ -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 diff --git a/app/models/play.rb b/app/models/play.rb index 602b449b..f02c0592 100644 --- a/app/models/play.rb +++ b/app/models/play.rb @@ -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? diff --git a/app/views/games/show.html.haml b/app/views/games/show.html.haml index a8f9e917..44d3f965 100644 --- a/app/views/games/show.html.haml +++ b/app/views/games/show.html.haml @@ -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 diff --git a/app/views/games/show.json.jbuilder b/app/views/games/show.json.jbuilder index c064b1a8..7ce7e626 100644 --- a/app/views/games/show.json.jbuilder +++ b/app/views/games/show.json.jbuilder @@ -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 diff --git a/db/migrate/20151107111235_add_winner_player_id_to_game.rb b/db/migrate/20151107111235_add_winner_player_id_to_game.rb new file mode 100644 index 00000000..751441a5 --- /dev/null +++ b/db/migrate/20151107111235_add_winner_player_id_to_game.rb @@ -0,0 +1,5 @@ +class AddWinnerPlayerIdToGame < ActiveRecord::Migration + def change + add_column :games, :winner_player_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 8c663dad..af75c7e9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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 diff --git a/spec/models/play_spec.rb b/spec/models/play_spec.rb index 24905ce5..7791c804 100644 --- a/spec/models/play_spec.rb +++ b/spec/models/play_spec.rb @@ -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