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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1743f315c3e1b74182843039b68e4a94274b9b32d29e4006ab50bc40a1b9bef2
4
- data.tar.gz: 4562d14615ea91676b026d3fa4038c3542c5293cbc3c1e12bc159b08002e9bef
3
+ metadata.gz: c76e659029aa6dd462471931657ed63a1c5f6dbfaf4482a2785b04e6ff283c30
4
+ data.tar.gz: 484a39816c3997e458abdbd079294cf54ecaac28b5403893eff8df04e00b1c41
5
5
  SHA512:
6
- metadata.gz: 53365788f599671f07b0b59725ebb0d2e080ec7d62117052807c2995c384f3b7da63cafd4c8b99a0cc486fcfaa78f6e1d83f151c6f15a62d869659907cd32aef
7
- data.tar.gz: b28fda65ac98bdcf8c5385c068620d5e66fde3ae818a6fe3c044dc85e9cd1b25b432b2cd4167fa06237c842c5d05189ec251f88e299ed7c9ddf9438bee2ea12d
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)
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
@@ -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
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ I18n.config.load_path << Dir[File.expand_path('config/locales').concat('/*.yml')]
@@ -0,0 +1,7 @@
1
+ en:
2
+ game:
3
+ start: "start"
4
+ rules: "rules"
5
+ stats: "stats"
6
+ exit: "exit"
7
+ difficulty_input_error: "This difficulty is not available."
@@ -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, :difficulty, :attempts_total, :hints_total, :secret_code
10
- attr_accessor :hints_left, :attempts_left, :secret_code_cope
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
- @difficulty = difficulty
22
- @attempts_left = 0
23
- @hints_left = 0
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 initialize_class
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
- @secret_code_cope = @secret_code.dup
27
+ @available_hints = @secret_code.join.dup
33
28
  end
34
29
 
35
- def show_hints
36
- hints_left
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 compare_codes(guess)
40
- return '++++' if exact_match(guess)
39
+ def left_hint?
40
+ @used_hints < @difficulties.hints
41
+ end
41
42
 
42
- ('+' * pluses(guess)) + ('-' * minuses(guess))
43
+ def left_attempts?
44
+ @used_attempts < @difficulties.attempts
43
45
  end
44
46
 
45
- private
47
+ def win?(guees)
48
+ return true if @secret_code.join == guees
46
49
 
47
- def exact_match(guess)
48
- @secret_code == guess
50
+ false
49
51
  end
50
52
 
51
- def pluses(guess)
52
- zipped(guess)
53
- .select { |el| el[0] == el[1] }
54
- .count
53
+ def lose
54
+ return false unless left_attempts?
55
+
56
+ true
55
57
  end
56
58
 
57
- def minuses(guess)
58
- return 0 if exact_match(guess)
59
+ def compare_codes(guess)
60
+ @used_attempts += 1
59
61
 
60
- arr = delete_pairs(guess)
61
- arr[1].each do |number|
62
- next unless arr[0].include?(number)
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
- arr[0].delete_at(arr[0].index(number))
65
- end
66
- arr[1].size - arr[0].size
66
+ check_result(result, guess)
67
67
  end
68
68
 
69
- def zipped(guess)
70
- @secret_code.chars.zip(guess.chars)
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 delete_pairs(guess)
74
- zipped(guess)
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 generate_code
80
- (Array.new(CODE_LENGTH_COUNT) { rand(CODE_START_LENGTH..CODE_LENGTH) }).join.to_s
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.difficulty.to_sym], item.attempts_left, item.hints_left] }
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 AndriiCodebreaker::Validate
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 hints(game)
15
- return unless game.hints_total > game.hints_left
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AndriiCodebreaker
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.10'
5
5
  end
@@ -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.5
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-13 00:00:00.000000000 Z
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