mail_chess 0.1.0 → 0.2.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.
@@ -34,10 +34,13 @@ module MailChess
34
34
  @db_entry = @db[:boards].filter(:id => board_id).first
35
35
 
36
36
  @id = @db_entry[:id].to_i
37
+
37
38
  @pieces = {}
38
39
  @db[:pieces].filter(:board_id => @id).all.each do |p|
39
40
  Piece::Piece.load! db, p[:id], self
40
41
  end
42
+
43
+ generate_pieces_moves
41
44
  end
42
45
 
43
46
  # Checks if needed to create tables.
@@ -105,13 +108,16 @@ module MailChess
105
108
 
106
109
  # Delete game -- +save!+ won't fix it!
107
110
  def delete!
108
- pieces.values.each do |p|
109
- p.delete!
110
- end
111
+ @db[:pieces].filter(:board_id => @id).delete
111
112
 
112
113
  # board deleted in Game class
113
114
  end
114
115
 
116
+ # Generates the available hits and moves for every pieces.
117
+ def generate_pieces_moves
118
+ @pieces.values.each { |p| p.generate_moves }
119
+ end
120
+
115
121
  # Add a new piece to board.
116
122
  #
117
123
  # Arguments:
@@ -219,4 +225,8 @@ module MailChess
219
225
  return result
220
226
  end
221
227
  end
228
+
229
+ # Error for invalid moves.
230
+ class MoveError < StandardError
231
+ end
222
232
  end
@@ -21,12 +21,16 @@ module MailChess
21
21
  # Current player's color.
22
22
  attr_accessor :current
23
23
 
24
+ # Who tries to move.
25
+ attr_reader :initiator
26
+
24
27
  # Create a new Game object.
25
28
  #
26
29
  # Arguments:
27
30
  # db: Sequel database object
28
31
  # game_id: (Integer)
29
- def initialize db, game_id
32
+ # initiator: (Symbol) :white or :black
33
+ def initialize db, game_id, initiator
30
34
  @db = db
31
35
 
32
36
  Game.create_tables(@db) if Game.need_to_create_tables?(@db)
@@ -43,6 +47,7 @@ module MailChess
43
47
  @players[p[:color].to_sym] = Player.load!(@db, :id, p[:player_id].to_i)
44
48
  end
45
49
 
50
+ @initiator = initiator
46
51
  end
47
52
 
48
53
  # Checks if needed to create tables.
@@ -103,7 +108,7 @@ module MailChess
103
108
  :game_id => id,
104
109
  :color => 'black')
105
110
 
106
- return Game.new db, id
111
+ return Game.new db, id, :white
107
112
  end
108
113
 
109
114
  # Load game from database.
@@ -112,15 +117,16 @@ module MailChess
112
117
  # db: Sequel database object
113
118
  # filter: (Symbol) :id or :reference
114
119
  # value: filters value
120
+ # initiator: (Symbol) :white or :black
115
121
  #
116
122
  # Returns: (Game)
117
- def self.load! db, filter, value
123
+ def self.load! db, filter, value, initiator
118
124
  raise ArgumentError unless [:id, :reference].index(filter)
119
125
  dataset = db[:games].filter(filter => value)
120
126
  return nil unless dataset.all.size == 1
121
127
  id = dataset.first[:id]
122
128
 
123
- return Game.new db, id
129
+ return Game.new db, id, initiator
124
130
  end
125
131
 
126
132
  # Save game -- update the +current+ field.
@@ -135,5 +141,43 @@ module MailChess
135
141
  @db[:games].filter(:id => @id).delete
136
142
  @db[:boards].filter(:id => @board.id).delete
137
143
  end
144
+
145
+ # Perform the move.
146
+ #
147
+ # Arguments:
148
+ # move: (String) eg.: e2e4
149
+ #
150
+ # Exceptions:
151
+ # (MoveError) if move is invalid
152
+ # (TurnError) if this is not the requester's turn
153
+ def perform! move
154
+ from, to = move[0] + move[1], move[2] + move[3]
155
+ p = @board.pieces[from]
156
+ k = nil
157
+
158
+ @board.pieces.values.each do |piece|
159
+ k = piece if piece.type == 'king' and piece.color == @current
160
+ end
161
+
162
+ raise TurnError.new('not your turn') if @initiator != @current
163
+ raise MoveError.new('piece not exists') if p == nil
164
+ raise MoveError.new('not your piece') if p.color != @current
165
+ raise MoveError.new('invalid move') if !p.can_move?(to) & !p.can_hit?(to)
166
+
167
+ old_p = @board.pieces[to]
168
+ p.move to
169
+
170
+ raise MoveError.new('checkmate') if k.in_checkmate?
171
+ raise MoveError.new('king in check') if k.in_check?
172
+
173
+ old_p.delete! if old_p
174
+ @current = (@current == :white ? :black : :white)
175
+ @board.save!
176
+ save!
177
+ end
178
+ end
179
+
180
+ # Error for invalid turns.
181
+ class TurnError < StandardError
138
182
  end
