tic_tac_toes 0.0.8 → 0.0.9

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: 085e4d7d1fd5316dd0a28ca154203ae9411e3c2f
4
- data.tar.gz: ef98016568277620377b83e02aa0ea58827a379b
3
+ metadata.gz: 919ce75f7f8ad28d261cef9d2a9c7dc1cb0fdad7
4
+ data.tar.gz: 676c42fa2f8acb3c7dc03d989ab40febdd9958ee
5
5
  SHA512:
6
- metadata.gz: 688112f80e57889cbd0cf27e190f3f2a7a8e41dc6823ef9ee1d47bf622cd5f554c52b8684c4332c97d838ea923c5b32cb2f0687f92f9a2d3ff9169c5730ba308
7
- data.tar.gz: ccf022fc972444762499b6ac6a9450dc91ae27be064d24692c11cbdfe232814ff6ad18425e98f56c052c6649aa8de7a0a3c56b1f664fea422ec3aee2db4af24a
6
+ metadata.gz: 8e94d802c318a795d6272a5341a2183248cf355109abf6022ce3fd725c2080987028bc1037fb3134fc1e31f321468b93c21e66e4ea3d663c98cd45a69164efef
7
+ data.tar.gz: 7bd562a193cde805efb2d9ee5c12f4dc10b4e9fa78b6f1ccc622d1e4cc1c7b1438f5bf3adf523ee41ddab88362fdee97301c2f6c114ac40096fbbad4b7600342
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tic_tac_toes (0.0.8)
4
+ tic_tac_toes (0.0.9)
5
5
  pg
6
6
 
7
7
  GEM
@@ -5,6 +5,7 @@ module TicTacToes
5
5
  module MoveStrategies
6
6
  module HardAI
7
7
  def self.move(board, players)
8
+ return 0 if nine_board_first_move?(board)
8
9
  return second_move(board) if nine_board_second_move?(board)
9
10
 
10
11
  open_spaces = Hash[board.open_spaces.map { |space| [space, nil] }]
@@ -60,6 +61,10 @@ module TicTacToes
60
61
  end
61
62
  end
62
63
 
64
+ def self.nine_board_first_move?(board)
65
+ board.size == 9 && board.open_spaces.count == 9
66
+ end
67
+
63
68
  def self.nine_board_second_move?(board)
64
69
  board.size == 9 && board.open_spaces.count == 8
65
70
  end
@@ -1,95 +1,39 @@
1
- require 'tic_tac_toes/core/board'
2
- require 'tic_tac_toes/core/game_state'
3
- require 'tic_tac_toes/core/player_factory'
4
- require 'tic_tac_toes/core/rules'
5
-
6
1
  module TicTacToes
7
2
  module UI
8
3
  module Adapter
9
- def self.new_board_structure
10
- board = Core::Board.new
11
- board.spaces
12
- end
13
-
14
- def self.make_move(board_structure, move, listener)
15
- move = move.to_i
16
- game_state = game_state_from_board_structure(board_structure)
17
-
18
- human_player = game_state.players.first
19
- game_state.board.place(human_player, move)
4
+ def self.make_move(game_state, move, listener)
5
+ unless move.nil?
6
+ move = move.to_i
7
+ game_state.board.place(game_state.current_player, move)
8
+ end
20
9
 
21
- if Core::Rules.game_over?(game_state.board, game_state.players)
22
- return listener.game_is_over(game_state_to_board_structure(game_state), "Game over")
10
+ if game_state.game_over?
11
+ tell_listener_game_is_over(game_state, listener)
12
+ return
23
13
  end
24
14
 
25
15
  game_state.turn_over(move)
16
+ game_state.current_player.place_and_return_move(game_state.board, game_state.players)
26
17
 
27
- computer_player = game_state.players.first
28
- computer_player.place_and_return_move(game_state.board, game_state.players)
29
-
30
- if Core::Rules.game_over?(game_state.board, game_state.players)
31
- return listener.game_is_over(game_state_to_board_structure(game_state), "Game over")
18
+ if game_state.game_over?
19
+ tell_listener_game_is_over(game_state, listener)
20
+ return
32
21
  end
33
22
 
