tic_tac_toes 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77b92da0b3d048f306b6ac300f94e94fcd656ef7
4
- data.tar.gz: 10497e3ed936e362e8ae20e1e85282b8990e92f7
3
+ metadata.gz: 973d4205866381b247cee7397ef538d46d26dbd3
4
+ data.tar.gz: 8383fa3bd6d89f0e1dc082bf15d58e22315c4d16
5
5
  SHA512:
6
- metadata.gz: d33321f395dae4c693c0610a51b998d7b606bc00408ffe65cfcc305f8f06278f5bf09085ea1de4d7a4556fe80ad0a302a4c006c2a887f8b31db59dacb3ee4983
7
- data.tar.gz: 5e7f86e90489fdc057a6804b77e85ed2ba067c189585d9d813051abbc2e5d5bae2dc34a270a2b9c3d477e8a92ed20fab08d82b17c36114434eb3e5917ee10473
6
+ metadata.gz: 38e1a5192560eb071120b41079ae56a77e442b5fefe60659537868e45eb76277f05ffd74b4510c1d707009c3a5a9bb22582bd30cd66a9fdc67ec6524d471a92f
7
+ data.tar.gz: 81602fbe1f20241e27b4400815bc4ee3fdbbb1bdaa9622de099134e4b043db4dd640bb6880258b072f7d8e16b0827dc9717904749ff8ae94ca5d4518cbfa0177
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tic_tac_toes (0.1.4)
4
+ tic_tac_toes (0.1.6)
5
5
  pg
6
6
 
7
7
  GEM
data/bin/game_histories CHANGED
@@ -4,10 +4,11 @@ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + '/../lib')
4
4
 
5
5
  require 'tic_tac_toes/database/pg_wrapper'
6
6
  require 'tic_tac_toes/command_line/history_reader'
7
+ require 'tic_tac_toes/command_line/prompt'
7
8
 
8
9
  database = 'tic_tac_toes'
9
10
 
10
11
  wrapper = TicTacToes::Database::PGWrapper.new(database)
11
12
  reader = TicTacToes::CommandLine::HistoryReader.new(wrapper)
12
13
 
13
- reader.display_game_histories
14
+ reader.game_history_strings.each { |history| TicTacToes::CommandLine::Prompt.display(history) }
@@ -29,11 +29,19 @@ module TicTacToes
29
29
  @players[1]
30
30
  end
31
31
 
32
+ def computer_player
33
+ @players.detect { |player| player.move_strategy.type == MoveStrategies::COMPUTER }
34
+ end
35
+
32
36
  def turn_over(move)
33
37
  @history.record_move(move)
34
38
  @players.rotate!
35
39
  end
36
40
 
41
+ def moves
42
+ @history.moves
43
+ end
44
+
37
45
  def end_game(winner)
38
46
  @history.record_winner(winner)
39
47
  @history.persist
@@ -54,7 +62,6 @@ module TicTacToes
54
62
  end
55
63
 
56
64
  def record_difficulty
57
- computer_player = @players.detect { |player| player.move_strategy.type == MoveStrategies::COMPUTER }
58
65
  @history.record_difficulty(computer_player.move_strategy)
59
66
  end
60
67
  end
@@ -17,7 +17,7 @@ module TicTacToes
17
17
 
18
18
  def record_move(move)
19
19
  @moves ||= []
20
- @moves << move
20
+ @moves << move unless move.nil?
21
21
  end
22
22
 
23
23
  def record_winner(winner)
@@ -1,4 +1,4 @@
1
- require 'tic_tac_toes/core/strings'
1
+ require 'tic_tac_toes/core/presenter'
2
2
 
3
3
  module TicTacToes
4
4
  module Core
@@ -27,41 +27,41 @@ module TicTacToes
27
27
  end
28
28
 
29
29
  def draw_board(board)
30
- @io_strategy.display(Strings.board(board))
30
+ @io_strategy.display(Presenter.board(board))
31
31
  end
32
32
 
33
33
  def invalid_row_size_error
34
- @io_strategy.display_red(Strings::INVALID_ROW_SIZE)
34
+ @io_strategy.display_red(Presenter::INVALID_ROW_SIZE)
35
35
  end
36
36
 
37
37
  def invalid_token_error
38
- @io_strategy.display_red(Strings::INVALID_TOKEN)
38
+ @io_strategy.display_red(Presenter::INVALID_TOKEN)
39
39
  end
40
40
 
41
41
  def invalid_difficulty_error
42
- @io_strategy.display_red(Strings::INVALID_DIFFICULTY)
42
+ @io_strategy.display_red(Presenter::INVALID_DIFFICULTY)
43
43
  end
44
44
 
45
45
  def invalid_move_error
46
- @io_strategy.display_red(Strings::INVALID_MOVE)
46
+ @io_strategy.display_red(Presenter::INVALID_MOVE)
47
47
  end
48
48
 
49
49
  def thinking_notification
50
- @io_strategy.display_red(Strings::THINKING)
50
+ @io_strategy.display_red(Presenter::THINKING)
51
51
  end
52
52
 
53
53
  def game_over_notification(winner)
54
54
  winner = "Nobody" if winner.nil?
55
55
  winner = winner.token unless winner.is_a? String
56
- @io_strategy.display(Strings.game_over_notification(winner))
56
+ @io_strategy.display(Presenter.game_over_notification(winner))
57
57
  end
58
58
 
59
59
  def move_solicitation
60
- @io_strategy.display(Strings::MOVE_SOLICITATION)
60
+ @io_strategy.display(Presenter::MOVE_SOLICITATION)
61
61
  end
62
62
 
63
63
  def not_an_integer_error
64
- @io_strategy.display_red(Strings::NOT_AN_INTEGER)
64
+ @io_strategy.display_red(Presenter::NOT_AN_INTEGER)
65
65
  end
66
66
 
67
67
  def solicit_input
@@ -79,15 +79,15 @@ module TicTacToes
79
79
  private
80
80
 
81
81
  def row_size_solicitation
82
- @io_strategy.display(Strings::ROW_SIZE_SOLICITATION)
82
+ @io_strategy.display(Presenter::ROW_SIZE_SOLICITATION)
83
83
  end
84
84
 
85
85
  def token_solicitation(player)
86
- @io_strategy.display(Strings.token_solicitation(player))
86
+ @io_strategy.display(Presenter.token_solicitation(player))
87
87
  end
88
88
 
89
89
  def difficulty_solicitation
90
- @io_strategy.display(Strings::DIFFICULTY_SOLICITATION)
90
+ @io_strategy.display(Presenter::DIFFICULTY_SOLICITATION)
91
91
  end
92
92
  end
93
93
  end
@@ -3,7 +3,7 @@ require 'tic_tac_toes/core/rules'
3
3
 
4
4
  module TicTacToes
5
5
  module Core
6
- module Strings
6
+ module Presenter
7
7
  smallest_row_size = Rules::ROW_SIZE_RANGE.min
8
8
  largest_row_size = Rules::ROW_SIZE_RANGE.max
9
9
 
@@ -101,6 +101,22 @@ module TicTacToes
101
101
  truncated_length.times { horizontal_divider << divider_unit }
102
102
  horizontal_divider
103
103
  end
104
+
105
+ def self.game_history_strings(wrapper)
106
+ game_histories = wrapper.read_game_histories
107
+ game_histories.map { |history| game_history_string(history) }
108
+ end
109
+
110
+ def self.game_history_string(history)
111
+ history_string = ''
112
+ history_string << "Board size: #{history.board_size.to_s}\n"
113
+ history_string << "Difficulty: #{history.difficulty}\n"
114
+ history_string << "Winner: #{history.winner}\n"
115
+ history_string << "Move history:\n"
116
+ history.moves.each { |move| history_string << " #{move.join(' -> ')}\n" }
117
+ history_string << "\n"
118
+ history_string
119
+ end
104
120
  end
105
121
  end
106
122
  end
@@ -1,37 +1,29 @@
1
1
  require 'tic_tac_toes/core/player_factory'
2
2
  require 'tic_tac_toes/core/move_strategies/hard_ai'
3
+ require 'tic_tac_toes/core/move_strategies/types'
3
4
 
4
5
  module TicTacToes
5
6
  module UI
6
7
  module Adapter
7
8
  def self.start_game(order, game_state, listener)
8
- case order
9
- when 'first'
10
- listener.moves_were_made(game_state)
11
- when 'second'
12
- make_move(game_state, nil, listener)
13
- end
9
+ user_is_first = order == 'first'
10
+
11
+ user_is_first ? listener.moves_were_made(game_state) : make_move(game_state, nil, listener)
14
12
  end
15
13
 
16
14
  def self.make_move(game_state, move, listener)
17
- unless move.nil?
18
- move = move.to_i
19
- game_state.place_move(move)
20
- end
21
-
22
- if game_state.game_over?
23
- tell_listener_game_is_over(game_state, listener)
24
- return
25
- end
15
+ computer_first = move.nil?
26
16
 