139
183
  end
@@ -21,7 +21,13 @@ module MailChess
21
21
 
22
22
  # HTML tag of this piece.
23
23
  attr_reader :html
24
-
24
+
25
+ # Available moves.
26
+ attr_reader :moves
27
+
28
+ # Available hits.
29
+ attr_reader :hits
30
+
25
31
  # Create a new Piece object.
26
32
  #
27
33
  # Arguments:
@@ -39,6 +45,8 @@ module MailChess
39
45
  @color = @db_entry[:color].to_sym
40
46
  @board = board
41
47
  @board.add @db_entry[:position], self
48
+
49
+ @possibilities_generated = false
42
50
  end
43
51
 
44
52
  # Checks if needed to create tables.
@@ -70,6 +78,15 @@ module MailChess
70
78
  return @board.pieces.key(self)
71
79
  end
72
80
 
81
+ # Moves the piece.
82
+ #
83
+ # Arguments:
84
+ # to: (String) destination field
85
+ def move to
86
+ @board.pieces[to] = @board.pieces.delete(position)
87
+ @board.pieces[to].generate_moves
88
+ end
89
+
73
90
  # ABSTRACT Create a new piece and add to a table.
74
91
  #
75
92
  # Arguments:
@@ -108,11 +125,36 @@ module MailChess
108
125
  def save!
109
126
  @db[:pieces].filter(:id => @id).update(:position => position)
110
127
  end
111
-
112
- # Delete piece -- +save!+ won't fix it!
128
+
129
+ # Delete piece
113
130
  def delete!
114
131
  @db[:pieces].filter(:id => @id).delete
115
132
  end
133
+
134
+ # Decide if piece can move to +field+.
135
+ #
136
+ # Arguments:
137
+ # field: (String)
138
+ #
139
+ # Returns: (Boolean)
140
+ def can_move? field
141
+ return @moves.index(field) != nil
142
+ end
143
+
144
+ # Decide if piece can hit piece on +field+.
145
+ #
146
+ # Arguments:
147
+ # field: (String)
148
+ #
149
+ # Returns: (Boolean)
150
+ def can_hit? field
151
+ return @hits.index(field) != nil
152
+ end
153
+
154
+ # Generate the possible moves.
155
+ def generate_moves
156
+ @hits, @moves = [], []
157
+ end
116
158
  end
117
159
  end
118
160
  end
@@ -25,6 +25,36 @@ module MailChess
25
25
 
26
26
  return Bishop.new db, id, board
27
27
  end
28
+
29
+ # Generate the possible moves.
30
+ def generate_moves
31
+ super
32
+
33
+ r, c = ROWS.index(position[1]), COLS.index(position[0])
34
+ f = {:ul => false, :ur => false, :bl => false, :br => false}
35
+
36
+ (1..7).each do |i|
37
+ pos = []
38
+ pos << [:ul, COLS[c - i] + ROWS[r - i]] if
39
+ c - i >= 0 and r - i >= 0 and !f[:ul]
40
+ pos << [:ur, COLS[c - i] + ROWS[r + i]] if
41
+ c - i >= 0 and r + i <= 7 and !f[:ur]
42
+ pos << [:bl, COLS[c + i] + ROWS[r - i]] if
43
+ c + i <= 7 and r - i >= 0 and !f[:bl]
44
+ pos << [:br, COLS[c + i] + ROWS[r + i]] if
45
+ c + i <= 7 and r + i <= 7 and !f[:br]
46
+
47
+ break if pos.empty?
48
+ pos.each do |s, p|
49
+ if @board.pieces[p]
50
+ @hits << p if @board.pieces[p].color != @color
51
+ f[s] = true
52
+ else
53
+ @moves << p
54
+ end
55
+ end
56
+ end
57
+ end
28
58
  end
29
59
  end
30
60
  end
@@ -25,6 +25,65 @@ module MailChess
25
25
 
26
26
  return King.new db, id, board
27
27
  end
