games_bfox 0.2.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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +6 -0
- data/exe/mastermind +8 -0
- data/exe/setup +8 -0
- data/exe/tictactoe +8 -0
- data/games.gemspec +36 -0
- data/lib/games/mastermind/board.rb +43 -0
- data/lib/games/mastermind/board_builder.rb +9 -0
- data/lib/games/mastermind/board_presenter_terminal.rb +69 -0
- data/lib/games/mastermind/colors.rb +14 -0
- data/lib/games/mastermind/game.rb +64 -0
- data/lib/games/mastermind/game_config.rb +48 -0
- data/lib/games/mastermind/game_resetter.rb +19 -0
- data/lib/games/mastermind/game_state_changer.rb +41 -0
- data/lib/games/mastermind/guess_evaluator.rb +85 -0
- data/lib/games/mastermind/input_helper.rb +54 -0
- data/lib/games/mastermind/move_generator.rb +46 -0
- data/lib/games/mastermind/peg.rb +15 -0
- data/lib/games/mastermind/pegs.rb +50 -0
- data/lib/games/mastermind/pegs_factory.rb +26 -0
- data/lib/games/mastermind/players_factory.rb +15 -0
- data/lib/games/mastermind.rb +13 -0
- data/lib/games/shared/array_iterator.rb +28 -0
- data/lib/games/shared/game.rb +155 -0
- data/lib/games/shared/input_helper.rb +74 -0
- data/lib/games/shared/io_terminal.rb +25 -0
- data/lib/games/shared/player.rb +15 -0
- data/lib/games/shared/version.rb +3 -0
- data/lib/games/tictactoe/board.rb +40 -0
- data/lib/games/tictactoe/board_builder.rb +10 -0
- data/lib/games/tictactoe/board_presenter_terminal.rb +28 -0
- data/lib/games/tictactoe/game.rb +60 -0
- data/lib/games/tictactoe/game_config.rb +73 -0
- data/lib/games/tictactoe/game_resetter.rb +16 -0
- data/lib/games/tictactoe/game_state_changer.rb +17 -0
- data/lib/games/tictactoe/input_helper.rb +80 -0
- data/lib/games/tictactoe/minimax.rb +81 -0
- data/lib/games/tictactoe/move_generator.rb +68 -0
- data/lib/games/tictactoe/player.rb +11 -0
- data/lib/games/tictactoe/players_factory.rb +11 -0
- data/lib/games/tictactoe/square.rb +30 -0
- data/lib/games/tictactoe/squares.rb +129 -0
- data/lib/games/tictactoe/squares_factory.rb +56 -0
- data/lib/games/tictactoe.rb +13 -0
- data/lib/games/version.rb +3 -0
- data/lib/games.rb +5 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ff3dcb410111396a3ce03ef859fb52d70a5b5d5d
|
4
|
+
data.tar.gz: 269d8193da9129cf52efd370764abc318d376de6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cabca83cb240420badc2e59c271f6ef5de2c9ac9b2825fedbf65ef2f20d14b14f3ac9a9593e709381bdb55a2f38c86217b65134aa3d7eb36856e566b046f0f73
|
7
|
+
data.tar.gz: 648ab711ef30fc5ba0f7b9bc3fdb082bfbc761e4e03c9cf67f90c9ef5504533042bf3774d121d93592402cbd348ff6984fdea9851d996d2dbc84346a23ca1d74
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Games
|
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.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'games'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install games
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
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.
|
30
|
+
|
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).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/games.
|
36
|
+
|
data/Rakefile
ADDED
data/exe/mastermind
ADDED
data/exe/setup
ADDED
data/exe/tictactoe
ADDED
data/games.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
games = File.expand_path('../lib/games', __FILE__)
|
4
|
+
mastermind = File.expand_path('../lib/games/mastermind', __FILE__)
|
5
|
+
shared = File.expand_path('../lib/games/shared', __FILE__)
|
6
|
+
tictactoe = File.expand_path('../lib/games/tictactoe', __FILE__)
|
7
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
8
|
+
$LOAD_PATH.unshift(games) unless $LOAD_PATH.include?(games)
|
9
|
+
$LOAD_PATH.unshift(mastermind) unless $LOAD_PATH.include?(mastermind)
|
10
|
+
$LOAD_PATH.unshift(shared) unless $LOAD_PATH.include?(shared)
|
11
|
+
$LOAD_PATH.unshift(tictactoe) unless $LOAD_PATH.include?(tictactoe)
|
12
|
+
require 'games/version'
|
13
|
+
|
14
|
+
Gem::Specification.new do |spec|
|
15
|
+
spec.name = "games_bfox"
|
16
|
+
spec.version = Games::VERSION
|
17
|
+
spec.authors = ["Brett Fox"]
|
18
|
+
spec.email = ["brettfox11@gmail.com"]
|
19
|
+
|
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.}
|
22
|
+
spec.homepage = "https://github.com/brett11/games"
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
f.match(%r{^(test|spec|features)/})
|
26
|
+
end
|
27
|
+
spec.bindir = "exe"
|
28
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
|
31
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
32
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
33
|
+
spec.add_development_dependency "rspec", "~> 3.6"
|
34
|
+
spec.add_development_dependency 'pry', '~> 0.10.4'
|
35
|
+
spec.add_development_dependency 'logging', '~> 2.2', '>= 2.2.2'
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module MM
|
2
|
+
class Board
|
3
|
+
attr_accessor :number_of_rows, :number_of_cols, :pegs, :result_pegs
|
4
|
+
|
5
|
+
def initialize(args = {})
|
6
|
+
@number_of_rows = args[:number_of_rows]
|
7
|
+
@number_of_cols = args[:number_of_cols]
|
8
|
+
@pegs = args[:pegs]
|
9
|
+
@result_pegs = args[:result_pegs]
|
10
|
+
end
|
11
|
+
|
12
|
+
def change_peg(row, col, new_value)
|
13
|
+
peg_to_change = retrieve_peg(row, col)
|
14
|
+
peg_to_change.change_value(new_value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def display_values
|
18
|
+
pegs.display_values
|
19
|
+
end
|
20
|
+
|
21
|
+
def result_values
|
22
|
+
result_pegs.display_values
|
23
|
+
end
|
24
|
+
|
25
|
+
def pegs_current_row(number_of_turns_taken)
|
26
|
+
pegs.current_row(number_of_turns_taken)
|
27
|
+
end
|
28
|
+
|
29
|
+
def result_pegs_current_row(number_of_turns_taken)
|
30
|
+
result_pegs.current_row(number_of_turns_taken)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def retrieve_peg(row, col)
|
35
|
+
return pegs.retrieve_peg(row, col)
|
36
|
+
end
|
37
|
+
|
38
|
+
#result_pegs is an instance of pegs
|
39
|
+
def retrieve_result_peg(row, col)
|
40
|
+
return result_pegs.retrieve_peg(row,col)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative 'pegs_factory'
|
2
|
+
|
3
|
+
module MM
|
4
|
+
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) )
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module MM
|
2
|
+
class BoardPresenterTerminal
|
3
|
+
attr_accessor :board
|
4
|
+
|
5
|
+
def present_board(board)
|
6
|
+
@board = board
|
7
|
+
present_board_and_results(self.board)
|
8
|
+
end
|
9
|
+
|
10
|
+
def present_board_only(board)
|
11
|
+
#board.display_values will return multidimensional array
|
12
|
+
display_values.each_with_index do |row, row_number|
|
13
|
+
row.each_with_index do |display_value, index|
|
14
|
+
#http://www.evc-cit.info/cit020/beginning-programming/chp_04/file_printf.html
|
15
|
+
if display_value == nil
|
16
|
+
print " "
|
17
|
+
else
|
18
|
+
printf "%2s", display_value
|
19
|
+
end
|
20
|
+
|
21
|
+
print " | " unless index == (row.size - 1)
|
22
|
+
end
|
23
|
+
print "\n"
|
24
|
+
puts "_"*(row.size * 5) unless row_number.equal? (number_of_rows - 1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def present_board_and_results(board)
|
29
|
+
@board = board
|
30
|
+
|
31
|
+
print " Guess" + " " +"Result"
|
32
|
+
print "\n"
|
33
|
+
puts "-" * 40
|
34
|
+
guesses_and_results = display_values.zip(result_values)
|
35
|
+
#board.display_values will return multidimensional array
|
36
|
+
guesses_and_results.each do |values|
|
37
|
+
#values is either display_values or result_values
|
38
|
+
values.each_with_index do |row, row_number|
|
39
|
+
row.each_with_index do |display_value, index|
|
40
|
+
#http://www.evc-cit.info/cit020/beginning-programming/chp_04/file_printf.html
|
41
|
+
if display_value == nil
|
42
|
+
print " "
|
43
|
+
else
|
44
|
+
printf "%2s", display_value
|
45
|
+
end
|
46
|
+
|
47
|
+
print " | " unless index == (row.size - 1)
|
48
|
+
end
|
49
|
+
print " " unless row.equal? values.last
|
50
|
+
end
|
51
|
+
print "\n"
|
52
|
+
puts "_"*(values.size * 20) unless values.equal? guesses_and_results.last
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def display_values
|
57
|
+
board.display_values
|
58
|
+
end
|
59
|
+
|
60
|
+
def result_values
|
61
|
+
board.result_values
|
62
|
+
end
|
63
|
+
|
64
|
+
def number_of_rows
|
65
|
+
board.number_of_rows
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative '../shared/game'
|
2
|
+
|
3
|
+
module MM
|
4
|
+
class Game < Shared::Game
|
5
|
+
attr_accessor :code_setter, :secret_code, :guess_evaluator, :current_guess, :current_result, :won_flag
|
6
|
+
|
7
|
+
def local_setup
|
8
|
+
self.code_setter = config.code_setter
|
9
|
+
self.secret_code = config.secret_code
|
10
|
+
print secret_code
|
11
|
+
print "\n"
|
12
|
+
self.guess_evaluator = MM::GuessEvaluator.new
|
13
|
+
self.current_guess = []
|
14
|
+
self.current_result = []
|
15
|
+
self.won_flag = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def over?
|
19
|
+
won? || over_with_no_winner?
|
20
|
+
end
|
21
|
+
|
22
|
+
def over_with_no_winner?
|
23
|
+
number_of_turns_taken >= 12
|
24
|
+
end
|
25
|
+
|
26
|
+
def won?
|
27
|
+
#depends on evaluate_guess returning an array of all "X"s for perfect guess
|
28
|
+
if won_flag
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
|
32
|
+
if current_result == ("X" * number_of_cols).chars
|
33
|
+
self.won_flag = true
|
34
|
+
true
|
35
|
+
else
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def change_peg(row, col, new_value)
|
41
|
+
board.change_peg(row, col, new_value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def evaluate_guess(secret_code, guess)
|
45
|
+
guess_evaluator.evaluate_guess(secret_code, guess)
|
46
|
+
end
|
47
|
+
|
48
|
+
def pegs_current_row
|
49
|
+
board.pegs_current_row(number_of_turns_taken)
|
50
|
+
end
|
51
|
+
|
52
|
+
def result_pegs_current_row
|
53
|
+
board.result_pegs_current_row(number_of_turns_taken)
|
54
|
+
end
|
55
|
+
|
56
|
+
def number_of_cols
|
57
|
+
board.number_of_cols
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_secret_code
|
61
|
+
config.set_secret_code
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module MM
|
2
|
+
class GameConfig
|
3
|
+
attr_accessor :input_helper
|
4
|
+
|
5
|
+
attr_accessor :player_1_name
|
6
|
+
attr_accessor :code_setter
|
7
|
+
attr_accessor :secret_code
|
8
|
+
attr_accessor :number_of_rows
|
9
|
+
attr_accessor :number_of_cols
|
10
|
+
|
11
|
+
def initialize(input_helper)
|
12
|
+
@input_helper = input_helper
|
13
|
+
@number_of_rows = 12
|
14
|
+
@number_of_cols = 4
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def one_time_setup
|
19
|
+
self.player_1_name = input_helper.get_player_1_name
|
20
|
+
#defaults set above. uncomment to ask the player to choose
|
21
|
+
# self.number_of_rows = input_helper.get_number_of_rows
|
22
|
+
# self.number_of_cols = input_helper.get_number_of_cols
|
23
|
+
end
|
24
|
+
|
25
|
+
def every_time_setup
|
26
|
+
self.code_setter = input_helper.computer_or_human_code_setter_inquiry(player_1_name)
|
27
|
+
self.secret_code = get_secret_code
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_secret_code
|
31
|
+
code = nil
|
32
|
+
if code_setter == :human
|
33
|
+
code = input_helper.get_secret_code_from_user(player_1_name)
|
34
|
+
elsif code_setter == :computer
|
35
|
+
code = set_secret_code
|
36
|
+
end
|
37
|
+
code
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_secret_code
|
41
|
+
secret_code = []
|
42
|
+
4.times do
|
43
|
+
secret_code.push((1..6).to_a.sample)
|
44
|
+
end
|
45
|
+
secret_code
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MM
|
2
|
+
class GameResetter
|
3
|
+
attr_accessor :game
|
4
|
+
|
5
|
+
def reset_game(game)
|
6
|
+
@game = game
|
7
|
+
reset_board
|
8
|
+
game.number_of_turns_taken = 0
|
9
|
+
game.won_flag = false
|
10
|
+
game.secret_code = game.set_secret_code
|
11
|
+
game.current_guess = []
|
12
|
+
game.current_result = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset_board
|
16
|
+
game.board = game.generate_empty_board(game.config)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module MM
|
2
|
+
class GameStateChanger
|
3
|
+
attr_accessor :game
|
4
|
+
|
5
|
+
def change_game_state(guess, game)
|
6
|
+
@game = game
|
7
|
+
game.current_guess = guess
|
8
|
+
game.current_result = game.evaluate_guess(secret_code, current_guess)
|
9
|
+
change_pegs(guess, game.current_result)
|
10
|
+
if !game.won?
|
11
|
+
game.move_forward_one_turn
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def change_pegs(guess, current_result)
|
16
|
+
current_row.each_with_index do |peg, index|
|
17
|
+
peg.change_value(guess[index])
|
18
|
+
end
|
19
|
+
|
20
|
+
result_pegs_current_row.each_with_index do |peg, index|
|
21
|
+
peg.change_value(current_result[index])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def current_row
|
26
|
+
game.pegs_current_row
|
27
|
+
end
|
28
|
+
|
29
|
+
def result_pegs_current_row
|
30
|
+
game.result_pegs_current_row
|
31
|
+
end
|
32
|
+
|
33
|
+
def secret_code
|
34
|
+
game.secret_code
|
35
|
+
end
|
36
|
+
|
37
|
+
def current_guess
|
38
|
+
game.current_guess
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require_relative '../shared/array_iterator'
|
2
|
+
require 'set.rb'
|
3
|
+
|
4
|
+
module MM
|
5
|
+
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 []
|
17
|
+
end
|
18
|
+
@result = find_result
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_result
|
22
|
+
resX = find_exact_matches
|
23
|
+
resO = find_partial_matches
|
24
|
+
resX.concat resO
|
25
|
+
end
|
26
|
+
|
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
|
35
|
+
end
|
36
|
+
delete_elements_already_matched(set_of_matched_indexes)
|
37
|
+
resX
|
38
|
+
end
|
39
|
+
|
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 }
|
43
|
+
end
|
44
|
+
|
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
|
81
|
+
end
|
82
|
+
resO
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative '../shared/input_helper'
|
2
|
+
|
3
|
+
module MM
|
4
|
+
class InputHelper < Shared::InputHelper
|
5
|
+
def computer_or_human_code_setter_inquiry(name)
|
6
|
+
user_choice = get_user_input("#{name}, please enter \"1\" if you would like to be the code-guesser. Enter \"2\" 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|
|
7
|
+
input == 1 || input == 2
|
8
|
+
end
|
9
|
+
if user_choice == 1
|
10
|
+
return :computer
|
11
|
+
elsif user_choice == 2
|
12
|
+
return :human
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_secret_code_from_user(name)
|
17
|
+
user_choice = get_user_input("#{name}, 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|
|
18
|
+
input.to_s =~ /^[1-6]{4}$/
|
19
|
+
end
|
20
|
+
user_choice.to_s.chars.map(&:to_i)
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_player_choice(game)
|
24
|
+
user_choice = get_user_input("#{game.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|
|
25
|
+
input.to_s =~ /^[1-6]{4}$/
|
26
|
+
end
|
27
|
+
user_choice.to_s.chars.map(&:to_i)
|
28
|
+
end
|
29
|
+
|
30
|
+
def draw_prompt
|
31
|
+
io.present_with_new_line("No such luck! Please try again.")
|
32
|
+
end
|
33
|
+
|
34
|
+
def winning_prompt(current_player_name)
|
35
|
+
io.present_with_new_line("#{current_player_name} wins!")
|
36
|
+
end
|
37
|
+
|
38
|
+
def no_winner_prompt
|
39
|
+
io.present_with_new_line("Game over!")
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_number_of_rows
|
43
|
+
get_user_input("Please choose how many rows of pegs you would like, from 4 to 12.", "Please choose a number between 4 and 12.") do |input|
|
44
|
+
input.to_i >=4 && input.to_i <=12
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_number_of_cols
|
49
|
+
get_user_input("Please choose how many pegs you would like in each row, from 4 to 6.", "Please choose a number between 4 and 6.") do |input|
|
50
|
+
input.to_i >=4 && input.to_i <=6
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module MM
|
2
|
+
class MoveGenerator
|
3
|
+
|
4
|
+
attr_accessor :game
|
5
|
+
|
6
|
+
def get_player_choice(game)
|
7
|
+
@game = game
|
8
|
+
get_move
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_move
|
12
|
+
if human?
|
13
|
+
input_helper.get_player_choice(game)
|
14
|
+
elsif computer?
|
15
|
+
input_helper.computer_choosing_graphic
|
16
|
+
computer_move
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def computer_move
|
21
|
+
secret_code = []
|
22
|
+
4.times do
|
23
|
+
secret_code.push((1..6).to_a.sample)
|
24
|
+
end
|
25
|
+
secret_code
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def current_player
|
30
|
+
game.current_player
|
31
|
+
end
|
32
|
+
|
33
|
+
def input_helper
|
34
|
+
game.input_helper
|
35
|
+
end
|
36
|
+
|
37
|
+
def human?
|
38
|
+
game.current_player_human?
|
39
|
+
end
|
40
|
+
|
41
|
+
def computer?
|
42
|
+
game.current_player_computer?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MM
|
2
|
+
class Peg
|
3
|
+
attr_accessor :display_value, :row, :col
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@display_value = args.fetch(:display_value, nil)
|
7
|
+
@row = args[:row]
|
8
|
+
@col = args[:col]
|
9
|
+
end
|
10
|
+
|
11
|
+
def change_value(new_value)
|
12
|
+
self.display_value = new_value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|