chadet 0.0.1

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: 6cfd2236b309e3803cd4a359698031aa14bc4769
4
+ data.tar.gz: 482cfc03d09d4d6521d9b132caa172f24cb44929
5
+ SHA512:
6
+ metadata.gz: 553de67587410c0583ada232854e81061d4da84e22d5f05dfe60d8eeaa5a82da61a6fa647ce09ed862396f5eeb83bc15478ea92f7c354e5d5800a6e5b167adac
7
+ data.tar.gz: 210db35063e06da63b93862978cc84c7302591900bb50a24b2be7a244f0a944b45ed4b7432b687c703b51ccb248deca02f8996c037ecf8038ad4e7ae7bcd0e29
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chadet.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 astyd
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Chadet
2
+
3
+ Characters Detective. Game of guessing characters intelligently.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'chadet'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install chadet
20
+
21
+ ## Usage
22
+
23
+ Type: 'chadet --help' for options.
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://bitbucket.org/astyd/chadet/ )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/chadet ADDED
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse' # to parse the command options
4
+ require 'set' # to check character redundancy
5
+ require 'chadet'
6
+
7
+ class String
8
+ # define methods for coloring text
9
+ colors = {:red => 31, :green => 32, :yellow => 33, :blue => 34, :cyan=> 36}
10
+ colors.each do |k, v|
11
+ define_method(k) {return "\e[#{v}m#{self}\e[0m" }
12
+ end
13
+
14
+ def flash seconds = 2
15
+ info = " " + self
16
+ print info
17
+ sleep seconds
18
+ print "\r" + " "*info.gsub(/\e\[\d*m(.*)\e\[0m/, '\1').length
19
+ print "\r"
20
+ end
21
+
22
+ def blink num_of_times = 4
23
+ info = " " + self
24
+ print "\n"
25
+ x = num_of_times
26
+ x.times do
27
+ print info.gsub(/[\w!?\.\'\(\)˚\-。ー\;\/\"\:<>+,★·.·´¯`░]/, " ")
28
+ sleep 0.18*x/4
29
+ print (info.lines.length == 1 ? "\r" : "\r\e[#{info.lines.count-1}A")
30
+ print info.yellow
31
+ sleep 0.1
32
+ print (info.lines.length == 1 ? "\r" : "\r\e[#{info.lines.count-1}A")
33
+ x -= 0.2
34
+ end
35
+ puts info.yellow
36
+ end
37
+
38
+ def flash seconds = 2
39
+ info = " " + self
40
+ print info
41
+ sleep seconds
42
+ print "\r" + " "*info.gsub(/\e\[\d*m(.*)\e\[0m/, '\1').length
43
+ print "\r"
44
+ end
45
+
46
+ def blink num_of_times = 4
47
+ info = " " + self
48
+ print "\n"
49
+ x = num_of_times
50
+ x.times do
51
+ print info.gsub(/[\w!?\.\'\(\)˚\-。ー\;\/\"\:<>+,★·.·´¯`░]/, " ")
52
+ sleep 0.18*x/4
53
+ print (info.lines.length == 1 ? "\r" : "\r\e[#{info.lines.count-1}A")
54
+ print info.yellow
55
+ sleep 0.1
56
+ print (info.lines.length == 1 ? "\r" : "\r\e[#{info.lines.count-1}A")
57
+ x -= 0.2
58
+ end
59
+ puts info.yellow
60
+ end
61
+ end
62
+
63
+ # Specify new Hash to store the options
64
+ options = {}
65
+
66
+ # Create an option parser object to describe the type of options and their description
67
+ optparse = OptionParser.new do |opts|
68
+ opts.banner = "Usage:\n\n" \
69
+ + " chadet " \
70
+ + "[Options] Number... [Options] Characters... [Options]\n\n" \
71
+ + "Description:\n\n" \
72
+ + " Characters Detective.\n" \
73
+ + " Game of guessing characters. The default number of characters is 4 and\n" \
74
+ + " the default set of characters is decimal digits from 0 to 9.\n\n" \
75
+ + "Options:\n\n"
76
+
77
+ opts.on '-r', '--rules', 'How to play this game' do
78
+ rules_of_play = <<rules
79
+ -----------------------------------
80
+ How to play Characters Detective:
81
+ -----------------------------------
82
+ +-------------------------------------------------------------+
83
+ ◙ | As the game begins, computer generates a random set of |
84
+ | characters for you to guess. |
85
+ +-------------------------------------------------------------+
86
+ +-------------------------------------------------------------+
87
+ ◙ | This random set of characters is by default a 4 digit |
88
+ | decimal numbers, or the standard Bulls and Cows game, as |
89
+ | people know it. To change this behaviour, simply specify |
90
+ | the '--number=' (or simply '-n') option to change the |
91
+ | number of characters to guess and/or specify the |
92
+ | '--characters=' (or '-c') option to change the default set |
93
+ | of characters to guess. |
94
+ | |
95
+ | Example: |
96
+ | If you type \e[32mchadet --number=2 --characters=abcdef\e[0m you will |
97
+ | then play the game like this: |
98
+ | ,¸¸,ø¤º°``°º¤ø,¸¸,ø¤°``°º¤ø,¸¸,ø¤º°``°º¤ø,¸¸,ø¤º°``°º¤ø,¸¸ |
99
+ | ------------------ ------------------- |
100
+ | no.| chars cc. cp. |Set of characters| |
101
+ | ------------------ |to guess with: | |
102
+ | 1| \e[33mab\e[0m [\e[32m0\e[0m] [\e[32m0\e[0m] ------------------- |
103
+ | 2| \e[33mcd\e[0m [\e[32m1\e[0m] [\e[32m0\e[0m] |\e[33mabcdef\e[0m | |
104
+ | \e[32mGuess:\e[0m _ ------------------- |
105
+ | |
106
+ | |
107
+ | For more options, type: \e[32mchadet --help\e[0m |
108
+ +-------------------------------------------------------------+
109
+ +-------------------------------------------------------------+
110
+ ◙ | At first, you have to blindly guess the characters. |
111
+ +-------------------------------------------------------------+
112
+ +-------------------------------------------------------------+
113
+ ◙ | After each guess, computer will give you answer on how many |
114
+ | characters you guessed correctly (Correct Characters or |
115
+ | cc.) and how many characters that their positions you |
116
+ | guessed correctly (Correct Positions or cp.). |
117
+ +-------------------------------------------------------------+
118
+ +-------------------------------------------------------------+
119
+ ◙ | By analizing computer answers in the previous guesses, you |
120
+ | can guess inteligently next. |
121
+ +-------------------------------------------------------------+
122
+ +-------------------------------------------------------------+
123
+ ◙ | You can type \e[32msave\e[0m, \e[32mquit\e[0m, \e[32mload\e[0m or \e[32mhint\e[0m during the game. |
124
+ | Their names should imply what they can do. |
125
+ +-------------------------------------------------------------+
126
+ rules
127
+ puts rules_of_play
128
+ exit
129
+ end
130
+
131
+ options[:num_of_chars] = 4
132
+ opts.on '-n', '--number NUMBER', Integer, 'How many characters you want to play' do |num|
133
+ options[:num_of_chars] = num
134
+ end
135
+
136
+ options[:characters] = "0123456789"
137
+ opts.on '-c', '--characters CHARS SET', 'Set of characters you want to play' do |chars|
138
+ options[:characters] = chars
139
+ end
140
+
141
+ options[:test] = false
142
+ opts.on '-t', '--test [TEST MODE]', 'Display the characters to guess' do
143
+ options[:test] = true
144
+ end
145
+
146
+ options[:load] = false
147
+ opts.on '-g', '--load [LOAD GAME]', 'Load previously saved game' do
148
+ options[:load] = true
149
+ end
150
+
151
+ opts.on '-h', '--help', 'Display this message' do
152
+ puts opts
153
+ puts ""
154
+ exit
155
+ end
156
+
157
+ opts.on '-v', '--version', 'Display the version of this game' do
158
+ version = "Chadet v.0.0.1"
159
+ puts version
160
+ exit
161
+ end
162
+ end
163
+
164
+ # Run parse! on the parser object
165
+ optparse.parse!
166
+
167
+ # Set of characters to play with
168
+ chars_set = options[:characters]
169
+ if chars_set.length < 2
170
+ print "Chadet: ".green
171
+ puts "Cannot play with a set of character less than 2 characters.".red
172
+ exit
173
+ end
174
+
175
+ # Set number of characters based on option -d given or the default number of 4
176
+ num_of_chars = options[:num_of_chars]
177
+ if num_of_chars > chars_set.length
178
+ num_of_chars = chars_set.length
179
+ elsif num_of_chars < 1
180
+ print "Chadet: ".green
181
+ puts "Cannot play with less than 1 character to guess.".red
182
+ exit
183
+ end
184
+
185
+ secret_obj = Chadet::SecretCharacters.new(chars_set, num_of_chars)
186
+ chars_to_guess = secret_obj.secret_chars
187
+ num_of_chars = secret_obj.num_of_chars
188
+
189
+ # Set the number to guess
190
+ puts "The secret characters are: #{chars_to_guess}".blue if options[:test] == true
191
+
192
+ system('clear')
193
+ play = Chadet::Play.new(secret_obj)
194
+ play.header
195
+ play.chars_to_use
196
+ play.table_header
197
+
198
+ go = Chadet::Guess.new(chars_set)
199
+
200
+
201
+ # list of commands
202
+ load_commands = %w{load laod}
203
+ save_commands = %w{save svae saev sav sev}
204
+ exit_commands = %w{quit exit solve solv}
205
+ cheat_commands = %w{hint hit cheat clue bonus}
206
+
207
+ # Play the game until cc. & cp. = num_of_chars
208
+ begin
209
+ print "Guess: ".green
210
+ go.guess = gets.chomp
211
+ print "\r\e[1A" + " "*(go.guess.length + 7)
212
+ print "\r"
213
+ # Check for exit commands
214
+ if load_commands.include? go.guess.downcase
215
+ go.guess_num = play.load_game go, secret_obj
216
+ elsif save_commands.include? go.guess.downcase
217
+ go.guess_num = play.do_save go.guess_num
218
+ break if go.guess_num < 0
219
+ elsif exit_commands.include? go.guess.downcase
220
+ go.guess_num = play.do_quit go.guess_num
221
+ break if go.guess_num < 0
222
+ elsif cheat_commands.include? go.guess.downcase
223
+ play.do_hint
224
+ elsif go.guess.length < num_of_chars
225
+ "Not enough input characters!".red.flash 1
226
+ elsif go.wrong_input?
227
+ "Wrong input character!".red.flash 1
228
+ elsif go.is_redundant?
229
+ go.handle_redundancy
230
+ elsif go.guess.length > num_of_chars
231
+ ("We'll take the first#{num_of_chars == 1 ? '' : ' ' + num_of_chars.to_s} "\
232
+ + "character#{num_of_chars == 1 ? '' : 's'}.").green.flash 1.5
233
+ go.guess = go.guess[0...num_of_chars]
234
+ go.guess_num += 1
235
+ puts play.answer go.guess, go.guess_num
236
+ else
237
+ go.guess = go.guess[0...num_of_chars]
238
+ go.guess_num += 1
239
+ puts play.answer go.guess, go.guess_num
240
+ end
241
+ end until go.guess == secret_obj.secret_chars
242
+
243
+ play.end_game if go.guess_num > 0
244
+
245
+ # Congratulate the player for finishing the game
246
+ save = "Your game has been saved."
247
+ quit = "Try it again!"
248
+ lucky = "Wow! (˚o˚) Lucky guess."
249
+ congratulate = "★·.·´¯`·.·★·.·´¯`·.·★\n ░G░O░O░D░ ░J░O░B░!░\n ★·.·´¯`·.·★·.·´¯`·.·★\n" \
250
+ + " You did it in " + go.guess_num.to_s + " steps."
251
+ a_bit_slow = "(-。ー;) Finally..\n But don't beat yourself up. Try it again!\n I know you "\
252
+ + "can do better than " + go.guess_num.to_s + " guesses."
253
+
254
+ # To decide what message to display after the game finished
255
+ case go.guess_num
256
+ when -2
257
+ message = save
258
+ when -1
259
+ message = quit
260
+ when 1
261
+ message = lucky
262
+ when 2..chars_set.length
263
+ message = congratulate
264
+ else
265
+ message = a_bit_slow
266
+ end
267
+
268
+ if message == a_bit_slow
269
+ puts "\n " + message.yellow
270
+ else
271
+ message.blink
272
+ end
data/chadet.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chadet/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "chadet"
8
+ spec.version = Chadet::VERSION
9
+ spec.authors = ["Adrian Setyadi"]
10
+ spec.email = ["a.styd@yahoo.com"]
11
+ spec.summary = %q{Characters Detective. Game of guessing characters intelligently.}
12
+ spec.description = %q{Computer will generate a random set of characters. The default number of characters is 4 and the default set of characters is decimal digits from 0 to 9. After each guess you make, computer will tell you how many characters you guessed correctly and how many characters that their position you guessed correctly.}
13
+ spec.homepage = "https://bitbucket.org/astyd"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ end
@@ -0,0 +1,3 @@
1
+ module Chadet
2
+ VERSION = "0.0.1"
3
+ end
data/lib/chadet.rb ADDED
@@ -0,0 +1,296 @@
1
+ require "chadet/version"
2
+
3
+ module Chadet
4
+ class Play
5
+ def initialize secret_chars_object
6
+ @chars_set = secret_chars_object.chars_set
7
+ @num_of_chars = secret_chars_object.num_of_chars
8
+ @secret_chars = secret_chars_object.secret_chars
9
+ @loaded = false
10
+ @used_true = ""
11
+ @used_false = ""
12
+ @max_hint = (@chars_set.length/@num_of_chars).to_i
13
+ @hint_used = 0
14
+ @moves = ""
15
+ end
16
+
17
+ def header
18
+ puts "Type: " + "chadet --help".green + " in the terminal to see more options.\n"\
19
+ + "To quit this game at any time, type: " + "quit".green + "\n"
20
+ puts ",¸¸,ø¤º°``°º¤ø,¸¸,ø¤°``°º¤ø,¸¸,ø¤º°``°º¤ø,¸¸,ø¤º°``°º¤ø,¸¸"
21
+ end
22
+
23
+ def chars_to_use
24
+ @chars_set.length >= 17 ? box_width = @chars_set.length + 2 : box_width = 19
25
+ end_pos = 58
26
+ start_pos = end_pos - box_width
27
+ puts " "*start_pos + "+" + "-"*(box_width-2) + "+" + "\n"\
28
+ + " "*start_pos + "|Set of characters" + " "*(box_width - 19) + "|\n" \
29
+ + " "*start_pos + "|to guess with:" + " "*(box_width - 16) + "|\n" \
30
+ + " "*start_pos + "+" + "-"*(box_width-2) + "+" + "\n" \
31
+ + " "*start_pos + "|" + @chars_set.yellow + " "*(box_width - @chars_set.length - 2) + "|\n" \
32
+ + " "*start_pos + "+" + "-"*(box_width-2) + "+"
33
+ print "\r\e[6A"
34
+ end
35
+
36
+ def table_header
37
+ chars_pos = (5 + @num_of_chars - "chars".length)/2
38
+ cc_pos = 10 + @num_of_chars
39
+ cp_pos = 12 + @num_of_chars + 2*@num_of_chars.to_s.length
40
+ table_width = cp_pos + 2
41
+ puts " " + "-"*table_width + "\n"\
42
+ + " no.|" + " "*chars_pos + "chars" + " "*(cc_pos - chars_pos - "chars".length - " no.|".length) \
43
+ + "cc." + " "*(cp_pos - cc_pos - "cc.".length)\
44
+ + "cp." + "\n"\
45
+ + " " + "-"*table_width
46
+ end
47
+
48
+ def end_game
49
+ # table bottom horizontal line
50
+ cp_pos = 12 + @num_of_chars + 2*@num_of_chars.to_s.length
51
+ table_width = cp_pos + 2
52
+ puts " " + "-"*table_width
53
+ end
54
+
55
+ def answer guess, guess_num
56
+ # Display number of correct characters and number of correct positions
57
+ _G_ = guess_num.abs.to_s
58
+ _g_ = _G_.length
59
+ _N_ = @num_of_chars.to_s
60
+ _n_ = _N_.length
61
+ _B_ = checkCC(guess).to_s
62
+ _b_ = _B_.length
63
+ _U_ = checkCO(guess).to_s
64
+ _u_ = _U_.length
65
+ output = (guess_num == -1 ? ' XXX' : " "*(4-_g_) + _G_) + "| #{guess.yellow}" \
66
+ + " [" + ("0"*(_n_-_b_) + _B_).green + "] [" \
67
+ + ("0"*(_n_-_u_) + _U_).green + "]"
68
+ @moves << (output + "\n")
69
+ if _U_ == _N_ && @loaded == true
70
+ filename = ".filename"
71
+ work_dir = File.dirname(__FILE__)
72
+ file = work_dir + "/" + filename + ".4dig"
73
+ File.delete(file) if File.exists?(file)
74
+ end
75
+ return output
76
+ end
77
+
78
+ # Method to check how many digits are correctly guessed
79
+ def checkCC guess
80
+ cc = 0
81
+ guess.each_char do |x|
82
+ if @secret_chars.include? x.to_s
83
+ cc += 1
84
+ end
85
+ end
86
+ return cc
87
+ end
88
+
89
+ # Method to check how many correct digits are presented in correct positions
90
+ def checkCO guess
91
+ co = 0
92
+ for i in 0...@num_of_chars
93
+ if @secret_chars[i] == guess[i]
94
+ co += 1
95
+ end
96
+ end
97
+ return co
98
+ end
99
+
100
+ # Method to display hint
101
+ def hint
102
+ picked_number = 0
103
+ clue = ""
104
+ chance = rand 1..100
105
+ if chance < (@num_of_chars.to_f/@chars_set.length.to_f*100) \
106
+ && chance > (@num_of_chars.to_f/@chars_set.length.to_f*20) #display one correct number
107
+ picked_number = rand 0...(@num_of_chars-@used_true.length) || 0
108
+ true_characters = @secret_chars.tr(@used_true, '')
109
+ picked_true = true_characters[picked_number] || ""
110
+ @used_true += picked_true
111
+ if picked_true == ""
112
+ clue = "You've already known #{@num_of_chars == 1 ? 'the' : 'all'} true "\
113
+ + "character#{'s' unless @num_of_chars == 1}."
114
+ else
115
+ clue = "'#{picked_true}' is#{@num_of_chars == 1 ? '' : ' among'} the true "\
116
+ + "character#{'s' unless @num_of_chars == 1}."
117
+ end
118
+ else
119
+ picked_number = rand 0...(@chars_set.length - @num_of_chars - @used_false.length) || 0
120
+ false_characters = @chars_set.tr(@secret_chars, '').tr(@used_false, '') || ""
121
+ picked_false = false_characters[picked_number] || ""
122
+ @used_false += picked_false
123
+ if picked_false == ""
124
+ clue = "You've already known #{(@chars_set.length - @num_of_chars) == 1 ? 'the' : 'all'} "\
125
+ + "false character#{'s' unless (@chars_set.length - @num_of_chars) == 1}."
126
+ else
127
+ clue = "One can simply omit '#{picked_false}'."
128
+ end
129
+ end
130
+ return clue.yellow
131
+ end
132
+
133
+ def do_hint
134
+ if @hint_used != @max_hint
135
+ hint.flash 1.1
136
+ @hint_used += 1
137
+ else
138
+ ("Sorry, you've used #{@max_hint == 1 ? 'the' : 'up all'} #{@max_hint.to_s + " " unless @max_hint == 1}"\
139
+ + "hint#{'s' unless @max_hint == 1}.").red.flash 1.2
140
+ end
141
+ end
142
+
143
+ def save_game guess_num
144
+ end_game if guess_num > 0
145
+ # generate filename
146
+ time = Time.now
147
+ work_dir = File.dirname(__FILE__)
148
+ filename = ".filename" # "."+time.strftime("%y%m%d%H%M%S").to_i.to_s(36)
149
+ # save file
150
+ File.open(work_dir + "/" + filename + ".4dig", "w+") do |f|
151
+ f.write("[set of chars]\n")
152
+ f.write(@chars_set + "\n"*2)
153
+ f.write("[secret chars]\n")
154
+ f.write(@secret_chars + "\n"*2)
155
+ f.write("[hint used]\n")
156
+ f.write(@hint_used.to_s + "\n"*2)
157
+ f.write("[moves]\n")
158
+ f.write(@moves)
159
+ end
160
+ guess_num = -2
161
+ return guess_num
162
+ end
163
+
164
+ def do_save guess_num
165
+ if guess_num > 0
166
+ guess_num = save_game guess_num
167
+ else
168
+ "No game to save.".red.flash 1
169
+ end
170
+ return guess_num
171
+ end
172
+
173
+ def quit_game guess_num
174
+ print "\r"
175
+ "¯\\(°_o)/¯ I give up.".yellow.flash 1
176
+ guess_num = -1
177
+ puts answer @secret_chars, guess_num
178
+ end_game
179
+ return guess_num
180
+ end
181
+
182
+ def do_quit guess_num
183
+ if guess_num > 0
184
+ yes_commands = %w{yes yse ys ye y save saev seav sav sev s}
185
+ print "\r "
186
+ print "\r " + "Save game? (yes/no): ".yellow
187
+ save = gets.chomp
188
+ print "\r\e[1A" + " "*25
189
+ print "\r"
190
+ if yes_commands.include? save.downcase
191
+ guess_num = do_save guess_num
192
+ else
193
+ guess_num = quit_game guess_num
194
+ end
195
+ else
196
+ guess_num = quit_game guess_num
197
+ end
198
+ return guess_num
199
+ end
200
+
201
+ def load_game guess_object, secret_object
202
+ filename = ".filename"
203
+ work_dir = File.dirname(__FILE__)
204
+ if File.exists?(work_dir + "/" + filename + ".4dig")
205
+ @loaded = true
206
+ table_width = 15 + @num_of_chars + 2*@num_of_chars.to_s.length
207
+ print "\r\e[#{guess_object.guess_num+3}A"
208
+ print (" "*table_width + "\n")*(guess_object.guess_num+3)
209
+ print "\r\e[#{guess_object.guess_num+3}A"
210
+ saved_game = File.read(work_dir + "/" + filename + ".4dig")
211
+ saved_game_arr = saved_game.split("\n")
212
+ @chars_set = saved_game_arr[1]
213
+ @secret_chars = saved_game_arr[4]
214
+ secret_object.secret_chars = @secret_chars
215
+ @num_of_chars = @secret_chars.length
216
+ @hint_used = saved_game_arr[7].to_i
217
+ @max_hint = (@chars_set.length/@num_of_chars).to_i
218
+ @moves = saved_game_arr[10..-1]
219
+ guess_object.guess_num = @moves.length
220
+ chars_to_use
221
+ table_header
222
+ @moves = @moves.inject("") {|result, line| result + line + "\n"}
223
+ puts @moves
224
+ else
225
+ "No saved game found.".yellow.flash 1.5
226
+ end
227
+ return guess_object.guess_num
228
+ end
229
+ end
230
+
231
+ class SecretCharacters
232
+ attr_reader :num_of_chars, :chars_set, :max_hint
233
+ attr_accessor :secret_chars
234
+
235
+ # default chars = "0123456789" and default num = 4, see option parser.
236
+ def initialize chars_set, num_of_chars
237
+ @num_of_chars = num_of_chars
238
+ @chars_set = chars_set
239
+ @secret_chars = do_shuffle
240
+ end
241
+
242
+ # Shuffle a set of number from 0-9
243
+ def do_shuffle
244
+ prep_chars = @chars_set.chars.to_a.shuffle
245
+ secret_chars = prep_chars[0, @num_of_chars].join.to_s
246
+ return secret_chars
247
+ end
248
+ end
249
+
250
+ class Guess
251
+ # check if guess has redundant characters
252
+ attr_accessor :guess, :guess_num, :chars_set
253
+ def initialize chars_set
254
+ @guess = ""
255
+ @guess_num = 0
256
+ @chars_set = chars_set
257
+ end
258
+
259
+ def is_redundant?
260
+ redundant = false
261
+ a = @guess.split("").to_set.length
262
+ b = @guess.length
263
+ redundant = true if a < b
264
+ return redundant
265
+ end
266
+
267
+ def handle_redundancy
268
+ char_freq = {}
269
+ @guess.each_char do |char|
270
+ char_freq[char] ? char_freq[char] += 1 : char_freq[char] = 1
271
+ end
272
+ redundant_char = char_freq.select {|k, v| v > 1}
273
+ sorted_red_char = redundant_char.sort_by {|k, v| v}
274
+ sorted_red_char.reverse! unless sorted_red_char[1].nil? || sorted_red_char[0][1] == sorted_red_char[1][1]
275
+ redundant = sorted_red_char[0][0]
276
+ frequency = sorted_red_char[0][1]
277
+ if frequency == 2
278
+ freq_string = "twice"
279
+ else
280
+ freq_string = "#{frequency} times"
281
+ end
282
+ "Redundant: you mentioned \"#{redundant}\" #{freq_string}.".yellow.flash 1.1
283
+ end
284
+
285
+ # Check if wrong character is input
286
+ def wrong_input?
287
+ wrong_char = false
288
+ error_num = 0
289
+ @guess.each_char do |char|
290
+ error_num += 1 unless chars_set.include? char
291
+ end
292
+ wrong_char = true if error_num > 0
293
+ return wrong_char
294
+ end
295
+ end
296
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chadet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Adrian Setyadi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Computer will generate a random set of characters. The default number
14
+ of characters is 4 and the default set of characters is decimal digits from 0 to
15
+ 9. After each guess you make, computer will tell you how many characters you guessed
16
+ correctly and how many characters that their position you guessed correctly.
17
+ email:
18
+ - a.styd@yahoo.com
19
+ executables:
20
+ - chadet
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - ".gitignore"
25
+ - Gemfile
26
+ - LICENSE.txt
27
+ - README.md
28
+ - Rakefile
29
+ - bin/chadet
30
+ - chadet.gemspec
31
+ - lib/chadet.rb
32
+ - lib/chadet/version.rb
33
+ homepage: https://bitbucket.org/astyd
34
+ licenses:
35
+ - MIT
36
+ metadata: {}
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 2.2.2
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Characters Detective. Game of guessing characters intelligently.
57
+ test_files: []