28
+
29
+ # Generate the possible moves.
30
+ def generate_moves
31
+ super
32
+
33
+ r, c = ROWS.index(position[1]), COLS.index(position[0])
34
+ (r - 1..r + 1).each do |y|
35
+ (c - 1..c + 1).each do |x|
36
+ if x >= 0 and x <= 7 and y >= 0 and y <= 7
37
+ f = COLS[x] + ROWS[y]
38
+ if @board.pieces[f] # is there a piece
39
+ @hits << f
40
+ else
41
+ @moves << f
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ @hits.delete(position)
48
+ end
49
+
50
+ # Decide wether this king is in check.
51
+ #
52
+ # Returns: (Boolean)
53
+ def in_check?
54
+ @board.pieces.values.each do |p|
55
+ if p.color != @color # if opponent's piece
56
+ return true if p.can_hit?(position)
57
+ end
58
+ end
59
+
60
+ return false
61
+ end
62
+
63
+ # Decide wether this king is in checkmate. (dumb method, FIXME)
64
+ #
65
+ # Returns: (Boolean)
66
+ def in_checkmate?
67
+ return false if not in_check? # if not in even check
68
+
69
+ original = @board.pieces
70
+
71
+ @board.pieces.values.each do |p|
72
+ if p.color == @color # if player's piece
73
+ original_moves_hits = p.moves + p.hits
74
+ original_moves_hits.each do |m|
75
+ p.move m
76
+ @board.generate_pieces_moves
77
+ if not in_check?
78
+ @board.pieces = original
79
+ return false
80
+ end
81
+ @board.pieces = original
82
+ end
83
+ end
84
+ end
85
+ return true
86
+ end
28
87
  end
29
88
  end
30
89
  end
@@ -25,7 +25,31 @@ module MailChess
25
25
 
26
26
  return Knight.new db, id, board
27
27
  end
28
+
29
+ # Generate the possible moves.
30
+ def generate_moves
31
+ super
32
+
33
+ r, c = ROWS.index(position[1]), COLS.index(position[0])
34
+
35
+ pos = []
36
+ pos << COLS[c - 1] + ROWS[r - 2] if c > 0 and r > 1
37
+ pos << COLS[c + 1] + ROWS[r - 2] if c < 7 and r > 1
38
+ pos << COLS[c - 2] + ROWS[r - 1] if c > 1 and r > 0
39
+ pos << COLS[c + 2] + ROWS[r - 1] if c < 6 and r > 0
40
+ pos << COLS[c - 2] + ROWS[r + 1] if c > 1 and r < 7
41
+ pos << COLS[c + 2] + ROWS[r + 1] if c < 6 and r < 7
42
+ pos << COLS[c - 1] + ROWS[r + 2] if c > 0 and r < 6
43
+ pos << COLS[c + 1] + ROWS[r + 2] if c < 7 and r < 6
44
+
45
+ pos.each do |p|
46
+ if @board.pieces[p]
47
+ @hits << p
48
+ else
49
+ @moves << p
50
+ end
51
+ end
52
+ end
28
53
  end
29
54
  end
30
55
  end
31
-
@@ -25,6 +25,41 @@ module MailChess
25
25
 
26
26
  return Pawn.new db, id, board
27
27
  end
28
+
29
+ # Generate the possible moves.
30
+ def generate_moves
31
+ super
32
+
33
+ r, c = ROWS.index(position[1]), COLS.index(position[0])
34
+ dir = @color == :white ? -1 : 1
35
+ first_step =
36
+ ((@color == :white and position[1] == 2.to_s) or
37
+ (@color == :black and position[1] == 7.to_s) ? true : false)
38
+
39
+ # moves
40
+ if (r + dir >= 0 and @color == :white) or (r + dir <= 7 and
41
+ @color == :black)
42
+ f = COLS[c] + ROWS[r + dir]
43
+ @moves << f unless @board.pieces[f]
44
+ end
45
+
46
+ if (r + dir * 2 >= 0 and @color == :white) or (r + dir * 2 <= 7 and
47
+ @color == :black)
48
+ f = COLS[c] + ROWS[r + dir * 2]
49
+ @moves << f if !@board.pieces[f] and first_step
50
+ end
51
+
52
+ # hits
53
+ [-1, 1].each do |x|
54
+ if c + x >= 0 and c + x <= 7
55
+ if (r - 1 >= 0 and @color == :white) or (r + 1 <= 7 and
56
+ @color == :black)
57
+ f = COLS[c + x] + ROWS[r + dir]
58
+ @hits << f if @board.pieces[f]
59
+ end
60
+ end
61
+ end
62
+ end
28
63
  end
29
64
  end
30
65
  end
@@ -25,7 +25,40 @@ module MailChess
25
25
 
26
26
  return Queen.new db, id, board
27
27
  end
