tic_tac_toes 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/tic_tac_toes/command_line/menu.rb +3 -2
- data/lib/tic_tac_toes/core/player_factory.rb +18 -12
- data/lib/tic_tac_toes/ui/adapter.rb +9 -0
- data/lib/tic_tac_toes/ui/serializer.rb +20 -4
- data/lib/tic_tac_toes/version.rb +1 -1
- data/spec/tic_tac_toes/core/move_strategies/easy_ai_spec.rb +2 -2
- data/spec/tic_tac_toes/core/move_strategies/medium_ai_spec.rb +2 -2
- data/spec/tic_tac_toes/core/player_factory_spec.rb +14 -18
- data/spec/tic_tac_toes/ui/adapter_spec.rb +27 -2
- data/spec/tic_tac_toes/ui/serializer_spec.rb +19 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e7b4f6653858ee05ee85a0ad10f519879bed750
|
4
|
+
data.tar.gz: e5aaea09afc5342b96fb823881ba26ef691f00af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49287beb325485b2b1affb085f082f03804f8c0a9a21bd761ca8bddca64e681fb98be844dac1c6ec0d1f3df58ee96e7e23518b18351c06b021838c5cbf05cb19
|
7
|
+
data.tar.gz: 0874989c2aaf4f7dd1712266303fbad25c4f911507c158b65d0e1ae72b94605e842366b708485f21f51420cb99823e7bd403f8ada58b58cb947783e377cc310b
|
data/Gemfile.lock
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'tic_tac_toes/core/board'
|
2
2
|
require 'tic_tac_toes/core/rules'
|
3
|
+
require 'tic_tac_toes/core/player_factory'
|
3
4
|
|
4
5
|
module TicTacToes
|
5
6
|
module CommandLine
|
@@ -20,8 +21,8 @@ module TicTacToes
|
|
20
21
|
computer_token = get_token(:computer, taken_tokens)
|
21
22
|
difficulty = get_difficulty
|
22
23
|
|
23
|
-
human_player = @player_factory.
|
24
|
-
computer_player = @player_factory.
|
24
|
+
human_player = @player_factory.generate_player(human_token, Core::PlayerFactory::HUMAN)
|
25
|
+
computer_player = @player_factory.generate_player(computer_token, difficulty)
|
25
26
|
[human_player, computer_player]
|
26
27
|
end
|
27
28
|
|
@@ -7,23 +7,29 @@ require 'tic_tac_toes/core/player'
|
|
7
7
|
module TicTacToes
|
8
8
|
module Core
|
9
9
|
class PlayerFactory
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
|
11
|
+
HUMAN = :human
|
12
|
+
EASY_AI = :easy
|
13
|
+
MEDIUM_AI = :medium
|
14
|
+
HARD_AI = :hard
|
13
15
|
|
14
16
|
AIS = {
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
EASY_AI => MoveStrategies::EasyAI,
|
18
|
+
MEDIUM_AI => MoveStrategies::MediumAI,
|
19
|
+
HARD_AI => MoveStrategies::HardAI
|
20
|
+
}
|
18
21
|
|
19
|
-
def
|
20
|
-
|
21
|
-
Player.new(TicTacToes::Core::MoveStrategies::Human.new(@io), token, needs_to_think, @io)
|
22
|
+
def initialize(io)
|
23
|
+
@io = io
|
22
24
|
end
|
23
25
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
26
|
+
def generate_player(token, type)
|
27
|
+
case type
|
28
|
+
when HUMAN
|
29
|
+
Player.new(MoveStrategies::Human.new(@io), token, false, @io)
|
30
|
+
else
|
31
|
+
Player.new(AIS.fetch(type), token, true, @io)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
@@ -1,6 +1,15 @@
|
|
1
1
|
module TicTacToes
|
2
2
|
module UI
|
3
3
|
module Adapter
|
4
|
+
def self.start_game(order, game_state, listener)
|
5
|
+
case order
|
6
|
+
when 'first'
|
7
|
+
listener.moves_were_made(game_state)
|
8
|
+
when 'second'
|
9
|
+
make_move(game_state, nil, listener)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
def self.make_move(game_state, move, listener)
|
5
14
|
unless move.nil?
|
6
15
|
move = move.to_i
|
@@ -13,10 +13,10 @@ module TicTacToes
|
|
13
13
|
board.spaces
|
14
14
|
end
|
15
15
|
|
16
|
-
def self.game_state_from_board_structure(board_structure)
|
16
|
+
def self.game_state_from_board_structure(board_structure, computer_type)
|
17
17
|
player_factory = Core::PlayerFactory.new('unused_io')
|
18
|
-
human_player = player_factory.
|
19
|
-
computer_player = player_factory.
|
18
|
+
human_player = player_factory.generate_player(X, Core::PlayerFactory::HUMAN)
|
19
|
+
computer_player = player_factory.generate_player(O, Core::PlayerFactory.const_get(computer_type))
|
20
20
|
players = [human_player, computer_player]
|
21
21
|
|
22
22
|
board_structure_with_players = replace_tokens_with_players(board_structure, human_player, computer_player)
|
@@ -25,12 +25,28 @@ module TicTacToes
|
|
25
25
|
Core::GameState.new(board, players, NullHistory.new)
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.
|
28
|
+
def self.board_structure_from_game_state(game_state)
|
29
29
|
structure_with_players = game_state.board.spaces
|
30
30
|
|
31
31
|
replace_players_with_tokens(structure_with_players)
|
32
32
|
end
|
33
33
|
|
34
|
+
def self.computer_type_from_game_state(game_state)
|
35
|
+
type = nil
|
36
|
+
|
37
|
+
game_state.players.each do |player|
|
38
|
+
if player.move_strategy == Core::PlayerFactory::AIS.fetch(Core::PlayerFactory::EASY_AI)
|
39
|
+
type = 'EASY_AI'
|
40
|
+
elsif player.move_strategy == Core::PlayerFactory::AIS.fetch(Core::PlayerFactory::MEDIUM_AI)
|
41
|
+
type = 'MEDIUM_AI'
|
42
|
+
elsif player.move_strategy == Core::PlayerFactory::AIS.fetch(Core::PlayerFactory::HARD_AI)
|
43
|
+
type = 'HARD_AI'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
type
|
48
|
+
end
|
49
|
+
|
34
50
|
private
|
35
51
|
|
36
52
|
def self.replace_tokens_with_players(board_structure, human_player, computer_player)
|
data/lib/tic_tac_toes/version.rb
CHANGED
@@ -7,8 +7,8 @@ describe TicTacToes::Core::MoveStrategies::EasyAI do
|
|
7
7
|
describe '#move' do
|
8
8
|
it "returns a randomly-selected valid move" do
|
9
9
|
player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
|
10
|
-
x = player_factory.
|
11
|
-
o = player_factory.
|
10
|
+
x = player_factory.generate_player('x', TicTacToes::Core::PlayerFactory::HUMAN)
|
11
|
+
o = player_factory.generate_player('o', TicTacToes::Core::PlayerFactory::EASY_AI)
|
12
12
|
players = [x, o]
|
13
13
|
|
14
14
|
board = TicTacToes::TestBoardGenerator.generate([ o, nil, nil,
|
@@ -7,8 +7,8 @@ describe TicTacToes::Core::MoveStrategies::MediumAI do
|
|
7
7
|
describe '#move' do
|
8
8
|
it "returns a valid move (based on either EasyAI or HardAI)" do
|
9
9
|
player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
|
10
|
-
x = player_factory.
|
11
|
-
o = player_factory.
|
10
|
+
x = player_factory.generate_player('x', TicTacToes::Core::PlayerFactory::HUMAN)
|
11
|
+
o = player_factory.generate_player('o', TicTacToes::Core::PlayerFactory::MEDIUM_AI)
|
12
12
|
players = [x, o]
|
13
13
|
|
14
14
|
board = TicTacToes::TestBoardGenerator.generate([ o, o, x,
|
@@ -3,29 +3,25 @@ require 'tic_tac_toes/core/move_strategies/medium_ai'
|
|
3
3
|
require 'tic_tac_toes/core/player_factory'
|
4
4
|
|
5
5
|
describe TicTacToes::Core::PlayerFactory do
|
6
|
-
|
6
|
+
describe '#generate_player' do
|
7
|
+
before { @player_factory = TicTacToes::Core::PlayerFactory.new('io') }
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
token = 'X'
|
9
|
+
context 'when passed HUMAN' do
|
10
|
+
it "returns a player with the correct token and a Human move strategy" do
|
11
|
+
human_player = @player_factory.generate_player('X', TicTacToes::Core::PlayerFactory::HUMAN)
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
expect(human_player.token).to eq('X')
|
14
|
+
expect(human_player.move_strategy).to be_a TicTacToes::Core::MoveStrategies::Human
|
15
|
+
end
|
16
16
|
end
|
17
|
-
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
difficulty = :medium
|
23
|
-
strategy = TicTacToes::Core::MoveStrategies::MediumAI
|
18
|
+
context 'when passed EASY_AI, MEDIUM_AI, or HARD_AI' do
|
19
|
+
it 'returns a player with the correct token and correct AI move strategy' do
|
20
|
+
computer_player = @player_factory.generate_player('O', TicTacToes::Core::PlayerFactory::MEDIUM_AI)
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
expect(computer_player.token).to eq(token)
|
22
|
+
expect(computer_player.move_strategy).to eq(TicTacToes::Core::MoveStrategies::MediumAI)
|
23
|
+
expect(computer_player.token).to eq('O')
|
24
|
+
end
|
29
25
|
end
|
30
26
|
end
|
31
27
|
end
|
@@ -4,12 +4,37 @@ require 'tic_tac_toes/test_board_generator'
|
|
4
4
|
require 'tic_tac_toes/ui/adapter'
|
5
5
|
|
6
6
|
describe TicTacToes::UI::Adapter do
|
7
|
+
describe '#start_game' do
|
8
|
+
context 'when passed an order of “first”' do
|
9
|
+
it 'sends its listener #moves_were_made with the game state' do
|
10
|
+
order = 'first'
|
11
|
+
game_state = double
|
12
|
+
listener = double
|
13
|
+
|
14
|
+
expect(listener).to receive(:moves_were_made).with(game_state)
|
15
|
+
TicTacToes::UI::Adapter.start_game(order, game_state, listener)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when passed an order of “second”' do
|
20
|
+
it 'sends its listener #moves_were_made with the game state' do
|
21
|
+
order = 'second'
|
22
|
+
computer_player = double(place_and_return_move: 0)
|
23
|
+
game_state = double(game_over?: false, turn_over: true, current_player: computer_player)
|
24
|
+
listener = double
|
25
|
+
|
26
|
+
expect(listener).to receive(:moves_were_made).with(game_state)
|
27
|
+
TicTacToes::UI::Adapter.start_game(order, game_state, listener)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
7
32
|
describe '#make_move' do
|
8
33
|
let(:history) { TicTacToes::UI::NullHistory.new }
|
9
34
|
|
10
35
|
player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
|
11
|
-
let(:x) { player_factory.
|
12
|
-
let(:o) { player_factory.
|
36
|
+
let(:x) { player_factory.generate_player('x', TicTacToes::Core::PlayerFactory::HUMAN) }
|
37
|
+
let(:o) { player_factory.generate_player('o', TicTacToes::Core::PlayerFactory::HARD_AI) }
|
13
38
|
let(:players) { [x, o] }
|
14
39
|
|
15
40
|
context 'when the game is still in progress' do
|
@@ -12,10 +12,12 @@ describe TicTacToes::UI::Serializer do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
describe '#game_state_from_board_structure' do
|
15
|
-
it 'returns a game state object based on a board structure' do
|
15
|
+
it 'returns a game state object based on a board structure and computer type' do
|
16
16
|
board_structure = [nil, nil, nil, nil, 'X', nil, nil, nil, nil]
|
17
|
+
computer_type = 'EASY_AI'
|
18
|
+
ai = TicTacToes::Core::PlayerFactory::AIS.fetch(TicTacToes::Core::PlayerFactory::EASY_AI)
|
17
19
|
|
18
|
-
game_state = TicTacToes::UI::Serializer.game_state_from_board_structure(board_structure)
|
20
|
+
game_state = TicTacToes::UI::Serializer.game_state_from_board_structure(board_structure, computer_type)
|
19
21
|
middle_space = game_state.board.space(4)
|
20
22
|
first_player = game_state.players.first
|
21
23
|
second_player = game_state.players.last
|
@@ -23,21 +25,32 @@ describe TicTacToes::UI::Serializer do
|
|
23
25
|
expect(middle_space.token).to eq(TicTacToes::UI::Serializer::X)
|
24
26
|
expect(first_player.token).to eq(TicTacToes::UI::Serializer::X)
|
25
27
|
expect(second_player.token).to eq(TicTacToes::UI::Serializer::O)
|
28
|
+
expect(second_player.move_strategy).to eq(ai)
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
|
-
describe '#
|
32
|
+
describe '#board_structure_from_game_state' do
|
30
33
|
it 'returns a board structure based on a game state object' do
|
31
34
|
player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
|
32
|
-
first_player = player_factory.
|
33
|
-
second_player = player_factory.
|
35
|
+
first_player = player_factory.generate_player(TicTacToes::UI::Serializer::X, TicTacToes::Core::PlayerFactory::HUMAN)
|
36
|
+
second_player = player_factory.generate_player(TicTacToes::UI::Serializer::O, TicTacToes::Core::PlayerFactory::HARD_AI)
|
34
37
|
players = [first_player, second_player]
|
35
38
|
board = TicTacToes::Core::Board.new
|
36
39
|
board.place(first_player, 4)
|
37
40
|
|
38
41
|
game_state = TicTacToes::Core::GameState.new(board, players, TicTacToes::UI::NullHistory.new)
|
39
42
|
board_structure = [nil, nil, nil, nil, 'X', nil, nil, nil, nil]
|
40
|
-
expect(TicTacToes::UI::Serializer.
|
43
|
+
expect(TicTacToes::UI::Serializer.board_structure_from_game_state(game_state)).to eq(board_structure)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#computer_type_from_game_state' do
|
48
|
+
it 'returns the type of a game state’s computer player' do
|
49
|
+
move_strategy = TicTacToes::Core::PlayerFactory::AIS.fetch(TicTacToes::Core::PlayerFactory::EASY_AI)
|
50
|
+
computer_player = double(move_strategy: move_strategy)
|
51
|
+
players = [computer_player]
|
52
|
+
game_state = double(players: players)
|
53
|
+
expect(TicTacToes::UI::Serializer.computer_type_from_game_state(game_state)).to eq('EASY_AI')
|
41
54
|
end
|
42
55
|
end
|
43
56
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tic_tac_toes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Spatafora
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|