codebreaker-rg-te 0.1.11
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/lib/codebreaker.rb +12 -0
- data/lib/codebreaker/console.rb +125 -0
- data/lib/codebreaker/game.rb +82 -0
- data/lib/codebreaker/localization.rb +2 -0
- data/lib/codebreaker/stats.rb +13 -0
- data/lib/codebreaker/storage/StorageInterceptor.rb +17 -0
- data/lib/codebreaker/validation.rb +15 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b6869d918ca7fb102606e9971b61daac14bec4c5
|
4
|
+
data.tar.gz: b08d74fe29a5f5745ed3f14abc47c958696c48a4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc2bfdd1e7f2529aa225e1f20de7ce59deb0cf5a0fc9917962888ef7fff6ce352983a0e87f2223a2662f560e9715736992ecacab040a4c3c887171633c0fcbff
|
7
|
+
data.tar.gz: 2c8c1eb12e345f6831fe4860d026484e2778d2694507f546767291c8c0a27ec6f4834eaed53ed2fb194d24e0a5394aedcf0e161cc4793c9de4ee1e43d6ffb4f7
|
data/lib/codebreaker.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
require 'yaml'
|
3
|
+
require './lib/codebreaker/storage/StorageInterceptor.rb'
|
4
|
+
require './lib/codebreaker/console.rb'
|
5
|
+
require './lib/codebreaker/localization.rb'
|
6
|
+
require './lib/codebreaker/validation.rb'
|
7
|
+
require './lib/codebreaker/stats.rb'
|
8
|
+
require './lib/codebreaker/game.rb'
|
9
|
+
require './lib/codebreaker.rb'
|
10
|
+
|
11
|
+
module Codebreaker
|
12
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Codebreaker
|
2
|
+
class Console
|
3
|
+
YES = 'yes'.freeze
|
4
|
+
HINT = 'hint'.freeze
|
5
|
+
START = 'start'.freeze
|
6
|
+
RULES = 'rules'.freeze
|
7
|
+
STATS = 'stats'.freeze
|
8
|
+
EXIT = 'exit'.freeze
|
9
|
+
|
10
|
+
DIFFICULTIES = %w[easy medium hard].freeze
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@game = Codebreaker::Game.new
|
14
|
+
@stat = Codebreaker::Stats.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def launch
|
18
|
+
loop do
|
19
|
+
message(:start_game)
|
20
|
+
message(:wel_instruct, start: START, rules: RULES, stats: STATS, exit: EXIT)
|
21
|
+
@answer = read_from_console
|
22
|
+
check_answer
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def start_game
|
27
|
+
enter_name
|
28
|
+
enter_level
|
29
|
+
@game.new_game
|
30
|
+
round_game
|
31
|
+
end
|
32
|
+
|
33
|
+
def round_game
|
34
|
+
loop do
|
35
|
+
return loose if @game.attempts.zero?
|
36
|
+
|
37
|
+
message(:question_num, attempts: @game.attempts, hints: @game.hints)
|
38
|
+
user_answer = read_from_console
|
39
|
+
hint_show if user_answer == HINT
|
40
|
+
next message(:invalid_number) unless @game.validate_answer(user_answer)
|
41
|
+
|
42
|
+
@game.take_attempts
|
43
|
+
@game.set_user_code(user_answer)
|
44
|
+
return win if @game.equal_codes?(user_answer)
|
45
|
+
|
46
|
+
puts @game.game_result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def hint_show
|
51
|
+
if @game.hints.zero?
|
52
|
+
message(:over_hint)
|
53
|
+
round_game
|
54
|
+
end
|
55
|
+
puts @game.show_hints
|
56
|
+
@game.take_hints
|
57
|
+
round_game
|
58
|
+
end
|
59
|
+
|
60
|
+
def win
|
61
|
+
message(:win)
|
62
|
+
message(:progress)
|
63
|
+
@game.save if read_from_console.eql? YES
|
64
|
+
continue_game? ? start_game : exit
|
65
|
+
end
|
66
|
+
|
67
|
+
def loose
|
68
|
+
message(:lose)
|
69
|
+
continue_game? ? start_game : exit
|
70
|
+
end
|
71
|
+
|
72
|
+
def continue_game?
|
73
|
+
message(:new_game)
|
74
|
+
read_from_console.eql? YES
|
75
|
+
end
|
76
|
+
|
77
|
+
def stats_show
|
78
|
+
data = @stat.stats
|
79
|
+
|
80
|
+
return message(:empty_stat) unless data
|
81
|
+
|
82
|
+
message(:stats)
|
83
|
+
message(:col_table)
|
84
|
+
data.each_with_index do |val, index|
|
85
|
+
print "#{index}\t"
|
86
|
+
val.each do |_key, value|
|
87
|
+
print "#{value}\t"
|
88
|
+
end
|
89
|
+
print "\n"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def check_answer
|
96
|
+
case @answer
|
97
|
+
when START then start_game
|
98
|
+
when RULES then message(:rulegame)
|
99
|
+
when STATS then stats_show
|
100
|
+
when EXIT then exit
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def message(msg, params = {})
|
105
|
+
puts I18n.t(msg, params)
|
106
|
+
end
|
107
|
+
|
108
|
+
def read_from_console
|
109
|
+
gets.chomp
|
110
|
+
end
|
111
|
+
|
112
|
+
def enter_name
|
113
|
+
message(:username)
|
114
|
+
name = read_from_console
|
115
|
+
return enter_name unless @game.enter_name(name)
|
116
|
+
|
117
|
+
message(:hello, name: name)
|
118
|
+
end
|
119
|
+
|
120
|
+
def enter_level
|
121
|
+
message(:choose_difficulty, difficulties: DIFFICULTIES.join(' '))
|
122
|
+
return input_level unless @game.enter_level(read_from_console)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Codebreaker
|
3
|
+
class Game
|
4
|
+
include Validation
|
5
|
+
attr_reader :attempts, :hints, :level, :name, :level_num
|
6
|
+
attr_reader :hints_index, :result
|
7
|
+
attr_reader :user_code, :secret_code, :phrases
|
8
|
+
RANGE = (1..6).freeze
|
9
|
+
|
10
|
+
GAME_LEVELS = {
|
11
|
+
easy: { attempts: 30, hints: 3, level_num: 0 },
|
12
|
+
medium: { attempts: 15, hints: 2, level_num: 1 },
|
13
|
+
hard: { attempts: 10, hints: 1, level_num: 2 }
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
DIGITS_COUNT = 4
|
17
|
+
|
18
|
+
def new_game
|
19
|
+
@secret_code = Array.new(DIGITS_COUNT) { rand(RANGE) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_user_code(enter_code)
|
23
|
+
@user_code = enter_code.each_char.map(&:to_i)
|
24
|
+
end
|
25
|
+
|
26
|
+
def enter_level(level)
|
27
|
+
return unless validate_level(level)
|
28
|
+
|
29
|
+
@level = level
|
30
|
+
|
31
|
+
@attempts = GAME_LEVELS.dig(level.to_sym, :attempts)
|
32
|
+
@hints = GAME_LEVELS.dig(level.to_sym, :hints)
|
33
|
+
@level_num = GAME_LEVELS.dig(level.to_sym, :level_num)
|
34
|
+
@hints_index = (0..3).to_a.sample @hints
|
35
|
+
end
|
36
|
+
|
37
|
+
def enter_name(name)
|
38
|
+
return unless validate_name(name)
|
39
|
+
|
40
|
+
@name = name
|
41
|
+
end
|
42
|
+
|
43
|
+
def equal_codes?(user_answer)
|
44
|
+
secret_code.join == user_answer
|
45
|
+
end
|
46
|
+
|
47
|
+
def take_attempts
|
48
|
+
@attempts -= 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def take_hints
|
52
|
+
@hints -= 1
|
53
|
+
end
|
54
|
+
|
55
|
+
def show_hints
|
56
|
+
secret_code[hints_index.shift]
|
57
|
+
end
|
58
|
+
|
59
|
+
def game_result
|
60
|
+
result = ''
|
61
|
+
(0..3).each do |index|
|
62
|
+
result += '+' if @user_code[index] == @secret_code[index]
|
63
|
+
end
|
64
|
+
return result if result.eql?('++++')
|
65
|
+
|
66
|
+
(0..3).each do |index|
|
67
|
+
result += '-' if @secret_code.include?(@user_code[index]) && @user_code[index] != @secret_code[index]
|
68
|
+
end
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def save
|
73
|
+
di = StorageInterceptor.new
|
74
|
+
codebreaker_data = di.read_database || []
|
75
|
+
attempts_used = GAME_LEVELS.dig(level.to_sym, :attempts) - attempts
|
76
|
+
hints_used = GAME_LEVELS.dig(level.to_sym, :hints) - hints
|
77
|
+
hash_stat = { name: @name, level: @level, level_num: @level_num, attempts: @attempts, attempts_used: attempts_used, hints: @hints, hints_used: hints_used }
|
78
|
+
codebreaker_data << hash_stat
|
79
|
+
di.write_database(codebreaker_data)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Codebreaker
|
2
|
+
class Stats
|
3
|
+
def stats
|
4
|
+
di = StorageInterceptor.new
|
5
|
+
codebreaker_data = di.read_database
|
6
|
+
|
7
|
+
return unless codebreaker_data
|
8
|
+
|
9
|
+
codebreaker_data.sort_by! { |stat| [stat[:level_num], stat[:hints], stat[:attempts]] }
|
10
|
+
codebreaker_data.each { |stat| stat.delete_if { |key, _value| key == :level_num } }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Codebreaker
|
2
|
+
class StorageInterceptor
|
3
|
+
DEFAULT_PATH_TO_FILE = './data/stat.yml'.freeze
|
4
|
+
|
5
|
+
def initialize(path_to_file = DEFAULT_PATH_TO_FILE)
|
6
|
+
@path_to_file = path_to_file.empty? ? DEFAULT_PATH_TO_FILE : path_to_file
|
7
|
+
end
|
8
|
+
|
9
|
+
def read_database
|
10
|
+
YAML.load_file(@path_to_file) if File.exist?(@path_to_file)
|
11
|
+
end
|
12
|
+
|
13
|
+
def write_database(library)
|
14
|
+
File.open(@path_to_file, 'w') { |file| file.write(library.to_yaml) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Validation
|
2
|
+
USER_ANSWER_REX = /^[1-6]{4}$/
|
3
|
+
|
4
|
+
def validate_name(name)
|
5
|
+
name.size > 2 && name.size < 21
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate_level(level)
|
9
|
+
%w[easy medium hard].include? level
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_answer(user_answer)
|
13
|
+
user_answer =~ USER_ANSWER_REX
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: codebreaker-rg-te
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.11
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eugene Tereschenko
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.1
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fasterer
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: i18n
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec_junit_formatter
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: simplecov
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description:
|
154
|
+
email:
|
155
|
+
- tereschenko.eugene@gmail.com
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- lib/codebreaker.rb
|
161
|
+
- lib/codebreaker/console.rb
|
162
|
+
- lib/codebreaker/game.rb
|
163
|
+
- lib/codebreaker/localization.rb
|
164
|
+
- lib/codebreaker/stats.rb
|
165
|
+
- lib/codebreaker/storage/StorageInterceptor.rb
|
166
|
+
- lib/codebreaker/validation.rb
|
167
|
+
homepage: https://github.com/EugeneTereschenko/codebreaker
|
168
|
+
licenses: []
|
169
|
+
metadata:
|
170
|
+
allowed_push_host: https://rubygems.org
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options: []
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0'
|
185
|
+
requirements: []
|
186
|
+
rubyforge_project:
|
187
|
+
rubygems_version: 2.6.14
|
188
|
+
signing_key:
|
189
|
+
specification_version: 4
|
190
|
+
summary: Codebreaker app
|
191
|
+
test_files: []
|