mastermind-orion 0.0.1
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/bin/mastermind-orion +7 -0
- data/lib/display.rb +90 -0
- data/lib/game.rb +93 -0
- data/lib/game_interface.rb +83 -0
- data/lib/guess.rb +24 -0
- data/lib/guess_stats.rb +22 -0
- data/lib/sequence.rb +15 -0
- data/lib/trash_talking.rb +27 -0
- data/mastermind-orion.gemspec +23 -0
- data/mastermind.rb +5 -0
- metadata +68 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 13cae8fa270e213595e02d183851ded101cf90ad
|
|
4
|
+
data.tar.gz: 82f5a407bc19aa1014c263a29750e753921d82e4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: fb6e1b5cf3f29199383c3f3d23e7a1e10f4d73f0fd49c5df46dd38eff0e8d00b14930310d4a5565097c444a26f4f3cc3d7a7a78439f78cfb5a81811abce3ff54
|
|
7
|
+
data.tar.gz: 4a3d74d7c45a4e45e16dfb48fad043c5bbe2ebfeabf7ed1323327e3a09b1961e161f4212a70f95b98d36e33be2bda799edb8f4c8043a079b618642e782c31c7c
|
data/lib/display.rb
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'colorize'
|
|
2
|
+
|
|
3
|
+
class Display
|
|
4
|
+
COLORS = {
|
|
5
|
+
"r" => "(#{"r".colorize(:red)})ed",
|
|
6
|
+
"g" => "(#{"g".colorize(:green)})reen",
|
|
7
|
+
"b" => "(#{"b".colorize(:blue)})lue",
|
|
8
|
+
"y" => "(#{"y".colorize(:yellow)})ellow",
|
|
9
|
+
"w" => "(#{"w".colorize(:white)})hite",
|
|
10
|
+
"c" => "(#{"c".colorize(:cyan)})yan",
|
|
11
|
+
"m" => "(#{"m".colorize(:magenta)})agenta"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
GUESS_COLORS = {
|
|
15
|
+
"r" => "#{"R".colorize(:red)}",
|
|
16
|
+
"g" => "#{"G".colorize(:green)}",
|
|
17
|
+
"b" => "#{"B".colorize(:blue)}",
|
|
18
|
+
"y" => "#{"Y".colorize(:yellow)}",
|
|
19
|
+
"w" => "#{"W".colorize(:white)}",
|
|
20
|
+
"c" => "#{"C".colorize(:cyan)}",
|
|
21
|
+
"m" => "#{"M".colorize(:magenta)}"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
attr_reader :welcome,
|
|
25
|
+
:initial_message,
|
|
26
|
+
:invalid_input,
|
|
27
|
+
:instructions,
|
|
28
|
+
:guess_too_short,
|
|
29
|
+
:guess_too_long,
|
|
30
|
+
:play_message,
|
|
31
|
+
:invalid_guess,
|
|
32
|
+
:guess_question,
|
|
33
|
+
:win_question,
|
|
34
|
+
:level
|
|
35
|
+
|
|
36
|
+
def initialize
|
|
37
|
+
@welcome = "\nWelcome to...\n" +
|
|
38
|
+
"
|
|
39
|
+
|
|
40
|
+
_/ _/ _/_/ _/_/_/ _/_/_/_/_/ _/_/_/_/ _/_/_/ _/ _/ _/_/_/ _/ _/ _/_/_/
|
|
41
|
+
_/_/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/_/ _/_/ _/ _/_/ _/ _/ _/
|
|
42
|
+
_/ _/ _/ _/_/_/_/ _/_/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/
|
|
43
|
+
_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/ _/ _/
|
|
44
|
+
_/ _/ _/ _/ _/_/_/ _/ _/_/_/_/ _/ _/ _/ _/ _/_/_/ _/ _/ _/_/_/
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
".colorize(:blue)
|
|
48
|
+
|
|
49
|
+
@initial_message = "Would you like to (p)lay, read the (i)nstructions, or (q)uit?"
|
|
50
|
+
@invalid_input = "Invalid input! Please type (p) for play, (i) for instructions, or (q) for quit."
|
|
51
|
+
@instructions =
|
|
52
|
+
|
|
53
|
+
"\nThe computer will select a set of four, five, or seven colors at random,
|
|
54
|
+
depending upon the difficulty level selected. Duplicates may be possible.
|
|
55
|
+
Your task will be to guess the colors and order in which they are placed.
|
|
56
|
+
You will be prompted to enter your guess using the first letter of the color,
|
|
57
|
+
for example [rbgy]. After each guess the correct number of colors guessed,
|
|
58
|
+
regardless of position, will be displayed. The number of correctly placed
|
|
59
|
+
colors will also be displayed. Using that information and multiple guesses
|
|
60
|
+
you will be able to discover the answer and win!\n"
|
|
61
|
+
|
|
62
|
+
@guess_too_short = "Your guess was too short."
|
|
63
|
+
@guess_too_long = "Your guess was too long."
|
|
64
|
+
@guess_question = "\nWhat's your guess?\n"
|
|
65
|
+
@invalid_guess = "Invalid guess."
|
|
66
|
+
@win_question = "\nDo you want to (p)lay again or (q)uit?"
|
|
67
|
+
@level = "\nWould you like to play (e)asy, (i)ntermediate, or (h)ard?"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def determine_play_message(colors)
|
|
71
|
+
possible_colors_message = ""
|
|
72
|
+
colors.chars.each do |color|
|
|
73
|
+
possible_colors_message += COLORS[color] + "\n"
|
|
74
|
+
end
|
|
75
|
+
difficulty_level = {
|
|
76
|
+
'rgby' => 'beginner',
|
|
77
|
+
'rgbyw' => 'intermediate',
|
|
78
|
+
'rgbywcm' => 'expert'
|
|
79
|
+
}
|
|
80
|
+
@play_message = "\nI have generated a#{'n' if difficulty_level[colors] == 'intermediate' || difficulty_level[colors] == 'expert'} #{difficulty_level[colors]} sequence with #{colors.length} elements made up of:\n\n#{possible_colors_message}\nUse (q)uit at any time to end the game.\n"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def guess_stats(player_guess, number_of_correct_colors, number_of_correct_positions, guess_count)
|
|
84
|
+
"'#{player_guess.chars.map { |color| GUESS_COLORS[color]}.join}' has #{number_of_correct_colors} of the correct elements with #{number_of_correct_positions} in the correct positions.\nYou have taken #{ guess_count } guess#{ "es" if guess_count > 1 }"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def win_message(player_guess, guess_count, minutes, seconds)
|
|
88
|
+
@win_message = "Congratulations! You guessed the sequence '#{player_guess}' in #{guess_count} guesses over #{minutes} #{minutes == 1 ? 'minute' : 'minutes'},\n#{seconds} seconds."
|
|
89
|
+
end
|
|
90
|
+
end
|
data/lib/game.rb
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require_relative 'sequence'
|
|
2
|
+
require_relative 'guess'
|
|
3
|
+
require_relative 'display'
|
|
4
|
+
require_relative 'guess_stats'
|
|
5
|
+
require_relative 'trash_talking'
|
|
6
|
+
|
|
7
|
+
class Game
|
|
8
|
+
include GuessStats
|
|
9
|
+
include TrashTalking
|
|
10
|
+
|
|
11
|
+
attr_reader :in_stream,
|
|
12
|
+
:out_stream,
|
|
13
|
+
:sequence,
|
|
14
|
+
:display,
|
|
15
|
+
:beginning_time,
|
|
16
|
+
:ending_time,
|
|
17
|
+
:guess_count,
|
|
18
|
+
:guess,
|
|
19
|
+
:colors
|
|
20
|
+
|
|
21
|
+
def initialize(in_stream, out_stream, display, colors='rgby')
|
|
22
|
+
@in_stream = in_stream
|
|
23
|
+
@out_stream = out_stream
|
|
24
|
+
@display = display
|
|
25
|
+
@colors = colors
|
|
26
|
+
@sequence = Sequence.new(colors)
|
|
27
|
+
@guess = Guess.new('', colors)
|
|
28
|
+
@guess_count = 0
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def play
|
|
32
|
+
@beginning_time = Time.now
|
|
33
|
+
out_stream.puts display.determine_play_message(colors)
|
|
34
|
+
out_stream.puts display.guess_question
|
|
35
|
+
until win? || exit?
|
|
36
|
+
@guess = Guess.new(in_stream.gets.strip, colors)
|
|
37
|
+
exit! if exit?
|
|
38
|
+
@guess_count += 1
|
|
39
|
+
process_game_turn
|
|
40
|
+
end
|
|
41
|
+
if win?
|
|
42
|
+
@ending_time = Time.now
|
|
43
|
+
compute_game_stats
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def process_game_turn
|
|
48
|
+
case
|
|
49
|
+
when guess.invalid?
|
|
50
|
+
out_stream.puts display.invalid_guess
|
|
51
|
+
when guess.too_short?
|
|
52
|
+
out_stream.puts display.guess_too_short
|
|
53
|
+
trash_talk_too_short
|
|
54
|
+
when guess.too_long?
|
|
55
|
+
out_stream.puts display.guess_too_long
|
|
56
|
+
when win?
|
|
57
|
+
trash_talk_congratulations
|
|
58
|
+
when exit?
|
|
59
|
+
exit!
|
|
60
|
+
else
|
|
61
|
+
compute_guess_stats
|
|
62
|
+
trash_talk_quip if guess_count % 3 == 0
|
|
63
|
+
end
|
|
64
|
+
out_stream.puts display.guess_question if (!win? || !exit?)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def win?
|
|
68
|
+
guess.player_guess == sequence.solution
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def exit?
|
|
72
|
+
trash_talk_quit if guess.player_guess == 'q' || guess.player_guess == 'quit'
|
|
73
|
+
guess.player_guess == 'q' || guess.player_guess == 'quit'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def compute_guess_stats
|
|
77
|
+
number_of_correct_colors = compute_correct_colors(sequence.solution, guess.player_guess)
|
|
78
|
+
number_of_correct_positions = compute_correct_positions(sequence.solution, guess.player_guess)
|
|
79
|
+
out_stream.puts display.guess_stats(guess.player_guess, number_of_correct_colors, number_of_correct_positions, guess_count)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def compute_game_stats
|
|
83
|
+
beginning_seconds = convert_to_seconds(beginning_time)
|
|
84
|
+
ending_seconds = convert_to_seconds(ending_time)
|
|
85
|
+
minutes = (ending_seconds - beginning_seconds) / 60
|
|
86
|
+
seconds = (ending_seconds - beginning_seconds) % 60
|
|
87
|
+
out_stream.puts display.win_message(guess.player_guess, guess_count, minutes, seconds)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def convert_to_seconds(time)
|
|
91
|
+
time.hour * 60 * 60 + time.min * 60 + time.sec
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require_relative 'display'
|
|
2
|
+
require_relative 'game'
|
|
3
|
+
|
|
4
|
+
class GameInterface
|
|
5
|
+
attr_reader :command,
|
|
6
|
+
:display,
|
|
7
|
+
:in_stream,
|
|
8
|
+
:out_stream
|
|
9
|
+
|
|
10
|
+
def initialize(in_stream, out_stream)
|
|
11
|
+
@command = ''
|
|
12
|
+
@display = Display.new
|
|
13
|
+
@in_stream = in_stream
|
|
14
|
+
@out_stream = out_stream
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def start
|
|
18
|
+
out_stream.puts display.welcome
|
|
19
|
+
out_stream.puts display.initial_message
|
|
20
|
+
until finished?
|
|
21
|
+
@command = in_stream.gets.strip
|
|
22
|
+
process_initial_command
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def process_initial_command
|
|
27
|
+
case
|
|
28
|
+
when play?
|
|
29
|
+
play_game
|
|
30
|
+
when instructions?
|
|
31
|
+
display_instructions
|
|
32
|
+
when finished?
|
|
33
|
+
else
|
|
34
|
+
display_invalid_input_message
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def play_game
|
|
39
|
+
out_stream.puts display.level
|
|
40
|
+
@command = in_stream.gets.strip
|
|
41
|
+
Game.new(in_stream, out_stream, display, selected_level).play
|
|
42
|
+
out_stream.puts display.win_question
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def display_instructions
|
|
46
|
+
out_stream.puts display.instructions
|
|
47
|
+
out_stream.puts display.win_question
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def display_invalid_input_message
|
|
51
|
+
out_stream.puts display.invalid_input
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def play?
|
|
55
|
+
command == 'p'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def instructions?
|
|
59
|
+
command == 'i'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def finished?
|
|
63
|
+
command == 'q' || command == 'quit'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def selected_level
|
|
69
|
+
levels[@command] || default_level
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def levels
|
|
73
|
+
@levels ||= {
|
|
74
|
+
'e' => 'rgby',
|
|
75
|
+
'i' => 'rgbyw',
|
|
76
|
+
'h' => 'rgbywcm'
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def default_level
|
|
81
|
+
'rgby'
|
|
82
|
+
end
|
|
83
|
+
end
|
data/lib/guess.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Guess
|
|
2
|
+
attr_reader :player_guess,
|
|
3
|
+
:possible_colors,
|
|
4
|
+
:solution_length
|
|
5
|
+
|
|
6
|
+
def initialize(player_guess, colors='rgby')
|
|
7
|
+
@player_guess = player_guess
|
|
8
|
+
@possible_colors = colors
|
|
9
|
+
@solution_length = colors.length
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def invalid?
|
|
13
|
+
valid_colors = /[^#{possible_colors}]+/
|
|
14
|
+
player_guess.match(valid_colors)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def too_short?
|
|
18
|
+
player_guess.length < solution_length
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def too_long?
|
|
22
|
+
player_guess.length > solution_length
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/guess_stats.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module GuessStats
|
|
2
|
+
def compute_correct_colors(solution, player_guess)
|
|
3
|
+
solution = solution.chars
|
|
4
|
+
player_guess = player_guess.chars
|
|
5
|
+
correct_color_count = 0
|
|
6
|
+
solution.each do |color|
|
|
7
|
+
if player_guess.include?(color)
|
|
8
|
+
player_guess.delete_at(player_guess.index(color))
|
|
9
|
+
correct_color_count += 1
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
correct_color_count
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def compute_correct_positions(solution, player_guess)
|
|
16
|
+
solution = solution.chars
|
|
17
|
+
player_guess = player_guess.chars
|
|
18
|
+
solution.zip(player_guess).select do |item|
|
|
19
|
+
item[0] == item[1]
|
|
20
|
+
end.length
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/sequence.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module TrashTalking
|
|
2
|
+
def trash_talk_too_short
|
|
3
|
+
system("say 'Your guess was too small, like your brain.'")
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def trash_talk_congratulations
|
|
7
|
+
system("say 'Congratulations. We are all a little bit dumber for having watched you play.'")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def trash_talk_quit
|
|
11
|
+
system("say 'Your parents were right, you are a quitter.'")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def trash_talk_quip
|
|
15
|
+
system("say #{generate_quip}")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def generate_quip
|
|
19
|
+
possible_quips = [
|
|
20
|
+
'You are a good example of why some animals eat their young.',
|
|
21
|
+
'Are you even trying?',
|
|
22
|
+
'Why dont you slip into something more comfortable? Like a coma.',
|
|
23
|
+
'I could say nice things about you, but I would rather tell the truth.'
|
|
24
|
+
]
|
|
25
|
+
possible_quips.sample
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = 'mastermind-orion'
|
|
3
|
+
s.version = '0.0.1'
|
|
4
|
+
s.date = '2014-11-13'
|
|
5
|
+
s.summary = "Try to guess the secret code."
|
|
6
|
+
s.description = "The Mastermind Game"
|
|
7
|
+
s.authors = ["Orion Osborn"]
|
|
8
|
+
s.email = 'orion.osborn@gmail.com'
|
|
9
|
+
s.files = %w[mastermind-orion.gemspec
|
|
10
|
+
mastermind.rb
|
|
11
|
+
lib/display.rb
|
|
12
|
+
lib/game_interface.rb
|
|
13
|
+
lib/game.rb
|
|
14
|
+
lib/guess_stats.rb
|
|
15
|
+
lib/guess.rb
|
|
16
|
+
lib/sequence.rb
|
|
17
|
+
lib/trash_talking.rb ]
|
|
18
|
+
s.homepage = 'http://rubygems.org/gems/mastermind-orion'
|
|
19
|
+
s.license = 'OLO'
|
|
20
|
+
s.executables << 'mastermind-orion'
|
|
21
|
+
|
|
22
|
+
s.add_runtime_dependency 'colorize', '>= 0.7.3'
|
|
23
|
+
end
|
data/mastermind.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mastermind-orion
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Orion Osborn
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-11-13 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: colorize
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.7.3
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.7.3
|
|
27
|
+
description: The Mastermind Game
|
|
28
|
+
email: orion.osborn@gmail.com
|
|
29
|
+
executables:
|
|
30
|
+
- mastermind-orion
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- bin/mastermind-orion
|
|
35
|
+
- lib/display.rb
|
|
36
|
+
- lib/game.rb
|
|
37
|
+
- lib/game_interface.rb
|
|
38
|
+
- lib/guess.rb
|
|
39
|
+
- lib/guess_stats.rb
|
|
40
|
+
- lib/sequence.rb
|
|
41
|
+
- lib/trash_talking.rb
|
|
42
|
+
- mastermind-orion.gemspec
|
|
43
|
+
- mastermind.rb
|
|
44
|
+
homepage: http://rubygems.org/gems/mastermind-orion
|
|
45
|
+
licenses:
|
|
46
|
+
- OLO
|
|
47
|
+
metadata: {}
|
|
48
|
+
post_install_message:
|
|
49
|
+
rdoc_options: []
|
|
50
|
+
require_paths:
|
|
51
|
+
- lib
|
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0'
|
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
requirements: []
|
|
63
|
+
rubyforge_project:
|
|
64
|
+
rubygems_version: 2.4.2
|
|
65
|
+
signing_key:
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: Try to guess the secret code.
|
|
68
|
+
test_files: []
|