mastermind-oscar 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f3032d53bfa63eb3052ad5ee7968cfc56e579729
4
+ data.tar.gz: 25805dcf3f4cc27e7d1e275bbe2a667f71090e41
5
+ SHA512:
6
+ metadata.gz: 12eb3f4b3d3a8d8974819d00ce8d45c7400a2df4a8d9f35cae54b13f0295121ba5c280a76fc2d995eed77cbb5b5c3b5f4129cc47e1623b989208ce458b112cc7
7
+ data.tar.gz: d13e7176e148ff319baf4b9137bc3ad6c0eca6cc0cbb842954426114d38aa2163808802ff3acc912a349b3fcd9471c0a1cdef46ecfe10dce5bcc03b68dc89b72
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /files/expert_record.txt
11
+ /files/beginner_record.txt
12
+ /files/intermediate_record.txt
13
+ /files/top_ten_beginner.yaml
14
+ /files/top_ten_expert.yaml
15
+ /files/top_ten_intermediate.yaml
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mastermind-oscar.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Oscar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Mastermind::Oscar
2
+
3
+ Mastermind_Oscar is a Ruby implementation of the classic board game of same name. The game is a code breaking game between two players; in this implementation, it is between a player and the computer.
4
+
5
+ The computer selects a random sequence of color characters whose length depends on the game level (beginner, intermediate and expert). The player tries to guess the sequence generated by the computer using the feedback from the computer at every attempt as a guide.
6
+ The game is over either when the player correctly guess the sequence or the player runs out of guesses; player has 12 guesses.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'mastermind-oscar'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install mastermind-oscar
23
+
24
+ ## Usage
25
+
26
+ To play the game, open your terminal and run mastermind_oscar. You can also run the game with a desired level as an optional argument e.g mastermind_oscar intermediate
27
+
28
+ ## Development
29
+
30
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/mastermind_oscar` for an interactive prompt that will allow you to experiment.
31
+
32
+ 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` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it ( https://github.com/andela-ooranagwa/mastermind-oscar/fork)
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create a new Pull Request
41
+
42
+ [![Coverage Status](https://coveralls.io/repos/andela-ooranagwa/mastermind-oscar/badge.svg?branch=master&service=github)](https://coveralls.io/github/andela-ooranagwa/mastermind-oscar?branch=master)
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ end
7
+
8
+ desc "Run tests"
9
+ task :default => :test
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mastermind/oscar"
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/circle.yml ADDED
@@ -0,0 +1,3 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.1.2
@@ -0,0 +1,16 @@
1
+ require "mastermind/oscar/version"
2
+ require "mastermind/oscar/game_manager"
3
+
4
+ module Mastermind
5
+ module Oscar
6
+ extend self
7
+ def mastermind
8
+ $*.empty? ? arg = nil : arg = Mastermind::Oscar.game_level($*.first[0])
9
+ game = Mastermind::Oscar::GameManager.new(arg)
10
+ game.start_game
11
+ end
12
+ end
13
+ end
14
+
15
+
16
+ Mastermind::Oscar.mastermind
@@ -0,0 +1,208 @@
1
+ require_relative "time_manager"
2
+
3
+ module Mastermind
4
+ module Oscar
5
+ class Codemaker
6
+ attr_reader :code, :timer, :difficulty, :recorder, :guess
7
+ def initialize(difficulty, recorder)
8
+ @difficulty = difficulty
9
+ @recorder = recorder
10
+ end
11
+
12
+ def start
13
+ generate_code
14
+ @timer = TimeManager.new
15
+ @recorder.open_save_file(difficulty)
16
+ @recorder.print_to_file("Sequence: \t\t<#{code.join}>")
17
+ @timer.start_timer
18
+ init_message
19
+
20
+ return game_play
21
+ end
22
+
23
+ def game_play
24
+ max_guess = 12
25
+ @guess = 0
26
+
27
+ while !out_of_guess?(guess, max_guess)
28
+ input = get_input
29
+
30
+ if quit?(input)
31
+ return :quit
32
+ elsif cheat?(input)
33
+ cheat
34
+ return
35
+ elsif is_valid_input?(input)
36
+ @guess += 1
37
+ status = analyze_input(input)
38
+ return congratulations if status
39
+ end
40
+ Printer.output("\t\t\nYou've taken #{guess} out of #{max_guess} guesses.\n")
41
+ guess_again
42
+ end
43
+
44
+ #Some one that is out of guesses
45
+ return game_over
46
+ end
47
+
48
+ def get_input(stream = STDIN)
49
+ input = stream.gets.chomp
50
+ input = input.nil? ? " " : input.upcase.strip
51
+
52
+ input
53
+ end
54
+
55
+ def analyze_input(input)
56
+ @recorder.print_to_file("Guess #{guess}:\t\t#{input}")
57
+
58
+ input = input.split("")
59
+ return true if input == code
60
+
61
+ exact = exact_match(code, input)
62
+ partial = partial_match(code, input, exact)
63
+ exact = exact.size
64
+
65
+ give_guess_feedback(input, exact, partial)
66
+
67
+ false
68
+ end
69
+
70
+ def exact_match(game_code, input)
71
+ exact = []
72
+ input.each_index do |index|
73
+ exact << index if game_code[index] == input[index]
74
+ end
75
+ exact
76
+ end
77
+
78
+ def partial_match(game_code, input,exact)
79
+ partials = [] + game_code
80
+ exact.each{|elt| partials[elt] = nil}
81
+ partial = 0
82
+
83
+ input.each_with_index do |item, index|
84
+ pIndex = partials.index(item)
85
+
86
+ if(pIndex && !exact.include?(index))
87
+ partial += 1
88
+ partials[pIndex] = nil
89
+ end
90
+ end
91
+ partial
92
+ end
93
+
94
+ def give_guess_feedback(input, exact, partial)
95
+ feedback = "Hmmm! Your guess, " + Printer.colour_letters(input) + ", has #{exact + partial} of the correct elements with #{exact} in the correct positions."
96
+
97
+ Printer.output(feedback)
98
+ end
99
+
100
+ def out_of_guess?(guess, max_guess)
101
+ guess.eql? max_guess
102
+ end
103
+
104
+ def quit?(input)
105
+ input[0].upcase == 'Q' if !input.empty?
106
+ end
107
+
108
+ def cheat?(input)
109
+ input.upcase == 'C' && input.length == 1
110
+ end
111
+
112
+ def cheat
113
+ Printer.show_cheat(color_code)
114
+ end
115
+
116
+ def generate_code
117
+ @code = []
118
+ specs = difficulties(difficulty)
119
+ @possible_colours = specs[1]
120
+ characters = specs[0]
121
+
122
+ characters.times do
123
+ index = rand(0...@possible_colours)
124
+ @code << colors[index]
125
+ end
126
+ end
127
+
128
+ def difficulties(key)
129
+ #key => [characters, colors]
130
+ specs = {
131
+ :beginner => [4, 4],
132
+ :intermediate => [6, 5],
133
+ :expert => [8, 6]
134
+ }
135
+ specs[key]
136
+ end
137
+
138
+ def colors
139
+ Printer.colors.keys
140
+ end
141
+
142
+ def init_message
143
+ a = (difficulty == :beginner) ? 'a' : 'an'
144
+ Printer.greet_user(@recorder.user, a, difficulty, code.size, create_color_string)
145
+ end
146
+
147
+ def create_color_string
148
+ count = 0
149
+ string = []
150
+ Printer.colors.each do |key, colo|
151
+ break if count == @possible_colours
152
+ text = colo.to_s
153
+ text.gsub!(text[0],"(#{text[0]})")
154
+ string << Printer.colour_text(text, colo)
155
+ count += 1
156
+ end
157
+ string[0...-1].join(", ") + ", and " + string.last
158
+ end
159
+
160
+ def is_valid_input?(input)
161
+ length = code.size
162
+ return true if input.length == length
163
+
164
+ puts "\t" + Printer.colour_background(" !!!::: Oops! Your input is too short :::!!!", :red) if input.length < length
165
+ puts "\t" + Printer.colour_background(" !!!::: Oops! Your input is too long :::!!!", :red) if input.length > length
166
+
167
+ false
168
+ end
169
+
170
+ def congratulations
171
+ @timer.stop_timer
172
+ play_time = @timer.get_time
173
+ congratulation_msg(play_time)
174
+ save_game(play_time)
175
+
176
+ :won
177
+ end
178
+
179
+ def congratulation_msg(play_time)
180
+ Printer.congratulations(@recorder.user,color_code, guess, play_time)
181
+ end
182
+
183
+ def save_game(play_time)
184
+ @recorder.print_to_file("Guessed the sequence in: #{play_time}")
185
+ @recorder.check_for_top_ten(code.join, guess, @timer.get_seconds, difficulty.to_s)
186
+ @recorder.close
187
+ end
188
+
189
+ def game_over
190
+ @timer.stop_timer
191
+ Printer.game_over(@recorder.user, color_code)
192
+ @recorder.print_to_file("Game over! #{@timer.get_time}")
193
+ @recorder.close
194
+
195
+ :end
196
+ end
197
+
198
+ def color_code
199
+ Printer.colour_letters(code.join)
200
+ end
201
+
202
+ def guess_again
203
+ Printer.output "\t\t\tGuess again"
204
+ end
205
+
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,123 @@
1
+ require_relative "printer"
2
+ require_relative "codemaker"
3
+ require_relative "record_manager"
4
+ require_relative "time_manager"
5
+
6
+ module Mastermind
7
+ module Oscar
8
+ class GameManager
9
+ attr_reader :difficulty, :user
10
+
11
+ def initialize(diff = nil)
12
+ @difficulty = diff
13
+ set_read_stream
14
+
15
+ RecordManager.create_save_files
16
+ end
17
+
18
+ # useful for testing inputs
19
+ def set_read_stream (stream = STDIN)
20
+ @stream = stream
21
+ end
22
+
23
+ def alert_invalid_input
24
+ Printer.output "\tHmmm! You entry seems incorrect. Try again."
25
+ end
26
+
27
+ def start_game(stub_for_test=false)
28
+ Printer.welcome_msg
29
+ status = true
30
+
31
+ while status
32
+ Printer.format_input_query
33
+
34
+ input = get_first_char
35
+ if input == 'q'
36
+ break
37
+ elsif input == 't'
38
+ show_top_10
39
+ status = !stub_for_test
40
+ elsif input == 'i'
41
+ show_instructions
42
+ status = !stub_for_test
43
+ elsif input == "r"
44
+ show_records
45
+ status = !stub_for_test
46
+ elsif input == 'p'
47
+ # play game
48
+ status = game_on? play
49
+ @difficulty = nil
50
+ else
51
+ alert_invalid_input
52
+ status = !stub_for_test
53
+ end
54
+ end
55
+ @user ||= ''
56
+ Printer.quit_msg(user)
57
+ end
58
+
59
+ def play(allowed = true)
60
+ return :quit unless set_difficulty
61
+ @recorder= RecordManager.new(user)
62
+ @user = @recorder.user unless user
63
+
64
+ codemaker = Codemaker.new(difficulty, @recorder)
65
+ return codemaker.start if allowed
66
+ end
67
+
68
+ def get_first_char
69
+ return (@stream.gets + " ").chomp[0].downcase.strip
70
+ end
71
+
72
+ def set_difficulty
73
+ return true if difficulty
74
+ Printer.level_select_msg
75
+ input = get_first_char
76
+
77
+ return false if input.eql? 'q'
78
+
79
+ @difficulty = Mastermind::Oscar.game_level(input)
80
+ end
81
+
82
+ def game_on? (arg)
83
+ return false if arg == :quit
84
+
85
+ show_top_10(@difficulty) if arg == :won
86
+ return true
87
+ end
88
+
89
+ def show_records
90
+ Printer.output_file(RecordManager.get_records)
91
+ end
92
+
93
+ def show_instructions
94
+ Printer.output(RecordManager.get_instructions)
95
+ end
96
+
97
+ def show_top_10 (level = nil)
98
+ list = level.nil? ? Mastermind::Oscar.game_level.values : [level]
99
+
100
+ t_obj = TimeManager.new
101
+
102
+ list.each do |lvl|
103
+ lvl = lvl.to_s
104
+ rec = RecordManager.get_top_ten(lvl)
105
+ Printer.output_top_ten(lvl,rec,t_obj)
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+
112
+ def self.game_level(input = nil)
113
+ levels = Hash.new(:beginner)
114
+ levels['a'] = :expert
115
+ levels['i'] = :intermediate
116
+ levels['b'] = :beginner
117
+
118
+ return levels if input.nil?
119
+
120
+ levels[input]
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,180 @@
1
+ require "colorize"
2
+
3
+ module Mastermind
4
+ module Oscar
5
+ class Printer
6
+ @@stream = STDOUT
7
+ def self.initialize
8
+ set_output_stream
9
+ end
10
+
11
+ def self.output (content)
12
+ @@stream.puts content
13
+ end
14
+
15
+ def self.stream
16
+ @@stream
17
+ end
18
+
19
+ def self.colors
20
+ {
21
+ "R" => :red,
22
+ "G" => :green,
23
+ "B" => :blue,
24
+ "Y" => :yellow,
25
+ "C" => :cyan,
26
+ "M" => :magenta
27
+ }
28
+ end
29
+
30
+ def self.colour_letters(word)
31
+ word = word.split("") unless word.is_a?(Array)
32
+
33
+ word = word.map!{ |letter| colour_text(letter,colors[letter]) }
34
+ word.join
35
+ end
36
+
37
+ def self.colour_text (content, colour)
38
+ content.colorize(:color => colour)
39
+ end
40
+
41
+ def self.colour_background (content, colour)
42
+ content.colorize(:background => colour)
43
+ end
44
+
45
+ def self.colour_background_text (content, colour, b_colour)
46
+ content.colorize(:background => b_colour).colorize(:color => colour)
47
+ end
48
+
49
+ def self.set_output_stream (stream = STDOUT)
50
+ @@stream = stream
51
+ end
52
+
53
+ def self.format_input_query
54
+ output game_message
55
+ end
56
+
57
+ def self.output_file(file)
58
+ file.each do |f|
59
+ f.each_line do |line|
60
+ fColor = line.split("\t\t")
61
+ if fColor.size == 2
62
+ fColor[-1] = colour_letters(fColor.last);
63
+ line = fColor.join("\t\t")
64
+ end
65
+ print line
66
+ end
67
+ f.close
68
+ puts "\n\n"
69
+ end
70
+ end
71
+
72
+ def self.output_top_ten(level, array,time_obj)
73
+ puts "\t\t*****#{level.upcase} Leaderboard*****"
74
+ count = 1
75
+ array.each do |entry|
76
+ name = entry[:name]
77
+ code = colour_letters(entry[:code])
78
+ guess = entry[:guess]
79
+ time = time_obj.get_time(entry[:time])
80
+ output(top_score_display_text(count,name,code,guess,time))
81
+ count += 1
82
+ end
83
+ puts ""
84
+ end
85
+
86
+ def self.top_score_display_text(count,name,code,guess,time)
87
+ "#{count}. #{name} solved '#{code}' in #{guess} guesses over #{time}"
88
+ end
89
+
90
+ def self.game_message
91
+ mess = <<-EOS
92
+ \t* Enter p to play
93
+ \t* Enter i for instructions
94
+ \t* Enter t for top scores
95
+ \t* Enter r for records
96
+ \t* Enter q to quit
97
+ \n
98
+ EOS
99
+ end
100
+
101
+ def self.welcome_msg
102
+ output <<-EOS
103
+
104
+ ( ` ) (
105
+ )\))( ) ( /( ( ( ) ( )\ )
106
+ ((_)()\ ( /( ( )\()) ))\ )( ( )\ ( (()/(
107
+ (_()((_) )(_)) )\ (_))/ /((_)(()\ )\ '((_) )\ ) ((_))
108
+ | \/ |((_)_ ((_)| |_ (_)) ((_) _((_)) (_) _(_/( _| |
109
+ | |\/| |/ _` |(_-<| _|/ -_) | '_|| ' \() | || ' \))/ _` |
110
+ |_| |_|\__,_|/__/ \__|\___| |_| |_|_|_| |_||_||_| \__,_| "
111
+
112
+ \n\t\t.::::::::::::::. WELCOME .:::::::::::::::.\n\n
113
+ EOS
114
+ end
115
+
116
+ def self.level_select_msg
117
+ output <<-EOS
118
+ ******* SET GAME DIFFICULTY *******
119
+ * Enter b for beginner
120
+ * Enter i for intermediate
121
+ * Enter a for expert
122
+ [invalid entry will default to beginner]
123
+ \n
124
+ EOS
125
+ end
126
+
127
+ def self.quit_msg(user)
128
+ output <<-EOS
129
+ \n\t\t.:::::::::. Thank you for playing, #{user} .::::::::::.
130
+ \t
131
+ \t\t+-+-+-+-+-+-+-+
132
+ \t\t|C|I|A|O|!|!|!|
133
+ \t\t+-+-+-+-+-+-+-+
134
+ EOS
135
+ end
136
+
137
+ def self.greet_user(user, a, diff, csize, colors)
138
+ output <<-EOS
139
+ \n\t\t.:: Nice to meet you, #{user} ::.
140
+
141
+ Ok, I have generated a #{diff} sequence with #{csize} elements made of :
142
+ \t#{colors}
143
+ \tEnter (q)uit at any time to exit the game\n\n
144
+ \t CAN YOU GUESS THE SEQUENCE?
145
+ EOS
146
+ end
147
+
148
+ def self.show_cheat(code)
149
+ output <<-EOS
150
+ \n\t\t\tThe sequence is
151
+ \t\t\t ========
152
+ \t\t\t ||#{code}||
153
+ \t\t\t ========\n\n
154
+ EOS
155
+ line
156
+ end
157
+
158
+ def self.line
159
+ puts "-"*80 + "\n\n"
160
+ end
161
+
162
+ def self.game_over(user, color)
163
+ output <<-EOS
164
+ \t ____ ______ ______ _______ __________
165
+ \t (( __||=||| \/ ||== (( ))\ //|==||_//
166
+ \t \\_||| ||| ||___ \\_// \V/||__|| \\
167
+ \t\tYou have used up all your guesses.
168
+ EOS
169
+ show_cheat(color)
170
+ end
171
+
172
+ def self.congratulations(user,color,guess, time)
173
+ output <<-EOS
174
+ \tCongratulations!!! #{user}
175
+ You guessed the sequence #{color} in #{guess} guesses over #{time}\n
176
+ EOS
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,185 @@
1
+ require "yaml"
2
+ module Mastermind
3
+ module Oscar
4
+ class RecordManager
5
+ attr_reader :user
6
+
7
+ def initialize(name = nil, stream = STDIN)
8
+ set_read_stream(stream)
9
+ name.nil? ? set_user : @user = name
10
+ end
11
+
12
+ def self.create_save_files
13
+ Dir.mkdir(file_path) unless Dir.exist?(file_path)
14
+ level = Mastermind::Oscar.game_level.values
15
+ level.each do |lvl|
16
+ File.open("#{file_path}top_ten_#{lvl}.yaml","w+")
17
+ File.open("#{file_path}#{lvl}_record.txt", "w+")
18
+ end
19
+ end
20
+
21
+ def file_path
22
+ RecordManager.file_path
23
+ end
24
+
25
+ def self.file_path
26
+ # File.join(File.dirname(File.expand_path(__FILE__)), '../../../files/')
27
+ "files/"
28
+ end
29
+
30
+ def set_user
31
+ print <<-EOS
32
+ \tAwesome!, you want to play. Let's begin!
33
+ \tMy name is Mastermind; what's is yours?
34
+ EOS
35
+ @user = @stream.gets.chomp.capitalize
36
+ @user = "Anonymous" if @user.empty?
37
+ end
38
+
39
+ def open_save_file(difficulty)
40
+ @input_file = File.open(file_path+difficulty.to_s+"_record.txt", "a+")
41
+ initalize_file
42
+ end
43
+
44
+ def set_read_stream (stream = STDIN)
45
+ @stream = stream
46
+ end
47
+
48
+ def print_to_file (content)
49
+ @input_file.puts content
50
+ end
51
+
52
+ def initalize_file
53
+ text = "\nName:\t#{@user}\n"
54
+ text += Time.now.strftime("%l:%M%P %b %d, %Y")
55
+ print_to_file(text)
56
+ end
57
+
58
+ def close
59
+ @input_file.close if @input_file
60
+ end
61
+
62
+ def check_for_top_ten(code, guess, time, difficulty)
63
+ top_ten = self.class.get_top_ten(difficulty)
64
+ position = is_hero?(top_ten, guess, time)
65
+
66
+ position = top_ten.size if(!position && top_ten.size < 10)
67
+
68
+ if position
69
+ top_ten = insert_in_top_ten(prep_hash(code, guess, time), position, top_ten)
70
+
71
+ save_top_ten(top_ten, difficulty)
72
+ return position
73
+ end
74
+ end
75
+
76
+ def save_top_ten(array,difficulty)
77
+ file = self.class.get_heros_file(difficulty)
78
+ serial = YAML::dump(array)
79
+ File.open(file, "w+") {|f| f.puts serial}
80
+ end
81
+
82
+ def self.get_heros_file(difficulty)
83
+ "#{file_path}top_ten_#{difficulty}.yaml"
84
+ end
85
+
86
+ def insert_in_top_ten(hero, position, array)
87
+ new_arr = []
88
+ i = 0
89
+ shift = false
90
+ limit = array.size
91
+ limit = (limit >= 10) ? limit : limit + 1
92
+
93
+ limit.times do
94
+ if i == position
95
+ new_arr << hero
96
+ shift = true
97
+ else
98
+ index = shift ? i - 1 : i
99
+ new_arr << array[index]
100
+ end
101
+ i += 1
102
+ end
103
+
104
+ new_arr
105
+ end
106
+
107
+ def prep_hash(code, guess, time)
108
+ {
109
+ name: user,
110
+ code: code,
111
+ guess: guess,
112
+ time: time
113
+ }
114
+ end
115
+
116
+ def self.get_records
117
+ #levels = []
118
+ #if difficulty
119
+ # levels << difficulty
120
+ #else
121
+ levels = Mastermind::Oscar.game_level
122
+ levels = levels.values
123
+ #end
124
+
125
+ files = []
126
+ levels.each do |level|
127
+ files << File.open("files/"+level.to_s+"_record.txt", "r+")
128
+ end
129
+ files
130
+ end
131
+
132
+ def self.get_instructions
133
+ msg = <<-EOS
134
+ Playing Mastermind is pretty easy.
135
+
136
+ ##Rules
137
+
138
+ * Once the game starts, you have the option to either play, view instructions, view top ten scores or view score records
139
+ * To play the game, enter p
140
+ * To view instructions, enter i
141
+ * To view top ten scores, enter t
142
+ * To view score records, enter s
143
+ * Once you enter p to play, your are given the option to select a difficulty level; beginner, intermediate or expert. The level default to beginner for invalid choice.
144
+ * You will be required to enter you name to aid in recording your score
145
+ * Computer will generate a set of random characters made of colours. The lenght of the characters generated and the colours used depends on the game level.
146
+ * For beginners, 4 characters consisting of red, blue, green and/or yellow. e.g. rbgy
147
+ * For intermediate, 6 characters consisting of red, blue, green, yellow and/or cyan e.g. rrbyc
148
+ * For expert, 8 characters consisting of red, blue, green, yellow, cyan and magenta e.g. bgrrgm
149
+ * Note that colours can be repeated in the sequence
150
+ * You are to guess the sequence by inputing the combination.
151
+ * You will be given helpful feedback on each guess you make. Study the feedback to know the colours you were able to guess and their right position in the sequence.
152
+ * After 12 unsuccessful attempts, the game is over and you lost
153
+ * You can stop the game at any time by inputing q
154
+
155
+ Have fun
156
+ EOS
157
+ end
158
+
159
+ def self.get_top_ten (difficulty)
160
+ file = get_heros_file(difficulty)
161
+ content = []
162
+ File.open(file, "r+") do |val|
163
+ content = YAML::load(val)
164
+ end
165
+ content = [] if !content
166
+ content
167
+ end
168
+
169
+ def is_hero?(heros, guess, time)
170
+ return unless heros.is_a?(Array)
171
+ guess = guess.to_i
172
+ heros.each_with_index do |hero, index|
173
+ hero[:guess] = hero[:guess].to_i
174
+ if hero[:guess].to_i > guess
175
+ return index
176
+ elsif hero[:guess] == guess
177
+ return index if hero[:time] >time
178
+ end
179
+ end
180
+ nil
181
+ end
182
+
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,45 @@
1
+ module Mastermind
2
+ module Oscar
3
+ class TimeManager
4
+ attr_reader :start, :stop
5
+ def start_timer
6
+ @start = Time.now
7
+ end
8
+
9
+ def stop_timer
10
+ @stop = Time.now
11
+ end
12
+
13
+ def get_time(secs = get_seconds)
14
+ secs = secs.to_i
15
+ days, secs = evaluate(secs, 86400)
16
+ hour, secs = evaluate(secs, 3600)
17
+ min, secs = evaluate(secs, 60)
18
+
19
+ string = []
20
+ string << to_string(days, 'day')
21
+ string << to_string(hour, 'hour')
22
+ string << to_string(min, 'minute')
23
+ string << to_string(secs, 'second')
24
+
25
+ string.select!{|x| !x.nil?}
26
+ string.join(", ")
27
+ end
28
+
29
+ def evaluate(x,y)
30
+ [x / y, x % y]
31
+ end
32
+
33
+ def get_seconds
34
+ stop - start
35
+ end
36
+
37
+ def to_string(time, unit)
38
+ return if time == 0
39
+
40
+ time > 1 ? s = 's' : s = ''
41
+ "#{time} #{unit}#{s}"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ module Mastermind
2
+ module Oscar
3
+ VERSION = "0.1.3"
4
+ end
5
+ end
Binary file
Binary file
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mastermind/oscar/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mastermind-oscar"
8
+ spec.version = Mastermind::Oscar::VERSION
9
+ spec.authors = ["Oscar"]
10
+ spec.email = ["oskarromero3@gmail.com"]
11
+
12
+ spec.summary = %q{Implements the popular classic game: MASTERMIND}
13
+ spec.description = %q{Mastermind_Oscar is a Ruby implementation of the classic board game of same name. The game is a code breaking game between two players; in this implementation, it is between a player and the computer.}
14
+ spec.homepage = "https://github.com/andela-ooranagwa/mastermind-oscar.git"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "bin"
27
+ spec.executables = ['mastermind_oscar']
28
+ spec.require_paths = ["lib"]
29
+ spec.add_development_dependency 'pry', "~> 0.10", ">= 0.10.1"
30
+ spec.add_development_dependency "bundler", "~> 1.9"
31
+ spec.add_development_dependency "minitest-reporters", "~> 1.1", ">= 1.1.0"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_runtime_dependency "colorize", "~> 0.7", ">= 0.7.7"
34
+ spec.add_development_dependency 'simplecov', "~> 0.10", ">= 0.10.0" #, require: false
35
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mastermind-oscar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Oscar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.10.1
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.10'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.10.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.9'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.9'
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest-reporters
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.1'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 1.1.0
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '1.1'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 1.1.0
67
+ - !ruby/object:Gem::Dependency
68
+ name: rake
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '10.0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '10.0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: colorize
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '0.7'
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 0.7.7
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.7'
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 0.7.7
101
+ - !ruby/object:Gem::Dependency
102
+ name: simplecov
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '0.10'
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 0.10.0
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.10'
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 0.10.0
121
+ description: Mastermind_Oscar is a Ruby implementation of the classic board game of
122
+ same name. The game is a code breaking game between two players; in this implementation,
123
+ it is between a player and the computer.
124
+ email:
125
+ - oskarromero3@gmail.com
126
+ executables:
127
+ - mastermind_oscar
128
+ extensions: []
129
+ extra_rdoc_files: []
130
+ files:
131
+ - ".gitignore"
132
+ - ".travis.yml"
133
+ - CODE_OF_CONDUCT.md
134
+ - Gemfile
135
+ - LICENSE.txt
136
+ - README.md
137
+ - Rakefile
138
+ - bin/mastermind_oscar
139
+ - bin/setup
140
+ - circle.yml
141
+ - lib/mastermind/oscar.rb
142
+ - lib/mastermind/oscar/codemaker.rb
143
+ - lib/mastermind/oscar/game_manager.rb
144
+ - lib/mastermind/oscar/printer.rb
145
+ - lib/mastermind/oscar/record_manager.rb
146
+ - lib/mastermind/oscar/time_manager.rb
147
+ - lib/mastermind/oscar/version.rb
148
+ - mastermind-oscar-0.1.1.gem
149
+ - mastermind-oscar-0.1.2.gem
150
+ - mastermind-oscar.gemspec
151
+ homepage: https://github.com/andela-ooranagwa/mastermind-oscar.git
152
+ licenses:
153
+ - MIT
154
+ metadata:
155
+ allowed_push_host: https://rubygems.org
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.2.2
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: 'Implements the popular classic game: MASTERMIND'
176
+ test_files: []
177
+ has_rdoc: