mail_chess 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +3 -0
- data/Rakefile +12 -0
- data/lib/mail_chess/board.rb +222 -0
- data/lib/mail_chess/game.rb +139 -0
- data/lib/mail_chess/pieces/base.rb +118 -0
- data/lib/mail_chess/pieces/bishop.rb +30 -0
- data/lib/mail_chess/pieces/king.rb +30 -0
- data/lib/mail_chess/pieces/knight.rb +31 -0
- data/lib/mail_chess/pieces/pawn.rb +30 -0
- data/lib/mail_chess/pieces/queen.rb +31 -0
- data/lib/mail_chess/pieces/rook.rb +31 -0
- data/lib/mail_chess/player.rb +100 -0
- data/lib/mail_chess.rb +13 -0
- data/test/db_operations_test.rb +56 -0
- metadata +74 -0
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
# Columns of a chessboard
|
8
|
+
COLS = %w[a b c d e f g h]
|
9
|
+
|
10
|
+
# Rows of a chessboard
|
11
|
+
ROWS = %w[8 7 6 5 4 3 2 1]
|
12
|
+
|
13
|
+
# Represents a chessboard.
|
14
|
+
class Board
|
15
|
+
# Board ID in database.
|
16
|
+
attr_reader :id
|
17
|
+
|
18
|
+
# Board itself.
|
19
|
+
attr_accessor :board
|
20
|
+
|
21
|
+
# Pieces on this board.
|
22
|
+
attr_accessor :pieces
|
23
|
+
|
24
|
+
# Create a new Board object.
|
25
|
+
#
|
26
|
+
# Arguments:
|
27
|
+
# db: Sequel database object
|
28
|
+
# board_id: (Integer)
|
29
|
+
def initialize db, board_id
|
30
|
+
@db = db
|
31
|
+
|
32
|
+
Board.create_tables(@db) if Board.need_to_create_tables?(@db)
|
33
|
+
|
34
|
+
@db_entry = @db[:boards].filter(:id => board_id).first
|
35
|
+
|
36
|
+
@id = @db_entry[:id].to_i
|
37
|
+
@pieces = {}
|
38
|
+
@db[:pieces].filter(:board_id => @id).all.each do |p|
|
39
|
+
Piece::Piece.load! db, p[:id], self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Checks if needed to create tables.
|
44
|
+
#
|
45
|
+
# Returns: (Boolean)
|
46
|
+
def self.need_to_create_tables? db
|
47
|
+
return (db.tables + [:boards, :pieces]).uniq.size != db.tables.size
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create tables.
|
51
|
+
def self.create_tables db
|
52
|
+
db.create_table? :boards do
|
53
|
+
primary_key :id
|
54
|
+
end
|
55
|
+
|
56
|
+
db.create_table? :pieces do
|
57
|
+
primary_key :id
|
58
|
+
String :type
|
59
|
+
String :color
|
60
|
+
String :position
|
61
|
+
foreign_key :board_id, :boards, :key => :id
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Create new board object and save it to database.
|
66
|
+
#
|
67
|
+
# Arguments:
|
68
|
+
# db: Sequel database object
|
69
|
+
#
|
70
|
+
# Returns: (Board)
|
71
|
+
def self.new! db
|
72
|
+
Board.create_tables(db) if Board.need_to_create_tables?(db)
|
73
|
+
|
74
|
+
id = db[:boards].insert
|
75
|
+
|
76
|
+
return Board.new db, id
|
77
|
+
end
|
78
|
+
|
79
|
+
# Load game from database.
|
80
|
+
#
|
81
|
+
# Arguments:
|
82
|
+
# db: Sequel database object
|
83
|
+
# filter: (Symbol) :id only (for now)
|
84
|
+
# value: filters value
|
85
|
+
#
|
86
|
+
# Returns: (Board)
|
87
|
+
def self.load! db, filter, value
|
88
|
+
raise ArgumentError unless [:id, :reference].index(filter)
|
89
|
+
dataset = db[:games].filter(filter => value)
|
90
|
+
raise ArgumentError unless dataset.all.size == 1
|
91
|
+
|
92
|
+
id = dataset.first[:id]
|
93
|
+
|
94
|
+
b = Board.new db, id
|
95
|
+
|
96
|
+
return b
|
97
|
+
end
|
98
|
+
|
99
|
+
# Save game -- save the pieces.
|
100
|
+
def save!
|
101
|
+
pieces.values.each do |p|
|
102
|
+
p.save!
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Delete game -- +save!+ won't fix it!
|
107
|
+
def delete!
|
108
|
+
pieces.values.each do |p|
|
109
|
+
p.delete!
|
110
|
+
end
|
111
|
+
|
112
|
+
# board deleted in Game class
|
113
|
+
end
|
114
|
+
|
115
|
+
# Add a new piece to board.
|
116
|
+
#
|
117
|
+
# Arguments:
|
118
|
+
# field: (String)
|
119
|
+
# piece: (Piece)
|
120
|
+
#
|
121
|
+
# Returns: (Piece)
|
122
|
+
def add field, piece
|
123
|
+
@pieces[field] = piece
|
124
|
+
|
125
|
+
return piece
|
126
|
+
end
|
127
|
+
|
128
|
+
# Removes a piece from board.
|
129
|
+
#
|
130
|
+
# Arguments:
|
131
|
+
# field: (String)
|
132
|
+
#
|
133
|
+
# Returns: (Piece)
|
134
|
+
def remove field
|
135
|
+
piece = @pieces[field]
|
136
|
+
@pieces.delete(field)
|
137
|
+
|
138
|
+
return piece
|
139
|
+
end
|
140
|
+
|
141
|
+
# Place the start position of pieces.
|
142
|
+
def start!
|
143
|
+
COLS.each do |c|
|
144
|
+
Piece::Pawn.new!(@db, self, c + '2', :white)
|
145
|
+
Piece::Pawn.new!(@db, self, c + '7', :black)
|
146
|
+
end
|
147
|
+
|
148
|
+
%w[a h].each do |c|
|
149
|
+
Piece::Rook.new!(@db, self, c + '1', :white)
|
150
|
+
Piece::Rook.new!(@db, self, c + '8', :black)
|
151
|
+
end
|
152
|
+
|
153
|
+
%w[b g].each do |c|
|
154
|
+
Piece::Knight.new!(@db, self, c + '1', :white)
|
155
|
+
Piece::Knight.new!(@db, self, c + '8', :black)
|
156
|
+
end
|
157
|
+
|
158
|
+
%w[c f].each do |c|
|
159
|
+
Piece::Bishop.new!(@db, self, c + '1', :white)
|
160
|
+
Piece::Bishop.new!(@db, self, c + '8', :black)
|
161
|
+
end
|
162
|
+
|
163
|
+
Piece::Queen.new!(@db, self, 'd1', :white)
|
164
|
+
Piece::Queen.new!(@db, self, 'd8', :black)
|
165
|
+
|
166
|
+
Piece::King.new!(@db, self, 'e1', :white)
|
167
|
+
Piece::King.new!(@db, self, 'e8', :black)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Generate HTML output.
|
171
|
+
#
|
172
|
+
# Attributes:
|
173
|
+
# player: (Symbol) which view
|
174
|
+
#
|
175
|
+
# Returns: (String)
|
176
|
+
def to_html player = :white
|
177
|
+
result = '<table border="0" cellpadding="0" cellspacing="0">'
|
178
|
+
result << '<tr height="40"><td align="center" width="40"></td>'
|
179
|
+
|
180
|
+
cols = (player == :white ? COLS : COLS.reverse)
|
181
|
+
cols.each do |c|
|
182
|
+
result << '<td align="center" width="40"><b>'
|
183
|
+
result << c.capitalize + '</b></td>'
|
184
|
+
end
|
185
|
+
result << '<td align="center" width="40"></td></tr>'
|
186
|
+
|
187
|
+
rows = (player == :white ? ROWS : ROWS.reverse)
|
188
|
+
start_color = :white
|
189
|
+
|
190
|
+
rows.each do |r|
|
191
|
+
result << '<tr height="40"><td align="center"><b>' + r + '</b></td>'
|
192
|
+
cell_color = start_color
|
193
|
+
cols.each do |c|
|
194
|
+
result << '<td align="center" bgcolor="'
|
195
|
+
result << (cell_color == :white ? '#ffffff' : '#d0d0d0')
|
196
|
+
result << '">'
|
197
|
+
|
198
|
+
if @pieces[c + r]
|
199
|
+
result << '<font size="6">'
|
200
|
+
result << @pieces[c + r].html
|
201
|
+
result << '</font>'
|
202
|
+
end
|
203
|
+
result << '</td>'
|
204
|
+
cell_color = (cell_color == :white ? :black : :white)
|
205
|
+
end
|
206
|
+
result << '<td align="center"><b>' + r + '</b></td></tr>'
|
207
|
+
start_color = (start_color == :white ? :black : :white)
|
208
|
+
end
|
209
|
+
|
210
|
+
result << '<tr height="40"><td align="center" width="40"></td>'
|
211
|
+
cols.each do |c|
|
212
|
+
result << '<td align="center" width="40"><b>'
|
213
|
+
result << c.capitalize + '</b></td>'
|
214
|
+
end
|
215
|
+
result << '<td align="center" width="40"></td></tr>'
|
216
|
+
|
217
|
+
result << '</table>'
|
218
|
+
|
219
|
+
return result
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
# Represents a chess game.
|
8
|
+
class Game
|
9
|
+
# Game ID in database.
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
# Game reference.
|
13
|
+
attr_reader :reference
|
14
|
+
|
15
|
+
# Board belongs to this game.
|
16
|
+
attr_reader :board
|
17
|
+
|
18
|
+
# Players hash. (keys: :white, :black)
|
19
|
+
attr_reader :players
|
20
|
+
|
21
|
+
# Current player's color.
|
22
|
+
attr_accessor :current
|
23
|
+
|
24
|
+
# Create a new Game object.
|
25
|
+
#
|
26
|
+
# Arguments:
|
27
|
+
# db: Sequel database object
|
28
|
+
# game_id: (Integer)
|
29
|
+
def initialize db, game_id
|
30
|
+
@db = db
|
31
|
+
|
32
|
+
Game.create_tables(@db) if Game.need_to_create_tables?(@db)
|
33
|
+
|
34
|
+
@db_entry = @db[:games].filter(:id => game_id).first
|
35
|
+
|
36
|
+
@id = @db_entry[:id].to_i
|
37
|
+
@reference = @db_entry[:reference]
|
38
|
+
@current = @db_entry[:current].to_sym
|
39
|
+
@board = Board.load! @db, :id, @db_entry[:board_id]
|
40
|
+
|
41
|
+
@players = Hash.new
|
42
|
+
@db[:pairs].filter(:game_id => @id).all.each do |p|
|
43
|
+
@players[p[:color].to_sym] = Player.load!(@db, :id, p[:player_id].to_i)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# Checks if needed to create tables.
|
49
|
+
#
|
50
|
+
# Returns: (Boolean)
|
51
|
+
def self.need_to_create_tables? db
|
52
|
+
return (db.tables + [:boards, :games, :players,
|
53
|
+
:pairs]).uniq.size != db.tables.size
|
54
|
+
end
|
55
|
+
|
56
|
+
# Create tables.
|
57
|
+
def self.create_tables db
|
58
|
+
db.create_table? :boards do
|
59
|
+
primary_key :id
|
60
|
+
end
|
61
|
+
|
62
|
+
db.create_table? :games do
|
63
|
+
primary_key :id
|
64
|
+
String :reference
|
65
|
+
String :current
|
66
|
+
foreign_key :board_id, :boards, :key => :id
|
67
|
+
end
|
68
|
+
|
69
|
+
db.create_table? :players do
|
70
|
+
primary_key :id
|
71
|
+
String :name
|
72
|
+
String :email
|
73
|
+
end
|
74
|
+
|
75
|
+
db.create_table? :pairs do
|
76
|
+
primary_key :id
|
77
|
+
foreign_key :player_id, :players, :key => :id
|
78
|
+
foreign_key :game_id, :games, :key => :id
|
79
|
+
String :color
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Create a new game object and save it to database.
|
84
|
+
#
|
85
|
+
# Arguments:
|
86
|
+
# db: Sequel database object
|
87
|
+
# white: (Player) first player
|
88
|
+
# black: (Player) second player
|
89
|
+
# reference: (String)
|
90
|
+
#
|
91
|
+
# Returns: (Game)
|
92
|
+
def self.new! db, white, black, reference
|
93
|
+
Game.create_tables(db) if Game.need_to_create_tables?(db)
|
94
|
+
|
95
|
+
b = Board.new! db
|
96
|
+
id = db[:games].insert(:reference => reference,
|
97
|
+
:current => 'white',
|
98
|
+
:board_id => b.id)
|
99
|
+
db[:pairs].insert(:player_id => white.id,
|
100
|
+
:game_id => id,
|
101
|
+
:color => 'white')
|
102
|
+
db[:pairs].insert(:player_id => black.id,
|
103
|
+
:game_id => id,
|
104
|
+
:color => 'black')
|
105
|
+
|
106
|
+
return Game.new db, id
|
107
|
+
end
|
108
|
+
|
109
|
+
# Load game from database.
|
110
|
+
#
|
111
|
+
# Arguments:
|
112
|
+
# db: Sequel database object
|
113
|
+
# filter: (Symbol) :id or :reference
|
114
|
+
# value: filters value
|
115
|
+
#
|
116
|
+
# Returns: (Game)
|
117
|
+
def self.load! db, filter, value
|
118
|
+
raise ArgumentError unless [:id, :reference].index(filter)
|
119
|
+
dataset = db[:games].filter(filter => value)
|
120
|
+
return nil unless dataset.all.size == 1
|
121
|
+
id = dataset.first[:id]
|
122
|
+
|
123
|
+
return Game.new db, id
|
124
|
+
end
|
125
|
+
|
126
|
+
# Save game -- update the +current+ field.
|
127
|
+
def save!
|
128
|
+
@db[:games].filter(:id => @id).update(:current => current.to_s)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Delete game -- +save!+ won't fix it!
|
132
|
+
def delete!
|
133
|
+
@board.delete!
|
134
|
+
@db[:pairs].filter(:game_id => @id).delete
|
135
|
+
@db[:games].filter(:id => @id).delete
|
136
|
+
@db[:boards].filter(:id => @board.id).delete
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
module Piece
|
8
|
+
# Represents a chesspiece.
|
9
|
+
class Piece
|
10
|
+
# Piece ID in database.
|
11
|
+
attr_reader :id
|
12
|
+
|
13
|
+
# Piece type.
|
14
|
+
attr_reader :type
|
15
|
+
|
16
|
+
# Piece color.
|
17
|
+
attr_reader :color
|
18
|
+
|
19
|
+
# Board where this piece standing.
|
20
|
+
attr_reader :board
|
21
|
+
|
22
|
+
# HTML tag of this piece.
|
23
|
+
attr_reader :html
|
24
|
+
|
25
|
+
# Create a new Piece object.
|
26
|
+
#
|
27
|
+
# Arguments:
|
28
|
+
# db: Sequel database object
|
29
|
+
# piece_id: (Integer)
|
30
|
+
def initialize db, piece_id, board
|
31
|
+
@db = db
|
32
|
+
|
33
|
+
Piece.create_tables(@db) if Piece.need_to_create_tables?(@db)
|
34
|
+
|
35
|
+
@db_entry = @db[:pieces].filter(:id => piece_id).first
|
36
|
+
|
37
|
+
@id = @db_entry[:id].to_i
|
38
|
+
@type = @db_entry[:type]
|
39
|
+
@color = @db_entry[:color].to_sym
|
40
|
+
@board = board
|
41
|
+
@board.add @db_entry[:position], self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Checks if needed to create tables.
|
45
|
+
#
|
46
|
+
# Returns: (Boolean)
|
47
|
+
def self.need_to_create_tables? db
|
48
|
+
return (db.tables + [:boards, :pieces]).uniq.size != db.tables.size
|
49
|
+
end
|
50
|
+
|
51
|
+
# Create tables.
|
52
|
+
def self.create_tables db
|
53
|
+
db.create_table? :boards do
|
54
|
+
primary_key :id
|
55
|
+
end
|
56
|
+
|
57
|
+
db.create_table? :pieces do
|
58
|
+
primary_key :id
|
59
|
+
String :type
|
60
|
+
String :color
|
61
|
+
String :position
|
62
|
+
foreign_key :board_id, :boards, :key => :id
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Find out the position of this piece.
|
67
|
+
#
|
68
|
+
# Returns: (String)
|
69
|
+
def position
|
70
|
+
return @board.pieces.key(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
# ABSTRACT Create a new piece and add to a table.
|
74
|
+
#
|
75
|
+
# Arguments:
|
76
|
+
# db: Sequel database object
|
77
|
+
# board: (Board)
|
78
|
+
# position: (String) eg.: 'f3'
|
79
|
+
# color: (Symbol) :white or :black
|
80
|
+
#
|
81
|
+
# Returns: (Piece)
|
82
|
+
def self.new! db, board, position, color
|
83
|
+
Piece.create_tables(db) if Piece.need_to_create_tables?(db)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Load the pieces to a board.
|
87
|
+
#
|
88
|
+
# Arguments:
|
89
|
+
# db: Sequel database object
|
90
|
+
# board: (Board)
|
91
|
+
#
|
92
|
+
# Returns: (Piece)
|
93
|
+
def self.load! db, piece_id, board
|
94
|
+
p = db[:pieces].filter(:id => piece_id).first
|
95
|
+
color = p[:color].to_sym
|
96
|
+
position = p[:position]
|
97
|
+
case p[:type]
|
98
|
+
when 'bishop' then Bishop.new(db, piece_id, board)
|
99
|
+
when 'king' then King.new(db, piece_id, board)
|
100
|
+
when 'knight' then Knight.new(db, piece_id, board)
|
101
|
+
when 'pawn' then Pawn.new(db, piece_id, board)
|
102
|
+
when 'rook' then Rook.new(db, piece_id, board)
|
103
|
+
when 'queen' then Queen.new(db, piece_id, board)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Save piece -- position.
|
108
|
+
def save!
|
109
|
+
@db[:pieces].filter(:id => @id).update(:position => position)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Delete piece -- +save!+ won't fix it!
|
113
|
+
def delete!
|
114
|
+
@db[:pieces].filter(:id => @id).delete
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
module Piece
|
8
|
+
# Represents a bishop chess piece.
|
9
|
+
class Bishop < Piece
|
10
|
+
# Calls the superclass.
|
11
|
+
def initialize db, piece_id, board = nil
|
12
|
+
super db, piece_id, board
|
13
|
+
|
14
|
+
@html = @color == :white ? '♗' : '♝'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Overwrite superclass method.
|
18
|
+
def self.new! db, board, position, color
|
19
|
+
super db, board, position, color
|
20
|
+
|
21
|
+
id = db[:pieces].insert(:type => 'bishop',
|
22
|
+
:color => color.to_s,
|
23
|
+
:position => position,
|
24
|
+
:board_id => board.id)
|
25
|
+
|
26
|
+
return Bishop.new db, id, board
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
module Piece
|
8
|
+
# Represents a king chess piece.
|
9
|
+
class King < Piece
|
10
|
+
# Calls the superclass.
|
11
|
+
def initialize db, piece_id, board = nil
|
12
|
+
super db, piece_id, board
|
13
|
+
|
14
|
+
@html = @color == :white ? '♔' : '♚'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Overwrite superclass method.
|
18
|
+
def self.new! db, board, position, color
|
19
|
+
super db, board, position, color
|
20
|
+
|
21
|
+
id = db[:pieces].insert(:type => 'king',
|
22
|
+
:color => color.to_s,
|
23
|
+
:position => position,
|
24
|
+
:board_id => board.id)
|
25
|
+
|
26
|
+
return King.new db, id, board
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
module Piece
|
8
|
+
# Represents a knight chess piece.
|
9
|
+
class Knight < Piece
|
10
|
+
# Calls the superclass.
|
11
|
+
def initialize db, piece_id, board = nil
|
12
|
+
super db, piece_id, board
|
13
|
+
|
14
|
+
@html = @color == :white ? '♘' : '♞'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Overwrite superclass method.
|
18
|
+
def self.new! db, board, position, color
|
19
|
+
super db, board, position, color
|
20
|
+
|
21
|
+
id = db[:pieces].insert(:type => 'knight',
|
22
|
+
:color => color.to_s,
|
23
|
+
:position => position,
|
24
|
+
:board_id => board.id)
|
25
|
+
|
26
|
+
return Knight.new db, id, board
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
module Piece
|
8
|
+
# Represents a pawn chess piece.
|
9
|
+
class Pawn < Piece
|
10
|
+
# Calls the superclass.
|
11
|
+
def initialize db, piece_id, board = nil
|
12
|
+
super db, piece_id, board
|
13
|
+
|
14
|
+
@html = @color == :white ? '♙' : '♟'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Overwrite superclass method.
|
18
|
+
def self.new! db, board, position, color
|
19
|
+
super db, board, position, color
|
20
|
+
|
21
|
+
id = db[:pieces].insert(:type => 'pawn',
|
22
|
+
:color => color.to_s,
|
23
|
+
:position => position,
|
24
|
+
:board_id => board.id)
|
25
|
+
|
26
|
+
return Pawn.new db, id, board
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
module Piece
|
8
|
+
# Represents a queen chess piece.
|
9
|
+
class Queen < Piece
|
10
|
+
# Calls the superclass.
|
11
|
+
def initialize db, piece_id, board = nil
|
12
|
+
super db, piece_id, board
|
13
|
+
|
14
|
+
@html = @color == :white ? '♕' : '♛'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Overwrite superclass method.
|
18
|
+
def self.new! db, board, position, color
|
19
|
+
super db, board, position, color
|
20
|
+
|
21
|
+
id = db[:pieces].insert(:type => 'queen',
|
22
|
+
:color => color.to_s,
|
23
|
+
:position => position,
|
24
|
+
:board_id => board.id)
|
25
|
+
|
26
|
+
return Queen.new db, id, board
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
module Piece
|
8
|
+
# Represents a rook chess piece.
|
9
|
+
class Rook < Piece
|
10
|
+
# Calls the superclass.
|
11
|
+
def initialize db, piece_id, board = nil
|
12
|
+
super db, piece_id, board
|
13
|
+
|
14
|
+
@html = @color == :white ? '♖' : '♜'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Overwrite superclass method.
|
18
|
+
def self.new! db, board, position, color
|
19
|
+
super db, board, position, color
|
20
|
+
|
21
|
+
id = db[:pieces].insert(:type => 'rook',
|
22
|
+
:color => color.to_s,
|
23
|
+
:position => position,
|
24
|
+
:board_id => board.id)
|
25
|
+
|
26
|
+
return Rook.new db, id, board
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess'
|
4
|
+
require 'sequel'
|
5
|
+
|
6
|
+
module MailChess
|
7
|
+
# Represents a player with an email account.
|
8
|
+
class Player
|
9
|
+
# Player ID in the database.
|
10
|
+
attr_reader :id
|
11
|
+
|
12
|
+
# Player name.
|
13
|
+
attr_accessor :name
|
14
|
+
|
15
|
+
# Player email address.
|
16
|
+
attr_reader :email
|
17
|
+
|
18
|
+
# Create a new Player object.
|
19
|
+
#
|
20
|
+
# Arguments:
|
21
|
+
# db: Sequel database object
|
22
|
+
# player_id: (Integer)
|
23
|
+
def initialize db, player_id
|
24
|
+
@db = db
|
25
|
+
|
26
|
+
Player.create_tables(@db) if Player.need_to_create_tables?(@db)
|
27
|
+
|
28
|
+
@db_entry = @db[:players].filter(:id => player_id).first
|
29
|
+
|
30
|
+
@id = @db_entry[:id].to_i
|
31
|
+
@name = @db_entry[:name]
|
32
|
+
@email = @db_entry[:email]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Checks if needed to create tables.
|
36
|
+
#
|
37
|
+
# Returns: (Boolean)
|
38
|
+
def self.need_to_create_tables? db
|
39
|
+
return (db.tables + [:players]).uniq.size != db.tables.size
|
40
|
+
end
|
41
|
+
|
42
|
+
# Create tables.
|
43
|
+
def self.create_tables db
|
44
|
+
db.create_table? :players do
|
45
|
+
primary_key :id
|
46
|
+
String :name
|
47
|
+
String :email
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Create a new player object and save it to the database.
|
52
|
+
#
|
53
|
+
# Arguments:
|
54
|
+
# db: Sequel database object
|
55
|
+
# email: (String) players email address
|
56
|
+
# name: (String) players name
|
57
|
+
#
|
58
|
+
# Returns: (Player)
|
59
|
+
def self.new! db, email, name = ""
|
60
|
+
Player.create_tables(db) if Player.need_to_create_tables?(db)
|
61
|
+
|
62
|
+
id = db[:players].insert(:name => name, :email => email)
|
63
|
+
|
64
|
+
return Player.new db, id
|
65
|
+
end
|
66
|
+
|
67
|
+
# Load player from database.
|
68
|
+
#
|
69
|
+
# Arguments:
|
70
|
+
# db: Sequel database object
|
71
|
+
# filter: (Symbol) :id or :email
|
72
|
+
# value: filters value
|
73
|
+
#
|
74
|
+
# Returns: (Player)
|
75
|
+
def self.load! db, filter, value
|
76
|
+
raise ArgumentError unless [:id, :email].index(filter)
|
77
|
+
dataset = db[:players].filter(filter => value)
|
78
|
+
raise ArgumentError unless dataset.all.size == 1
|
79
|
+
|
80
|
+
id = dataset.first[:id]
|
81
|
+
|
82
|
+
return Player.new db, id
|
83
|
+
end
|
84
|
+
|
85
|
+
# Find player's game by a reference string.
|
86
|
+
#
|
87
|
+
# Arguments:
|
88
|
+
# reference: (String) game reference string
|
89
|
+
#
|
90
|
+
# Returns: (Game) or nil
|
91
|
+
def game reference
|
92
|
+
return Game.load! @db, :reference, reference
|
93
|
+
end
|
94
|
+
|
95
|
+
# Save player -- name only
|
96
|
+
def save!
|
97
|
+
@db[:players].filter(:id => @id).update(:name => @name)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/mail_chess.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mail_chess/board'
|
4
|
+
require 'mail_chess/game'
|
5
|
+
require 'mail_chess/player'
|
6
|
+
|
7
|
+
require 'mail_chess/pieces/base'
|
8
|
+
require 'mail_chess/pieces/bishop'
|
9
|
+
require 'mail_chess/pieces/king'
|
10
|
+
require 'mail_chess/pieces/knight'
|
11
|
+
require 'mail_chess/pieces/pawn'
|
12
|
+
require 'mail_chess/pieces/queen'
|
13
|
+
require 'mail_chess/pieces/rook'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'mail_chess'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class DatabaseOperationsTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@db = Sequel.connect 'sqlite:/'
|
7
|
+
|
8
|
+
p1 = MailChess::Player.new!(@db, 'john@doe.net', 'John Doe')
|
9
|
+
p2 = MailChess::Player.new!(@db, 'jane@doe.net')
|
10
|
+
|
11
|
+
g = MailChess::Game.new!(@db, p1, p2, 'abc')
|
12
|
+
g.board.start!
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_load
|
16
|
+
g = MailChess::Player.load!(@db, :email, 'john@doe.net').game('abc')
|
17
|
+
|
18
|
+
assert_equal 2, g.players.size
|
19
|
+
assert_equal :white, g.current
|
20
|
+
assert_not_nil g.board
|
21
|
+
assert_equal 32, g.board.pieces.size
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_save
|
25
|
+
g = MailChess::Player.load!(@db, :email, 'john@doe.net').game('abc')
|
26
|
+
|
27
|
+
g.players[:white].name = 'John'
|
28
|
+
g.players[:white].save!
|
29
|
+
|
30
|
+
g.current = :black
|
31
|
+
g.save!
|
32
|
+
|
33
|
+
g.board.pieces['a3'] = g.board.pieces.delete('a2')
|
34
|
+
g.board.save!
|
35
|
+
|
36
|
+
# check
|
37
|
+
g_new = MailChess::Player.load!(@db, :email, 'john@doe.net').game('abc')
|
38
|
+
|
39
|
+
assert_equal 'John', g_new.players[:white].name
|
40
|
+
assert_equal :black, g_new.current
|
41
|
+
assert_nil g_new.board.pieces['a2']
|
42
|
+
assert_not_nil g_new.board.pieces['a3']
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_delete
|
46
|
+
g = MailChess::Player.load!(@db, :email, 'john@doe.net').game('abc')
|
47
|
+
|
48
|
+
g.delete!
|
49
|
+
|
50
|
+
assert_equal 0, @db[:pieces].all.size
|
51
|
+
assert_equal 0, @db[:boards].all.size
|
52
|
+
assert_equal 0, @db[:games].all.size
|
53
|
+
assert_equal 0, @db[:pairs].all.size
|
54
|
+
assert_equal 2, @db[:players].all.size
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mail_chess
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- András Kárász
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sequel
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Play chess with your friends in email!
|
31
|
+
email: karaszandris@gmail.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- lib/mail_chess/game.rb
|
37
|
+
- lib/mail_chess/player.rb
|
38
|
+
- lib/mail_chess/pieces/rook.rb
|
39
|
+
- lib/mail_chess/pieces/queen.rb
|
40
|
+
- lib/mail_chess/pieces/knight.rb
|
41
|
+
- lib/mail_chess/pieces/bishop.rb
|
42
|
+
- lib/mail_chess/pieces/pawn.rb
|
43
|
+
- lib/mail_chess/pieces/base.rb
|
44
|
+
- lib/mail_chess/pieces/king.rb
|
45
|
+
- lib/mail_chess/board.rb
|
46
|
+
- lib/mail_chess.rb
|
47
|
+
- Rakefile
|
48
|
+
- README
|
49
|
+
- test/db_operations_test.rb
|
50
|
+
homepage: http://rubygems.org/gems/mail_chess
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.23
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Mail Chess
|
74
|
+
test_files: []
|