tic_tac_toes 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +8 -0
- data/Rakefile +25 -0
- data/bin/tic_tac_toes +23 -0
- data/lib/command_line/io.rb +27 -0
- data/lib/command_line/menu.rb +54 -0
- data/lib/command_line/runner.rb +37 -0
- data/lib/database/pg_wrapper.rb +72 -0
- data/lib/tic_tac_toes/board.rb +62 -0
- data/lib/tic_tac_toes/easy_ai.rb +9 -0
- data/lib/tic_tac_toes/hard_ai.rb +57 -0
- data/lib/tic_tac_toes/history.rb +27 -0
- data/lib/tic_tac_toes/io_interface.rb +96 -0
- data/lib/tic_tac_toes/medium_ai.rb +11 -0
- data/lib/tic_tac_toes/player.rb +20 -0
- data/lib/tic_tac_toes/player_factory.rb +24 -0
- data/lib/tic_tac_toes/rules.rb +64 -0
- data/lib/tic_tac_toes/strings.rb +103 -0
- data/lib/tic_tac_toes/version.rb +3 -0
- data/spec/command_line/menu_spec.rb +103 -0
- data/spec/command_line/runner_spec.rb +119 -0
- data/spec/database/pg_wrapper_spec.rb +56 -0
- data/spec/tic_tac_toes/board_spec.rb +104 -0
- data/spec/tic_tac_toes/easy_ai_spec.rb +20 -0
- data/spec/tic_tac_toes/hard_ai_spec.rb +103 -0
- data/spec/tic_tac_toes/history_spec.rb +41 -0
- data/spec/tic_tac_toes/io_interface_spec.rb +175 -0
- data/spec/tic_tac_toes/medium_ai_spec.rb +22 -0
- data/spec/tic_tac_toes/player_factory_spec.rb +34 -0
- data/spec/tic_tac_toes/player_spec.rb +34 -0
- data/spec/tic_tac_toes/rules_spec.rb +159 -0
- data/spec/tic_tac_toes/spec_helper.rb +13 -0
- data/spec/tic_tac_toes/strings_spec.rb +50 -0
- data/tic_tac_toes.gemspec +24 -0
- metadata +151 -0
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'tic_tac_toes/board'
|
2
|
+
require 'tic_tac_toes/io_interface'
|
3
|
+
require 'tic_tac_toes/spec_helper'
|
4
|
+
require 'tic_tac_toes/strings'
|
5
|
+
|
6
|
+
describe TicTacToes::IOInterface do
|
7
|
+
let(:strings) { TicTacToes::Strings }
|
8
|
+
let(:io) { double("io", solicit_input: 0, display: true, display_red: true) }
|
9
|
+
let(:io_interface) { TicTacToes::IOInterface.new(io) }
|
10
|
+
|
11
|
+
|
12
|
+
describe '#make_move' do
|
13
|
+
it "displays a move solicitation" do
|
14
|
+
expect(io_interface).to receive(:move_solicitation)
|
15
|
+
io_interface.make_move("_board", "_players")
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when given not-integer-like input' do
|
19
|
+
let(:not_integer_like) { "string" }
|
20
|
+
let(:integer_like) { "100" }
|
21
|
+
|
22
|
+
it "displays a not an integer error" do
|
23
|
+
allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
|
24
|
+
|
25
|
+
expect(io_interface).to receive(:not_an_integer_error).once
|
26
|
+
io_interface.make_move("_board", "_players")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "only returns a move (converted to integer) once it gets integer-like input" do
|
30
|
+
allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
|
31
|
+
|
32
|
+
expect(io_interface.make_move("_board", "_players")).to eq(100)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
describe '#get_row_size' do
|
39
|
+
it "displays a row size solicitation" do
|
40
|
+
expect(io_interface).to receive(:row_size_solicitation)
|
41
|
+
io_interface.get_row_size
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when given not-integer-like input' do
|
45
|
+
let(:not_integer_like) { "string" }
|
46
|
+
let(:integer_like) { "100" }
|
47
|
+
|
48
|
+
it "displays a not an integer error" do
|
49
|
+
allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
|
50
|
+
|
51
|
+
expect(io_interface).to receive(:not_an_integer_error).once
|
52
|
+
io_interface.get_row_size
|
53
|
+
end
|
54
|
+
|
55
|
+
it "only returns a row size (converted to integer) once it gets integer-like input" do
|
56
|
+
allow(io).to receive(:solicit_input).and_return(not_integer_like, integer_like)
|
57
|
+
|
58
|
+
expect(io_interface.get_row_size).to eq(100)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
describe '#get_token' do
|
65
|
+
let(:player) { double("player") }
|
66
|
+
|
67
|
+
it "displays a token solicitation with the name of the player whose token is to be set" do
|
68
|
+
expect(io_interface).to receive(:token_solicitation).with(player)
|
69
|
+
io_interface.get_token(player)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns the user input" do
|
73
|
+
token = "X"
|
74
|
+
allow(io).to receive(:solicit_input) { token }
|
75
|
+
|
76
|
+
expect(io_interface.get_token(player)).to equal(token)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
describe '#get_difficulty' do
|
82
|
+
let(:difficulty) { "HARD" }
|
83
|
+
|
84
|
+
it "displays a difficulty solicitation" do
|
85
|
+
allow(io).to receive(:solicit_input) { difficulty }
|
86
|
+
|
87
|
+
expect(io_interface).to receive(:difficulty_solicitation)
|
88
|
+
io_interface.get_difficulty
|
89
|
+
end
|
90
|
+
|
91
|
+
it "returns the user input (downcased and converted into a symbol)" do
|
92
|
+
allow(io).to receive(:solicit_input) { difficulty }
|
93
|
+
|
94
|
+
expect(io_interface.get_difficulty).to equal(:hard)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
describe '#draw_board' do
|
100
|
+
it "displays a board string" do
|
101
|
+
board = TicTacToes::Board.new
|
102
|
+
board_string = strings.board(board)
|
103
|
+
|
104
|
+
expect(io).to receive(:display).with(board_string)
|
105
|
+
io_interface.draw_board(board)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
describe '#invalid_row_size_error' do
|
111
|
+
it "displays a red invalid row size message" do
|
112
|
+
expect(io).to receive(:display_red).with(strings::INVALID_ROW_SIZE)
|
113
|
+
io_interface.invalid_row_size_error
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
describe '#invalid_token_error' do
|
119
|
+
it "displays a red invalid token message" do
|
120
|
+
expect(io).to receive(:display_red).with(strings::INVALID_TOKEN)
|
121
|
+
io_interface.invalid_token_error
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
describe '#invalid_difficulty_error' do
|
127
|
+
it "displays a red invalid difficulty message" do
|
128
|
+
expect(io).to receive(:display_red).with(strings::INVALID_DIFFICULTY)
|
129
|
+
io_interface.invalid_difficulty_error
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
describe '#invalid_move_error' do
|
135
|
+
it "displays a red invalid move message" do
|
136
|
+
expect(io).to receive(:display_red).with(strings::INVALID_MOVE)
|
137
|
+
io_interface.invalid_move_error
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
describe '#thinking_notification' do
|
143
|
+
it "displays a red thinking message" do
|
144
|
+
expect(io).to receive(:display_red).with(strings::THINKING)
|
145
|
+
io_interface.thinking_notification
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
describe '#game_over_notification' do
|
151
|
+
it "displays a game over message with the name of the winner" do
|
152
|
+
winner = :X
|
153
|
+
game_over_message = strings.game_over_notification(winner)
|
154
|
+
|
155
|
+
expect(io).to receive(:display).with(game_over_message)
|
156
|
+
io_interface.game_over_notification(winner)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
describe '#red' do
|
162
|
+
it "calls its IO's red method with the passed message" do
|
163
|
+
expect(io).to receive(:red).with("message")
|
164
|
+
io_interface.red("message")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
describe '#blue' do
|
170
|
+
it "calls its IO's blue method with the passed message" do
|
171
|
+
expect(io).to receive(:blue).with("message")
|
172
|
+
io_interface.blue("message")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'tic_tac_toes/medium_ai'
|
2
|
+
require 'tic_tac_toes/spec_helper'
|
3
|
+
|
4
|
+
describe TicTacToes::MediumAI do
|
5
|
+
let(:ai) { TicTacToes::MediumAI }
|
6
|
+
let(:x) { TicTacToes::Player.new("decider", "x", false, "interface") }
|
7
|
+
let(:o) { TicTacToes::Player.new(ai, "o", true, "interface") }
|
8
|
+
let(:players) { [x, o] }
|
9
|
+
|
10
|
+
describe '#make_move' do
|
11
|
+
it "makes a valid move (based on either EasyAI or HardAI)" do
|
12
|
+
structure = [ o, o, x,
|
13
|
+
nil, x, nil,
|
14
|
+
nil, x, nil]
|
15
|
+
board = generate_board(structure)
|
16
|
+
valid_moves = [3, 5, 6, 8]
|
17
|
+
|
18
|
+
move = ai.make_move(board, players)
|
19
|
+
expect(valid_moves).to include(move)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'command_line/io'
|
2
|
+
require 'tic_tac_toes/io_interface'
|
3
|
+
require 'tic_tac_toes/medium_ai'
|
4
|
+
require 'tic_tac_toes/player_factory'
|
5
|
+
require 'tic_tac_toes/spec_helper'
|
6
|
+
|
7
|
+
describe TicTacToes::PlayerFactory do
|
8
|
+
let(:io) { CommandLine::IO }
|
9
|
+
let(:io_interface) { TicTacToes::IOInterface.new(io) }
|
10
|
+
let(:player_factory) { TicTacToes::PlayerFactory.new(io_interface) }
|
11
|
+
|
12
|
+
|
13
|
+
describe '#generate_human_player' do
|
14
|
+
it "returns a player with the correct token and decider" do
|
15
|
+
token = "X"
|
16
|
+
|
17
|
+
human_player = player_factory.generate_human_player(token)
|
18
|
+
expect(human_player.decider).to be_a TicTacToes::IOInterface
|
19
|
+
expect(human_player.token).to eq(token)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe '#generate_computer_player' do
|
25
|
+
it "returns a player with the correct token and decider when given a valid difficulty" do
|
26
|
+
token = "O"
|
27
|
+
difficulty = :medium
|
28
|
+
|
29
|
+
computer_player = player_factory.generate_computer_player(token, difficulty)
|
30
|
+
expect(computer_player.decider).to eql(TicTacToes::MediumAI)
|
31
|
+
expect(computer_player.token).to eq(token)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'tic_tac_toes/board'
|
2
|
+
require 'tic_tac_toes/io_interface'
|
3
|
+
require 'tic_tac_toes/player'
|
4
|
+
require 'tic_tac_toes/spec_helper'
|
5
|
+
|
6
|
+
describe TicTacToes::Player do
|
7
|
+
let(:board) { TicTacToes::Board.new(row_size: 3) }
|
8
|
+
let(:io_interface) { double("io_interface", invalid_move_error: true) }
|
9
|
+
let(:players) { double("players") }
|
10
|
+
|
11
|
+
describe '#make_move' do
|
12
|
+
let(:decider) { double("decider") }
|
13
|
+
let(:token) { "X" }
|
14
|
+
let(:needs_to_think) { false }
|
15
|
+
|
16
|
+
let(:player) { TicTacToes::Player.new(decider, token, needs_to_think, io_interface) }
|
17
|
+
|
18
|
+
it "only returns a move once it receives a valid move" do
|
19
|
+
invalid_space, valid_space = 9, 0
|
20
|
+
allow(decider).to receive(:make_move).and_return(invalid_space, valid_space)
|
21
|
+
|
22
|
+
player.make_move(board, players)
|
23
|
+
expect(board.space(valid_space)).to eq(player)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "displays an invalid move error when given an invalid move" do
|
27
|
+
invalid_space, valid_space = 9, 0
|
28
|
+
allow(decider).to receive(:make_move).and_return(invalid_space, valid_space)
|
29
|
+
|
30
|
+
expect(io_interface).to receive(:invalid_move_error)
|
31
|
+
player.make_move(board, players)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'tic_tac_toes/spec_helper'
|
2
|
+
require 'tic_tac_toes/rules'
|
3
|
+
|
4
|
+
describe TicTacToes::Rules do
|
5
|
+
let(:rules) { TicTacToes::Rules }
|
6
|
+
let(:x) { double("human player", token: "x") }
|
7
|
+
let(:o) { double("computer player", token: "o") }
|
8
|
+
let(:players) { [x, o] }
|
9
|
+
|
10
|
+
describe '#row_size_valid?' do
|
11
|
+
it "returns false if the row size is outside the range 2 to 10" do
|
12
|
+
invalid_row_size = 11
|
13
|
+
|
14
|
+
expect(rules.row_size_valid?(invalid_row_size)).to be false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns true if the row size is in the range 2 to 10" do
|
18
|
+
valid_row_size = 10
|
19
|
+
|
20
|
+
expect(rules.row_size_valid?(valid_row_size)).to be true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe '#token_valid?' do
|
26
|
+
it "returns false if the token is not a single character" do
|
27
|
+
long_token, taken_tokens = :long, []
|
28
|
+
|
29
|
+
expect(rules.token_valid?(long_token, taken_tokens)).to be false
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns false if the token is already taken" do
|
33
|
+
taken_token, taken_tokens = :X, [:X]
|
34
|
+
|
35
|
+
expect(rules.token_valid?(taken_token, taken_tokens)).to be false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns true if the token is a single character and untaken" do
|
39
|
+
valid_token, taken_tokens = :O, [:X]
|
40
|
+
|
41
|
+
expect(rules.token_valid?(valid_token, taken_tokens)).to be true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
describe '#difficulty_valid?' do
|
47
|
+
it "returns false if the difficulty is not a key in AI_DIFFICULTIES" do
|
48
|
+
invalid_difficulty = :invalid
|
49
|
+
|
50
|
+
expect(rules.difficulty_valid?(invalid_difficulty)).to be false
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns true if the difficulty is a key in AI_DIFFICULTIES" do
|
54
|
+
valid_difficulty = :medium
|
55
|
+
|
56
|
+
expect(rules.difficulty_valid?(valid_difficulty)).to be true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
describe '#game_over?' do
|
62
|
+
it "returns false if there is not yet a winner and the board is not full" do
|
63
|
+
structure = [x, x, o,
|
64
|
+
o, o, nil,
|
65
|
+
x, o, x]
|
66
|
+
board = generate_board(structure)
|
67
|
+
|
68
|
+
expect(rules.game_over?(board, players)).to be false
|
69
|
+
end
|
70
|
+
|
71
|
+
it "returns true if any player has won" do
|
72
|
+
structure = [ x, nil, nil,
|
73
|
+
nil, x, nil,
|
74
|
+
nil, nil, x]
|
75
|
+
board = generate_board(structure)
|
76
|
+
|
77
|
+
expect(rules.game_over?(board, players)).to be true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns true if the board is full" do
|
81
|
+
structure = [x, x, o,
|
82
|
+
o, o, x,
|
83
|
+
x, o, x]
|
84
|
+
board = generate_board(structure)
|
85
|
+
|
86
|
+
expect(rules.game_over?(board, players)).to be true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
describe '#determine_winner' do
|
92
|
+
it "returns the winning token when there is a winner" do
|
93
|
+
structure = [ o, nil, nil,
|
94
|
+
nil, o, nil,
|
95
|
+
nil, nil, o]
|
96
|
+
board = generate_board(structure)
|
97
|
+
winning_token = "o"
|
98
|
+
|
99
|
+
expect(rules.determine_winner(board, players)).to eql(winning_token)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns nil if there is not a winner" do
|
103
|
+
structure = [x, x, o,
|
104
|
+
o, o, nil,
|
105
|
+
x, o, x]
|
106
|
+
board = generate_board(structure)
|
107
|
+
|
108
|
+
expect(rules.determine_winner(board, players)).to be_nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
describe '#win?' do
|
114
|
+
it "returns false if the given token has not won" do
|
115
|
+
structure = [x, x, o,
|
116
|
+
o, o, nil,
|
117
|
+
x, o, x]
|
118
|
+
board = generate_board(structure)
|
119
|
+
|
120
|
+
expect(rules.win?(board, x)).to be false
|
121
|
+
end
|
122
|
+
|
123
|
+
it "returns true if the given token has achieved a back diagonal win" do
|
124
|
+
structure = [ x, nil, nil,
|
125
|
+
nil, x, nil,
|
126
|
+
nil, nil, x]
|
127
|
+
board = generate_board(structure)
|
128
|
+
|
129
|
+
expect(rules.win?(board, x)).to be true
|
130
|
+
end
|
131
|
+
|
132
|
+
it "returns true if the given token has achieved a front diagonal win" do
|
133
|
+
structure = [nil, nil, x,
|
134
|
+
nil, x, nil,
|
135
|
+
x, nil, nil]
|
136
|
+
board = generate_board(structure)
|
137
|
+
|
138
|
+
expect(rules.win?(board, x)).to be true
|
139
|
+
end
|
140
|
+
|
141
|
+
it "returns true if the given token has achieved a horizonatal win" do
|
142
|
+
structure = [nil, nil, nil,
|
143
|
+
x, x, x,
|
144
|
+
nil, nil, nil]
|
145
|
+
board = generate_board(structure)
|
146
|
+
|
147
|
+
expect(rules.win?(board, x)).to be true
|
148
|
+
end
|
149
|
+
|
150
|
+
it "returns true if the given token has achieved a vertical win" do
|
151
|
+
structure = [nil, x, nil,
|
152
|
+
nil, x, nil,
|
153
|
+
nil, x, nil]
|
154
|
+
board = generate_board(structure)
|
155
|
+
|
156
|
+
expect(rules.win?(board, x)).to be true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'tic_tac_toes/board'
|
2
|
+
|
3
|
+
def generate_board(structure)
|
4
|
+
board_size = structure.count
|
5
|
+
row_size = Math.sqrt(board_size)
|
6
|
+
board = TicTacToes::Board.new(row_size: row_size)
|
7
|
+
|
8
|
+
structure.each_with_index do |player, index|
|
9
|
+
board.place(player, index)
|
10
|
+
end
|
11
|
+
|
12
|
+
board
|
13
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'tic_tac_toes/board'
|
2
|
+
require 'tic_tac_toes/rules'
|
3
|
+
require 'tic_tac_toes/spec_helper'
|
4
|
+
require 'tic_tac_toes/strings'
|
5
|
+
|
6
|
+
describe TicTacToes::Strings do
|
7
|
+
let(:strings) { TicTacToes::Strings }
|
8
|
+
|
9
|
+
describe '#invalid_row_size' do
|
10
|
+
it "returns a string containing the minimum and maximum allowed row sizes" do
|
11
|
+
smallest_row_size = TicTacToes::Rules::ROW_SIZE_RANGE.min.to_s
|
12
|
+
largest_row_size = TicTacToes::Rules::ROW_SIZE_RANGE.max.to_s
|
13
|
+
|
14
|
+
expect(strings::INVALID_ROW_SIZE).to include(smallest_row_size, largest_row_size)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#token_solicitation' do
|
19
|
+
it "returns a string containing the name of the player whose token is being picked" do
|
20
|
+
player = "human"
|
21
|
+
expect(strings.token_solicitation(player)).to include(player)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#game_over_notification' do
|
26
|
+
it "returns a string containing the name of the winner" do
|
27
|
+
winner = "X"
|
28
|
+
expect(strings.game_over_notification(winner)).to include(winner)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#board' do
|
33
|
+
it "returns a board string" do
|
34
|
+
board = TicTacToes::Board.new(row_size: 3)
|
35
|
+
|
36
|
+
leading_spaces_regexp = /^[[:blank:]]+/
|
37
|
+
board_string = <<-END.gsub(leading_spaces_regexp, '')
|
38
|
+
|
39
|
+
[0]|[1]|[2]
|
40
|
+
-----------
|
41
|
+
[3]|[4]|[5]
|
42
|
+
-----------
|
43
|
+
[6]|[7]|[8]
|
44
|
+
|
45
|
+
END
|
46
|
+
|
47
|
+
expect(strings.board(board)).to eql(board_string)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tic_tac_toes/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tic_tac_toes"
|
8
|
+
spec.version = TicTacToes::VERSION
|
9
|
+
spec.authors = ["Ben Spatafora"]
|
10
|
+
spec.email = ["benjamin.spatafora@gmail.com"]
|
11
|
+
spec.summary = %q{The game Tic-tac-toe, featuring an unbeatable AI}
|
12
|
+
spec.homepage = "http://github.com/bspatafora/tic_tac_toes"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = ["tic_tac_toes"]
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_dependency "pg"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tic_tac_toes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Spatafora
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pg
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- benjamin.spatafora@gmail.com
|
72
|
+
executables:
|
73
|
+
- tic_tac_toes
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/tic_tac_toes
|
83
|
+
- lib/command_line/io.rb
|
84
|
+
- lib/command_line/menu.rb
|
85
|
+
- lib/command_line/runner.rb
|
86
|
+
- lib/database/pg_wrapper.rb
|
87
|
+
- lib/tic_tac_toes/board.rb
|
88
|
+
- lib/tic_tac_toes/easy_ai.rb
|
89
|
+
- lib/tic_tac_toes/hard_ai.rb
|
90
|
+
- lib/tic_tac_toes/history.rb
|
91
|
+
- lib/tic_tac_toes/io_interface.rb
|
92
|
+
- lib/tic_tac_toes/medium_ai.rb
|
93
|
+
- lib/tic_tac_toes/player.rb
|
94
|
+
- lib/tic_tac_toes/player_factory.rb
|
95
|
+
- lib/tic_tac_toes/rules.rb
|
96
|
+
- lib/tic_tac_toes/strings.rb
|
97
|
+
- lib/tic_tac_toes/version.rb
|
98
|
+
- spec/command_line/menu_spec.rb
|
99
|
+
- spec/command_line/runner_spec.rb
|
100
|
+
- spec/database/pg_wrapper_spec.rb
|
101
|
+
- spec/tic_tac_toes/board_spec.rb
|
102
|
+
- spec/tic_tac_toes/easy_ai_spec.rb
|
103
|
+
- spec/tic_tac_toes/hard_ai_spec.rb
|
104
|
+
- spec/tic_tac_toes/history_spec.rb
|
105
|
+
- spec/tic_tac_toes/io_interface_spec.rb
|
106
|
+
- spec/tic_tac_toes/medium_ai_spec.rb
|
107
|
+
- spec/tic_tac_toes/player_factory_spec.rb
|
108
|
+
- spec/tic_tac_toes/player_spec.rb
|
109
|
+
- spec/tic_tac_toes/rules_spec.rb
|
110
|
+
- spec/tic_tac_toes/spec_helper.rb
|
111
|
+
- spec/tic_tac_toes/strings_spec.rb
|
112
|
+
- tic_tac_toes.gemspec
|
113
|
+
homepage: http://github.com/bspatafora/tic_tac_toes
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.2.2
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: The game Tic-tac-toe, featuring an unbeatable AI
|
137
|
+
test_files:
|
138
|
+
- spec/command_line/menu_spec.rb
|
139
|
+
- spec/command_line/runner_spec.rb
|
140
|
+
- spec/database/pg_wrapper_spec.rb
|
141
|
+
- spec/tic_tac_toes/board_spec.rb
|
142
|
+
- spec/tic_tac_toes/easy_ai_spec.rb
|
143
|
+
- spec/tic_tac_toes/hard_ai_spec.rb
|
144
|
+
- spec/tic_tac_toes/history_spec.rb
|
145
|
+
- spec/tic_tac_toes/io_interface_spec.rb
|
146
|
+
- spec/tic_tac_toes/medium_ai_spec.rb
|
147
|
+
- spec/tic_tac_toes/player_factory_spec.rb
|
148
|
+
- spec/tic_tac_toes/player_spec.rb
|
149
|
+
- spec/tic_tac_toes/rules_spec.rb
|
150
|
+
- spec/tic_tac_toes/spec_helper.rb
|
151
|
+
- spec/tic_tac_toes/strings_spec.rb
|