tic_tac_toes 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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