34
- listener.move_was_valid(game_state_to_board_structure(game_state))
35
- end
36
-
37
- def self.game_state_from_board_structure(board_structure)
38
- player_factory = Core::PlayerFactory.new('unused_io')
39
- human_player = player_factory.generate_human_player('X')
40
- computer_player = player_factory.generate_computer_player('O', :hard)
41
- players = [human_player, computer_player]
42
-
43
- board_structure_with_players = replace_tokens_with_players(board_structure, human_player, computer_player)
44
- board = board_from_structure(board_structure_with_players)
45
-
46
- Core::GameState.new(board, players, NullHistory.new)
47
- end
48
-
49
- def self.game_state_to_board_structure(game_state)
50
- structure_with_players = game_state.board.spaces
51
-
52
- replace_players_with_tokens(structure_with_players)
23
+ listener.moves_were_made(game_state)
53
24
  end
54
25
 
55
26
  private
56
27
 
57
- def self.replace_tokens_with_players(board_structure, human_player, computer_player)
58
- board_structure.map do |space|
59
- case space
60
- when 'X'
61
- human_player
62
- when 'O'
63
- computer_player
64
- else
65
- nil
66
- end
67
- end
68
- end
69
-
70
- def self.replace_players_with_tokens(board_structure)
71
- board_structure.map { |space| space.token unless space.nil? }
72
- end
73
-
74
- def self.board_from_structure(board_structure)
75
- row_size = Math.sqrt(board_structure.count).to_i
76
- board = Core::Board.new(row_size: row_size)
28
+ def self.tell_listener_game_is_over(game_state, listener)
29
+ winning_token = game_state.determine_winner
77
30
 
78
- board_structure.each_with_index do |player, index|
79
- board.place(player, index)
31
+ case winning_token
32
+ when nil
33
+ listener.game_ended_in_draw(game_state)
34
+ else
35
+ listener.game_ended_in_winner(game_state, winning_token)
80
36
  end
81
-
82
- board
83
- end
84
- end
85
-
86
- class NullHistory
87
- def record_board_size(size)
88
- nil
89
- end
90
-
91
- def record_move(move)
92
- nil
93
37
  end
94
38
  end
95
39
  end
@@ -0,0 +1,75 @@
1
+ require 'tic_tac_toes/core/board'
2
+ require 'tic_tac_toes/core/game_state'
3
+ require 'tic_tac_toes/core/player_factory'
4
+
5
+ module TicTacToes
6
+ module UI
7
+ module Serializer
8
+ X = 'X'
9
+ O = 'O'
10
+
11
+ def self.new_board_structure
12
+ board = Core::Board.new
13
+ board.spaces
14
+ end
15
+
16
+ def self.game_state_from_board_structure(board_structure)
17
+ player_factory = Core::PlayerFactory.new('unused_io')
18
+ human_player = player_factory.generate_human_player(X)
19
+ computer_player = player_factory.generate_computer_player(O, :hard)
20
+ players = [human_player, computer_player]
21
+
22
+ board_structure_with_players = replace_tokens_with_players(board_structure, human_player, computer_player)
23
+ board = board_from_structure(board_structure_with_players)
24
+
25
+ Core::GameState.new(board, players, NullHistory.new)
26
+ end
27
+
28
+ def self.game_state_to_board_structure(game_state)
29
+ structure_with_players = game_state.board.spaces
30
+
31
+ replace_players_with_tokens(structure_with_players)
32
+ end
33
+
34
+ private
35
+
36
+ def self.replace_tokens_with_players(board_structure, human_player, computer_player)
37
+ board_structure.map do |space|
38
+ case space
39
+ when X
40
+ human_player
41
+ when O
42
+ computer_player
43
+ else
44
+ nil
45
+ end
46
+ end
47
+ end
48
+
49
+ def self.replace_players_with_tokens(board_structure)
50
+ board_structure.map { |space| space.token unless space.nil? }
51
+ end
52
+
53
+ def self.board_from_structure(board_structure)
54
+ row_size = Math.sqrt(board_structure.count).to_i
55
+ board = Core::Board.new(row_size: row_size)
56
+
57
+ board_structure.each_with_index do |player, index|
58
+ board.place(player, index)
59
+ end
60
+
61
+ board
62
+ end
63
+ end
64
+
65
+ class NullHistory
66
+ def record_board_size(size)
67
+ nil
68
+ end
69
+
70
+ def record_move(move)
71
+ nil
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,3 +1,3 @@
1
1
  module TicTacToes
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -20,6 +20,14 @@ describe TicTacToes::Core::MoveStrategies::HardAI do
20
20
  end
