Created
July 30, 2012 09:59
-
-
Save danielholmstrom/3205956 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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