ruby-chess 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rook.rb ADDED
@@ -0,0 +1,56 @@
1
+ module Rook
2
+
3
+ extend self
4
+ include Moves
5
+
6
+ def illegal(board,x,y)
7
+ possible_moves = []
8
+
9
+ 7.times do |coord|
10
+ possible_moves += Board.board_safe(
11
+ horizontal(coord) + vertical(coord)
12
+ )
13
+ end
14
+
15
+ if not(possible_moves.any? {|move| move == [x,y]})
16
+ raise Game::IllegalMove, "#{x},#{y} is not a possible move"
17
+ elsif board.at(x,y).friend_of?(self)
18
+ raise Game::IllegalMove, "#{x},#{y} is occupied by a friend"
19
+ elsif jumped?(board,x,y)
20
+ raise Game::IllegalMove, "Rooks cannot jump"
21
+ else
22
+ :legal_move
23
+ end
24
+ end
25
+ end
26
+
27
+ class WhiteRook < WhitePiece
28
+
29
+ include Rook
30
+
31
+ attr_reader :start
32
+ def initialize(x,y)
33
+ super
34
+ @start = true
35
+ end
36
+
37
+ def to_s
38
+ "WR"
39
+ end
40
+ end
41
+
42
+ class BlackRook < BlackPiece
43
+
44
+ include Rook
45
+
46
+ attr_reader :start
47
+ def initialize(x,y)
48
+ super
49
+ @start = true
50
+ end
51
+
52
+ def to_s
53
+ "BR"
54
+ end
55
+ end
56
+
data/lib/space.rb ADDED
@@ -0,0 +1,52 @@
1
+ class EmptySpace
2
+
3
+ attr_reader :color
4
+ def initialize(x,y)
5
+ @x, @y = x, y
6
+ @color = :none
7
+ end
8
+
9
+ def place_on(board)
10
+ board.board[@y][@x] = self
11
+ end
12
+
13
+ def remove_from(board)
14
+ board.board[@y][@x] = EmptySpace.new(@x, @y)
15
+ end
16
+
17
+ def empty?
18
+ color == :none
19
+ end
20
+
21
+ def enemy_of?(piece)
22
+ false
23
+ end
24
+
25
+ def friend_of?(piece)
26
+ false
27
+ end
28
+
29
+ def to_coord
30
+ [@x, @y]
31
+ end
32
+
33
+ def to_s
34
+ (@x + @y) % 2 == 0 ? "__" : "##"
35
+ end
36
+ end
37
+
38
+ class NullSpace < EmptySpace
39
+
40
+ attr_reader :direction
41
+ def initialize
42
+ end
43
+
44
+ def to_coord
45
+ [nil, nil]
46
+ end
47
+
48
+ def place_on(board)
49
+ end
50
+ end
51
+
52
+
data/rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake'
2
+
3
+ task :run_all_tests do
4
+ Dir.glob('test/*.rb').each {|file| load file}
5
+ end
6
+
7
+ task default: [:run_all_tests]
@@ -0,0 +1,63 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class BishopTest < Minitest::Test
6
+
7
+ def test_bishop_moves
8
+ board = Board.new(:empty)
9
+ bishop = WhiteBishop.new(4,4)
10
+ board.place(bishop)
11
+ board.move(bishop,5,5)
12
+ assert_equal bishop, board.at(5,5)
13
+ end
14
+
15
+ def test_bishop_moves_more_than_one_space
16
+ board = Board.new(:empty)
17
+ bishop = WhiteBishop.new(4,4)
18
+ board.place(bishop)
19
+ assert_silent do
20
+ board.move(bishop,3,3)
21
+ board.move(bishop,4,4)
22
+ board.move(bishop,5,5)
23
+ board.move(bishop,4,4)
24
+ board.move(bishop,7,7)
25
+ board.move(bishop,4,4)
26
+ board.move(bishop,1,1)
27
+ board.move(bishop,4,4)
28
+ board.move(bishop,5,3)
29
+ board.move(bishop,4,4)
30
+
31
+ board.move(bishop,3,5)
32
+ board.move(bishop,4,4)
33
+ board.move(bishop,0,0)
34
+ board.move(bishop,4,4)
35
+ board.move(bishop,1,7)
36
+ end
37
+ end
38
+
39
+ def test_bishop_cannot_move_vertically
40
+ board = Board.new(:empty)
41
+ bishop = WhiteBishop.new(4,4)
42
+ board.place(bishop)
43
+ assert_raises(Game::IllegalMove) do
44
+ board.move(bishop,4,0)
45
+ end
46
+ end
47
+
48
+ def test_bishop_cannot_jump
49
+ board = Board.new()
50
+ bishop = board.at(2,0)
51
+ assert_raises(Game::IllegalMove) do
52
+ board.move(bishop,5,3)
53
+ end
54
+ end
55
+
56
+ def test_bishop_blocked_by_friend
57
+ board = Board.new()
58
+ bishop = board.at(2,0)
59
+ assert_raises(Game::IllegalMove) do
60
+ board.move(bishop,3,1)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,81 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class CastleTest < Minitest::Test
6
+
7
+ def test_rook_moves_when_king_castles_right
8
+ board = Board.new(:empty)
9
+ king = BlackKing.new(4,7)
10
+ rook = BlackRook.new(7,7)
11
+ board.place(king)
12
+ board.place(rook)
13
+ board.move(king,6,7)
14
+ assert_equal rook, board.at(5,7)
15
+ end
16
+
17
+ def test_rook_moves_when_king_castles_left
18
+ board = Board.new(:empty)
19
+ king = BlackKing.new(4,7)
20
+ rook = BlackRook.new(0,7)
21
+ board.place(king)
22
+ board.place(rook)
23
+ board.move(king,2,7)
24
+ assert_equal rook, board.at(3,7)
25
+ end
26
+
27
+ def test_black_king_can_move_to_castle_right
28
+ board = Board.new(:empty)
29
+ king = BlackKing.new(4,7)
30
+ rook = BlackRook.new(7,7)
31
+ board.place(king)
32
+ board.place(rook)
33
+ assert_silent do
34
+ board.move(king,6,7)
35
+ end
36
+ end
37
+
38
+ def test_black_king_can_move_to_castle_left
39
+ board = Board.new(:empty)
40
+ king = BlackKing.new(4,7)
41
+ rook = BlackRook.new(0,7)
42
+ board.place(king)
43
+ board.place(rook)
44
+ assert_silent do
45
+ board.move(king,2,7)
46
+ end
47
+ end
48
+
49
+ def test_white_king_can_move_to_castle_right
50
+ board = Board.new(:empty)
51
+ king = WhiteKing.new(3,0)
52
+ rook = WhiteRook.new(7,0)
53
+ board.place(king)
54
+ board.place(rook)
55
+ assert_silent do
56
+ board.move(king,5,0)
57
+ end
58
+ end
59
+
60
+ def test_white_king_can_move_to_castle_left
61
+ board = Board.new(:empty)
62
+ king = WhiteKing.new(3,0)
63
+ rook = WhiteRook.new(0,0)
64
+ board.place(king)
65
+ board.place(rook)
66
+ assert_silent do
67
+ board.move(king,1,0)
68
+ end
69
+ end
70
+
71
+ def test_king_cannot_jump_to_castle
72
+ board = Board.new(:empty)
73
+ king = WhiteKing.new(3,0)
74
+ queen = WhiteQueen.new(4,0)
75
+ board.place(king)
76
+ board.place(queen)
77
+ assert_raises(Game::IllegalMove) do
78
+ board.move(king,5,0)
79
+ end
80
+ end
81
+ end
data/test/game_test.rb ADDED
@@ -0,0 +1,68 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+ require 'stringio'
5
+
6
+ class GameTest < Minitest::Test
7
+
8
+ def game
9
+ game = Game.new
10
+ white_pawn = game.at(1,1)
11
+ game.play([1,1],[1,3])
12
+ game
13
+ end
14
+
15
+ def white_in_check
16
+ game = Game.new
17
+ game.play([3,1],[3,3])
18
+ game.play([4,6],[4,5])
19
+ game.play([1,1],[1,3])
20
+ game.play([5,7],[1,3])
21
+ game
22
+ end
23
+
24
+ def test_can_play_white
25
+ assert_kind_of WhitePawn, game.at(1,3)
26
+ end
27
+
28
+ def test_can_play_black
29
+ this_game = game
30
+ this_game.play([6,6],[6,5])
31
+ assert_kind_of BlackPawn, this_game.at(6,5)
32
+ end
33
+
34
+ def test_game_can_undo_moves
35
+ game = white_in_check
36
+ 2.times {game.undo}
37
+ assert_kind_of EmptySpace, game.at(1,3)
38
+ end
39
+
40
+ def test_cannot_play_while_in_check
41
+ game = white_in_check
42
+ assert_raises(Game::IllegalMove) do
43
+ game.play([0,1],[0,2])
44
+ end
45
+ end
46
+
47
+ def test_cannot_move_into_check
48
+ game = white_in_check
49
+ game.play([2,1],[2,2])
50
+ game.play([6,6],[6,5])
51
+ assert_raises(Game::IllegalMove) do
52
+ game.play([2,2],[2,3])
53
+ end
54
+ end
55
+
56
+ def test_player_can_resign
57
+ out, temp = StringIO.new, $stdout
58
+ $stdout = out
59
+
60
+ game = white_in_check
61
+ game.resign
62
+
63
+ $stdout = temp
64
+ out.rewind
65
+
66
+ assert_match /White resigns, Black wins!/, out.read
67
+ end
68
+ end
data/test/king_test.rb ADDED
@@ -0,0 +1,61 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class KingTest < Minitest::Test
6
+
7
+ def test_king_moves
8
+ board = Board.new(:empty)
9
+ king = WhiteKing.new(4,4)
10
+ board.place(king)
11
+ board.move(king,4,5)
12
+ assert_equal king, board.at(4,5)
13
+ end
14
+
15
+ def test_king_can_move_in_any_direction
16
+ board = Board.new(:empty)
17
+ king = WhiteKing.new(4,4)
18
+ board.place(king)
19
+ assert_silent do
20
+ board.move(king,3,3)
21
+ board.move(king,4,4)
22
+ board.move(king,4,3)
23
+ board.move(king,4,4)
24
+ board.move(king,5,3)
25
+ board.move(king,4,4)
26
+
27
+ board.move(king,3,4)
28
+ board.move(king,4,4)
29
+ board.move(king,5,3)
30
+ board.move(king,4,4)
31
+
32
+ board.move(king,3,5)
33
+ board.move(king,4,4)
34
+ board.move(king,4,5)
35
+ board.move(king,4,4)
36
+ board.move(king,5,5)
37
+ end
38
+ end
39
+
40
+ def test_king_cannot_move_into_check
41
+ board = Board.new(:empty)
42
+ king = WhiteKing.new(3,0)
43
+ queen = BlackQueen.new(5,6)
44
+ board.place(king)
45
+ board.place(queen)
46
+ assert_raises(Game::IllegalMove) do
47
+ board.move(king,5,0)
48
+ end
49
+ end
50
+
51
+ def test_king_cannot_move_through_check
52
+ board = Board.new(:empty)
53
+ king = WhiteKing.new(3,0)
54
+ queen = BlackQueen.new(4,6)
55
+ board.place(king)
56
+ board.place(queen)
57
+ assert_raises(Game::IllegalMove) do
58
+ board.move(king,5,0)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,45 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class KnightTest < Minitest::Test
6
+
7
+ def test_knight_moves
8
+ board = Board.new(:empty)
9
+ knight = WhiteKnight.new(4,4)
10
+ board.place(knight)
11
+ board.move(knight,6,5)
12
+ assert_equal knight, board.at(6,5)
13
+ end
14
+
15
+ def test_knight_only_moves_in_l_shape
16
+ board = Board.new(:empty)
17
+ knight = WhiteKnight.new(4,4)
18
+ board.place(knight)
19
+ assert_raises(Game::IllegalMove) do
20
+ board.move(knight,6,6)
21
+ end
22
+ end
23
+
24
+ def test_knight_is_blocked_by_friend
25
+ board = Board.new(:empty)
26
+ knight = WhiteKnight.new(4,4)
27
+ pawn = WhitePawn.new(6,6)
28
+ board.place(knight)
29
+ board.place(pawn)
30
+ assert_raises(Game::IllegalMove) do
31
+ board.move(knight,6,6)
32
+ end
33
+ end
34
+
35
+ def test_knight_can_capture_enemy
36
+ board = Board.new(:empty)
37
+ knight = WhiteKnight.new(4,4)
38
+ pawn = BlackPawn.new(6,5)
39
+ board.place(knight)
40
+ board.place(pawn)
41
+ assert_silent do
42
+ board.move(knight,6,5)
43
+ end
44
+ end
45
+ end
data/test/pawn_test.rb ADDED
@@ -0,0 +1,119 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class PawnTest < Minitest::Test
6
+
7
+ def test_pawn_can_move_forward_one
8
+ board = Board.new(:empty)
9
+ pawn = WhitePawn.new(0,1)
10
+ board.place(pawn)
11
+ board.move(pawn,0,2)
12
+ assert_equal pawn, board.at(0,2)
13
+ end
14
+
15
+ def test_pawn_can_move_forward_two_if_at_starting_position
16
+ board = Board.new(:empty)
17
+ pawn = WhitePawn.new(0,1)
18
+ board.place(pawn)
19
+ board.move(pawn,0,3)
20
+ assert_equal pawn, board.at(0,3)
21
+ end
22
+
23
+ def test_pawn_cannot_move_forward_two_if_not_at_starting_position
24
+ board = Board.new(:empty)
25
+ pawn = WhitePawn.new(0,1)
26
+ board.place(pawn)
27
+ board.move(pawn,0,2)
28
+ assert_raises(Game::IllegalMove) do
29
+ board.move(pawn, 0,4)
30
+ end
31
+ end
32
+
33
+ def test_pawn_cannot_attack_forward
34
+ board = Board.new(:empty)
35
+ pawn = WhitePawn.new(0,1)
36
+ black_pawn = BlackPawn.new(0,3)
37
+ board.place(pawn)
38
+ board.place(black_pawn)
39
+ board.move(black_pawn,0,2)
40
+ assert_raises(Game::IllegalMove) do
41
+ board.move(pawn,0,2)
42
+ end
43
+ end
44
+
45
+ def test_pawn_can_attack_diagonally
46
+ board = Board.new(:empty)
47
+ pawn = WhitePawn.new(0,1)
48
+ black_pawn = BlackPawn.new(1,2)
49
+ board.place(pawn)
50
+ board.place(black_pawn)
51
+ board.move(pawn,1,2)
52
+ assert_equal pawn, board.at(1,2)
53
+ end
54
+
55
+ def test_pawn_cannot_move_where_a_piece_of_the_same_color_is
56
+ board = Board.new(:empty)
57
+ pawn = WhitePawn.new(0,1)
58
+ pawn2 = WhitePawn.new(0,2)
59
+ board.place(pawn)
60
+ board.place(pawn2)
61
+ assert_raises(Game::IllegalMove) do
62
+ board.move(pawn,0,2)
63
+ end
64
+ end
65
+
66
+ def test_pawn_cannot_jump
67
+ board = Board.new(:empty)
68
+ pawn = WhitePawn.new(0,1)
69
+ black_pawn = BlackPawn.new(0,2)
70
+ board.place(pawn)
71
+ board.place(black_pawn)
72
+ assert_raises(Game::IllegalMove) do
73
+ board.move(pawn,0,3)
74
+ end
75
+ end
76
+
77
+ def test_pawn_can_capture_en_passent
78
+ board = Board.new(:empty)
79
+ pawn = WhitePawn.new(0,1)
80
+ pawn2 = BlackPawn.new(1,3)
81
+ board.place(pawn)
82
+ board.place(pawn2)
83
+ board.move(pawn,0,3)
84
+ board.move(pawn2,0,2)
85
+ assert_equal pawn2, board.at(0,2)
86
+ end
87
+
88
+ def test_white_pawn_can_capture_en_passent
89
+ board = Board.new
90
+ white_pawn = board.at(3,1)
91
+ black_pawn = board.at(4,6)
92
+ board.move(white_pawn,3,3)
93
+ board.move(white_pawn,3,4)
94
+ board.move(black_pawn,4,4)
95
+ board.move(white_pawn,4,5)
96
+ assert_equal white_pawn, board.at(4,5)
97
+ end
98
+
99
+ def test_pawn_replaced_with_queen_when_it_reaches_the_back_row
100
+ board = Board.new(:empty)
101
+ pawn = WhitePawn.new(0,1)
102
+ 2.upto(7) {|y| board.move(pawn,0,y)}
103
+ assert_kind_of WhiteQueen, board.at(0,7)
104
+ end
105
+
106
+ def test_does_not_raise_illegal_move_twice_if_second_move_is_legal
107
+ board = Board.new
108
+ pawn = board.at(3,1)
109
+ board.move(pawn,3,3)
110
+ begin
111
+ board.move(pawn,3,5)
112
+ rescue Game::IllegalMove
113
+ :this_is_expected
114
+ end
115
+ assert_silent do
116
+ board.move(pawn,3,4)
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,103 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class QueenTest < Minitest::Test
6
+
7
+ def test_queen_moves
8
+ board = Board.new(:empty)
9
+ queen = WhiteQueen.new(4,4)
10
+ board.place(queen)
11
+ board.move(queen,4,5)
12
+ assert_equal queen, board.at(4,5)
13
+ end
14
+
15
+ def test_queen_can_move_in_any_direction
16
+ board = Board.new(:empty)
17
+ queen = WhiteQueen.new(4,4)
18
+ board.place(queen)
19
+ assert_silent do
20
+ board.move(queen,3,3)
21
+ board.move(queen,4,4)
22
+ board.move(queen,4,3)
23
+ board.move(queen,4,4)
24
+ board.move(queen,5,3)
25
+ board.move(queen,4,4)
26
+
27
+ board.move(queen,3,4)
28
+ board.move(queen,4,4)
29
+ board.move(queen,5,3)
30
+ board.move(queen,4,4)
31
+
32
+ board.move(queen,3,5)
33
+ board.move(queen,4,4)
34
+ board.move(queen,4,5)
35
+ board.move(queen,4,4)
36
+ board.move(queen,5,5)
37
+ end
38
+ end
39
+
40
+ def test_queen_can_move_in_any_direction_for_any_number_of_spaces
41
+ board = Board.new(:empty)
42
+ queen = WhiteQueen.new(4,4)
43
+ board.place(queen)
44
+ assert_silent do
45
+ board.move(queen,0,0)
46
+ board.move(queen,4,4)
47
+
48
+ board.move(queen,4,2)
49
+ board.move(queen,4,4)
50
+
51
+ board.move(queen,7,1)
52
+ board.move(queen,4,4)
53
+
54
+ board.move(queen,5,5)
55
+ board.move(queen,4,4)
56
+
57
+ board.move(queen,4,7)
58
+ board.move(queen,4,4)
59
+
60
+ board.move(queen,1,7)
61
+ board.move(queen,4,4)
62
+
63
+ board.move(queen,2,4)
64
+ board.move(queen,4,4)
65
+
66
+ board.move(queen,6,4)
67
+ end
68
+ end
69
+
70
+ def test_queen_cannot_move_in_an_l
71
+ board = Board.new(:empty)
72
+ queen = WhiteQueen.new(4,4)
73
+ board.place(queen)
74
+ assert_raises(Game::IllegalMove) do
75
+ board.move(queen,6,5)
76
+ end
77
+ end
78
+
79
+ def test_queen_cannot_jump
80
+ board = Board.new(:empty)
81
+ queen = WhiteQueen.new(4,4)
82
+ pawn = BlackPawn.new(1,1)
83
+ board.place(queen)
84
+ board.place(pawn)
85
+ assert_raises(Game::IllegalMove) do
86
+ board.move(queen,0,0)
87
+ end
88
+ end
89
+
90
+ def test_queen_can_capture_an_enemy_piece
91
+ board = Board.new
92
+ queen = BlackQueen.new(4,4)
93
+ # White Pawn at (1,1)
94
+ assert_silent {board.move(queen, 1,1)}
95
+ end
96
+
97
+ def test_queen_cannot_move_to_space_occupied_by_a_friend
98
+ board = Board.new
99
+ queen = BlackQueen.new(4,4)
100
+ # Black Pawn at (6,6)
101
+ assert_raises(Game::IllegalMove) {board.move(queen, 6,6)}
102
+ end
103
+ end
data/test/rook_test.rb ADDED
@@ -0,0 +1,41 @@
1
+ require_relative '../lib/chess'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class RookTest < Minitest::Test
6
+
7
+ def test_rook_moves
8
+ board = Board.new(:empty)
9
+ rook = WhiteRook.new(4,4)
10
+ board.place(rook)
11
+ board.move(rook,4,5)
12
+ assert_equal rook, board.at(4,5)
13
+ end
14
+
15
+ def test_rook_can_move_in_any_direction
16
+ board = Board.new(:empty)
17
+ rook = WhiteRook.new(4,4)
18
+ board.place(rook)
19
+ assert_silent do
20
+ board.move(rook,4,6)
21
+ board.move(rook,4,4)
22
+ board.move(rook,6,4)
23
+ board.move(rook,4,4)
24
+
25
+ board.move(rook,7,4)
26
+ board.move(rook,4,4)
27
+ board.move(rook,1,4)
28
+ board.move(rook,4,4)
29
+ board.move(rook,4,0)
30
+ end
31
+ end
32
+
33
+ def test_rook_cannot_move_diagonally
34
+ board = Board.new(:empty)
35
+ rook = BlackRook.new(7,7)
36
+ board.place(rook)
37
+ assert_raises(Game::IllegalMove) do
38
+ board.move(rook,4,4)
39
+ end
40
+ end
41
+ end