21
21
 
22
22
  context "when playing on a 3x3 board" do
23
+ it 'returns 0 when making the first move' do
24
+ board = TicTacToes::TestBoardGenerator.generate([nil, nil, nil,
25
+ nil, nil, nil,
26
+ nil, nil, nil])
27
+
28
+ expect(hard_ai.move(board, players)).to eq(0)
29
+ end
30
+
23
31
  it "returns 4 when the opponent’s first move was a corner" do
24
32
  board = TicTacToes::TestBoardGenerator.generate([nil, nil, nil,
25
33
  nil, nil, nil,
@@ -1,72 +1,69 @@
1
- require 'tic_tac_toes/core/board'
2
1
  require 'tic_tac_toes/core/game_state'
3
2
  require 'tic_tac_toes/core/player_factory'
3
+ 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 '#new_board_structure' do
8
- it 'returns a new board structure' do
9
- new_board_structure = [nil, nil, nil, nil, nil, nil, nil, nil, nil]
10
- expect(TicTacToes::UI::Adapter.new_board_structure).to eq(new_board_structure)
11
- end
12
- end
13
-
14
7
  describe '#make_move' do
8
+ let(:history) { double(record_board_size: true,
9
+ record_move: true) }
10
+ player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
11
+ let(:x) { player_factory.generate_human_player('x') }
12
+ let(:o) { player_factory.generate_computer_player('o', :hard) }
13
+ let(:players) { [x, o] }
14
+
15
15
  context 'when the game is still in progress' do
16
- it 'sends its listener a `valid` message with an updated board structure' do
17
- board_structure = ["X", nil, nil, nil, "O", nil, nil, nil, nil]
18
- move = "2"
16
+ it 'sends its listener #moves_were_made with the updated game state' do
17
+ board = TicTacToes::TestBoardGenerator.generate([ x, nil, nil,
18
+ nil, o, nil,
19
+ nil, nil, nil])
20
+ game_state = TicTacToes::Core::GameState.new(board, players, history)
21
+ move = '2'
19
22
  listener = double
20
23
 
21
- updated_board_structure = ["X", "O", "X", nil, "O", nil, nil, nil, nil]
24
+ allow(listener).to receive(:moves_were_made)
25
+ TicTacToes::UI::Adapter.make_move(game_state, move, listener)
22
26
 
23
- expect(listener).to receive(:move_was_valid).with(updated_board_structure)
24
- TicTacToes::UI::Adapter.make_move(board_structure, move, listener)
27
+ first_move, second_move = 2, 1
28
+ game_state.board.place(x, first_move)
29
+ game_state.board.place(o, second_move)
30
+ expect(listener).to have_received(:moves_were_made).with(game_state)
25
31
  end
26
32
  end
27
33
 
28
- context 'when the game has ended' do
29
- it 'sends its listener a `game_over` message with an updated board structure and a game over message' do
30
- board_structure = ["X", "X", nil, nil, nil, nil, nil, nil, nil]
31
- move = "2"
34
+ context 'when the game has ended with a winner' do
35
+ it 'sends its listener #game_ended_in_winner with the updated game state and the winning token' do
36
+ board = TicTacToes::TestBoardGenerator.generate([ x, x, nil,
37
+ nil, nil, nil,
38
+ nil, nil, nil])
39
+ game_state = TicTacToes::Core::GameState.new(board, players, history)
40
+ move = '2'
32
41
  listener = double
42
+ winning_token = 'x'
33
43
 
34
- updated_board_structure = ["X", "X", "X", nil, nil, nil, nil, nil, nil]
35
- game_over_message = "Game over"
44
+ allow(listener).to receive(:game_ended_in_winner)
45
+ TicTacToes::UI::Adapter.make_move(game_state, move, listener)
36
46
 
37
- expect(listener).to receive(:game_is_over).with(updated_board_structure, game_over_message)
38
- TicTacToes::UI::Adapter.make_move(board_structure, move, listener)
47
+ game_state.board.place(x, 2)
48
+ expect(listener).to have_received(:game_ended_in_winner).with(game_state, winning_token)
39
49
  end
40
50
  end
41
- end
42
-
43
- describe '#game_state_from_board_structure' do
44
- it 'returns a game state object based on a board structure' do
45
- board_structure = [nil, nil, nil, nil, "X", nil, nil, nil, nil]
46
51
 
47
- game_state = TicTacToes::UI::Adapter.game_state_from_board_structure(board_structure)
48
- middle_space = game_state.board.space(4)
49
- first_player = game_state.players.first
50
- second_player = game_state.players.last
51
-
52
- expect(middle_space.token).to eq('X')
53
- expect(first_player.token).to eq('X')
54
- expect(second_player.token).to eq('O')
55
- end
56
- end
52
+ context 'when the game has ended in a draw' do
53
+ it 'sends its listener #game_ended_in_draw with the updated game state' do
54
+ board = TicTacToes::TestBoardGenerator.generate([x, x, o,
55
+ o, o, x,
56
+ x, o, nil])
57
+ game_state = TicTacToes::Core::GameState.new(board, players, history)
58
+ move = '8'
59
+ listener = double
57
60
 
58
- describe '#game_state_to_board_structure' do
59
- it 'returns a board structure based on a game state object' do
60
- player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
61
- first_player = player_factory.generate_human_player('X')
62
- second_player = player_factory.generate_computer_player('O', :hard)
63
- players = [first_player, second_player]
64
- board = TicTacToes::Core::Board.new
65
- board.place(first_player, 4)
61
+ allow(listener).to receive(:game_ended_in_draw)
62
+ TicTacToes::UI::Adapter.make_move(game_state, move, listener)
66
63
 
67
- game_state = TicTacToes::Core::GameState.new(board, players, TicTacToes::UI::NullHistory.new)
68
- board_structure = [nil, nil, nil, nil, "X", nil, nil, nil, nil]
69
- expect(TicTacToes::UI::Adapter.game_state_to_board_structure(game_state)).to eq(board_structure)
64
+ game_state.board.place(x, 8)
65
+ expect(listener).to have_received(:game_ended_in_draw).with(game_state)
66
+ end
70
67
  end
71
68
  end
72
69
  end
@@ -0,0 +1,43 @@
1
+ require 'tic_tac_toes/core/board'
2
+ require 'tic_tac_toes/core/game_state'
3
+ require 'tic_tac_toes/core/player_factory'
4
+ require 'tic_tac_toes/ui/serializer'
5
+
6
+ describe TicTacToes::UI::Serializer do
7
+ describe '#new_board_structure' do
8
+ it 'returns a new board structure' do
9
+ new_board_structure = [nil, nil, nil, nil, nil, nil, nil, nil, nil]
10
+ expect(TicTacToes::UI::Serializer.new_board_structure).to eq(new_board_structure)
11
+ end
12
+ end
13
+
14
+ describe '#game_state_from_board_structure' do
15
+ it 'returns a game state object based on a board structure' do
16
+ board_structure = [nil, nil, nil, nil, 'X', nil, nil, nil, nil]
17
+
18
+ game_state = TicTacToes::UI::Serializer.game_state_from_board_structure(board_structure)
19
+ middle_space = game_state.board.space(4)
20
+ first_player = game_state.players.first
21
+ second_player = game_state.players.last
22
+
23
+ expect(middle_space.token).to eq(TicTacToes::UI::Serializer::X)
24
+ expect(first_player.token).to eq(TicTacToes::UI::Serializer::X)
25
+ expect(second_player.token).to eq(TicTacToes::UI::Serializer::O)
26
+ end
27
+ end
28
+
29
+ describe '#game_state_to_board_structure' do
30
+ it 'returns a board structure based on a game state object' do
31
+ player_factory = TicTacToes::Core::PlayerFactory.new('unused_io')
32
+ first_player = player_factory.generate_human_player(TicTacToes::UI::Serializer::X)
33
+ second_player = player_factory.generate_computer_player(TicTacToes::UI::Serializer::O, :hard)
34
+ players = [first_player, second_player]
35
+ board = TicTacToes::Core::Board.new
36
+ board.place(first_player, 4)
37
+
38
+ game_state = TicTacToes::Core::GameState.new(board, players, TicTacToes::UI::NullHistory.new)
39
+ board_structure = [nil, nil, nil, nil, 'X', nil, nil, nil, nil]
40
+ expect(TicTacToes::UI::Serializer.game_state_to_board_structure(game_state)).to eq(board_structure)
41
+ end
42
+ end
43
+ 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.0.8
4
+ version: 0.0.9
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-07-28 00:00:00.000000000 Z
11
+ date: 2014-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler