Class: MailChess::Game
- Inherits:
-
Object
- Object
- MailChess::Game
- Defined in:
- lib/mail_chess/game.rb
Overview
Represents a chess game.
Instance Attribute Summary collapse
-
#board ⇒ Object
readonly
Board belongs to this game.
-
#current ⇒ Object
Current player’s color.
-
#id ⇒ Object
readonly
Game ID in database.
-
#initiator ⇒ Object
readonly
Who tries to move.
-
#players ⇒ Object
readonly
Players hash.
-
#reference ⇒ Object
readonly
Game reference.
Class Method Summary collapse
-
.create_tables(db) ⇒ Object
Create tables.
-
.load!(db, filter, value, initiator) ⇒ Object
Load game from database.
-
.need_to_create_tables?(db) ⇒ Boolean
Checks if needed to create tables.
-
.new!(db, white, black, reference) ⇒ Object
Create a new game object and save it to database.
Instance Method Summary collapse
-
#delete! ⇒ Object
Delete game –
save!
won’t fix it!. -
#initialize(db, game_id, initiator) ⇒ Game
constructor
Create a new Game object.
-
#perform!(move) ⇒ Object
Perform the move.
-
#save! ⇒ Object
Save game – update the
current
field.
Constructor Details
#initialize(db, game_id, initiator) ⇒ Game
Create a new Game object.
Arguments:
db: Sequel database object
game_id: (Integer)
initiator: (Symbol) :white or :black
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/mail_chess/game.rb', line 33 def initialize db, game_id, initiator @db = db Game.create_tables(@db) if Game.need_to_create_tables?(@db) @db_entry = @db[:games].filter(:id => game_id).first @id = @db_entry[:id].to_i @reference = @db_entry[:reference] @current = @db_entry[:current].to_sym @board = Board.load! @db, :id, @db_entry[:board_id] @players = Hash.new @db[:pairs].filter(:game_id => @id).all.each do |p| @players[p[:color].to_sym] = Player.load!(@db, :id, p[:player_id].to_i) end @initiator = initiator end |
Instance Attribute Details
#board ⇒ Object (readonly)
Board belongs to this game.
16 17 18 |
# File 'lib/mail_chess/game.rb', line 16 def board @board end |
#current ⇒ Object
Current player’s color.
22 23 24 |
# File 'lib/mail_chess/game.rb', line 22 def current @current end |
#id ⇒ Object (readonly)
Game ID in database.
10 11 12 |
# File 'lib/mail_chess/game.rb', line 10 def id @id end |
#initiator ⇒ Object (readonly)
Who tries to move.
25 26 27 |
# File 'lib/mail_chess/game.rb', line 25 def initiator @initiator end |
#players ⇒ Object (readonly)
Players hash. (keys: :white, :black)
19 20 21 |
# File 'lib/mail_chess/game.rb', line 19 def players @players end |
#reference ⇒ Object (readonly)
Game reference.
13 14 15 |
# File 'lib/mail_chess/game.rb', line 13 def reference @reference end |
Class Method Details
.create_tables(db) ⇒ Object
Create tables.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/mail_chess/game.rb', line 62 def self.create_tables db db.create_table? :boards do primary_key :id end db.create_table? :games do primary_key :id String :reference String :current foreign_key :board_id, :boards, :key => :id end db.create_table? :players do primary_key :id String :name String :email end db.create_table? :pairs do primary_key :id foreign_key :player_id, :players, :key => :id foreign_key :game_id, :games, :key => :id String :color end end |
.load!(db, filter, value, initiator) ⇒ Object
Load game from database.
Arguments:
db: Sequel database object
filter: (Symbol) :id or :reference
value: filters value
initiator: (Symbol) :white or :black
Returns: (Game)
123 124 125 126 127 128 129 130 |
# File 'lib/mail_chess/game.rb', line 123 def self.load! db, filter, value, initiator raise ArgumentError unless [:id, :reference].index(filter) dataset = db[:games].filter(filter => value) return nil unless dataset.all.size == 1 id = dataset.first[:id] return Game.new db, id, initiator end |
.need_to_create_tables?(db) ⇒ Boolean
Checks if needed to create tables.
Returns: (Boolean)
56 57 58 59 |
# File 'lib/mail_chess/game.rb', line 56 def self.need_to_create_tables? db return (db.tables + [:boards, :games, :players, :pairs]).uniq.size != db.tables.size end |
.new!(db, white, black, reference) ⇒ Object
Create a new game object and save it to database.
Arguments:
db: Sequel database object
white: (Player) first player
black: (Player) second player
reference: (String)
Returns: (Game)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/mail_chess/game.rb', line 97 def self.new! db, white, black, reference Game.create_tables(db) if Game.need_to_create_tables?(db) b = Board.new! db id = db[:games].insert(:reference => reference, :current => 'white', :board_id => b.id) db[:pairs].insert(:player_id => white.id, :game_id => id, :color => 'white') db[:pairs].insert(:player_id => black.id, :game_id => id, :color => 'black') return Game.new db, id, :white end |
Instance Method Details
#delete! ⇒ Object
Delete game – save!
won’t fix it!
138 139 140 141 142 143 |
# File 'lib/mail_chess/game.rb', line 138 def delete! @board.delete! @db[:pairs].filter(:game_id => @id).delete @db[:games].filter(:id => @id).delete @db[:boards].filter(:id => @board.id).delete end |
#perform!(move) ⇒ Object
Perform the move.
Arguments:
move: (String) eg.: e2e4
Exceptions:
(MoveError) if move is invalid
(TurnError) if this is not the requester's turn
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/mail_chess/game.rb', line 153 def perform! move from, to = move[0] + move[1], move[2] + move[3] p = @board.pieces[from] k = nil @board.pieces.values.each do |piece| k = piece if piece.type == 'king' and piece.color == @current end raise TurnError.new('not your turn') if @initiator != @current raise MoveError.new('piece not exists') if p == nil raise MoveError.new('not your piece') if p.color != @current raise MoveError.new('invalid move') if !p.can_move?(to) & !p.can_hit?(to) old_p = @board.pieces[to] p.move to raise MoveError.new('checkmate') if k.in_checkmate? raise MoveError.new('king in check') if k.in_check? old_p.delete! if old_p @current = (@current == :white ? :black : :white) @board.save! save! end |
#save! ⇒ Object
Save game – update the current
field.
133 134 135 |
# File 'lib/mail_chess/game.rb', line 133 def save! @db[:games].filter(:id => @id).update(:current => current.to_s) end |