andrii_codebreaker 0.1.8 → 0.1.10
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 +4 -4
- data/.rubocop.yml +3 -3
- data/Gemfile.lock +3 -1
- data/andrii_codebreaker.gemspec +1 -0
- data/config/i18n.rb +3 -0
- data/config/locales/en.yml +7 -0
- data/lib/andrii_codebreaker/constants.rb +2 -0
- data/lib/andrii_codebreaker/difficulty.rb +9 -12
- data/lib/andrii_codebreaker/game.rb +43 -57
- data/lib/andrii_codebreaker/statistic.rb +1 -1
- data/lib/andrii_codebreaker/user.rb +3 -9
- data/lib/andrii_codebreaker/version.rb +1 -1
- data/lib/andrii_codebreaker.rb +2 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c76e659029aa6dd462471931657ed63a1c5f6dbfaf4482a2785b04e6ff283c30
|
4
|
+
data.tar.gz: 484a39816c3997e458abdbd079294cf54ecaac28b5403893eff8df04e00b1c41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9780ba3df83d7369cc5beb19a85e3c3db5f2e6f36da96b1f1fcf9cba60c9714c6fe22e808e083f6ab37e45fae933cf1e6434d58bd5734d131edd425708ecb026
|
7
|
+
data.tar.gz: e6dcf5747d03569eed9d26072668a2a8cae95381088a294e78c3bfac39c57d9158b6e2543fb0fda1606f2803890d514cbb80fd00aee6be001aeb6f47eb940983
|
data/.rubocop.yml
CHANGED
@@ -10,12 +10,12 @@ Style/Documentation:
|
|
10
10
|
Metrics/LineLength:
|
11
11
|
Max: 120
|
12
12
|
|
13
|
-
RSpec/AnyInstance:
|
14
|
-
Enabled: false
|
15
|
-
|
16
13
|
Metrics/BlockLength:
|
17
14
|
Exclude:
|
18
15
|
- 'Rakefile'
|
19
16
|
- '**/*.rake'
|
20
17
|
- 'spec/**/*.rb'
|
21
18
|
- '*.gemspec'
|
19
|
+
|
20
|
+
RSpec/NamedSubject:
|
21
|
+
Enabled: false
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
andrii_codebreaker (0.1.
|
4
|
+
andrii_codebreaker (0.1.10)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -14,6 +14,7 @@ GEM
|
|
14
14
|
fasterer (0.9.0)
|
15
15
|
colorize (~> 0.7)
|
16
16
|
ruby_parser (>= 3.14.1)
|
17
|
+
ffaker (2.20.0)
|
17
18
|
i18n (1.8.11)
|
18
19
|
concurrent-ruby (~> 1.0)
|
19
20
|
parallel (1.21.0)
|
@@ -67,6 +68,7 @@ PLATFORMS
|
|
67
68
|
DEPENDENCIES
|
68
69
|
andrii_codebreaker!
|
69
70
|
fasterer
|
71
|
+
ffaker
|
70
72
|
i18n
|
71
73
|
rake
|
72
74
|
rspec
|
data/andrii_codebreaker.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.metadata['source_code_uri'] = spec.homepage
|
21
21
|
|
22
22
|
spec.add_development_dependency 'fasterer'
|
23
|
+
spec.add_development_dependency 'ffaker'
|
23
24
|
spec.add_development_dependency 'i18n'
|
24
25
|
spec.add_development_dependency 'rake'
|
25
26
|
spec.add_development_dependency 'rspec'
|
data/config/i18n.rb
ADDED
@@ -2,11 +2,13 @@
|
|
2
2
|
|
3
3
|
module AndriiCodebreaker
|
4
4
|
module Constant
|
5
|
+
LALA = 2
|
5
6
|
NAME_MIN_LENGTH = 3
|
6
7
|
NAME_MAX_LENGTH = 20
|
7
8
|
CODE_START_LENGTH = 1
|
8
9
|
CODE_LENGTH = 6
|
9
10
|
CODE_LENGTH_COUNT = 4
|
11
|
+
RANGE_SECRET_CODE = (CODE_START_LENGTH..CODE_LENGTH).freeze
|
10
12
|
DIFFICULTY = {
|
11
13
|
easy: { attempts: 15, hints: 2 },
|
12
14
|
medium: { attempts: 10, hints: 1 },
|
@@ -4,22 +4,19 @@ module AndriiCodebreaker
|
|
4
4
|
class Difficulty
|
5
5
|
include Constant
|
6
6
|
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :name, :hints, :attempts
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
|
9
|
+
def initialize(name)
|
10
|
+
validate_difficulty(name)
|
11
|
+
@name = name
|
12
|
+
@hints = DIFFICULTY[name.to_sym][:hints]
|
13
|
+
@attempts = DIFFICULTY[name.to_sym][:attempts]
|
11
14
|
end
|
12
15
|
|
13
|
-
def
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def attempts
|
18
|
-
difficult[:attempts]
|
19
|
-
end
|
16
|
+
def validate_difficulty(name)
|
17
|
+
return DIFFICULTY[name.to_sym] if DIFFICULTY.keys.include? name.to_sym
|
20
18
|
|
21
|
-
|
22
|
-
DIFFICULTY[@difficulty.to_sym]
|
19
|
+
raise ArgumentError, I18n.t('game.difficulty_input_error')
|
23
20
|
end
|
24
21
|
end
|
25
22
|
end
|
@@ -5,94 +5,80 @@ module AndriiCodebreaker
|
|
5
5
|
include Statistic
|
6
6
|
include Constant
|
7
7
|
|
8
|
-
attr_reader :player_name, :difficulties, :
|
9
|
-
attr_accessor :
|
8
|
+
attr_reader :player_name, :difficulties, :secret_code
|
9
|
+
attr_accessor :used_hints, :used_attempts, :available_hints
|
10
10
|
|
11
11
|
CONST_COMMAND = {
|
12
|
-
start: 'start',
|
13
|
-
rules: 'rules',
|
14
|
-
stats: 'stats',
|
15
|
-
exit: 'exit'
|
12
|
+
start: I18n.t('game.start'),
|
13
|
+
rules: I18n.t('game.rules'),
|
14
|
+
stats: I18n.t('game.stats'),
|
15
|
+
exit: I18n.t('game.exit')
|
16
16
|
}.freeze
|
17
17
|
|
18
18
|
def initialize(player_name, difficulty)
|
19
|
-
@player_name = player_name
|
19
|
+
@player_name = User.new(player_name)
|
20
20
|
@difficulties = Difficulty.new(difficulty)
|
21
|
-
@
|
22
|
-
@
|
21
|
+
@used_attempts = 0
|
22
|
+
@used_hints = 0
|
23
23
|
end
|
24
24
|
|
25
25
|
def start
|
26
26
|
@secret_code = generate_code
|
27
|
-
@
|
28
|
-
@hints_total = @difficulties.hint
|
29
|
-
@attempts_total = @difficulties.attempts
|
30
|
-
@difficulty = @difficulties.difficulty
|
27
|
+
@available_hints = @secret_code.join.dup
|
31
28
|
end
|
32
29
|
|
33
|
-
def
|
34
|
-
return unless
|
30
|
+
def hint
|
31
|
+
return unless left_hint?
|
35
32
|
|
36
|
-
|
37
|
-
@
|
33
|
+
hint = @available_hints.chars.sample
|
34
|
+
@available_hints.sub!(hint, '')
|
35
|
+
@used_hints += 1
|
36
|
+
hint
|
38
37
|
end
|
39
38
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
39
|
+
def left_hint?
|
40
|
+
@used_hints < @difficulties.hints
|
41
|
+
end
|
42
|
+
|
43
|
+
def left_attempts?
|
44
|
+
@used_attempts < @difficulties.attempts
|
45
|
+
end
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
code_guess = string_to_integer(guess)
|
47
|
-
secret_code = string_to_integer(@secret_code)
|
47
|
+
def win?(guees)
|
48
|
+
return true if @secret_code.join == guees
|
48
49
|
|
49
|
-
|
50
|
+
false
|
51
|
+
end
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
+
def lose
|
54
|
+
return false unless left_attempts?
|
53
55
|
|
54
|
-
|
56
|
+
true
|
55
57
|
end
|
56
58
|
|
57
|
-
|
59
|
+
def compare_codes(guess)
|
60
|
+
@used_attempts += 1
|
58
61
|
|
59
|
-
|
60
|
-
|
62
|
+
guess = guess.chars.map(&:to_i)
|
63
|
+
minuses = (@secret_code & guess).map { |element| [@secret_code.count(element), guess.count(element)].min }.sum
|
64
|
+
result = MINUS * minuses
|
61
65
|
|
62
|
-
|
63
|
-
if code_guess[i] == secret_code[i]
|
64
|
-
result += PLUS
|
65
|
-
index << i
|
66
|
-
end
|
67
|
-
end
|
68
|
-
[result, index]
|
66
|
+
check_result(result, guess)
|
69
67
|
end
|
70
68
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
next unless secret_code.include?(i)
|
75
|
-
|
76
|
-
result += MINUS
|
77
|
-
index = secret_code.index(i)
|
78
|
-
secret_code.delete_at(index)
|
69
|
+
def check_result(result, guess)
|
70
|
+
guess.each.with_index do |code, index|
|
71
|
+
result.sub!(MINUS, PLUS) if code == @secret_code[index]
|
79
72
|
end
|
80
73
|
result
|
81
74
|
end
|
82
75
|
|
83
|
-
def
|
84
|
-
|
85
|
-
array_chars = input_code.chars
|
86
|
-
array_chars.each { |i| array_int << i.to_i }
|
87
|
-
array_int
|
88
|
-
end
|
89
|
-
|
90
|
-
def delete_index(array, index)
|
91
|
-
array.map!.with_index { |item, i| item unless index.include?(i) }.compact!
|
76
|
+
def generate_code
|
77
|
+
Array.new(CODE_LENGTH_COUNT) { rand(RANGE_SECRET_CODE) }
|
92
78
|
end
|
93
79
|
|
94
|
-
def
|
95
|
-
(
|
80
|
+
def code_valid?(code)
|
81
|
+
code.to_s.match(/^[1-6]{4}$/)
|
96
82
|
end
|
97
83
|
end
|
98
84
|
end
|
@@ -6,7 +6,7 @@ module AndriiCodebreaker
|
|
6
6
|
|
7
7
|
def statistics
|
8
8
|
data = DbYaml.load_file_stats('result.yml')
|
9
|
-
data.sort_by { |item| [-DIFFICULTY_SORT[item.
|
9
|
+
data.sort_by { |item| [-DIFFICULTY_SORT[item.difficulties.name.to_sym], item.used_attempts, item.used_hints] }
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -7,17 +7,11 @@ module AndriiCodebreaker
|
|
7
7
|
attr_reader :name
|
8
8
|
|
9
9
|
def initialize(name)
|
10
|
-
@name =
|
10
|
+
@name = name
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
def validates_name(name)
|
16
|
-
name if valid_name?(name)
|
17
|
-
end
|
18
|
-
|
19
|
-
def valid_name?(name)
|
20
|
-
name.length >= NAME_MIN_LENGTH && name.length <= NAME_MAX_LENGTH
|
13
|
+
def self.validate_name(name)
|
14
|
+
name if name.length >= NAME_MIN_LENGTH && name.length <= NAME_MAX_LENGTH
|
21
15
|
end
|
22
16
|
end
|
23
17
|
end
|
data/lib/andrii_codebreaker.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: andrii_codebreaker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrii
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fasterer
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ffaker
|
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'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: i18n
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,6 +144,8 @@ files:
|
|
130
144
|
- andrii_codebreaker.gemspec
|
131
145
|
- bin/console
|
132
146
|
- bin/setup
|
147
|
+
- config/i18n.rb
|
148
|
+
- config/locales/en.yml
|
133
149
|
- lib/andrii_codebreaker.rb
|
134
150
|
- lib/andrii_codebreaker/constants.rb
|
135
151
|
- lib/andrii_codebreaker/difficulty.rb
|