27
- game_state.turn_over(move)
28
- game_state.current_player.place_and_return_move(game_state)
29
-
30
- if game_state.game_over?
31
- tell_listener_game_is_over(game_state, listener)
32
- return
17
+ if computer_first
18
+ game_state.turn_over(nil)
19
+ computer_move(game_state, listener)
20
+ return game_over(game_state, listener) if game_state.game_over?
21
+ else
22
+ human_move(game_state, move, listener)
23
+ return game_over(game_state, listener) if game_state.game_over?
24
+ computer_move(game_state, listener)
25
+ return game_over(game_state, listener) if game_state.game_over?
33
26
  end
34
-
35
27
  listener.moves_were_made(game_state)
36
28
  end
37
29
 
@@ -43,7 +35,7 @@ module TicTacToes
43
35
  potential_game_state = generate_game_state(game_state, space)
44
36
  next predictions << predicted_result(potential_game_state) if potential_game_state.game_over?
45
37
 
46
- potential_game_state.turn_over([])
38
+ potential_game_state.turn_over(nil)
47
39
  potential_game_state.place_move(Core::MoveStrategies::HardAI.move(potential_game_state))
48
40
  next predictions << predicted_result(potential_game_state) if potential_game_state.game_over?
49
41
 
@@ -54,20 +46,36 @@ module TicTacToes
54
46
 
55
47
  private
56
48
 
57
- def self.tell_listener_game_is_over(game_state, listener)
49
+ def self.computer_move(game_state, listener)
50
+ computer_player = game_state.computer_player
51
+ computer_move = computer_player.place_and_return_move(game_state)
52
+ game_state.turn_over(computer_move)
53
+ end
54
+
55
+ def self.human_move(game_state, move, listener)
56
+ human_player = game_state.current_player
57
+ game_state.place_move(move.to_i)
58
+ game_state.turn_over([human_player.token, move.to_i])
59
+ end
60
+
61
+ def self.game_over(game_state, listener)
58
62
  winning_player = game_state.determine_winner
59
63
 
60
- case winning_player
61
- when nil
62
- listener.game_ended_in_draw(game_state)
63
- else
64
+ record_game_history(game_state, winning_player)
65
+ if winning_player
64
66
  listener.game_ended_in_winner(game_state, winning_player.token)
67
+ else
68
+ listener.game_ended_in_draw(game_state)
65
69
  end
66
70
  end
67
71
 
72
+ def self.record_game_history(game_state, winning_player)
73
+ game_state.start_game
74
+ game_state.end_game(winning_player)
75
+ end
76
+
68
77
  def self.generate_game_state(game_state, space)
69
78
  new_game_state = Marshal.load(Marshal.dump(game_state))
70
- new_game_state.turn_over([])
71
79
  new_game_state.place_move(space)
72
80
  new_game_state
73
81
  end
@@ -77,7 +85,7 @@ module TicTacToes
77
85
 
78
86
  if winner.nil?
79
87
  "tie"
80
- elsif winner.move_strategy.is_a? Core::MoveStrategies::Human
88
+ elsif winner.move_strategy.type == Core::MoveStrategies::HUMAN
81
89
  "win"
82
90
  else
83
91
  "loss"
@@ -1,6 +1,7 @@
1
1
  require 'tic_tac_toes/core/board'
2
2
  require 'tic_tac_toes/core/game_state'
3
3
  require 'tic_tac_toes/core/player_factory'
4
+ require 'tic_tac_toes/database/pg_wrapper'
4
5
 
5
6
  module TicTacToes
6
7
  module UI
@@ -13,30 +14,35 @@ module TicTacToes
13
14
  board.spaces
14
15
  end
15
16
 
16
- def self.game_state_from_board_structure(board_structure, computer_type)
17
+ def self.game_state(board_structure, computer_type, move_history)
17
18
  player_factory = Core::PlayerFactory.new('unused_io')
18
19
  human_player = player_factory.generate_player(X, Core::PlayerFactory::HUMAN)
19
20
  computer_player = player_factory.generate_player(O, Core::PlayerFactory.const_get(computer_type))
20
21
  players = [human_player, computer_player]
21
22
 
22
23
  board_structure_with_players = replace_tokens_with_players(board_structure, human_player, computer_player)
23
- board = board_from_structure(board_structure_with_players)
24
+ board = board(board_structure_with_players)
24
25
 
25
- Core::GameState.new(board, players, NullHistory.new)
26
+ history = history(move_history)
27
+
28
+ Core::GameState.new(board, players, history)
26
29
  end
27
30
 
28
- def self.board_structure_from_game_state(game_state)
31
+ def self.board_structure(game_state)
29
32
  structure_with_players = game_state.board.spaces
