games_bfox 0.3.0 → 0.4.0

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -12
  3. data/config/application.yml +5 -0
  4. data/games.gemspec +2 -1
  5. data/lib/games/mastermind/board_builder.rb +6 -2
  6. data/lib/games/mastermind/computer_player_expert.rb +31 -0
  7. data/lib/games/mastermind/computer_player_novice.rb +18 -0
  8. data/lib/games/mastermind/game.rb +69 -15
  9. data/lib/games/mastermind/guess_evaluator.rb +105 -68
  10. data/lib/games/mastermind/guess_evaluator_result.rb +11 -0
  11. data/lib/games/mastermind/human_player.rb +9 -0
  12. data/lib/games/mastermind/io_helpers.rb +65 -0
  13. data/lib/games/mastermind/peg.rb +2 -4
  14. data/lib/games/mastermind/pegs.rb +1 -9
  15. data/lib/games/mastermind/pegs_factory.rb +3 -5
  16. data/lib/games/mastermind/players_factory.rb +32 -8
  17. data/lib/games/mastermind/secret_code.rb +19 -0
  18. data/lib/games/mastermind.rb +9 -2
  19. data/lib/games/shared/game.rb +56 -70
  20. data/lib/games/shared/{input_helper.rb → io_helpers.rb} +40 -32
  21. data/lib/games/shared/player.rb +1 -3
  22. data/lib/games/shared/player_factory.rb +9 -0
  23. data/lib/games/shared/players_factory.rb +9 -0
  24. data/lib/games/tictactoe/board.rb +3 -4
  25. data/lib/games/tictactoe/board_builder.rb +3 -3
  26. data/lib/games/tictactoe/board_presenter_terminal.rb +3 -3
  27. data/lib/games/tictactoe/computer_player_expert.rb +12 -0
  28. data/lib/games/tictactoe/computer_player_novice.rb +10 -0
  29. data/lib/games/tictactoe/game.rb +45 -12
  30. data/lib/games/tictactoe/human_player.rb +9 -0
  31. data/lib/games/tictactoe/io_helpers.rb +81 -0
  32. data/lib/games/tictactoe/player.rb +4 -0
  33. data/lib/games/tictactoe/players_factory.rb +49 -5
  34. data/lib/games/tictactoe/square.rb +0 -3
  35. data/lib/games/tictactoe/squares.rb +1 -1
  36. data/lib/games/tictactoe/squares_factory.rb +7 -11
  37. data/lib/games/tictactoe.rb +9 -2
  38. data/lib/games/version.rb +1 -1
  39. metadata +32 -17
  40. data/lib/games/mastermind/colors.rb +0 -14
  41. data/lib/games/mastermind/game_config.rb +0 -48
  42. data/lib/games/mastermind/game_resetter.rb +0 -19
  43. data/lib/games/mastermind/game_state_changer.rb +0 -41
  44. data/lib/games/mastermind/input_helper.rb +0 -67
  45. data/lib/games/mastermind/move_generator.rb +0 -46
  46. data/lib/games/shared/array_iterator.rb +0 -28
  47. data/lib/games/tictactoe/game_config.rb +0 -73
  48. data/lib/games/tictactoe/game_resetter.rb +0 -16
  49. data/lib/games/tictactoe/game_state_changer.rb +0 -17
  50. data/lib/games/tictactoe/input_helper.rb +0 -87
  51. data/lib/games/tictactoe/move_generator.rb +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eea4457891bd6031147b650c010445ea236d8e74
4
- data.tar.gz: d37e19b5a8627b9d6b4c7cd5f2214c1c726f8d85
3
+ metadata.gz: b869fc9dbf4366e974cab29e2e0fec776fcd6f30
4
+ data.tar.gz: 47921477fd8d4c7d703cc5867a464bd26fac0050
5
5
  SHA512:
6
- metadata.gz: 9a19f97734b8a705a775424c3d18d52aa7174c379bf89061fd83e92cc2311a355b7650257712fa33f2b96c9751053e79e86b96ce5c52cd506a07921a5b520777
7
- data.tar.gz: 97764dfed555860fae880c91bfe2cf73ff2ca6448bf86e85018097329f2cefc9003cacae4a04be1da8104d4f758d1dfa6686d71bbf6fe1f1accb96ca8919ea34
6
+ metadata.gz: e69728ecffc7184b02c99a33d3d673defac42d8803bf113b2084ae45c6aee9598e11e3c40c536fa296877446541a53798a97baf799bfa507d9b8947c3961f788
7
+ data.tar.gz: bc49069cd841039d46e369b4276774084bff81f2c10a886eebf033fabda23fa8c83ef026c8d74c0cfe0a75da8298b2a578e94af55d2aff3e19c56c60dfd0e2dd
data/README.md CHANGED
@@ -1,15 +1,14 @@
1
- # Games
1
+ # games_bfox
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/games`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Welcome to the games_bfox gem!
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
6
5
 
7
6
  ## Installation
8
7
 
9
8
  Add this line to your application's Gemfile:
10
9
 
11
10
  ```ruby
12
- gem 'games'
11
+ gem 'games_bfox'
13
12
  ```
14
13
 
15
14
  And then execute:
@@ -18,19 +17,16 @@ And then execute:
18
17
 
19
18
  Or install it yourself as:
20
19
 
21
- $ gem install games
20
+ $ gem install games_bfox
22
21
 
23
22
  ## Usage
24
23
 
25
- TODO: Write usage instructions here
24
+ To play Mastermind, type the following into your command line to run the game executable :
26
25
 
27
- ## Development
26
+ $ mastermind
28
27
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
28
+ To play Tic Tac Toe, type the following into your command line to run the game executable :
30
29
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
30
+ $ tictactoe
32
31
 
33
- ## Contributing
34
-
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/games.
36
32
 
@@ -0,0 +1,5 @@
1
+ #not used. Figaro appears to rely on Rails
2
+ #https://github.com/laserlemon/figaro/issues/77
3
+
4
+ #POSTGRES_USERNAME: "Brett"
5
+ #POSTGRES_PASSWORD:
data/games.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.email = ["brettfox11@gmail.com"]
19
19
 
20
20
  spec.summary = %q{Play tic tac toe and mastermind on the command line}
21
- spec.description = %q{In order to play, download the gem, and type \"tictactoe\" or \"mastermind\" at your terminal.}
21
+ spec.description = %q{In order to play, download the gem, and type "tictactoe" or "mastermind" at your terminal. Type "exit" to quit the game.}
22
22
  spec.homepage = "https://github.com/brett11/games"
23
23
 
24
24
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
@@ -33,4 +33,5 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency "rspec", "~> 3.6"
34
34
  spec.add_development_dependency 'pry', '~> 0.10.4'
35
35
  spec.add_development_dependency 'logging', '~> 2.2', '>= 2.2.2'
36
+ spec.add_development_dependency 'paint', '~> 2.0'
36
37
  end
@@ -1,9 +1,13 @@
1
1
  require_relative 'pegs_factory'
2
+ require_relative 'board'
2
3
 
3
4
  module MM
4
5
  class BoardBuilder
5
- def generate_empty_board(config)
6
- Board.new(number_of_rows: config.number_of_rows, number_of_cols: config.number_of_cols, pegs: PegsFactory.build_empty_pegs(config.number_of_rows, config.number_of_cols), result_pegs: PegsFactory.build_empty_pegs(config.number_of_rows, config.number_of_cols) )
6
+ def generate_empty_board(number_of_rows = 12, number_of_cols = 4)
7
+ MM::Board.new(number_of_rows: number_of_rows,
8
+ number_of_cols: number_of_cols,
9
+ pegs: MM::PegsFactory.build_empty_pegs(number_of_rows, number_of_cols),
10
+ result_pegs: MM::PegsFactory.build_empty_pegs(number_of_rows, number_of_cols) )
7
11
  end
8
12
  end
9
13
  end
@@ -0,0 +1,31 @@
1
+ require_relative '../shared/player'
2
+
3
+ module MM
4
+ class ComputerPlayerExpert < Shared::Player
5
+ def make_move(game)
6
+ @game = game
7
+ computer_choosing_graphic
8
+ smart_move
9
+ end
10
+
11
+ def smart_move
12
+ secret_code = current_result_partial_match_values.concat(current_result_exact_match_values)
13
+ (4-(secret_code.size)).times do
14
+ secret_code.push((1..6).to_a.sample)
15
+ end
16
+ secret_code.shuffle
17
+ end
18
+
19
+ def computer_choosing_graphic
20
+ @game.computer_choosing_graphic
21
+ end
22
+
23
+ def current_result_partial_match_values
24
+ @game.current_result_partial_match_values
25
+ end
26
+
27
+ def current_result_exact_match_values
28
+ @game.current_result_exact_match_values
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../shared/player'
2
+
3
+ module MM
4
+ class ComputerPlayerNovice < Shared::Player
5
+ def make_move(game)
6
+ game.computer_choosing_graphic
7
+ random_move
8
+ end
9
+
10
+ def random_move
11
+ guess = []
12
+ 4.times do
13
+ guess.push((1..6).to_a.sample)
14
+ end
15
+ guess
16
+ end
17
+ end
18
+ end
@@ -3,26 +3,61 @@ require 'logger'
3
3
 
4
4
  module MM
5
5
  class Game < Shared::Game
6
- attr_accessor :code_setter, :secret_code, :guess_evaluator, :current_guess, :current_result, :won_flag
6
+ attr_accessor :secret_code, :current_result
7
7
 
8
- def local_setup
9
- self.code_setter = config.code_setter
10
- self.secret_code = config.secret_code
8
+ def one_time_setup
9
+ self.players = players_factory.generate_players
10
+ self.board = board_builder.generate_empty_board
11
+ end
12
+
13
+ def every_time_setup
14
+ self.number_of_turns_taken = 0
15
+ self.won_flag = false
16
+ self.secret_code = set_secret_code
17
+ self.current_result = MM::GuessEvaluatorResult.new
11
18
  logger = Logger.new(STDOUT)
12
19
  logger.level = Logger::DEBUG
13
20
  logger.debug("The secret code is #{secret_code.join(",")}.")
14
- self.guess_evaluator = MM::GuessEvaluator.new
15
- self.current_guess = []
16
- self.current_result = []
21
+ end
22
+
23
+
24
+ def set_secret_code
25
+ is_code_guesser_human = (players[0].kind_of?(MM::HumanPlayer))
26
+ MM::SecretCode.generate(io_helpers, is_code_guesser_human)
27
+ end
28
+
29
+ def change_game_state(move)
30
+ self.current_result = evaluate_guess(secret_code, move)
31
+ change_pegs(move)
32
+ if !won?
33
+ move_forward_one_turn
34
+ end
35
+ end
36
+
37
+ def current_result_partial_match_values
38
+ current_result.partial_match_values
39
+ end
40
+
41
+ def current_result_exact_match_values
42
+ current_result.exact_match_values
43
+ end
44
+
45
+ def reset_game
46
+ reset_board
47
+ self.number_of_turns_taken = 0
17
48
  self.won_flag = false
18
49
  end
19
50
 
20
- def over?
21
- won? || over_with_no_winner?
51
+ def reset_board
52
+ self.board = generate_empty_board
22
53
  end
23
54
 
24
- def over_with_no_winner?
25
- number_of_turns_taken >= 12
55
+ def generate_empty_board
56
+ board_builder.generate_empty_board
57
+ end
58
+
59
+ def over?
60
+ won? || no_more_turns?
26
61
  end
27
62
 
28
63
  def won?
@@ -31,7 +66,7 @@ module MM
31
66
  return true
32
67
  end
33
68
 
34
- if current_result == ("X" * number_of_cols).chars
69
+ if self.current_result.is_won
35
70
  self.won_flag = true
36
71
  true
37
72
  else
@@ -39,12 +74,27 @@ module MM
39
74
  end
40
75
  end
41
76
 
77
+ def no_more_turns?
78
+ number_of_turns_taken >= 12
79
+ end
80
+
81
+ def change_pegs(guess)
82
+ pegs_current_row.each_with_index do |peg, index|
83
+ peg.change_value(guess[index])
84
+ end
85
+
86
+ result_pegs_current_row.each_with_index do |result_peg, index|
87
+ result_peg.change_value(current_result.xo_key[index])
88
+ end
89
+ end
90
+
42
91
  def change_peg(row, col, new_value)
43
92
  board.change_peg(row, col, new_value)
44
93
  end
45
94
 
95
+ #below returns result object
46
96
  def evaluate_guess(secret_code, guess)
47
- guess_evaluator.evaluate_guess(secret_code, guess)
97
+ MM::GuessEvaluator.evaluate_guess(secret_code, guess)
48
98
  end
49
99
 
50
100
  def pegs_current_row
@@ -55,12 +105,16 @@ module MM
55
105
  board.result_pegs_current_row(number_of_turns_taken)
56
106
  end
57
107
 
108
+ def number_of_rows
109
+ board.number_of_rows
110
+ end
111
+
58
112
  def number_of_cols
59
113
  board.number_of_cols
60
114
  end
61
115
 
62
- def set_secret_code
63
- config.set_secret_code
116
+ def get_player_choice(current_player_name)
117
+ io_helpers.get_player_choice(current_player_name)
64
118
  end
65
119
  end
66
120
  end
@@ -1,85 +1,122 @@
1
- require_relative '../shared/array_iterator'
2
- require 'set.rb'
1
+ require_relative "../../../lib/games/mastermind/guess_evaluator_result"
3
2
 
4
3
  module MM
5
4
  class GuessEvaluator
6
- attr_accessor :secret_code
7
- attr_accessor :guess
8
- attr_accessor :result
9
-
10
- # returns "XXXX" if perfect guess. returns XXO, for example, if two perfect guesses and one right digit but wrong place
11
- def evaluate_guess(secret_code, guess)
12
- @secret_code = Marshal.load(Marshal.dump(secret_code))
13
- @guess = Marshal.load(Marshal.dump(guess))
14
- #default when game starts is to have empty current_guess array
15
- if guess.empty?
16
- return []
5
+ # below returns a Result object that summarizes the XO key, partial matches, exact matches, and if the guess was correct/won
6
+ # xo_key returns "XXXX" if perfect guess. returns XXO, for example, if two perfect guesses and one right digit but wrong place
7
+ def self.evaluate_guess(secret_code, guess)
8
+ #make arguments immutable
9
+ secret_code.freeze
10
+ guess.freeze
11
+
12
+ result = MM::GuessEvaluatorResult.new
13
+
14
+ resX = generate_Xs_for_exact_matches(secret_code, guess, [])
15
+ result.exact_match_values = find_exact_matches_from_secret_code(secret_code, guess, [])
16
+ secret_code_remaining = trim_exact_matches_from_secret_code(secret_code, guess, [])
17
+ guess_remaining = trim_exact_matches_from_guess(secret_code, guess, [])
18
+ resO = generate_Os_for_partial_matches(secret_code_remaining, guess_remaining)
19
+ result.xo_key = resX.concat resO
20
+ result.partial_match_values = values_of_partial_matches(secret_code_remaining, guess_remaining)
21
+ result.is_won = (result.xo_key == ("X" * secret_code.size).chars)
22
+ result
23
+ end
24
+
25
+ def self.generate_Xs_for_exact_matches(secret_code, guess, accum)
26
+ return accum if secret_code.empty? || guess.empty?
27
+ head_code, *tail_code = secret_code
28
+ head_guess, *tail_guess = guess
29
+
30
+ if head_code == head_guess
31
+ generate_Xs_for_exact_matches(tail_code, tail_guess, accum.push("X"))
32
+ else
33
+ generate_Xs_for_exact_matches(tail_code, tail_guess, accum)
17
34
  end
18
- @result = find_result
19
35
  end
20
36
 
21
- def find_result
22
- resX = find_exact_matches
23
- resO = find_partial_matches
24
- resX.concat resO
37
+ def self.find_exact_matches_from_secret_code(secret_code, guess, accum)
38
+ return accum if secret_code.empty? || guess.empty?
39
+ head_code, *tail_code = secret_code
40
+ head_guess, *tail_guess = guess
41
+
42
+ if head_code == head_guess
43
+ find_exact_matches_from_secret_code(tail_code, tail_guess, accum.push(head_code))
44
+ else
45
+ find_exact_matches_from_secret_code(tail_code, tail_guess, accum)
46
+ end
25
47
  end
26
48
 
27
- def find_exact_matches
28
- resX = []
29
- set_of_matched_indexes = Set.new
30
- guess.each_with_index do |element, index|
31
- if element == secret_code[index]
32
- resX.push ("X")
33
- set_of_matched_indexes.add(index)
34
- end
49
+ def self.trim_exact_matches_from_secret_code(secret_code, guess, accum)
50
+ return accum if secret_code.empty? || guess.empty?
51
+ head_code, *tail_code = secret_code
52
+ head_guess, *tail_guess = guess
53
+
54
+ if head_code == head_guess
55
+ trim_exact_matches_from_secret_code(tail_code, tail_guess, accum)
56
+ else
57
+ trim_exact_matches_from_secret_code(tail_code, tail_guess, accum.push(head_code))
35
58
  end
36
- delete_elements_already_matched(set_of_matched_indexes)
37
- resX
38
59
  end
39
60
 
40
- def delete_elements_already_matched(set_of_matched_indexes)
41
- secret_code.delete_if.with_index { |_, index| set_of_matched_indexes.include? index }
42
- guess.delete_if.with_index { |_, index| set_of_matched_indexes.include? index }
61
+ def self.trim_exact_matches_from_guess(secret_code, guess, accum)
62
+ return accum if secret_code.empty? || guess.empty?
63
+ head_code, *tail_code = secret_code
64
+ head_guess, *tail_guess = guess
65
+
66
+ if head_code == head_guess
67
+ trim_exact_matches_from_guess(tail_code, tail_guess, accum)
68
+ else
69
+ trim_exact_matches_from_guess(tail_code, tail_guess, accum.push(head_guess))
70
+ end
43
71
  end
44
72
 
45
- def find_partial_matches
46
- resO = []
47
- return resO if secret_code.empty? || guess.empty?
48
- secret_code.sort!
49
- guess.sort!
50
-
51
- secret_code_iterator = Shared::ArrayIterator.new(secret_code)
52
- guess_iterator = Shared::ArrayIterator.new(guess)
53
-
54
- #get first elements from enums
55
- code_element = secret_code_iterator.next_item
56
- guess_element = guess_iterator.next_item
57
-
58
-
59
- while true
60
- if guess_element == code_element
61
- resO.push("O")
62
- if secret_code_iterator.has_next? && guess_iterator.has_next?
63
- code_element = secret_code_iterator.next_item
64
- guess_element = guess_iterator.next_item
65
- else
66
- break
67
- end
68
- elsif guess_element > code_element
69
- if secret_code_iterator.has_next?
70
- code_element = secret_code_iterator.next_item
71
- else
72
- break
73
- end
74
- else
75
- if guess_iterator.has_next?
76
- guess_element = guess_iterator.next_item
77
- else
78
- break
79
- end
80
- end
73
+ def self.generate_Os_for_partial_matches(secret_code, guess)
74
+ secret_code.freeze
75
+ guess.freeze
76
+
77
+ secret_code_copy = secret_code.sort
78
+ guess_copy = guess.sort
79
+ find_partial_matches_helper(secret_code_copy, guess_copy, [])
80
+ end
81
+
82
+ def self.find_partial_matches_helper(secret_code, guess, accum)
83
+ return accum if secret_code.empty? || guess.empty?
84
+
85
+ head_code, *tail_code = secret_code
86
+ head_guess, *tail_guess = guess
87
+
88
+ if head_code == head_guess
89
+ find_partial_matches_helper(tail_code, tail_guess, accum.push("O"))
90
+ elsif head_code > head_guess
91
+ find_partial_matches_helper(secret_code, tail_guess, accum)
92
+ elsif head_code < head_guess
93
+ find_partial_matches_helper(tail_code, guess, accum)
94
+ end
95
+ end
96
+
97
+ def self.values_of_partial_matches(secret_code, guess)
98
+ secret_code.freeze
99
+ guess.freeze
100
+
101
+ secret_code_copy = secret_code.sort
102
+ guess_copy = guess.sort
103
+ values_of_partial_matches_helper(secret_code_copy, guess_copy, [])
104
+ end
105
+
106
+ def self.values_of_partial_matches_helper(secret_code, guess, accum)
107
+ return accum if secret_code.empty? || guess.empty?
108
+
109
+ head_code, *tail_code = secret_code
110
+ head_guess, *tail_guess = guess
111
+
112
+ if head_code == head_guess
113
+ #could push either head_code or guess, won't matter since equal
114
+ values_of_partial_matches_helper(tail_code, tail_guess, accum.push(head_guess))
115
+ elsif head_code > head_guess
116
+ values_of_partial_matches_helper(secret_code, tail_guess, accum)
117
+ elsif head_code < head_guess
118
+ values_of_partial_matches_helper(tail_code, guess, accum)
81
119
  end
82
- resO
83
120
  end
84
121
  end
85
122
  end
@@ -0,0 +1,11 @@
1
+ module MM
2
+ class GuessEvaluatorResult
3
+ attr_accessor :xo_key, :partial_match_values, :exact_match_values, :is_won
4
+ def initialize
5
+ @xo_key = []
6
+ @exact_match_values = []
7
+ @partial_match_values = []
8
+ @is_won = false
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../shared/player'
2
+
3
+ module MM
4
+ class HumanPlayer < Shared::Player
5
+ def make_move(game)
6
+ game.get_player_choice(game.current_player_name)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,65 @@
1
+ require_relative '../shared/io_helpers'
2
+ require 'paint'
3
+
4
+ module MM
5
+ class IOHelpers < Shared::IOHelpers
6
+ def custom_final_message(game)
7
+ io.present_with_new_line("The secret code was #{game.secret_code.join(",")}")
8
+ end
9
+
10
+ def initial_instructions
11
+ io.present_with_new_line(Paint["-" * 60 + "MASTERMIND" + "-" * 60, :blue, :bold, :bright, :underline])
12
+ io.present_with_new_line(Paint["INSTRUCTIONS: ", :green] + "Try to guess a 4 digit code that consists of only numbers 1-6 (\"3164\", for example).\n\n")
13
+ io.present_with_new_line("After each guess, the \"Result\" section will generate an "+ Paint["\"X\" ", :bold, :magenta] + "for each digit in the guess that is perfect(correct number and correct spot) and an "+ Paint["\"O\" ", :bold, :magenta] + "for each digit that is the correct number but in the wrong spot.")
14
+ io.present_with_new_line("-" * 130)
15
+ io.present_with_new_line(Paint["Type ",:red] + Paint["\"Exit\" ", :red, :bold] + Paint["to quit the game.", :red])
16
+ io.present_with_new_line("-" * 130)
17
+ end
18
+
19
+ def no_winner_prompt(game)
20
+ if game.players[0].kind_of?(MM::HumanPlayer)
21
+ io.present_with_new_line(Paint["No such luck! Please try again.", :red, :bold])
22
+ else
23
+ io.present_with_new_line(Paint["The computer has been stumped!", :green, :bold])
24
+ end
25
+
26
+ end
27
+
28
+ def computer_or_human_guesser_inquiry
29
+ user_choice = get_user_input("Please enter " + Paint["\"1\" ", :blue, :bold] + "if you would like to be the code-guesser. Enter " + Paint["\"2\" ", :blue, :bold] + "if you would like to set the code and have the computer guess.", "Invalid entry. Please enter either 1(computer picks code) or 2 (you pick code)") do |input|
30
+ input == 1 || input == 2
31
+ end
32
+ if user_choice == 1
33
+ return :human
34
+ elsif user_choice == 2
35
+ return :computer
36
+ end
37
+ end
38
+
39
+ def get_secret_code_from_user
40
+ user_choice = get_user_input("Please enter a secret code consisting of four numbers that each correspond to a color. Do not separate with punctuation. The computer will try to guess this code.", "Please re-enter a secret code, using only 4 numbers, 1 through 6.") do |input|
41
+ input.to_s =~ /^[1-6]{4}$/
42
+ end
43
+ user_choice.to_s.chars.map(&:to_i)
44
+ end
45
+
46
+ def get_player_choice(current_player_name)
47
+ user_choice = get_user_input("#{current_player_name}, please enter a secret code consisting of 4 numbers that correspond to the color of your guess. Do not separate with punctuation.", "Please re-enter a secret code guess, using exactly 4 numbers, each being a digit 1 through 6.") do |input|
48
+ input.to_s =~ /^[1-6]{4}$/
49
+ end
50
+ user_choice.to_s.chars.map(&:to_i)
51
+ end
52
+
53
+ def get_computer_knowledge_level
54
+ user_choice = get_user_input("Please enter " + Paint["\"D\" ", :blue, :bold] + "if you would like the computer to be kinda dumb. Enter " + Paint["\"S\" ", :blue, :bold] + "if you would like the computer to be pretty smart.", "Invalid character. Please enter either D (dumb) or S (Smart).") do |input|
55
+ input == 's' || input == 'S' || input == 'd' || input == 'D'
56
+ end
57
+ user_choice = user_choice.upcase
58
+ if user_choice == "S"
59
+ :expert
60
+ elsif user_choice == "D"
61
+ :novice
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,11 +1,9 @@
1
1
  module MM
2
2
  class Peg
3
- attr_accessor :display_value, :row, :col
3
+ attr_accessor :display_value
4
4
 
5
- def initialize(args)
5
+ def initialize(args = {})
6
6
  @display_value = args.fetch(:display_value, nil)
7
- @row = args[:row]
8
- @col = args[:col]
9
7
  end
10
8
 
11
9
  def change_value(new_value)
@@ -5,7 +5,7 @@ module MM
5
5
  #collection_of_pegs is a multi-dimensional array
6
6
 
7
7
  def initialize(args)
8
- @collection_of_pegs = args[:collection_of_pegs]
8
+ @collection_of_pegs = args.fetch(:collection_of_pegs)
9
9
  end
10
10
 
11
11
  def retrieve_peg(row, col)
@@ -29,14 +29,6 @@ module MM
29
29
  end
30
30
  end
31
31
 
32
- def result_values
33
- collection_of_pegs.reverse.map do |row|
34
- row.map do |peg|
35
- peg.result_value
36
- end
37
- end
38
- end
39
-
40
32
  private
41
33
  def number_of_rows
42
34
  collection_of_pegs.length
@@ -10,17 +10,15 @@ module MM
10
10
 
11
11
  pegs.each_with_index do |element, row|
12
12
  element.each_index do |col|
13
- pegs[row][col] = create_empty_peg(row, col)
13
+ pegs[row][col] = create_empty_peg
14
14
  end
15
15
  end
16
16
 
17
17
  pegs_class.new(collection_of_pegs: pegs)
18
18
  end
19
19
 
20
- def self.create_empty_peg(row, col, display_value = nil, peg_class = Peg)
21
- peg_class.new(display_value: display_value,
22
- row: row,
23
- col: col )
20
+ def self.create_empty_peg( peg_class = Peg)
21
+ peg_class.new
24
22
  end
25
23
  end
26
24
  end
@@ -1,15 +1,39 @@
1
- require_relative '../shared/player'
1
+ require_relative 'human_player'
2
+ require_relative 'computer_player_expert'
3
+ require_relative 'computer_player_novice'
2
4
 
3
5
  module MM
4
- class PlayersFactory
5
- #returns an array in case we would like to extend the game to allow for multiple players
6
- def generate_players(config)
7
- if config.code_setter == :computer
8
- player_1 = Shared::Player.new(name: config.player_1_name)
6
+ class PlayersFactory < Shared::PlayersFactory
7
+ def generate_players
8
+ player_1 = generate_player_1
9
+ [player_1]
10
+ end
11
+
12
+ def generate_player_1
13
+ code_guesser = io_helpers.computer_or_human_guesser_inquiry
14
+ if code_guesser == :human
15
+ generate_player_1_new
9
16
  else
10
- player_1 = Shared::Player.new(name: config.player_1_name, type: :computer)
17
+ computer_knowledge_level = io_helpers.get_computer_knowledge_level
18
+ if computer_knowledge_level == :novice
19
+ generate_player_1_computer_novice
20
+ else
21
+ generate_player_1_computer_expert
22
+ end
11
23
  end
12
- [player_1]
24
+ end
25
+
26
+ def generate_player_1_new
27
+ player_name = io_helpers.get_player_1_name
28
+ MM::HumanPlayer.new(name: player_name)
29
+ end
30
+
31
+ def generate_player_1_computer_novice
32
+ MM::ComputerPlayerNovice.new(name: "Computer")
33
+ end
34
+
35
+ def generate_player_1_computer_expert
36
+ MM::ComputerPlayerExpert.new(name: "Computer")
13
37
  end
14
38
  end
15
39
  end