28
+
29
+ # Generate the possible moves.
30
+ def generate_moves
31
+ super
32
+
33
+ r, c = ROWS.index(position[1]), COLS.index(position[0])
34
+ f = {:ul => false, :uc => false, :ur => false,
35
+ :ml => false, :mc => true, :mr => false,
36
+ :bl => false, :bc => false, :br => false}
37
+
38
+ (1..7).each do |i|
39
+ pos = []
40
+ {'u' => -1, 'm' => 0, 'b' => 1}.each do |y, v|
41
+ {'l' => -1, 'c' => 0, 'r' => 1}.each do |x, w|
42
+ s, cc, rr = (y + x).to_sym, c + w * i, r + v * i
43
+ if cc >= 0 and cc <= 7 and rr >= 0 and rr <= 7
44
+ pos << [s, COLS[cc] + ROWS[rr]] if !f[s]
45
+ else
46
+ f[s] = true
47
+ end
48
+ end
49
+ end
50
+
51
+ break if pos.empty?
52
+ pos.each do |s, p|
53
+ if @board.pieces[p]
54
+ @hits << p if @board.pieces[p].color != @color
55
+ f[s] = true
56
+ else
57
+ @moves << p
58
+ end
59
+ end
60
+ end
61
+ end
28
62
  end
29
63
  end
30
64
  end
31
-
@@ -25,7 +25,32 @@ module MailChess
25
25
 
26
26
  return Rook.new db, id, board
27
27
  end
28
+
29
+ # Generate the possible moves.
30
+ def generate_moves
31
+ super
32
+
33
+ r, c = ROWS.index(position[1]), COLS.index(position[0])
34
+ f = {:u => false, :l => false, :r => false, :d => false}
35
+
36
+ (1..7).each do |i|
37
+ pos = []
38
+ pos << [:u, COLS[c] + ROWS[r - i]] if r - i >= 0 and !f[:u]
39
+ pos << [:l, COLS[c - i] + ROWS[r]] if c - i >= 0 and !f[:l]
40
+ pos << [:r, COLS[c + i] + ROWS[r]] if c + i <= 7 and !f[:r]
41
+ pos << [:d, COLS[c] + ROWS[r + i]] if r + i <= 7 and !f[:d]
42
+
43
+ break if pos.empty?
44
+ pos.each do |s, p|
45
+ if @board.pieces[p]
46
+ @hits << p if @board.pieces[p].color != @color
47
+ f[s] = true
48
+ else
49
+ @moves << p
50
+ end
51
+ end
52
+ end
53
+ end
28
54
  end
29
55
  end
30
56
  end
31
-
@@ -72,10 +72,14 @@ module MailChess
72
72
  # value: filters value
73
73
  #
74
74
  # Returns: (Player)
75
+ #
76
+ # Exceptions:
77
+ # (ArgumentError) if filter is invalid
78
+ # (PlayerError) if player not exists
75
79
  def self.load! db, filter, value
76
80
  raise ArgumentError unless [:id, :email].index(filter)
77
81
  dataset = db[:players].filter(filter => value)
78
- raise ArgumentError unless dataset.all.size == 1
82
+ raise PlayerError('player not exists') unless dataset.all.size == 1
79
83
 
80
84
  id = dataset.first[:id]
81
85
 
@@ -88,8 +92,19 @@ module MailChess
88
92
  # reference: (String) game reference string
89
93
  #
90
94
  # Returns: (Game) or nil
95
+ #
96
+ # Exceptions:
97
+ # (PlayerError) if initiator is invalid
91
98
  def game reference
92
- return Game.load! @db, :reference, reference
99
+ d = @db[:pairs]
100
+ .join(:games, :id => :game_id)
101
+ .filter(:reference => reference, :player_id => self.id)
102
+
103
+ if d.all.empty?
104
+ raise PlayerError('invalid initiator')
105
+ else
106
+ Game.load! @db, :reference, reference, d.first[:color].to_sym
107
+ end
93
108
  end
94
109
 
95
110
  # Save player -- name only
@@ -97,4 +112,8 @@ module MailChess
97
112
  @db[:players].filter(:id => @id).update(:name => @name)
98
113
  end
99
114
  end
115
+
116
+ # Error for players.
117
+ class PlayerError < StandardError
118
+ end
100
119
  end
