tictactien-gem 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +29 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/ai.rb +2 -0
- data/lib/board.rb +114 -0
- data/lib/console_game.rb +79 -0
- data/lib/cpu_player.rb +17 -0
- data/lib/game.rb +25 -0
- data/lib/game_state.rb +24 -0
- data/lib/human_player.rb +9 -0
- data/lib/minimax.rb +132 -0
- data/lib/perfect_ai.rb +14 -0
- data/lib/player.rb +7 -0
- data/lib/player_factory.rb +20 -0
- data/lib/rails_game.rb +36 -0
- data/lib/random_ai.rb +7 -0
- data/lib/tictactien-gem.rb +35 -0
- data/spec/ai_spec.rb +5 -0
- data/spec/board_spec.rb +75 -0
- data/spec/console_game_spec.rb +9 -0
- data/spec/cpu_player_spec.rb +21 -0
- data/spec/game_spec.rb +30 -0
- data/spec/game_state_spec.rb +34 -0
- data/spec/human_player_spec.rb +15 -0
- data/spec/minimax_spec.rb +130 -0
- data/spec/perfect_ai_spec.rb +35 -0
- data/spec/player_factory_spec.rb +26 -0
- data/spec/player_spec.rb +8 -0
- data/spec/rails_game_spec.rb +79 -0
- data/spec/random_ai_spec.rb +16 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/spec_helper_jeweler.rb +12 -0
- data/spec/tictactien-gem_spec.rb +45 -0
- data/tictactien-gem.gemspec +90 -0
- metadata +146 -0
data/spec/board_spec.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Board" do
|
4
|
+
|
5
|
+
it "returns its new grid" do
|
6
|
+
board = Board.new
|
7
|
+
board.grid.should == [[nil, nil, nil],
|
8
|
+
[nil, nil, nil],
|
9
|
+
[nil, nil, nil]]
|
10
|
+
end
|
11
|
+
|
12
|
+
['x', 'o'].each do |player_token|
|
13
|
+
[
|
14
|
+
[[], [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]],
|
15
|
+
[[[0,0]], [[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]],
|
16
|
+
[[[0,0],[0,1],[0,2]], [[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]],
|
17
|
+
[[[0,0],[0,1],[0,2],[1,0]], [[1,1],[1,2],[2,0],[2,1],[2,2]]],
|
18
|
+
[[[0,0],[0,1],[0,2],[1,0],[1,1]], [[1,2],[2,0],[2,1],[2,2]]],
|
19
|
+
[[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]], [[2,0],[2,1],[2,2]]],
|
20
|
+
[[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0]], [[2,1],[2,2]]],
|
21
|
+
[[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1]], [[2,2]]],
|
22
|
+
[[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]], []],
|
23
|
+
].each do |pieces, spaces|
|
24
|
+
it "finds available spaces" do
|
25
|
+
board = Board.new
|
26
|
+
pieces.each do |piece|
|
27
|
+
board.add_piece(player_token, piece)
|
28
|
+
end
|
29
|
+
board.available_spaces.should == spaces
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
['x', 'o'].each do |player_token|
|
35
|
+
[
|
36
|
+
[[0,0], [[player_token, nil, nil], [nil, nil, nil], [nil, nil, nil]]],
|
37
|
+
[[0,1], [[nil, player_token, nil], [nil, nil, nil], [nil, nil, nil]]],
|
38
|
+
[[0,2], [[nil, nil, player_token], [nil, nil, nil], [nil, nil, nil]]],
|
39
|
+
[[1,0], [[nil, nil, nil], [player_token, nil, nil], [nil, nil, nil]]],
|
40
|
+
[[1,1], [[nil, nil, nil], [nil, player_token, nil], [nil, nil, nil]]],
|
41
|
+
[[1,2], [[nil, nil, nil], [nil, nil, player_token], [nil, nil, nil]]],
|
42
|
+
[[2,0], [[nil, nil, nil], [nil, nil, nil], [player_token, nil, nil]]],
|
43
|
+
[[2,1], [[nil, nil, nil], [nil, nil, nil], [nil, player_token, nil]]],
|
44
|
+
[[2,2], [[nil, nil, nil], [nil, nil, nil], [nil, nil, player_token]]],
|
45
|
+
].each do |location, grid|
|
46
|
+
it "adds a piece to its grid at loc #{location.first},#{location.last}" do
|
47
|
+
board = Board.new
|
48
|
+
board.add_piece(player_token, location)
|
49
|
+
board.grid.should == grid
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
['x', 'o'].each do |player_token|
|
55
|
+
[
|
56
|
+
[[], nil],
|
57
|
+
[[[0,0],[1,1],[2,2]], player_token],
|
58
|
+
[[[0,2],[1,1],[2,0]], player_token],
|
59
|
+
[[[0,0],[0,1],[0,2]], player_token],
|
60
|
+
[[[1,0],[1,1],[1,2]], player_token],
|
61
|
+
[[[2,0],[2,1],[2,2]], player_token],
|
62
|
+
[[[0,0],[1,0],[2,0]], player_token],
|
63
|
+
[[[0,1],[1,1],[2,1]], player_token],
|
64
|
+
[[[0,2],[1,2],[2,2]], player_token],
|
65
|
+
].each do |pieces, result|
|
66
|
+
it "checks for a winning player" do
|
67
|
+
board = Board.new
|
68
|
+
pieces.each do |piece|
|
69
|
+
board.add_piece(player_token, piece)
|
70
|
+
end
|
71
|
+
board.calculate_win.should == result
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "CpuPlayer" do
|
4
|
+
it "it has an AI" do
|
5
|
+
cpu_player = CpuPlayer.new('x', RandomAi.new)
|
6
|
+
|
7
|
+
cpu_player.ai.should_not be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it "performs a move" do
|
11
|
+
cpu_player = CpuPlayer.new('x', RandomAi.new)
|
12
|
+
game_state = GameState.new(cpu_player)
|
13
|
+
board = game_state.board
|
14
|
+
|
15
|
+
move = mock('move', :first => 0, :last => 0)
|
16
|
+
cpu_player.ai.should_receive(:calculate_move).with(board, cpu_player).and_return(move)
|
17
|
+
board.should_receive(:add_piece).with(cpu_player.token, move)
|
18
|
+
|
19
|
+
cpu_player.perform_move(game_state)
|
20
|
+
end
|
21
|
+
end
|
data/spec/game_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Game" do
|
4
|
+
it "creates a new game" do
|
5
|
+
player_one = PlayerFactory.create_player('Random CPU', 'x')
|
6
|
+
player_two = PlayerFactory.create_player('Random CPU', 'o')
|
7
|
+
|
8
|
+
game = Game.new
|
9
|
+
game.players = {:one => player_one, :two => player_two}
|
10
|
+
game.game_state = GameState.new(player_one)
|
11
|
+
|
12
|
+
game.game_state.should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "switches the active player" do
|
16
|
+
player_one = PlayerFactory.create_player('Random CPU', 'x')
|
17
|
+
player_two = PlayerFactory.create_player('Random CPU', 'o')
|
18
|
+
|
19
|
+
game = Game.new
|
20
|
+
game.players = {:one => player_one, :two => player_two}
|
21
|
+
game.game_state = GameState.new(player_one)
|
22
|
+
|
23
|
+
game.switch_active_player
|
24
|
+
game.game_state.active_player.should == player_two
|
25
|
+
game.switch_active_player
|
26
|
+
game.game_state.active_player.should == player_one
|
27
|
+
game.switch_active_player
|
28
|
+
game.game_state.active_player.should == player_two
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "GameState" do
|
4
|
+
it "creates a snapshot of the current game state" do
|
5
|
+
board = Board.new
|
6
|
+
active_player = Player.new('x')
|
7
|
+
|
8
|
+
game_state = GameState.new(board, active_player)
|
9
|
+
|
10
|
+
game_state.board.should == board
|
11
|
+
game_state.active_player.should == active_player
|
12
|
+
end
|
13
|
+
|
14
|
+
it "updates its board state with a new move" do
|
15
|
+
board = Board.new
|
16
|
+
active_player = Player.new('x')
|
17
|
+
game_state = GameState.new(board, active_player)
|
18
|
+
|
19
|
+
move = mock('move', :first => 0, :last => 0)
|
20
|
+
game_state.board.should_receive(:add_piece).with(game_state.active_player.token, move)
|
21
|
+
game_state.update(move)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "does not update its board state with an invalid move" do
|
25
|
+
board = Board.new
|
26
|
+
board.grid[0][0] = 'x'
|
27
|
+
active_player = Player.new('x')
|
28
|
+
game_state = GameState.new(board, active_player)
|
29
|
+
|
30
|
+
move = mock('move', :first => 0, :last => 0)
|
31
|
+
game_state.board.should_receive(:add_piece).with(game_state.active_player.token, move).and_return(false)
|
32
|
+
game_state.update(move)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "HumanPlayer" do
|
4
|
+
it "performs a move" do
|
5
|
+
human_player = HumanPlayer.new('x')
|
6
|
+
game_state = GameState.new(human_player)
|
7
|
+
board = game_state.board
|
8
|
+
|
9
|
+
move = [0, 0]
|
10
|
+
# Game.stub(:ask_move).with(board, human_player.token).and_return(move)
|
11
|
+
board.should_receive(:add_piece).with(human_player.token, move)
|
12
|
+
|
13
|
+
human_player.perform_move(game_state, move)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Minimax" do
|
4
|
+
it "is created with a grid, a move and a player" do
|
5
|
+
board = Board.new
|
6
|
+
board.grid =
|
7
|
+
[[nil, nil, nil],
|
8
|
+
[nil, nil, nil],
|
9
|
+
[nil, nil, nil]]
|
10
|
+
last_move = [0, 0]
|
11
|
+
current_player = Player.new('x')
|
12
|
+
|
13
|
+
minimax_node = Minimax.new(board, last_move, current_player.token, current_player.token)
|
14
|
+
|
15
|
+
minimax_node.board.should == board
|
16
|
+
minimax_node.last_move.should == last_move
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
it "evaluates a score for a game in progress" do
|
21
|
+
board = Board.new
|
22
|
+
board.grid =
|
23
|
+
[[nil, nil, nil],
|
24
|
+
[nil, nil, nil],
|
25
|
+
[nil, nil, nil]]
|
26
|
+
|
27
|
+
current_player = Player.new('x')
|
28
|
+
|
29
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
30
|
+
minimax_node.game_ended.should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "evaluates the score for a winning game" do
|
34
|
+
board = Board.new
|
35
|
+
board.grid =
|
36
|
+
[['x', nil, nil],
|
37
|
+
[nil, 'x', nil],
|
38
|
+
[nil, nil, 'x']]
|
39
|
+
|
40
|
+
current_player = Player.new('x')
|
41
|
+
|
42
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
43
|
+
minimax_node.game_ended.should == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
it "evaluates the score for a losing game" do
|
47
|
+
board = Board.new
|
48
|
+
board.grid =
|
49
|
+
[[nil, nil, nil],
|
50
|
+
['o', 'o', 'o'],
|
51
|
+
[nil, nil, nil]]
|
52
|
+
|
53
|
+
current_player = Player.new('x')
|
54
|
+
|
55
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
56
|
+
minimax_node.game_ended.should == -1
|
57
|
+
end
|
58
|
+
|
59
|
+
it "evaluates the score for a cat game" do
|
60
|
+
board = Board.new
|
61
|
+
board.grid =
|
62
|
+
[['x', 'x', 'o'],
|
63
|
+
['o', 'o', 'x'],
|
64
|
+
['x', 'o', 'x']]
|
65
|
+
|
66
|
+
current_player = Player.new('x')
|
67
|
+
|
68
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
69
|
+
minimax_node.game_ended.should == 0
|
70
|
+
end
|
71
|
+
|
72
|
+
it "correctly evaluates the score of a sure game" do
|
73
|
+
board = Board.new
|
74
|
+
board.grid =
|
75
|
+
[['x', 'x', nil],
|
76
|
+
['o', 'o', 'x'],
|
77
|
+
['o', 'o', 'x']]
|
78
|
+
|
79
|
+
current_player = Player.new('x')
|
80
|
+
|
81
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
82
|
+
minimax_node.build_tree
|
83
|
+
|
84
|
+
minimax_node.score.should == 1
|
85
|
+
end
|
86
|
+
|
87
|
+
it "correctly evaluates the score of a cat game" do
|
88
|
+
board = Board.new
|
89
|
+
board.grid =
|
90
|
+
[['x', 'x', 'o'],
|
91
|
+
['o', 'o', 'x'],
|
92
|
+
['x', 'o', nil]]
|
93
|
+
|
94
|
+
current_player = Player.new('x')
|
95
|
+
|
96
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
97
|
+
minimax_node.build_tree
|
98
|
+
|
99
|
+
minimax_node.score.should == 0
|
100
|
+
end
|
101
|
+
|
102
|
+
it "correctly evaluates the score of a lost game" do
|
103
|
+
board = Board.new
|
104
|
+
board.grid =
|
105
|
+
[['x', 'x', nil],
|
106
|
+
['x', 'o', 'o'],
|
107
|
+
[nil, 'o', 'x']]
|
108
|
+
|
109
|
+
current_player = Player.new('o')
|
110
|
+
|
111
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
112
|
+
minimax_node.build_tree
|
113
|
+
|
114
|
+
minimax_node.score.should == -1
|
115
|
+
end
|
116
|
+
|
117
|
+
it "gets the next best move" do
|
118
|
+
board = Board.new
|
119
|
+
board.grid =
|
120
|
+
[['x', 'x', nil],
|
121
|
+
[nil, 'o', nil],
|
122
|
+
[nil, nil, nil]]
|
123
|
+
|
124
|
+
current_player = Player.new('o')
|
125
|
+
|
126
|
+
minimax_node = Minimax.new(board, nil, current_player.token, current_player.token)
|
127
|
+
minimax_node.build_tree
|
128
|
+
minimax_node.get_next_move.should == [0,2]
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "PerfectAi" do
|
4
|
+
it "calculates a perfect move 1" do
|
5
|
+
perfect_ai = PerfectAi.new
|
6
|
+
board = Board.new
|
7
|
+
current_player = Player.new('x')
|
8
|
+
|
9
|
+
perfect_ai.calculate_move(board, current_player).should == [0,0]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "calculates a perfect move 2" do
|
13
|
+
perfect_ai = PerfectAi.new
|
14
|
+
board = Board.new
|
15
|
+
current_player = Player.new('o')
|
16
|
+
|
17
|
+
board.grid = [['x', nil, nil],
|
18
|
+
[nil, nil, nil],
|
19
|
+
[nil, nil, nil]]
|
20
|
+
|
21
|
+
perfect_ai.calculate_move(board, current_player).should == [1,1]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "calculates a perfect move 3" do
|
25
|
+
perfect_ai = PerfectAi.new
|
26
|
+
board = Board.new
|
27
|
+
current_player = Player.new('x')
|
28
|
+
|
29
|
+
board.grid = [['x', nil, nil],
|
30
|
+
[nil, 'o', nil],
|
31
|
+
[nil, nil, nil]]
|
32
|
+
|
33
|
+
perfect_ai.calculate_move(board, current_player).should == [0,1]
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "PlayerFactory" do
|
4
|
+
it "creates a human player" do
|
5
|
+
human = PlayerFactory.create_player(PlayerFactory::HUMAN, 'x')
|
6
|
+
|
7
|
+
human.class.should == HumanPlayer
|
8
|
+
human.token.should == 'x'
|
9
|
+
end
|
10
|
+
|
11
|
+
it "creates a random cpu player" do
|
12
|
+
random_cpu = PlayerFactory.create_player(PlayerFactory::RANDOM_CPU, 'x')
|
13
|
+
|
14
|
+
random_cpu.class.should == CpuPlayer
|
15
|
+
random_cpu.token.should == 'x'
|
16
|
+
random_cpu.ai.class.should == RandomAi
|
17
|
+
end
|
18
|
+
|
19
|
+
it "creates a perfect cpu player" do
|
20
|
+
perfect_cpu = PlayerFactory.create_player(PlayerFactory::PERFECT_CPU, 'o')
|
21
|
+
|
22
|
+
perfect_cpu.class.should == CpuPlayer
|
23
|
+
perfect_cpu.token.should == 'o'
|
24
|
+
perfect_cpu.ai.class.should == PerfectAi
|
25
|
+
end
|
26
|
+
end
|
data/spec/player_spec.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "RailsGame" do
|
4
|
+
it "chooses the first player as human" do
|
5
|
+
rails_game = RailsGame.new
|
6
|
+
rails_game.choose_player_one("Human")
|
7
|
+
|
8
|
+
rails_game.players[:one].class.should == HumanPlayer
|
9
|
+
rails_game.players[:one].token.should == 'x'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "chooses the first player as a Random CPU" do
|
13
|
+
rails_game = RailsGame.new
|
14
|
+
rails_game.choose_player_one("RandomCPU")
|
15
|
+
|
16
|
+
rails_game.players[:one].class.should == CpuPlayer
|
17
|
+
rails_game.players[:one].ai.class.should == RandomAi
|
18
|
+
rails_game.players[:one].token.should == 'x'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "chooses the second player as a Perfect CPU" do
|
22
|
+
rails_game = RailsGame.new
|
23
|
+
rails_game.choose_player_two("PerfectCPU")
|
24
|
+
|
25
|
+
rails_game.players[:two].class.should == CpuPlayer
|
26
|
+
rails_game.players[:two].ai.class.should == PerfectAi
|
27
|
+
rails_game.players[:two].token.should == 'o'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "starts a rails game" do
|
31
|
+
rails_game = RailsGame.new
|
32
|
+
rails_game.choose_player_one("Human")
|
33
|
+
rails_game.choose_player_two("RandomCPU")
|
34
|
+
|
35
|
+
rails_game.start
|
36
|
+
|
37
|
+
rails_game.game_state.active_player.should == rails_game.players[:one]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "updates its state with a new move" do
|
41
|
+
rails_game = RailsGame.new
|
42
|
+
rails_game.choose_player_one("Human")
|
43
|
+
rails_game.choose_player_two("RandomCPU")
|
44
|
+
|
45
|
+
rails_game.start
|
46
|
+
|
47
|
+
move = mock('move', :first => 0, :last => 0)
|
48
|
+
rails_game.game_state.should_receive(:update).with(move)
|
49
|
+
rails_game.stub!(:switch_active_player)
|
50
|
+
|
51
|
+
rails_game.update(move)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "updates its state by switching the active player" do
|
55
|
+
rails_game = RailsGame.new
|
56
|
+
rails_game.choose_player_one("Human")
|
57
|
+
rails_game.choose_player_two("RandomCPU")
|
58
|
+
|
59
|
+
rails_game.start
|
60
|
+
|
61
|
+
move = mock('move', :first => 0, :last => 0)
|
62
|
+
rails_game.game_state.stub!(:update).with(move).and_return(true)
|
63
|
+
rails_game.should_receive(:switch_active_player)
|
64
|
+
|
65
|
+
rails_game.update(move)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "prints the current board" do
|
69
|
+
rails_game = RailsGame.new
|
70
|
+
rails_game.choose_player_one("Human")
|
71
|
+
rails_game.choose_player_two("RandomCPU")
|
72
|
+
|
73
|
+
rails_game.start
|
74
|
+
|
75
|
+
rails_game.game_state.board.should_receive(:print)
|
76
|
+
|
77
|
+
rails_game.print_board
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "RandomAi" do
|
4
|
+
it "calculates a random move" do
|
5
|
+
random_ai = RandomAi.new
|
6
|
+
board = Board.new
|
7
|
+
current_player = Player.new('x')
|
8
|
+
|
9
|
+
available_spaces = mock("list of spaces")
|
10
|
+
board.stub!(:available_spaces).and_return(available_spaces)
|
11
|
+
available_spaces.should_receive(:sample).and_return("the move")
|
12
|
+
|
13
|
+
random_ai.calculate_move(board, current_player).should == "the move"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Dir["../lib/*.rb"].each {|file| require file }
|
2
|
+
#require '../lib/tictactien-gem'
|
3
|
+
#require '../lib/board'
|
4
|
+
#require '../lib/game'
|
5
|
+
#require '../lib/console_game'
|
6
|
+
#require '../lib/ai'
|
7
|
+
#require '../lib/player'
|
8
|
+
#require '../lib/human_player'
|
9
|
+
#require '../lib/cpu_player'
|
10
|
+
#require '../lib/minimax'
|
11
|
+
#require '../lib/perfect_ai'
|
12
|
+
#require '../lib/random_ai'
|
13
|
+
#require '../lib/player_factory'
|
14
|
+
#require '../lib/game_state'
|
15
|
+
|
16
|
+
require 'tictactien-gem'
|
17
|
+
require 'board'
|
18
|
+
require 'game'
|
19
|
+
require 'rails_game'
|
20
|
+
require 'console_game'
|
21
|
+
require 'ai'
|
22
|
+
require 'player'
|
23
|
+
require 'human_player'
|
24
|
+
require 'cpu_player'
|
25
|
+
require 'minimax'
|
26
|
+
require 'perfect_ai'
|
27
|
+
require 'random_ai'
|
28
|
+
require 'player_factory'
|
29
|
+
require 'game_state'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'tictactien-gem'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Tictactien" do
|
4
|
+
# it "creates a human player" do
|
5
|
+
# human = Tictactien.create_player(Tictactien::HUMAN, 'x')
|
6
|
+
#
|
7
|
+
# human.class.should == HumanPlayer
|
8
|
+
# human.token.should == 'x'
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# it "creates a random cpu player" do
|
12
|
+
# random_cpu = Tictactien.create_player(Tictactien::RANDOM_CPU, 'x')
|
13
|
+
#
|
14
|
+
# random_cpu.class.should == CpuPlayer
|
15
|
+
# random_cpu.token.should == 'x'
|
16
|
+
# random_cpu.ai.class.should == RandomAi
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# it "creates a perfect cpu player" do
|
20
|
+
# perfect_cpu = Tictactien.create_player(Tictactien::PERFECT_CPU, 'o')
|
21
|
+
#
|
22
|
+
# perfect_cpu.class.should == CpuPlayer
|
23
|
+
# perfect_cpu.token.should == 'o'
|
24
|
+
# perfect_cpu.ai.class.should == PerfectAi
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# it "creates a snapshot of the current game state" do
|
28
|
+
# active_player = Player.new('x')
|
29
|
+
#
|
30
|
+
# game_state = Tictactien.create_new_game(active_player)
|
31
|
+
#
|
32
|
+
# game_state.board.should_not be_nil
|
33
|
+
# game_state.active_player.should == active_player
|
34
|
+
# end
|
35
|
+
|
36
|
+
# it "adds a piece to the board" do
|
37
|
+
# game_state = Tictactien.create_new_game('x')
|
38
|
+
# location = [0,0]
|
39
|
+
# Tictactien.add_piece(game_state.board, game_state.active_player, location)
|
40
|
+
#
|
41
|
+
# game_state.board.grid.should == [['x', nil, nil],
|
42
|
+
# [nil, nil, nil],
|
43
|
+
# [nil, nil, nil]]
|
44
|
+
# end
|
45
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{tictactien-gem}
|
8
|
+
s.version = "0.3.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Tien H. Nguyen"]
|
12
|
+
s.date = %q{2011-06-20}
|
13
|
+
s.description = %q{Tic-Tac-Toe game in Ruby...}
|
14
|
+
s.email = %q{nht007@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"lib/ai.rb",
|
29
|
+
"lib/board.rb",
|
30
|
+
"lib/console_game.rb",
|
31
|
+
"lib/cpu_player.rb",
|
32
|
+
"lib/game.rb",
|
33
|
+
"lib/game_state.rb",
|
34
|
+
"lib/human_player.rb",
|
35
|
+
"lib/minimax.rb",
|
36
|
+
"lib/perfect_ai.rb",
|
37
|
+
"lib/player.rb",
|
38
|
+
"lib/player_factory.rb",
|
39
|
+
"lib/rails_game.rb",
|
40
|
+
"lib/random_ai.rb",
|
41
|
+
"lib/tictactien-gem.rb",
|
42
|
+
"spec/ai_spec.rb",
|
43
|
+
"spec/board_spec.rb",
|
44
|
+
"spec/console_game_spec.rb",
|
45
|
+
"spec/cpu_player_spec.rb",
|
46
|
+
"spec/game_spec.rb",
|
47
|
+
"spec/game_state_spec.rb",
|
48
|
+
"spec/human_player_spec.rb",
|
49
|
+
"spec/minimax_spec.rb",
|
50
|
+
"spec/perfect_ai_spec.rb",
|
51
|
+
"spec/player_factory_spec.rb",
|
52
|
+
"spec/player_spec.rb",
|
53
|
+
"spec/rails_game_spec.rb",
|
54
|
+
"spec/random_ai_spec.rb",
|
55
|
+
"spec/spec_helper.rb",
|
56
|
+
"spec/spec_helper_jeweler.rb",
|
57
|
+
"spec/tictactien-gem_spec.rb",
|
58
|
+
"tictactien-gem.gemspec"
|
59
|
+
]
|
60
|
+
s.homepage = %q{http://github.com/nht007/tictactien-gem}
|
61
|
+
s.licenses = ["MIT"]
|
62
|
+
s.require_paths = ["lib"]
|
63
|
+
s.rubygems_version = %q{1.6.2}
|
64
|
+
s.summary = %q{Tic-Tac-Toe game in Ruby}
|
65
|
+
|
66
|
+
if s.respond_to? :specification_version then
|
67
|
+
s.specification_version = 3
|
68
|
+
|
69
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
70
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
71
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
|
73
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
74
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
75
|
+
else
|
76
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
77
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
78
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
79
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
80
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
81
|
+
end
|
82
|
+
else
|
83
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
84
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
85
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
86
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
87
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|