mail_chess 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: