andrii_codebreaker 0.1.5 → 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 +5 -0
- data/lib/andrii_codebreaker/difficulty.rb +22 -0
- data/lib/andrii_codebreaker/game.rb +46 -45
- data/lib/andrii_codebreaker/statistic.rb +1 -1
- data/lib/andrii_codebreaker/user.rb +3 -13
- data/lib/andrii_codebreaker/version.rb +1 -1
- data/lib/andrii_codebreaker.rb +3 -1
- metadata +19 -3
- data/lib/andrii_codebreaker/validate/validate.rb +0 -37
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,16 +2,21 @@
|
|
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 },
|
13
15
|
hell: { attempts: 5, hints: 1 }
|
14
16
|
}.freeze
|
15
17
|
DIFFICULTY_SORT = { easy: 1, medium: 2, hell: 3 }.freeze
|
18
|
+
WIN = '++++'
|
19
|
+
MINUS = '-'
|
20
|
+
PLUS = '+'
|
16
21
|
end
|
17
22
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AndriiCodebreaker
|
4
|
+
class Difficulty
|
5
|
+
include Constant
|
6
|
+
|
7
|
+
attr_reader :name, :hints, :attempts
|
8
|
+
|
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]
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_difficulty(name)
|
17
|
+
return DIFFICULTY[name.to_sym] if DIFFICULTY.keys.include? name.to_sym
|
18
|
+
|
19
|
+
raise ArgumentError, I18n.t('game.difficulty_input_error')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -2,82 +2,83 @@
|
|
2
2
|
|
3
3
|
module AndriiCodebreaker
|
4
4
|
class Game
|
5
|
-
include Validate
|
6
5
|
include Statistic
|
7
6
|
include Constant
|
8
7
|
|
9
|
-
attr_reader :player_name, :
|
10
|
-
attr_accessor :
|
8
|
+
attr_reader :player_name, :difficulties, :secret_code
|
9
|
+
attr_accessor :used_hints, :used_attempts, :available_hints
|
11
10
|
|
12
11
|
CONST_COMMAND = {
|
13
|
-
start: 'start',
|
14
|
-
rules: 'rules',
|
15
|
-
stats: 'stats',
|
16
|
-
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')
|
17
16
|
}.freeze
|
18
17
|
|
19
18
|
def initialize(player_name, difficulty)
|
20
|
-
@player_name = player_name
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
24
|
-
initialize_class
|
19
|
+
@player_name = User.new(player_name)
|
20
|
+
@difficulties = Difficulty.new(difficulty)
|
21
|
+
@used_attempts = 0
|
22
|
+
@used_hints = 0
|
25
23
|
end
|
26
24
|
|
27
|
-
def
|
28
|
-
difficult = DIFFICULTY[@difficulty.to_sym]
|
29
|
-
@hints_total = difficult[:hints]
|
30
|
-
@attempts_total = difficult[:attempts]
|
25
|
+
def start
|
31
26
|
@secret_code = generate_code
|
32
|
-
@
|
27
|
+
@available_hints = @secret_code.join.dup
|
33
28
|
end
|
34
29
|
|
35
|
-
def
|
36
|
-
|
30
|
+
def hint
|
31
|
+
return unless left_hint?
|
32
|
+
|
33
|
+
hint = @available_hints.chars.sample
|
34
|
+
@available_hints.sub!(hint, '')
|
35
|
+
@used_hints += 1
|
36
|
+
hint
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
|
39
|
+
def left_hint?
|
40
|
+
@used_hints < @difficulties.hints
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
+
def left_attempts?
|
44
|
+
@used_attempts < @difficulties.attempts
|
43
45
|
end
|
44
46
|
|
45
|
-
|
47
|
+
def win?(guees)
|
48
|
+
return true if @secret_code.join == guees
|
46
49
|
|
47
|
-
|
48
|
-
@secret_code == guess
|
50
|
+
false
|
49
51
|
end
|
50
52
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
def lose
|
54
|
+
return false unless left_attempts?
|
55
|
+
|
56
|
+
true
|
55
57
|
end
|
56
58
|
|
57
|
-
def
|
58
|
-
|
59
|
+
def compare_codes(guess)
|
60
|
+
@used_attempts += 1
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
63
65
|
|
64
|
-
|
65
|
-
end
|
66
|
-
arr[1].size - arr[0].size
|
66
|
+
check_result(result, guess)
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
|
69
|
+
def check_result(result, guess)
|
70
|
+
guess.each.with_index do |code, index|
|
71
|
+
result.sub!(MINUS, PLUS) if code == @secret_code[index]
|
72
|
+
end
|
73
|
+
result
|
71
74
|
end
|
72
75
|
|
73
|
-
def
|
74
|
-
|
75
|
-
.delete_if { |el| el[0] == el[1] }
|
76
|
-
.transpose
|
76
|
+
def generate_code
|
77
|
+
Array.new(CODE_LENGTH_COUNT) { rand(RANGE_SECRET_CODE) }
|
77
78
|
end
|
78
79
|
|
79
|
-
def
|
80
|
-
|
80
|
+
def code_valid?(code)
|
81
|
+
code.to_s.match(/^[1-6]{4}$/)
|
81
82
|
end
|
82
83
|
end
|
83
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
|
@@ -2,26 +2,16 @@
|
|
2
2
|
|
3
3
|
module AndriiCodebreaker
|
4
4
|
class User
|
5
|
-
include
|
5
|
+
include Constant
|
6
6
|
|
7
7
|
attr_reader :name
|
8
8
|
|
9
9
|
def initialize(name)
|
10
10
|
@name = name
|
11
|
-
validate_name
|
12
11
|
end
|
13
12
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
game.hints_left += 1
|
18
|
-
game.secret_code_cope.chars.pop
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def validate_name
|
24
|
-
@name = validates_name(name)
|
13
|
+
def self.validate_name(name)
|
14
|
+
name if name.length >= NAME_MIN_LENGTH && name.length <= NAME_MAX_LENGTH
|
25
15
|
end
|
26
16
|
end
|
27
17
|
end
|
data/lib/andrii_codebreaker.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'yaml'
|
4
|
+
require 'i18n'
|
5
|
+
require_relative '../config/i18n'
|
4
6
|
require_relative 'andrii_codebreaker/constants'
|
5
|
-
require_relative 'andrii_codebreaker/validate/validate'
|
6
7
|
require_relative 'andrii_codebreaker/model'
|
7
8
|
require_relative 'andrii_codebreaker/user'
|
9
|
+
require_relative 'andrii_codebreaker/difficulty'
|
8
10
|
require_relative 'andrii_codebreaker/statistic'
|
9
11
|
require_relative 'andrii_codebreaker/version'
|
10
12
|
require_relative 'andrii_codebreaker/game'
|
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,13 +144,15 @@ 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
|
151
|
+
- lib/andrii_codebreaker/difficulty.rb
|
135
152
|
- lib/andrii_codebreaker/game.rb
|
136
153
|
- lib/andrii_codebreaker/model.rb
|
137
154
|
- lib/andrii_codebreaker/statistic.rb
|
138
155
|
- lib/andrii_codebreaker/user.rb
|
139
|
-
- lib/andrii_codebreaker/validate/validate.rb
|
140
156
|
- lib/andrii_codebreaker/version.rb
|
141
157
|
homepage: https://github.com/Andrii-RubyGarage/Codebreker-Gem
|
142
158
|
licenses:
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AndriiCodebreaker
|
4
|
-
module Validate
|
5
|
-
include Constant
|
6
|
-
|
7
|
-
def validates_name(name)
|
8
|
-
name if valid_name?(name)
|
9
|
-
end
|
10
|
-
|
11
|
-
def validate_guess(code)
|
12
|
-
code = string_to_integer(code)
|
13
|
-
true if check_code_length?(code) && check_numbers?(code)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def string_to_integer(input_code)
|
19
|
-
array_int = []
|
20
|
-
array_chars = input_code.chars
|
21
|
-
array_chars.each { |i| array_int << i.to_i }
|
22
|
-
array_int
|
23
|
-
end
|
24
|
-
|
25
|
-
def valid_name?(name)
|
26
|
-
name.length >= NAME_MIN_LENGTH && name.length <= NAME_MAX_LENGTH
|
27
|
-
end
|
28
|
-
|
29
|
-
def check_code_length?(code)
|
30
|
-
code.length == CODE_LENGTH_COUNT
|
31
|
-
end
|
32
|
-
|
33
|
-
def check_numbers?(code)
|
34
|
-
code.all? { |value| value.between?(CODE_START_LENGTH, CODE_LENGTH) }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|