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.
-
#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
-
#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.
16 17 18 19 20 21 22 23 24 |
# File 'lib/gameworks/game.rb', line 16 def initialize(payload={}) @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.
14 15 16 |
# File 'lib/gameworks/game.rb', line 14 def delay_time @delay_time end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
14 15 16 |
# File 'lib/gameworks/game.rb', line 14 def id @id end |
#players ⇒ Object (readonly)
Returns the value of attribute players.
14 15 16 |
# File 'lib/gameworks/game.rb', line 14 def players @players end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
14 15 16 |
# File 'lib/gameworks/game.rb', line 14 def state @state end |
Instance Method Details
#active_players ⇒ Object
94 95 96 |
# File 'lib/gameworks/game.rb', line 94 def active_players raise NotImplementedError end |
#add_move(payload, player) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/gameworks/game.rb', line 116 def add_move(payload, player) 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
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/gameworks/game.rb', line 74 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
166 167 168 169 |
# File 'lib/gameworks/game.rb', line 166 def as_json(for_player=nil) { :players => @players.map{ |player| player.as_json(for_player) }, :state => @state } end |
#build_move(payload, player) ⇒ Object
128 129 130 |
# File 'lib/gameworks/game.rb', line 128 def build_move(payload, player) raise NotImplementedError end |
#delta(snapshot, for_player = nil) ⇒ Object
53 54 55 56 |
# File 'lib/gameworks/game.rb', line 53 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
140 141 142 143 144 145 146 147 148 149 |
# File 'lib/gameworks/game.rb', line 140 def disqualify(player) player.score = 'disqualified' update_observers if @players.select { |p| !p.disqualified? }.size < 2 end_game else update_observers end_turn end end |
#end_game ⇒ Object
151 152 153 154 155 156 |
# File 'lib/gameworks/game.rb', line 151 def end_game @state = STATE_COMPLETED @fuses.values.each(&:abort) update_observers(true) @players.each{ |p| p.signal_turn(nil) } end |
#full? ⇒ Boolean
58 59 60 |
# File 'lib/gameworks/game.rb', line 58 def full? raise NotImplementedError end |
#generate_uuid ⇒ Object
90 91 92 |
# File 'lib/gameworks/game.rb', line 90 def generate_uuid SecureRandom.uuid end |
#ignore_disqualified_players ⇒ Object
98 99 100 |
# File 'lib/gameworks/game.rb', line 98 def ignore_disqualified_players @players.rotate! while @players.first.disqualified? end |
#init_game ⇒ Object
85 86 87 88 |
# File 'lib/gameworks/game.rb', line 85 def init_game @players.shuffle! @state = STATE_IN_PLAY end |
#move_legal?(move, player) ⇒ Boolean
132 133 134 |
# File 'lib/gameworks/game.rb', line 132 def move_legal?(move, player) raise NotImplementedError end |
#player_changed?(player, snapshot, for_player = nil) ⇒ Boolean
49 50 51 |
# File 'lib/gameworks/game.rb', line 49 def player_changed?(player, snapshot, for_player=nil) player.score != snapshot.player_scores[player] end |
#player_class ⇒ Object
62 63 64 |
# File 'lib/gameworks/game.rb', line 62 def player_class Gameworks::Player end |
#player_for_token(token) ⇒ Object
112 113 114 |
# File 'lib/gameworks/game.rb', line 112 def player_for_token(token) @turns.delete(token) end |
#process_move(move, player) ⇒ Object
136 137 138 |
# File 'lib/gameworks/game.rb', line 136 def process_move(move, player) raise NotImplementedError end |
#register_observer(cb) ⇒ Object
26 27 28 29 30 |
# File 'lib/gameworks/game.rb', line 26 def register_observer(cb) token = generate_uuid @observers[token] = [self.snapshot, cb] token end |
#signal_turns ⇒ Object
102 103 104 105 106 107 108 109 110 |
# File 'lib/gameworks/game.rb', line 102 def signal_turns active_players.each do |player| token = generate_uuid @turns[token] = player @fuses[player].abort if @fuses[player] @fuses[player] = Gameworks::Fuse.new(TURN_TIME_LIMIT) { disqualify(player) } player.signal_turn(token) end end |
#snapshot ⇒ Object
162 163 164 |
# File 'lib/gameworks/game.rb', line 162 def snapshot snapshot_class.new(self) end |
#snapshot_class ⇒ Object
158 159 160 |
# File 'lib/gameworks/game.rb', line 158 def snapshot_class Gameworks::Game::Snapshot end |
#snapshot_for_observer(token) ⇒ Object
40 41 42 43 44 45 46 47 |
# File 'lib/gameworks/game.rb', line 40 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
66 67 68 69 70 71 72 |
# File 'lib/gameworks/game.rb', line 66 def start_if_ready if full? init_game signal_turns update_observers end end |
#to_json(for_player = nil) ⇒ Object
171 172 173 |
# File 'lib/gameworks/game.rb', line 171 def to_json(for_player=nil) as_json(for_player).to_json end |
#update_observers(end_game = false) ⇒ Object
32 33 34 35 36 37 38 |
# File 'lib/gameworks/game.rb', line 32 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 end |