class Gameworks::Game
Constants
- DEFAULT_DELAY
- STATE_COMPLETED
- STATE_INITIATING
- STATE_IN_PLAY
- TURN_TIME_LIMIT
Attributes
delay_time[R]
id[R]
moves[R]
notifier[R]
players[R]
state[R]
Public Class Methods
new(payload={})
click to toggle source
# 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 @moves = {} end
Public Instance Methods
active_players()
click to toggle source
# File lib/gameworks/game.rb, line 99 def active_players raise NotImplementedError end
add_move(payload, player)
click to toggle source
# File lib/gameworks/game.rb, line 124 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 moves[player] = move process_move(move, player) ignore_disqualified_players update_observers true end
add_player(payload={})
click to toggle source
# File lib/gameworks/game.rb, line 79 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)
click to toggle source
# File lib/gameworks/game.rb, line 183 def as_json(for_player=nil) { :id => id, :players => @players.map{ |player| player.as_json(for_player) }, :state => @state } end
build_move(payload, player)
click to toggle source
# File lib/gameworks/game.rb, line 141 def build_move(payload, player) raise NotImplementedError end
delta(snapshot, for_player=nil)
click to toggle source
# File lib/gameworks/game.rb, line 57 def delta(snapshot, for_player=nil) { :id => id, :players => @players.select{ |p| player_changed?(p, snapshot, for_player) }.map{ |p| p.as_json(for_player) }, :state => @state } end
disqualify(player)
click to toggle source
# File lib/gameworks/game.rb, line 157 def disqualify(player) player.disqualify! update_observers if @players.select { |p| !p.disqualified? }.size < 2 end_game elsif !waiting_on_moves? signal_turns end # else do nothing; waiting for other players end
end_game()
click to toggle source
# File lib/gameworks/game.rb, line 168 def end_game @state = STATE_COMPLETED @fuses.values.each(&:abort) update_observers(true) @players.each{ |p| p.signal_turn(nil) } end
full?()
click to toggle source
# File lib/gameworks/game.rb, line 63 def full? raise NotImplementedError end
generate_uuid()
click to toggle source
# File lib/gameworks/game.rb, line 95 def generate_uuid SecureRandom.uuid end
ignore_disqualified_players()
click to toggle source
# File lib/gameworks/game.rb, line 103 def ignore_disqualified_players @players.rotate! while @players.first.disqualified? end
init_game()
click to toggle source
# File lib/gameworks/game.rb, line 90 def init_game @players.shuffle! @state = STATE_IN_PLAY end
move_legal?(move, player)
click to toggle source
# File lib/gameworks/game.rb, line 145 def move_legal?(move, player) raise NotImplementedError end
player_changed?(player, snapshot, for_player=nil)
click to toggle source
# File lib/gameworks/game.rb, line 53 def player_changed?(player, snapshot, for_player=nil) player.score != snapshot.player_scores[player] end
player_class()
click to toggle source
# File lib/gameworks/game.rb, line 67 def player_class Gameworks::Player end
player_for_token(token)
click to toggle source
# File lib/gameworks/game.rb, line 120 def player_for_token(token) @turns.delete(token) end
process_move(move, player)
click to toggle source
# File lib/gameworks/game.rb, line 149 def process_move(move, player) raise NotImplementedError end
register_observer(cb)
click to toggle source
# File lib/gameworks/game.rb, line 29 def register_observer(cb) token = generate_uuid @observers[token] = [self.snapshot, cb] token end
signal_turns()
click to toggle source
# File lib/gameworks/game.rb, line 107 def signal_turns moves.clear 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()
click to toggle source
# File lib/gameworks/game.rb, line 179 def snapshot snapshot_class.new(self) end
snapshot_class()
click to toggle source
# File lib/gameworks/game.rb, line 175 def snapshot_class Gameworks::Game::Snapshot end
snapshot_for_observer(token)
click to toggle source
# File lib/gameworks/game.rb, line 44 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()
click to toggle source
# File lib/gameworks/game.rb, line 71 def start_if_ready if full? init_game signal_turns update_observers end end
to_json(for_player=nil)
click to toggle source
# File lib/gameworks/game.rb, line 189 def to_json(for_player=nil) as_json(for_player).to_json end
update_observers(end_game = false)
click to toggle source
# File lib/gameworks/game.rb, line 35 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, to_json) end
waiting_on_moves?()
click to toggle source
# File lib/gameworks/game.rb, line 153 def waiting_on_moves? (active_players - moves.keys).any? end