@@ -0,0 +1,95 @@
1
+ require 'test/unit'
2
+ require 'mail_chess'
3
+ require 'sequel'
4
+
5
+ class CheckMateTest < Test::Unit::TestCase
6
+ def setup
7
+ @db = Sequel.connect 'sqlite:/'
8
+ @p1 = MailChess::Player.new!(@db, 'john@doe.net')
9
+ @p2 = MailChess::Player.new!(@db, 'jane@doe.net')
10
+ end
11
+
12
+ def test_no_check_no_checkmate
13
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
14
+ b = g.board
15
+
16
+ k = MailChess::Piece::King.new!(@db, b, 'f2', :white)
17
+ MailChess::Piece::Queen.new!(@db, b, 'b5', :oblack)
18
+
19
+ b.generate_pieces_moves
20
+
21
+ assert !k.in_check?
22
+ assert !k.in_checkmate?
23
+
24
+ g.delete!
25
+ end
26
+
27
+ def test_check_with_king_can_hit
28
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
29
+ b = g.board
30
+
31
+ k = MailChess::Piece::King.new!(@db, b, 'f2', :white)
32
+ MailChess::Piece::Queen.new!(@db, b, 'g3', :black)
33
+ MailChess::Piece::Rook.new!(@db, b, 'e4', :black)
34
+ MailChess::Piece::Rook.new!(@db, b, 'a1', :black)
35
+
36
+ b.generate_pieces_moves
37
+
38
+ assert k.in_check?
39
+ assert !k.in_checkmate?
40
+
41
+ g.delete!
42
+ end
43
+
44
+ def test_check_with_king_can_move
45
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
46
+ b = g.board
47
+
48
+ k = MailChess::Piece::King.new!(@db, b, 'f2', :white)
49
+ MailChess::Piece::Rook.new!(@db, b, 'f8', :black)
50
+
51
+ b.generate_pieces_moves
52
+
53
+ assert k.in_check?
54
+ assert !k.in_checkmate?
55
+
56
+ g.delete!
57
+ end
58
+
59
+ def test_check_with_other_piece_can_move
60
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
61
+ b = g.board
62
+
63
+ k = MailChess::Piece::King.new!(@db, b, 'f2', :white)
64
+ MailChess::Piece::Bishop.new!(@db, b, 'd3', :white)
65
+ MailChess::Piece::Rook.new!(@db, b, 'e8', :black)
66
+ MailChess::Piece::Queen.new!(@db, b, 'f8', :black)
67
+ MailChess::Piece::Rook.new!(@db, b, 'g8', :black)
68
+
69
+ b.generate_pieces_moves
70
+
71
+ assert k.in_check?
72
+ assert !k.in_checkmate?
73
+
74
+ g.delete!
75
+ end
76
+
77
+ def test_checkmate
78
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
79
+ b = g.board
80
+
81
+ MailChess::Piece::Queen.new!(@db, b, 'a1', :black)
82
+ k = MailChess::Piece::King.new!(@db, b, 'h2', :white)
83
+ MailChess::Piece::Rook.new!(@db, b, 'c3', :black)
84
+ MailChess::Piece::Pawn.new!(@db, b, 'g3', :black)
85
+ MailChess::Piece::Knight.new!(@db, b, 'g5', :black)
86
+ MailChess::Piece::Bishop.new!(@db, b, 'b7', :black)
87
+
88
+ b.generate_pieces_moves
89
+
90
+ assert k.in_check?
91
+ assert k.in_checkmate?
92
+
93
+ g.delete!
94
+ end
95
+ end
@@ -1,5 +1,6 @@
1
- require 'mail_chess'
2
1
  require 'test/unit'
2
+ require 'mail_chess'
3
+ require 'sequel'
3
4
 
4
5
  class DatabaseOperationsTest < Test::Unit::TestCase
5
6
  def setup
