Class: Gameworks::Game
- Inherits:
-
Object
- Object
- Gameworks::Game
- Defined in:
- lib/gameworks/game.rb,
lib/gameworks/game_snapshot.rb
Defined Under Namespace
Classes: Snapshot
Constant Summary collapse
- TURN_TIME_LIMIT =
30- DEFAULT_DELAY =
0.3- STATE_INITIATING =
'initiating'- STATE_IN_PLAY =
'in play'- STATE_COMPLETED =
'completed'
Instance Attribute Summary collapse
-
#delay_time ⇒ Object
readonly
Returns the value of attribute delay_time.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#notifier ⇒ Object
readonly
Returns the value of attribute notifier.
-
#players ⇒ Object
readonly
Returns the value of attribute players.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Instance Method Summary collapse
- #active_players ⇒ Object
- #add_move(payload, player) ⇒ Object
- #add_player(payload = {}) ⇒ Object
- #as_json(for_player = nil) ⇒ Object
- #build_move(payload, player) ⇒ Object
- #delta(snapshot, for_player = nil) ⇒ Object
- #disqualify(player) ⇒ Object
- #end_game ⇒ Object
- #full? ⇒ Boolean
- #generate_uuid ⇒ Object
- #ignore_disqualified_players ⇒ Object
- #init_game ⇒ Object
- #initial_snapshot ⇒ Object
-
#initialize(payload = {}) ⇒ Game
constructor
A new instance of Game.
- #move_legal?(move, player) ⇒ Boolean
- #player_changed?(player, snapshot, for_player = nil) ⇒ Boolean
- #player_class ⇒ Object
- #player_for_token(token) ⇒ Object
- #process_move(move, player) ⇒ Object
- #register_observer(cb) ⇒ Object
- #signal_turns ⇒ Object
- #snapshot ⇒ Object
- #snapshot_class ⇒ Object
- #snapshot_for_observer(token) ⇒ Object
- #start_if_ready ⇒ Object
- #to_json(for_player = nil) ⇒ Object
- #update_observers(end_game = false) ⇒ Object
Constructor Details
#initialize(payload = {}) ⇒ Game
Returns a new instance of Game.
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/gameworks/game.rb', line 17 def initialize(payload={}) @notifier = Notifier.new @players = [] @state = STATE_INITIATING @delay_time = payload['delay_time'] || DEFAULT_DELAY @turns = {} @observers = {} @fuses = {} @id = generate_uuid.split('-').first end |
Instance Attribute Details
#delay_time ⇒ Object (readonly)
Returns the value of attribute delay_time.
15 16 17 |
# File 'lib/gameworks/game.rb', line 15 def delay_time @delay_time end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
15 16 17 |
# File 'lib/gameworks/game.rb', line 15 def id @id end |
#notifier ⇒ Object (readonly)
Returns the value of attribute notifier.
15 16 17 |
# File 'lib/gameworks/game.rb', line 15 def notifier @notifier end |
#players ⇒ Object (readonly)
Returns the value of attribute players.
15 16 17 |
# File 'lib/gameworks/game.rb', line 15 def players @players end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
15 16 17 |
# File 'lib/gameworks/game.rb', line 15 def state @state end |
Instance Method Details
#active_players ⇒ Object
101 102 103 |
# File 'lib/gameworks/game.rb', line 101 def active_players raise NotImplementedError end |
#add_move(payload, player) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/gameworks/game.rb', line 125 def add_move(payload, player) @fuses[player].abort move, error = build_move(payload, player) return false, error unless move legal, error = move_legal?(move, player) return false, error unless legal legal, error = process_move(move, player) return false, error unless legal ignore_disqualified_players update_observers return true end |
#add_player(payload = {}) ⇒ Object
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/gameworks/game.rb', line 81 def add_player(payload={}) return false if full? player = player_class.new(payload) return false unless player.valid? @players << player update_observers player end |
#as_json(for_player = nil) ⇒ Object
177 178 179 180 |
# File 'lib/gameworks/game.rb', line 177 def as_json(for_player=nil) { :players => @players.map{ |player| player.as_json(for_player) }, :state => @state } end |
#build_move(payload, player) ⇒ Object
139 140 141 |
# File 'lib/gameworks/game.rb', line 139 def build_move(payload, player) raise NotImplementedError end |
#delta(snapshot, for_player = nil) ⇒ Object
60 61 62 63 |
# File 'lib/gameworks/game.rb', line 60 def delta(snapshot, for_player=nil) { :players => @players.select{ |p| player_changed?(p, snapshot, for_player) }.map{ |p| p.as_json(for_player) }, :state => @state } end |
#disqualify(player) ⇒ Object
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/gameworks/game.rb', line 151 def disqualify(player) player.disqualify! update_observers if @players.select { |p| !p.disqualified? }.size < 2 end_game else update_observers end_turn end end |
#end_game ⇒ Object
162 163 164 165 166 167 |
# File 'lib/gameworks/game.rb', line 162 def end_game @state = STATE_COMPLETED @fuses.values.each(&:abort) update_observers(true) @players.each{ |p| p.signal_turn(nil) } end |
#full? ⇒ Boolean
65 66 67 |
# File 'lib/gameworks/game.rb', line 65 def full? raise NotImplementedError end |
#generate_uuid ⇒ Object
97 98 99 |
# File 'lib/gameworks/game.rb', line 97 def generate_uuid SecureRandom.uuid end |
#ignore_disqualified_players ⇒ Object
105 106 107 |
# File 'lib/gameworks/game.rb', line 105 def ignore_disqualified_players @players.rotate! while @players.first.disqualified? end |
#init_game ⇒ Object
92 93 94 95 |
# File 'lib/gameworks/game.rb', line 92 def init_game @players.shuffle! @state = STATE_IN_PLAY end |
#initial_snapshot ⇒ Object
52 53 54 |
# File 'lib/gameworks/game.rb', line 52 def initial_snapshot @initial_snapshot ||= snapshot end |
#move_legal?(move, player) ⇒ Boolean
143 144 145 |
# File 'lib/gameworks/game.rb', line 143 def move_legal?(move, player) raise NotImplementedError end |
#player_changed?(player, snapshot, for_player = nil) ⇒ Boolean
56 57 58 |
# File 'lib/gameworks/game.rb', line 56 def player_changed?(player, snapshot, for_player=nil) player.score != snapshot.player_scores[player] end |
#player_class ⇒ Object
69 70 71 |
# File 'lib/gameworks/game.rb', line 69 def player_class Gameworks::Player end |
#player_for_token(token) ⇒ Object
121 122 123 |
# File 'lib/gameworks/game.rb', line 121 def player_for_token(token) @turns.delete(token) end |
#process_move(move, player) ⇒ Object
147 148 149 |
# File 'lib/gameworks/game.rb', line 147 def process_move(move, player) raise NotImplementedError end |
#register_observer(cb) ⇒ Object
28 29 30 31 32 |
# File 'lib/gameworks/game.rb', line 28 def register_observer(cb) token = generate_uuid @observers[token] = [self.snapshot, cb] token end |
#signal_turns ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/gameworks/game.rb', line 109 def signal_turns active_players.each do |player| token = generate_uuid @turns[token] = player # This may no longer be necessary, since we abort the players' fuses # when they submit turns in #add_move. @fuses[player].abort if @fuses[player] @fuses[player] = Gameworks::Fuse.new(TURN_TIME_LIMIT) { disqualify(player) } player.signal_turn(token) end end |
#snapshot ⇒ Object
173 174 175 |
# File 'lib/gameworks/game.rb', line 173 def snapshot snapshot_class.new(self) end |
#snapshot_class ⇒ Object
169 170 171 |
# File 'lib/gameworks/game.rb', line 169 def snapshot_class Gameworks::Game::Snapshot end |
#snapshot_for_observer(token) ⇒ Object
43 44 45 46 47 48 49 50 |
# File 'lib/gameworks/game.rb', line 43 def snapshot_for_observer(token) snapshot = nil if @observers.has_key?(token) snapshot, cb = @observers[token] @observers[token][0] = self.snapshot end snapshot end |
#start_if_ready ⇒ Object
73 74 75 76 77 78 79 |
# File 'lib/gameworks/game.rb', line 73 def start_if_ready if full? init_game signal_turns update_observers end end |
#to_json(for_player = nil) ⇒ Object
182 183 184 |
# File 'lib/gameworks/game.rb', line 182 def to_json(for_player=nil) as_json(for_player).to_json end |
#update_observers(end_game = false) ⇒ Object
34 35 36 37 38 39 40 41 |
# File 'lib/gameworks/game.rb', line 34 def update_observers(end_game = false) @observers.each do |token, (_, cb)| snapshot = snapshot_for_observer(token) cb.call(delta(snapshot).to_json) cb.succeed if end_game end notifier.push(self, delta(initial_snapshot).to_json) end |