30
-
31
33
  replace_players_with_tokens(structure_with_players)
32
34
  end
33
35
 
34
- def self.ai_type_from_game_state(game_state)
36
+ def self.ai_type(game_state)
35
37
  computer = Core::MoveStrategies::COMPUTER
36
38
  computer_player = game_state.players.detect { |player| player.move_strategy.type == computer }
37
39
  computer_player.move_strategy.ai_type
38
40
  end
39
41
 
42
+ def self.move_history(game_state)
43
+ game_state.moves.flatten.join if game_state.moves
44
+ end
45
+
40
46
  private
41
47
 
42
48
  def self.replace_tokens_with_players(board_structure, human_player, computer_player)
@@ -56,7 +62,7 @@ module TicTacToes
56
62
  board_structure.map { |space| space.token unless space.nil? }
57
63
  end
58
64
 
59
- def self.board_from_structure(board_structure)
65
+ def self.board(board_structure)
60
66
  row_size = Math.sqrt(board_structure.count).to_i
61
67
  board = Core::Board.new(row_size: row_size)
62
68
 
@@ -66,6 +72,19 @@ module TicTacToes
66
72
 
67
73
  board
68
74
  end
75
+
76
+ def self.history(move_history)
77
+ storage_wrapper = Database::PGWrapper.new('tic_tac_toes')
78
+ history = Core::History.new(storage_wrapper)
79
+ if move_history
80
+ moves = move_history.split(//).each_slice(2).to_a
81
+ moves.each do |move|
82
+ move = [move.first, move.last.to_i]
83
+ history.record_move(move)
84
+ end
85
+ end
86
+ history
87
+ end
69
88
  end
70
89
 
71
90
  class NullHistory
@@ -80,6 +99,14 @@ module TicTacToes
80
99
  def record_move(move)
81
100
  nil
82
101
  end
102
+
103
+ def record_winner(winner)
104
+ nil
105
+ end
106
+
107
+ def persist
108
+ nil
109
+ end
83
110
  end
84
111
  end
85
112
  end
@@ -1,3 +1,3 @@
1
1
  module TicTacToes
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -88,6 +88,16 @@ describe TicTacToes::Core::GameState do
88
88
  end
89
89
  end
90
90
 
91
+ describe '#computer_player' do
92
+ it 'returns the game’s computer player' do
93
+ human_player = TicTacToes::Core::PlayerFactory.new('unused_io').generate_player('X', :human)
94
+ computer_player = TicTacToes::Core::PlayerFactory.new('unused_io').generate_player('O', :hard)
95
+ players = [human_player, computer_player]
96
+ game_state = TicTacToes::Core::GameState.new('board', players, 'history')
97
+ expect(game_state.computer_player).to eq(computer_player)
98
+ end
99
+ end
100
+
91
101
  describe '#turn_over' do
92
102
  it 'records the last move' do
93
103
  move = double
@@ -109,6 +119,15 @@ describe TicTacToes::Core::GameState do
109
119
  end
110
120
  end
111
121
 
122
+ describe '#moves' do
123
+ it 'returns it’s move history' do
124
+ moves = [['X', 0], ['O', 4]]
125
+ history = double(moves: moves)
126
+ game_state = TicTacToes::Core::GameState.new('board', 'players', history)
127
+ expect(game_state.moves).to eq(moves)
128
+ end
129
+ end
130
+
112
131
  describe '#end_game' do
113
132
  it 'records the winner' do
114
133
  winning_player = double
@@ -28,7 +28,14 @@ describe TicTacToes::Core::History do
28
28
  move = ["X", 0]
29
29
 
30
30
  history.record_move(move)
31
- expect(history.moves.first).to eql(move)
31
+ expect(history.moves.first).to eq(move)
32
+ end
33
+
34
+ it "doesn’t record anything if move is nil" do
35
+ move = nil
36
+
37
+ history.record_move(move)
38
+ expect(history.moves).to eq([])
32
39
  end
33
40
  end
34
41
 
@@ -1,9 +1,9 @@
1
1
  require 'tic_tac_toes/core/board'
2
2
  require 'tic_tac_toes/core/io'
3
- require 'tic_tac_toes/core/strings'
3
+ require 'tic_tac_toes/core/presenter'
4
4
 
5
5
  describe TicTacToes::Core::IO do
6
- let(:strings) { TicTacToes::Core::Strings }
6
+ let(:strings) { TicTacToes::Core::Presenter }
7
7
  let(:prompt) { double("prompt", solicit_input: 0, display: true, display_red: true) }
8
8
  let(:io) { TicTacToes::Core::IO.new(prompt) }
9
9
 
@@ -0,0 +1,95 @@
1
+ require 'tic_tac_toes/core/board'
2
+ require 'tic_tac_toes/core/rules'
3
+ require 'tic_tac_toes/core/presenter'
4
+
5
+ describe TicTacToes::Core::Presenter do
6
+ before do
7
+ @presenter = TicTacToes::Core::Presenter
8
+ end
9
+
10
+ describe '#invalid_row_size' do
11
+ it "returns a string containing the minimum and maximum allowed row sizes" do
12
+ smallest_row_size = TicTacToes::Core::Rules::ROW_SIZE_RANGE.min.to_s
13
+ largest_row_size = TicTacToes::Core::Rules::ROW_SIZE_RANGE.max.to_s
14
+
15
+ expect(@presenter::INVALID_ROW_SIZE).to include(smallest_row_size, largest_row_size)
16
+ end
17
+ end
18
+
19
+ describe '#token_solicitation' do
20
+ it "returns a string containing the name of the player whose token is being picked" do
21
+ player = "human"
22
+ expect(@presenter.token_solicitation(player)).to include(player)
23
+ end
24
+ end
25
+
26
+ describe '#game_over_notification' do
27
+ it "returns a string containing the name of the winner" do
28
+ winner = "X"
29
+ expect(@presenter.game_over_notification(winner)).to include(winner)
30
+ end
31
+ end
32
+
33
+ describe '#board' do
34
+ it "returns a board string" do
35
+ board = TicTacToes::Core::Board.new(row_size: 3)
36
+
37
+ leading_spaces_regexp = /^[[:blank:]]+/
38
+ board_string = <<-END.gsub(leading_spaces_regexp, '')
39
+
40
+ [0]|[1]|[2]
41
+ -----------
42
+ [3]|[4]|[5]
43
+ -----------
44
+ [6]|[7]|[8]
45
+
46
+ END
47
+
48
+ expect(@presenter.board(board)).to eql(board_string)
49
+ end
50
+ end
51
+
52
+ describe '#game_history_strings' do
53
+ it 'Returns an array with a string for each game history' do
54
+ history_double = double('history',
55
+ board_size: 9,
56
+ difficulty: 'Medium AI',
57
+ winner: 'X',
58
+ moves: [['A', 0], ['B', 4]])
59
+ histories_array = [history_double, history_double]
60
+ wrapper = double('wrapper', read_game_histories: histories_array)
61
+
62
+ expect(@presenter.game_history_strings(wrapper).count).to eq(2)
63
+ end
64
+ end
65
+
66
+ describe '#game_history_string' do
67
+ before do
68
+ @history_double = double('history',
69
+ board_size: 9,
70
+ difficulty: 'Medium AI',
71
+ winner: 'X',
72
+ moves: [['A', 0], ['B', 4]])
73
+ end
74
+
75
+ it 'Returns a string that includes the game history’s board size' do
76
+ history_string = @presenter.game_history_string(@history_double)
77
+ expect(history_string).to include('9')
78
+ end
79
+
80
+ it 'Returns a string that includes the game history’s difficulty' do
81
+ history_string = @presenter.game_history_string(@history_double)
82
+ expect(history_string).to include('Medium AI')
83
+ end
84
+
85
+ it 'Returns a string that includes the game history’s winner' do
86
+ history_string = @presenter.game_history_string(@history_double)
87
+ expect(history_string).to include('X')
88
+ end
89
+
90
+ it 'Returns a string that includes the game history’s move history' do
91
+ history_string = @presenter.game_history_string(@history_double)
92
+ expect(history_string).to include('A', '0', 'B', '4')
93
+ end
94
+ end
95
+ end
@@ -19,8 +19,8 @@ describe TicTacToes::UI::Adapter do
19
19
  context 'when passed an order of “second”' do
20
20
  it 'sends its listener #moves_were_made with the game state' do
21
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)
22
+ computer_player = double(place_and_return_move: 0, token: 'O')
23
+ game_state = double(game_over?: false, turn_over: true, computer_player: computer_player)
24
24
  listener = double
25
25
 
26
26
  expect(listener).to receive(:moves_were_made).with(game_state)
@@ -56,6 +56,21 @@ describe TicTacToes::UI::Adapter do
56
56
  end
57
57
  end
58
58
 
59
+ context 'when the game is over' do
60
+ it 'records the game history' do
61
+ board = TicTacToes::TestBoardGenerator.generate([ x, x, nil,
62
+ nil, nil, nil,
63
+ nil, nil, nil])
64
+ game_state = TicTacToes::Core::GameState.new(board, players, history)
65
+ move = '2'
66
+ listener = double(game_ended_in_winner: true)
67
+
68
+ expect(history).to receive(:persist)
69
+ TicTacToes::UI::Adapter.make_move(game_state, move, listener)
70
+ board.place(x, 2)
71
+ end
72
+ end
73
+
59
74
  context 'when the game has ended with a winner' do
60
75
  it 'sends its listener #game_ended_in_winner with the updated game state and the winning token' do
61
76
  board = TicTacToes::TestBoardGenerator.generate([ x, x, nil,
@@ -98,7 +113,7 @@ describe TicTacToes::UI::Adapter do
98
113
  player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
99
114
  let(:x) { player_factory.generate_player('x', TicTacToes::Core::PlayerFactory::HUMAN) }
100
115
  let(:o) { player_factory.generate_player('o', TicTacToes::Core::PlayerFactory::HARD_AI) }
101
- let(:players) { [o, x] }
116
+ let(:players) { [x, o] }
102
117
 
103
118
  it 'returns an array indicating which moves will result in a win' do
104
119
  board = TicTacToes::TestBoardGenerator.generate([ x, x, nil,
@@ -139,9 +154,9 @@ describe TicTacToes::UI::Adapter do
139
154
  nil, nil, x])
140
155
  game_state = TicTacToes::Core::GameState.new(board, players, history)
141
156
 
142
- expect(TicTacToes::UI::Adapter.predictions(game_state)).to eq([ nil, nil, nil,
143
- nil, nil, "loss",
144
- nil, "loss", nil])
157
+ expect(TicTacToes::UI::Adapter.predictions(game_state)).to eq([nil, nil, nil,
158
+ nil, nil, "loss",
159
+ nil, "loss", nil])
145
160
  end
146
161
  end
147
162
  end
@@ -11,13 +11,14 @@ describe TicTacToes::UI::Serializer do
11
11
  end
12
12
  end
13
13
 
14
- describe '#game_state_from_board_structure' do
15
- it 'returns a game state object based on a board structure and computer type' do
14
+ describe '#game_state' do
15
+ it 'returns a game state object based on a board structure and AI type' do
16
16
  board_structure = [nil, nil, nil, nil, 'X', nil, nil, nil, nil]
17
- computer_type = 'EASY_AI'
17
+ ai_type = 'EASY_AI'
18
+ move_history = 'X0O4'
18
19
  ai = TicTacToes::Core::PlayerFactory::AIS.fetch(TicTacToes::Core::PlayerFactory::EASY_AI)
19
20
 
20
- game_state = TicTacToes::UI::Serializer.game_state_from_board_structure(board_structure, computer_type)
21
+ game_state = TicTacToes::UI::Serializer.game_state(board_structure, ai_type, move_history)
21
22
  middle_space = game_state.board.space(4)
22
23
  first_player = game_state.players.first
23
24
  second_player = game_state.players.last
@@ -26,10 +27,11 @@ describe TicTacToes::UI::Serializer do
26
27
  expect(first_player.token).to eq(TicTacToes::UI::Serializer::X)
27
28
  expect(second_player.token).to eq(TicTacToes::UI::Serializer::O)
28
29
  expect(second_player.move_strategy).to eq(ai)
30
+ expect(game_state.moves).to eq([['X', 0], ['O', 4]])
29
31
  end
30
32
  end
31
33
 
32
- describe '#board_structure_from_game_state' do
34
+ describe '#board_structure' do
33
35
  it 'returns a board structure based on a game state object' do
34
36
  player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
35
37
  first_player = player_factory.generate_player(TicTacToes::UI::Serializer::X, TicTacToes::Core::PlayerFactory::HUMAN)
@@ -40,17 +42,25 @@ describe TicTacToes::UI::Serializer do
40
42
 
41
43
  game_state = TicTacToes::Core::GameState.new(board, players, TicTacToes::UI::NullHistory.new)
42
44
  board_structure = [nil, nil, nil, nil, 'X', nil, nil, nil, nil]
43
- expect(TicTacToes::UI::Serializer.board_structure_from_game_state(game_state)).to eq(board_structure)
45
+ expect(TicTacToes::UI::Serializer.board_structure(game_state)).to eq(board_structure)
44
46
  end
45
47
  end
46
48
 
47
- describe '#ai_type_from_game_state' do
49
+ describe '#ai_type' do
48
50
  it 'returns the type of a game state’s computer player' do
49
51
  move_strategy = TicTacToes::Core::PlayerFactory::AIS.fetch(TicTacToes::Core::PlayerFactory::EASY_AI)
50
52
  computer_player = double(move_strategy: move_strategy)
51
53
  players = [computer_player]
52
54
  game_state = double(players: players)
53
- expect(TicTacToes::UI::Serializer.ai_type_from_game_state(game_state)).to eq('EASY_AI')
55
+ expect(TicTacToes::UI::Serializer.ai_type(game_state)).to eq('EASY_AI')
56
+ end
57
+ end
58
+
59
+ describe '#move_history' do
60
+ it 'returns a move history structure based on a game state object' do
61
+ moves = [['X', 0], ['O', 4]]
62
+ game_state = double('game_state', moves: moves)
63
+ expect(TicTacToes::UI::Serializer.move_history(game_state)).to eq('X0O4')
54
64
  end
55
65
  end
56
66
  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
4
+ version: 0.1.6
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-08-26 00:00:00.000000000 Z
11
+ date: 2014-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -87,7 +87,6 @@ files:
87
87
  - bin/game_histories
88
88
  - bin/set_up_ttt_databases
89
89
  - bin/tic_tac_toes
90
- - lib/tic_tac_toes/command_line/history_reader.rb
91
90
  - lib/tic_tac_toes/command_line/menu.rb
92
91
  - lib/tic_tac_toes/command_line/prompt.rb
93
92
  - lib/tic_tac_toes/command_line/runner.rb
@@ -102,15 +101,14 @@ files:
102
101
  - lib/tic_tac_toes/core/move_strategies/types.rb
103
102
  - lib/tic_tac_toes/core/player.rb
104
103
  - lib/tic_tac_toes/core/player_factory.rb
104
+ - lib/tic_tac_toes/core/presenter.rb
105
105
  - lib/tic_tac_toes/core/rules.rb
106
- - lib/tic_tac_toes/core/strings.rb
107
106
  - lib/tic_tac_toes/database/pg_wrapper.rb
108
107
  - lib/tic_tac_toes/tasks/destroy_databases.rake
109
108
  - lib/tic_tac_toes/tasks/set_up_databases.rake
110
109
  - lib/tic_tac_toes/ui/adapter.rb
111
110
  - lib/tic_tac_toes/ui/serializer.rb
112
111
  - lib/tic_tac_toes/version.rb
113
- - spec/tic_tac_toes/command_line/history_reader_spec.rb
114
112
  - spec/tic_tac_toes/command_line/menu_spec.rb
115
113
  - spec/tic_tac_toes/core/board_spec.rb
116
114
  - spec/tic_tac_toes/core/game_state_spec.rb
@@ -122,8 +120,8 @@ files:
122
120
  - spec/tic_tac_toes/core/move_strategies/medium_ai_spec.rb
123
121
  - spec/tic_tac_toes/core/player_factory_spec.rb
124
122
  - spec/tic_tac_toes/core/player_spec.rb
123
+ - spec/tic_tac_toes/core/presenter_spec.rb
125
124
  - spec/tic_tac_toes/core/rules_spec.rb
126
- - spec/tic_tac_toes/core/strings_spec.rb
127
125
  - spec/tic_tac_toes/database/pg_wrapper_spec.rb
128
126
  - spec/tic_tac_toes/test_board_generator.rb
129
127
  - spec/tic_tac_toes/ui/adapter_spec.rb
@@ -154,7 +152,6 @@ signing_key:
154
152
  specification_version: 4
155
153
  summary: The game Tic-tac-toe, featuring an unbeatable AI
156
154
  test_files:
157
- - spec/tic_tac_toes/command_line/history_reader_spec.rb
158
155
  - spec/tic_tac_toes/command_line/menu_spec.rb
159
156
  - spec/tic_tac_toes/core/board_spec.rb
160
157
  - spec/tic_tac_toes/core/game_state_spec.rb
@@ -166,8 +163,8 @@ test_files:
166
163
  - spec/tic_tac_toes/core/move_strategies/medium_ai_spec.rb
167
164
  - spec/tic_tac_toes/core/player_factory_spec.rb
168
165
  - spec/tic_tac_toes/core/player_spec.rb
166
+ - spec/tic_tac_toes/core/presenter_spec.rb
169
167
  - spec/tic_tac_toes/core/rules_spec.rb
170
- - spec/tic_tac_toes/core/strings_spec.rb
171
168
  - spec/tic_tac_toes/database/pg_wrapper_spec.rb
172
169
  - spec/tic_tac_toes/test_board_generator.rb
173
170
  - spec/tic_tac_toes/ui/adapter_spec.rb
@@ -1,28 +0,0 @@
1
- require 'tic_tac_toes/command_line/prompt'
2
-
3
- module TicTacToes
4
- module CommandLine
5
- class HistoryReader
6
- def initialize(wrapper)
7
- @wrapper = wrapper
8
- end
9
-
10
- def display_game_histories
11
- game_histories = @wrapper.read_game_histories
12
- game_histories.each { |history| Prompt.display(game_history_string(history)) }
13
- nil
14
- end
15
-
16
- def game_history_string(history)
17
- history_string = ''
18
- history_string << "Board size: #{history.board_size.to_s}\n"
19
- history_string << "Difficulty: #{history.difficulty}\n"
20
- history_string << "Winner: #{history.winner}\n"
21
- history_string << "Move history:\n"
22
- history.moves.each { |move| history_string << " #{move.join(' -> ')}\n" }
23
- history_string << "\n"
24
- history_string
25
- end
26
- end
27
- end
28
- end
@@ -1,48 +0,0 @@
1
- require 'tic_tac_toes/command_line/history_reader'
2
-
3
- describe TicTacToes::CommandLine::HistoryReader do
4
- before do
5
- @history_double = double('history',
6
- board_size: 9,
7
- difficulty: 'Medium AI',
8
- winner: 'X',
9
- moves: [['A', 0], ['B', 4]])
10
- end
11
-
12
- describe '#display_game_histories' do
13
- it 'Displays something for each game history' do
14
- histories_array = [@history_double, @history_double]
15
- wrapper = double('wrapper', read_game_histories: histories_array)
16
-
17
- expect(TicTacToes::CommandLine::Prompt).to receive(:display).twice
18
- TicTacToes::CommandLine::HistoryReader.new(wrapper).display_game_histories
19
- end
20
- end
21
-
22
- describe '#game_history_string' do
23
- before do
24
- wrapper_double = double('wrapper')
25
- @history_reader = TicTacToes::CommandLine::HistoryReader.new(wrapper_double)
26
- end
27
-
28
- it 'Returns a string that includes the game history’s board size' do
29
- history_string = @history_reader.game_history_string(@history_double)
30
- expect(history_string).to include('9')
31
- end
32
-
33
- it 'Returns a string that includes the game history’s difficulty' do
34
- history_string = @history_reader.game_history_string(@history_double)
35
- expect(history_string).to include('Medium AI')
36
- end
37
-
38
- it 'Returns a string that includes the game history’s winner' do
39
- history_string = @history_reader.game_history_string(@history_double)
40
- expect(history_string).to include('X')
41
- end
42
-
43
- it 'Returns a string that includes the game history’s move history' do
44
- history_string = @history_reader.game_history_string(@history_double)
45
- expect(history_string).to include('A', '0', 'B', '4')
46
- end
47
- end
48
- end
@@ -1,49 +0,0 @@
1
- require 'tic_tac_toes/core/board'
2
- require 'tic_tac_toes/core/rules'
3
- require 'tic_tac_toes/core/strings'
4
-
5
- describe TicTacToes::Core::Strings do
6
- let(:strings) { TicTacToes::Core::Strings }
7
-
8
- describe '#invalid_row_size' do
9
- it "returns a string containing the minimum and maximum allowed row sizes" do
10
- smallest_row_size = TicTacToes::Core::Rules::ROW_SIZE_RANGE.min.to_s
11
- largest_row_size = TicTacToes::Core::Rules::ROW_SIZE_RANGE.max.to_s
12
-
13
- expect(strings::INVALID_ROW_SIZE).to include(smallest_row_size, largest_row_size)
14
- end
15
- end
16
-
17
- describe '#token_solicitation' do
18
- it "returns a string containing the name of the player whose token is being picked" do
19
- player = "human"
20
- expect(strings.token_solicitation(player)).to include(player)
21
- end
22
- end
23
-
24
- describe '#game_over_notification' do
25
- it "returns a string containing the name of the winner" do
26
- winner = "X"
27
- expect(strings.game_over_notification(winner)).to include(winner)
28
- end
29
- end
30
-
31
- describe '#board' do
32
- it "returns a board string" do
33
- board = TicTacToes::Core::Board.new(row_size: 3)
34
-
35
- leading_spaces_regexp = /^[[:blank:]]+/
36
- board_string = <<-END.gsub(leading_spaces_regexp, '')
37
-
38
- [0]|[1]|[2]
39
- -----------
40
- [3]|[4]|[5]
41
- -----------
42
- [6]|[7]|[8]
43
-
44
- END
45
-
46
- expect(strings.board(board)).to eql(board_string)
47
- end
48
- end
49
- end