@@ -0,0 +1,49 @@
1
+ require 'test/unit'
2
+ require 'mail_chess'
3
+ require 'sequel'
4
+
5
+ class PerformMoveTest < Test::Unit::TestCase
6
+ def setup
7
+ @db = Sequel.connect 'sqlite:/'
8
+
9
+ p1 = MailChess::Player.new!(@db, 'john@doe.net')
10
+ p2 = MailChess::Player.new!(@db, 'jane@doe.net')
11
+
12
+ g = MailChess::Game.new!(@db, p1, p2, 'abcd@mail')
13
+ g.current = :white
14
+ g.save!
15
+
16
+ MailChess::Piece::Queen.new!(@db, g.board, 'a1', :black)
17
+ MailChess::Piece::King.new!(@db, g.board, 'h2', :white)
18
+ MailChess::Piece::Rook.new!(@db, g.board, 'c3', :black)
19
+ MailChess::Piece::Knight.new!(@db, g.board, 'f4', :black)
20
+ MailChess::Piece::Pawn.new!(@db, g.board, 'g4', :black)
21
+ MailChess::Piece::Knight.new!(@db, g.board, 'a5', :black)
22
+ MailChess::Piece::Pawn.new!(@db, g.board, 'b6', :white)
23
+ MailChess::Piece::Bishop.new!(@db, g.board, 'c6', :black)
24
+ MailChess::Piece::King.new!(@db, g.board, 'h8', :black)
25
+
26
+ g.board.generate_pieces_moves
27
+ File.open('table.htm', 'w') { |f| f.write(g.board.to_html) }
28
+ end
29
+
30
+ def test_play
31
+ # Jane tries to move but it's not her turn
32
+ g = MailChess::Player.load!(@db, :email, 'jane@doe.net').game('abcd@mail')
33
+ assert_raise(MailChess::TurnError) { g.perform! 'g4g3' }
34
+
35
+ # Joe tries to move with a not existing piece, than finds the right move
36
+ g = MailChess::Player.load!(@db, :email, 'john@doe.net').game('abcd@mail')
37
+ assert_raise(MailChess::MoveError) { g.perform! 'a6a7' }
38
+ g.perform! 'b6b7'
39
+
40
+ # Jane's turn
41
+ g = MailChess::Player.load!(@db, :email, 'jane@doe.net').game('abcd@mail')
42
+ assert_raise(MailChess::MoveError) { g.perform! 'c8c7' }
43
+ assert_raise(MailChess::MoveError) { g.perform! 'b6c5' }
44
+ assert_raise(MailChess::MoveError) { g.perform! 'c6c5' }
45
+ g.perform! 'g4g3'
46
+
47
+ # the end.
48
+ end
49
+ end
@@ -0,0 +1,266 @@
1
+ require 'test/unit'
2
+ require 'mail_chess'
3
+ require 'sequel'
4
+
5
+ class PieceMovesTest < Test::Unit::TestCase
6
+ def setup
7
+ @db = Sequel.connect 'sqlite:/'
8
+ @p1 = MailChess::Player.new!(@db, 'john@doe.net')
9
+ @p2 = MailChess::Player.new!(@db, 'jane@doe.net')
10
+ end
11
+
12
+ def check_moves hits, moves, piece
13
+ all = MailChess::ROWS.product(MailChess::COLS).map! do |a| a.join end
14
+ all -= hits + moves
15
+ name = piece.position + " " + piece.type
16
+
17
+ all.each do |f|
18
+ assert !piece.can_move?(f), name + " shouldn't move to " + f
19
+ assert !piece.can_hit?(f), name + " shouldn't hit " + f
20
+ end
21
+
22
+ moves.each do |f|
23
+ assert piece.can_move?(f), name + " should move to " + f
24
+ assert !piece.can_hit?(f), name + " shouldn't hit " + f
25
+ end
26
+
27
+ hits.each do |f|
28
+ assert !piece.can_move?(f), name + " shouldn't move to " + f
29
+ assert piece.can_hit?(f), name + " should hit " + f
30
+ end
31
+ end
32
+
33
+ def test_bishop
34
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
35
+ b = g.board
36
+
37
+ MailChess::Piece::Bishop.new!(@db, b, 'c2', :black)
38
+ MailChess::Piece::Pawn.new!(@db, b, 'd3', :white)
39
+ MailChess::Piece::Bishop.new!(@db, b, 'g3', :black)
40
+ MailChess::Piece::Rook.new!(@db, b, 'a4', :white)
41
+ MailChess::Piece::Bishop.new!(@db, b, 'e4', :white)
42
+ MailChess::Piece::Knight.new!(@db, b, 'f4', :white)
43
+ MailChess::Piece::Pawn.new!(@db, b, 'h4', :black)
44
+ MailChess::Piece::Bishop.new!(@db, b, 'a8', :white)
45
+
46
+ b.generate_pieces_moves
47
+
48
+ # c2
49
+ hits = %w[d3 a4]
50
+ moves = %w[b1 d1 b3]
51
+ check_moves hits, moves, b.pieces['c2']
52
+
53
+ # g3
54
+ hits = %w[f4]
55
+ moves = %w[e1 f2 h2]
56
+ check_moves hits, moves, b.pieces['g3']
57
+
58
+ # e4
59
+ hits = %w[]
60
+ moves = %w[h1 g2 f3 d5 f5 c6 g6 b7 h7]
61
+ check_moves hits, moves, b.pieces['e4']
62
+
63
+ # a8
64
+ hits = %w[]
65
+ moves = %w[d5 c6 b7]
66
+ check_moves hits, moves, b.pieces['a8']
67
+
68
+ g.delete!
69
+ end
70
+
71
+ def test_king
72
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
73
+ b = g.board
74
+
75
+ MailChess::Piece::King.new!(@db, b, 'a1', :white)
76
+ MailChess::Piece::Pawn.new!(@db, b, 'a2', :black)
77
+ MailChess::Piece::Bishop.new!(@db, b, 'd2', :black)
78
+ MailChess::Piece::King.new!(@db, b, 'e2', :black)
79
+ MailChess::Piece::Knight.new!(@db, b, 'f3', :white)
80
+
81
+ b.generate_pieces_moves
82
+
83
+ # a1
84
+ hits = %w[a2]
85
+ moves = %w[b1 b2]
86
+ check_moves hits, moves, b.pieces['a1']
87
+
88
+ # e2
89
+ hits = %w[f3]
90
+ moves = %w[d1 e1 f1 f2 d3 e3]
91
+ check_moves hits, moves, b.pieces['e2']
92
+
93
+ g.delete!
94
+ end
95
+
96
+ def test_knight
97
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
98
+ b = g.board
99
+
100
+ MailChess::Piece::Knight.new!(@db, b, 'a2', :white)
101
+ MailChess::Piece::Pawn.new!(@db, b, 'c3', :white)
102
+ MailChess::Piece::Knight.new!(@db, b, 'f3', :black)
103
+ MailChess::Piece::Pawn.new!(@db, b, 'b4', :black)
104
+ MailChess::Piece::Knight.new!(@db, b, 'd4', :white)
105
+ MailChess::Piece::Pawn.new!(@db, b, 'h4', :black)
106
+ MailChess::Piece::Pawn.new!(@db, b, 'e6', :white)
107
+ MailChess::Piece::Knight.new!(@db, b, 'g7', :black)
108
+
109
+ b.generate_pieces_moves
110
+
111
+ # a2
112
+ hits = %w[b4]
113
+ moves = %w[c1]
114
+ check_moves hits, moves, b.pieces['a2']
115
+
116
+ # f3
117
+ hits = %w[d4]
118
+ moves = %w[e1 g1 d2 h2 e5 g5]
119
+ check_moves hits, moves, b.pieces['f3']
120
+
121
+ # d4
122
+ hits = %w[f3]
123
+ moves = %w[c2 e2 b3 b5 f5 c6]
124
+ check_moves hits, moves, b.pieces['d4']
125
+
126
+ # g7
127
+ hits = %w[e6]
128
+ moves = %w[f5 h5 e8]
129
+ check_moves hits, moves, b.pieces['g7']
130
+
131
+ g.delete!
132
+ end
133
+
134
+ def test_pawn
135
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
136
+ b = g.board
137
+
138
+ MailChess::Piece::Pawn.new!(@db, b, 'a1', :black)
139
+ MailChess::Piece::Pawn.new!(@db, b, 'c2', :white)
140
+ MailChess::Piece::Pawn.new!(@db, b, 'g2', :white)
141
+ MailChess::Piece::Rook.new!(@db, b, 'g4', :black)
142
+ MailChess::Piece::Pawn.new!(@db, b, 'a5', :white)
143
+ MailChess::Piece::Pawn.new!(@db, b, 'e5', :black)
144
+ MailChess::Piece::Pawn.new!(@db, b, 'f5', :white)
145
+ MailChess::Piece::Bishop.new!(@db, b, 'b6', :black)
146
+ MailChess::Piece::Pawn.new!(@db, b, 'f6', :black)
147
+ MailChess::Piece::Pawn.new!(@db, b, 'g6', :white)
148
+ MailChess::Piece::Pawn.new!(@db, b, 'h7', :black)
149
+ MailChess::Piece::Pawn.new!(@db, b, 'd8', :white)
150
+
151
+ b.generate_pieces_moves
152
+
153
+ # a1
154
+ hits = %w[]
155
+ moves = %w[]
156
+ check_moves hits, moves, b.pieces['a1']
157
+
158
+ # c2
159
+ hits = %w[]
160
+ moves = %w[c3 c4]
161
+ check_moves hits, moves, b.pieces['c2']
162
+
163
+ # g2
164
+ hits = %w[]
165
+ moves = %w[g3]
166
+ check_moves hits, moves, b.pieces['g2']
167
+
168
+ # a5
169
+ hits = %w[b6]
170
+ moves = %w[a6]
171
+ check_moves hits, moves, b.pieces['a5']
172
+
173
+ # e5
174
+ hits = %w[]
175
+ moves = %w[e4]
176
+ check_moves hits, moves, b.pieces['e5']
177
+
178
+ # f5
179
+ hits = %w[]
180
+ moves = %w[]
181
+ check_moves hits, moves, b.pieces['f5']
182
+
183
+ # f6
184
+ hits = %w[]
185
+ moves = %w[]
186
+ check_moves hits, moves, b.pieces['f6']
187
+
188
+ # g6
189
+ hits = %w[h7]
190
+ moves = %w[g7]
191
+ check_moves hits, moves, b.pieces['g6']
192
+
193
+ # h7
194
+ hits = %w[g6]
195
+ moves = %w[h6 h5]
196
+ check_moves hits, moves, b.pieces['h7']
197
+
198
+ # d8
199
+ hits = %w[]
200
+ moves = %w[]
201
+ check_moves hits, moves, b.pieces['d8']
202
+
203
+ g.delete!
204
+ end
205
+
206
+ def test_queen
207
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
208
+ b = g.board
209
+
210
+ MailChess::Piece::Bishop.new!(@db, b, 'g1', :white)
211
+ MailChess::Piece::Knight.new!(@db, b, 'b3', :white)
212
+ MailChess::Piece::Queen.new!(@db, b, 'e3', :black)
213
+ MailChess::Piece::Pawn.new!(@db, b, 'e5', :black)
214
+ MailChess::Piece::Knight.new!(@db, b, 'd6', :black)
215
+ MailChess::Piece::Rook.new!(@db, b, 'h6', :white)
216
+ MailChess::Piece::Queen.new!(@db, b, 'a7', :white)
217
+ MailChess::Piece::Pawn.new!(@db, b, 'f7', :white)
218
+ MailChess::Piece::Pawn.new!(@db, b, 'g7', :black)
219
+
220
+ b.generate_pieces_moves
221
+
222
+ # e3
223
+ hits = %w[g1 b3 h6 a7]
224
+ moves = %w[c1 e1 d2 e2 f2 c3 d3 f3 g3 h3 d4 e4 f4 c5 g5 b6]
225
+ check_moves hits, moves, b.pieces['e3']
226
+
227
+ # a7
228
+ hits = %w[e3]
229
+ moves = %w[a1 a2 a3 a4 d4 a5 c5 a6 b6 b7 c7 d7 e7 a8 b8]
230
+ check_moves hits, moves, b.pieces['a7']
231
+ end
232
+
233
+ def test_rook
234
+ g = MailChess::Game.new!(@db, @p1, @p2, 'test@mail')
235
+ b = g.board
236
+
237
+ MailChess::Piece::Rook.new!(@db, b, 'a3', :white)
238
+ MailChess::Piece::Knight.new!(@db, b, 'c3', :black)
239
+ MailChess::Piece::Rook.new!(@db, b, 'f4', :white)
240
+ MailChess::Piece::Pawn.new!(@db, b, 'h4', :black)
241
+ MailChess::Piece::Rook.new!(@db, b, 'c8', :black)
242
+ MailChess::Piece::Rook.new!(@db, b, 'f8', :black)
243
+
244
+ b.generate_pieces_moves
245
+
246
+ # a3
247
+ hits = %w[c3]
248
+ moves = %w[a1 a2 b3 a4 a5 a6 a7 a8]
249
+ check_moves hits, moves, b.pieces['a3']
250
+
251
+ # f4
252
+ hits = %w[f8 h4]
253
+ moves = %w[f1 f2 f3 a4 b4 c4 d4 e4 g4 f5 f6 f7]
254
+ check_moves hits, moves, b.pieces['f4']
255
+
256
+ # c8
257
+ hits = %w[]
258
+ moves = %w[c4 c5 c6 c7 a8 b8 d8 e8]
259
+ check_moves hits, moves, b.pieces['c8']
260
+
261
+ # f8
262
+ hits = %w[f4]
263
+ moves = %w[f5 f6 f7 d8 e8 g8 h8]
264
+ check_moves hits, moves, b.pieces['f8']
265
+ end
266
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail_chess
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-07 00:00:00.000000000 Z
12
+ date: 2012-07-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sequel
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: 3.37.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: '0'
29
+ version: 3.37.0
30
30
  description: Play chess with your friends in email!
31
31
  email: karaszandris@gmail.com
32
32
  executables: []
@@ -46,7 +46,10 @@ files:
46
46
  - lib/mail_chess.rb
47
47
  - Rakefile
48
48
  - README
49
+ - test/check_mate_test.rb
49
50
  - test/db_operations_test.rb
51
+ - test/piece_moves_test.rb
52
+ - test/perform_move_test.rb
50
53
  homepage: http://rubygems.org/gems/mail_chess
51
54
  licenses: []
52
55
  post_install_message: