Skip to content

Instantly share code, notes, and snippets.

@danielholmstrom
Created July 30, 2012 09:58
Show Gist options
  • Save danielholmstrom/3205953 to your computer and use it in GitHub Desktop.
Save danielholmstrom/3205953 to your computer and use it in GitHub Desktop.
# poker app in sinatra+sequel
require 'sinatra'
require 'sinatra/flash'
require 'sinatra/sequel'
require "sinatra/reloader"
set :database, 'sqlite::memory'
enable :sessions
enable :logging
Tilt.register "html.erb", Tilt[:erb]
# Database migrations
migration "Create account, player and game database" do
database.create_table :accounts do
primary_key :id
text :name, :null => false
end
database.create_table :games do
primary_key :id
end
database.create_table :game_events do
int :game_id
int :player_id
created_at :created_at
end
database.create_table :players do
primary_key :id
int :game_id, :null => false
int :account_id, :null => false
end
end
# Models
class M
class Account < Sequel::Model
many_to_one :game
def validate
super
errors.add(:name, 'cannot be empty') if !name || name.empty?
end
end
class Player < Sequel::Model
one_to_one :game
one_to_one :account
set_primary_key [:game_id, :account_id]
end
class Game < Sequel::Model
many_to_one :player
one_to_many :event
end
class GameEvent < Sequel::Model
many_to_one :game
many_to_one :player
end
end
class E
class Player
def initialize(game, account_id)
@game = game
@account_id = account_id
# Save a player in db
player = M::Player.new
player.game_id = @game.id
player.account_id = @account_id
player.save
@player_id = player.id
end
def quit
# Means the game is over
end
end
class Game
@@games = []
class << self; attr_accessor :min_players end
@min_players = 8
attr_reader :id, :accounts, :players
def initialize(accounts)
# accounts is a list of account id:s
raise "Min players is #{@min_players}" if accounts.count < min_players
@accounts = accounts
@players = []
end
def min_players
Game.min_players
end
def start
# Starts and saves the game and the players
game = M::Game.new
game.save
@id = game.id
self.accounts.each do |id|
@players << E::Player.new(self, id)
end
end
def quit
# Quits the game
@players.each do |p| p.quit end
end
end
end
# Middleware
before do
# Assert that session is valid and assing session[:account_name] if the account
# is logged in
if session[:account_id]
account = M::Account[session[:account_id]]
unless account
logger.info "Found invalid session[:account_id] : #{session[:account_id]}"
flash[:error] = "You have been logged out."
session.clear
redirect('/')
end
session[:account_name] = account.name
end
end
# Routes
get '/' do
erb :index
end
post '/account/register' do
session[:account_id] and halt 405, "You are already registered"
if (params[:name] || nil).empty?
flash[:error] = "Parameter 'name' is required"
redirect to('/')
end
M::Account.filter(:name => params[:name]).first and halt 401, "An account with the name '#{params[:name].to_s}' already exists"
logger.info "New account '#{params[:name]}'"
account = M::Account.new :name => params[:name]
account.save
session[:account_id] = account.id
params[:autojoin] and redirect to('/')
redirect to('/')
end
get '/logout' do
unless session[:account_id]
flash[:error] = 'You are not logged in'
redirect('/')
end
account = M::Account[session[:account_id]]
account.delete
flash[:info] = "You were logged out"
session.clear
redirect('/')
end
get '/game/join' do
# Join a game
session[:account_id] or redirect to('/')
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment