GemCodebreaker 0.1.6 → 0.2.0

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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -6
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +10 -3
  5. data/Gemfile.lock +5 -2
  6. data/{GemCodebreaker.gemspec → gem_codebreaker.gemspec} +3 -2
  7. data/lib/{GemCodebreaker/classes/codemaker.rb → gem_codebreaker/classes/code_maker.rb} +1 -2
  8. data/lib/gem_codebreaker/classes/game.rb +73 -0
  9. data/lib/gem_codebreaker/classes/game_config.rb +65 -0
  10. data/lib/{GemCodebreaker → gem_codebreaker}/classes/game_statistic.rb +2 -3
  11. data/lib/gem_codebreaker/classes/serializer_deserializer.rb +27 -0
  12. data/lib/{GemCodebreaker → gem_codebreaker}/classes/user.rb +3 -4
  13. data/lib/{GemCodebreaker → gem_codebreaker}/config/i18n_locales.rb +0 -0
  14. data/lib/{GemCodebreaker/errors/unknow_level_error.rb → gem_codebreaker/errors/inclusion_error.rb} +1 -1
  15. data/lib/{GemCodebreaker/errors/name_length_error.rb → gem_codebreaker/errors/length_error.rb} +3 -3
  16. data/lib/{GemCodebreaker → gem_codebreaker}/errors/no_attempts_error.rb +0 -0
  17. data/lib/{GemCodebreaker → gem_codebreaker}/errors/no_hints_error.rb +0 -0
  18. data/lib/{GemCodebreaker → gem_codebreaker}/errors/value_range_error.rb +0 -0
  19. data/lib/{GemCodebreaker → gem_codebreaker}/errors/wrong_class_error.rb +0 -0
  20. data/lib/gem_codebreaker/gem_codebreaker.rb +17 -0
  21. data/lib/gem_codebreaker/modules/validator.rb +17 -0
  22. data/lib/{GemCodebreaker → gem_codebreaker}/version.rb +1 -1
  23. metadata +34 -22
  24. data/lib/GemCodebreaker/classes/game.rb +0 -85
  25. data/lib/GemCodebreaker/classes/game_config.rb +0 -19
  26. data/lib/GemCodebreaker/errors/incorrect_length_error.rb +0 -10
  27. data/lib/GemCodebreaker/gem_codebreaker.rb +0 -23
  28. data/lib/GemCodebreaker/modules/game_configurations.rb +0 -18
  29. data/lib/GemCodebreaker/modules/serializer_deserializer.rb +0 -26
  30. data/lib/GemCodebreaker/modules/validator.rb +0 -35
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d68658435b24026df49116af030e2ed5ef790fdd7975f9c0532fbb1318cbef11
4
- data.tar.gz: e5693bc8fb47255ff1db31912f2c53214e6976cc42b025f62a249381139aad1a
3
+ metadata.gz: 8d128beb164e21cd400d768f1471fa4773bd12d298dc01e35f20aa2821e9f41b
4
+ data.tar.gz: 390ddb056e6a40e21e0303204a41e51569209a4868e534aa50db930ef72a0f07
5
5
  SHA512:
6
- metadata.gz: c0e3a636cbdc10ec10e12fc548088be337159ffd74f4c732543a695916a0b81ed91fb6bb8a98dfd8c93feb7cc84415ca6e5849c29e34a97c0f5e14444f80afaf
7
- data.tar.gz: 9c083514277ee9eea3ed8997b845bf78a11ee44e4ebccd23ee073b6df7b5e632fb5a1b84eaf07d539d4a654bfb3c832cd937eadc3f44af2ba7432d2b26f16cf1
6
+ metadata.gz: ff237177856acb512ccd3ac35c8ae5faeae3620b92975f9f150f2fc78625de14deda329bf98f816bd92909261992e3d97a6a933ac986ccc47f397092846b4468
7
+ data.tar.gz: e43687095f316b8a66019666ea56e1c195ef99789bf23ec012378fb3b804e533cdafa07af65c83b967362a39543959ccbbdf3e3ef8b781c90e2886ec0d174b71
@@ -38,12 +38,7 @@ commands:
38
38
  steps:
39
39
  - run:
40
40
  name: run spec
41
- command: |
42
- mkdir /tmp/test-results
43
- TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
44
- bundle exec rspec --format progress \
45
- --out /tmp/test-results/rspec.xml \
46
- $TEST_FILES
41
+ command: bundle exec rspec --format progress spec
47
42
 
48
43
  jobs:
49
44
  lintering:
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
3
  --require spec_helper
4
+ --order random
@@ -1,15 +1,22 @@
1
1
  require:
2
+ - rubocop-performance
2
3
  - rubocop-rspec
3
4
 
4
5
  AllCops:
5
6
  TargetRubyVersion: 2.7.1
6
7
  NewCops: enable
7
8
 
9
+ Style/Documentation:
10
+ Enabled: false
11
+
8
12
  Layout/LineLength:
9
13
  Max: 120
10
- Metrics/ModuleLength:
11
- Max: 270
14
+
12
15
  RSpec/MessageSpies:
13
16
  EnforcedStyle: receive
17
+
18
+ RSpec/NestedGroups:
19
+ Max: 6
20
+
14
21
  Metrics/BlockLength:
15
- ExcludedMethods: ['describe', 'context']
22
+ ExcludedMethods: ['describe', 'context']
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- GemCodebreaker (0.1.5)
4
+ GemCodebreaker (0.1.9)
5
+ i18n (~> 1.8.3)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
@@ -45,6 +46,8 @@ GEM
45
46
  unicode-display_width (>= 1.4.0, < 2.0)
46
47
  rubocop-ast (0.0.3)
47
48
  parser (>= 2.7.0.1)
49
+ rubocop-performance (1.6.1)
50
+ rubocop (>= 0.71.0)
48
51
  rubocop-rspec (1.41.0)
49
52
  rubocop (>= 0.68.1)
50
53
  ruby-progressbar (1.10.1)
@@ -63,10 +66,10 @@ PLATFORMS
63
66
  DEPENDENCIES
64
67
  GemCodebreaker!
65
68
  fasterer (~> 0.8.3)
66
- i18n (~> 1.8.3)
67
69
  rake (~> 13.0.1)
68
70
  rspec (~> 3.7.0)
69
71
  rubocop (~> 0.84.0)
72
+ rubocop-performance (~> 1.6.1)
70
73
  rubocop-rspec (~> 1.41.0)
71
74
  simplecov (~> 0.18.5)
72
75
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require_relative 'lib/GemCodebreaker/version'
5
+ require_relative 'lib/gem_codebreaker/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = 'GemCodebreaker'
@@ -28,10 +28,11 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ['lib']
30
30
  spec.add_development_dependency 'fasterer', '~> 0.8.3'
31
- spec.add_development_dependency 'i18n', '~> 1.8.3'
31
+ spec.add_dependency 'i18n', '~> 1.8.3'
32
32
  spec.add_development_dependency 'rake', '~> 13.0.1'
33
33
  spec.add_development_dependency 'rspec', '~> 3.7.0'
34
34
  spec.add_development_dependency 'rubocop', '~> 0.84.0'
35
+ spec.add_development_dependency 'rubocop-performance', '~> 1.6.1'
35
36
  spec.add_development_dependency 'rubocop-rspec', '~> 1.41.0'
36
37
  spec.add_development_dependency 'simplecov', '~> 0.18.5'
37
38
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GemCodebreaker
4
- # Marker class for game
5
4
  class CodeMaker
6
5
  attr_reader :plus_match, :minus_match, :empty_match
7
6
 
@@ -32,7 +31,7 @@ module GemCodebreaker
32
31
  @game_code.each do |secret_code_item|
33
32
  if @user_code.include?(secret_code_item)
34
33
  @minus_match += 1
35
- @user_code.delete(secret_code_item)
34
+ @user_code.delete_at(@user_code.index(secret_code_item))
36
35
  else
37
36
  @empty_match += 1
38
37
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemCodebreaker
4
+ class Game
5
+ LENGTH_OF_SECRET_CODE = 4
6
+ DIGIT_RANGE = (1..6).freeze
7
+
8
+ include Validator
9
+ attr_reader :statistic, :matcher_hash, :config
10
+
11
+ def initialize(user, level)
12
+ @config = GameConfig.new(user, level)
13
+ @statistic = []
14
+ secrete_code
15
+ end
16
+
17
+ def guess_start(input_code)
18
+ guess_valid?(input_code)
19
+ raise GemCodebreaker::NoAttemptsError if @config.attempts_used?
20
+
21
+ @config.increase_user_attempts
22
+ user_code = input_code.chars.map(&:to_i)
23
+ code_marker = CodeMaker.new(@secrete_code, user_code)
24
+ code_marker.calculate_result_code
25
+ @matcher_hash = { plus: code_marker.plus_match, minus: code_marker.minus_match, empty: code_marker.empty_match }
26
+ end
27
+
28
+ def win_game?
29
+ @matcher_hash[:plus] == LENGTH_OF_SECRET_CODE
30
+ end
31
+
32
+ def game_over?
33
+ @config.attempts_used? && win_game? == false
34
+ end
35
+
36
+ def show_secrete_code
37
+ @secrete_code if win_game? || game_over?
38
+ end
39
+
40
+ def hint
41
+ raise GemCodebreaker::NoHintsError if @config.hints_used?
42
+
43
+ @config.increase_user_hints
44
+ @secrete_code.sample
45
+ end
46
+
47
+ def restart_game
48
+ @config.reset_user_attempts_hints
49
+ @secrete_code = false
50
+ secrete_code
51
+ end
52
+
53
+ def save_user_statistic
54
+ @statistic << GameStatistic.new(self)
55
+ end
56
+
57
+ private
58
+
59
+ def guess_valid?(user_code)
60
+ validate_class(user_code, String)
61
+ raise GemCodebreaker::LengthError, I18n.t('errors.incorrect_length') if user_code.length != LENGTH_OF_SECRET_CODE
62
+ unless user_code[/\A[#{DIGIT_RANGE.first}-#{DIGIT_RANGE.last}]{#{LENGTH_OF_SECRET_CODE}}\z/]
63
+ raise GemCodebreaker::ValueRangeError
64
+ end
65
+
66
+ true
67
+ end
68
+
69
+ def secrete_code
70
+ @secrete_code ||= (1..LENGTH_OF_SECRET_CODE).map { rand DIGIT_RANGE }
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemCodebreaker
4
+ class GameConfig
5
+ GAME_LEVEL = {
6
+ easy: {
7
+ attempts: 15,
8
+ hints: 2
9
+ },
10
+ medium: {
11
+ attempts: 10,
12
+ hints: 1
13
+ },
14
+ hell: {
15
+ attempts: 5,
16
+ hints: 1
17
+ },
18
+ strong_hell: {
19
+ attempts: 1,
20
+ hints: 0
21
+ }
22
+ }.freeze
23
+
24
+ include Validator
25
+
26
+ attr_reader :user_nick_name, :difficulty, :max_attempts, :max_hints, :user_attempts, :user_hints
27
+
28
+ def initialize(user, level)
29
+ check_difficulty(level)
30
+ @user_nick_name = user.nick_name
31
+ @difficulty = level
32
+ @max_attempts = GAME_LEVEL[level][:attempts]
33
+ @max_hints = GAME_LEVEL[level][:hints]
34
+ @user_attempts = 0
35
+ @user_hints = 0
36
+ end
37
+
38
+ def increase_user_attempts
39
+ @user_attempts += 1
40
+ end
41
+
42
+ def increase_user_hints
43
+ @user_hints += 1
44
+ end
45
+
46
+ def attempts_used?
47
+ @user_attempts >= @max_attempts
48
+ end
49
+
50
+ def hints_used?
51
+ @user_hints >= @max_hints
52
+ end
53
+
54
+ def reset_user_attempts_hints
55
+ @user_attempts = 0
56
+ @user_hints = 0
57
+ end
58
+
59
+ private
60
+
61
+ def check_difficulty(difficulty)
62
+ validate_inclusion(GAME_LEVEL.keys, difficulty)
63
+ end
64
+ end
65
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GemCodebreaker
4
- # Game statistic class
5
4
  class GameStatistic
6
5
  attr_reader :user_nickname, :difficulty, :attempts_total, :attempts_used, :hints_total, :hints_used
7
6
 
@@ -9,9 +8,9 @@ module GemCodebreaker
9
8
  @user_nickname = game.config.user_nick_name
10
9
  @difficulty = game.config.difficulty
11
10
  @attempts_total = game.config.max_attempts
12
- @attempts_used = game.attempts
11
+ @attempts_used = game.config.user_attempts
13
12
  @hints_total = game.config.max_hints
14
- @hints_used = game.hints
13
+ @hints_used = game.config.user_hints
15
14
  end
16
15
  end
17
16
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemCodebreaker
4
+ class SerializerDeserializer
5
+ def initialize
6
+ @file_name = 'game_statistic.yml'
7
+ @statistic_dir = 'data'
8
+ @storage_path = File.expand_path("./#{@statistic_dir}/#{@file_name}")
9
+ end
10
+
11
+ def data_dir_get
12
+ data_directory = File.dirname(@storage_path)
13
+ Dir.mkdir(data_directory) unless File.directory?(data_directory)
14
+ end
15
+
16
+ def load_game_statistic
17
+ File.exist?(@storage_path) ? YAML.load_file(@storage_path) : []
18
+ end
19
+
20
+ def save_game_statistic(game_statistic)
21
+ save_game_stat = game_statistic | load_game_statistic
22
+ File.open(@storage_path, 'w') do |file|
23
+ YAML.dump(save_game_stat, file)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,18 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GemCodebreaker
4
- # User class for game
5
4
  class User
6
5
  include Validator
7
- attr_accessor :nick_name
6
+ attr_reader :nick_name
8
7
 
9
8
  def initialize(nick_name)
10
9
  @nick_name = nick_name
11
10
  end
12
11
 
13
12
  def nickname_valid?
14
- validate_string(@nick_name)
15
- validate_nickname_length(@nick_name)
13
+ validate_class(@nick_name, String)
14
+ validate_length(@nick_name, (3..20), I18n.t('errors.name_length'))
16
15
  true
17
16
  end
18
17
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GemCodebreaker
4
4
  # Error class to check game difficulty
5
- class UnknowLevelError < StandardError
5
+ class InclusionError < StandardError
6
6
  def initialize
7
7
  super(I18n.t('errors.unknow_level'))
8
8
  end
@@ -2,9 +2,9 @@
2
2
 
3
3
  module GemCodebreaker
4
4
  # Error class to check user nickname
5
- class NameLengthError < StandardError
6
- def initialize
7
- super(I18n.t('errors.name_length'))
5
+ class LengthError < StandardError
6
+ def initialize(message)
7
+ super(message)
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gem_codebreaker/config/i18n_locales'
4
+ require 'gem_codebreaker/version'
5
+ require 'gem_codebreaker/errors/length_error'
6
+ require 'gem_codebreaker/errors/no_attempts_error'
7
+ require 'gem_codebreaker/errors/no_hints_error'
8
+ require 'gem_codebreaker/errors/inclusion_error'
9
+ require 'gem_codebreaker/errors/value_range_error'
10
+ require 'gem_codebreaker/errors/wrong_class_error'
11
+ require 'gem_codebreaker/modules/validator'
12
+ require 'gem_codebreaker/classes/serializer_deserializer'
13
+ require 'gem_codebreaker/classes/user'
14
+ require 'gem_codebreaker/classes/code_maker'
15
+ require 'gem_codebreaker/classes/game_config'
16
+ require 'gem_codebreaker/classes/game_statistic'
17
+ require 'gem_codebreaker/classes/game'
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemCodebreaker
4
+ module Validator
5
+ def validate_inclusion(valid_values, check_value)
6
+ raise GemCodebreaker::InclusionError unless valid_values.include?(check_value)
7
+ end
8
+
9
+ def validate_class(user_code, klass)
10
+ raise GemCodebreaker::WrongClassError unless user_code.is_a?(klass)
11
+ end
12
+
13
+ def validate_length(check_value, valid_values, errors_message)
14
+ raise GemCodebreaker::LengthError, errors_message unless valid_values.member?(check_value.length)
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GemCodebreaker
4
- VERSION = '0.1.6'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: GemCodebreaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasyl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-14 00:00:00.000000000 Z
11
+ date: 2020-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fasterer
@@ -31,7 +31,7 @@ dependencies:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.8.3
34
- type: :development
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.84.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-performance
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.6.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.6.1
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rubocop-rspec
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -120,31 +134,29 @@ files:
120
134
  - ".gitignore"
121
135
  - ".rspec"
122
136
  - ".rubocop.yml"
123
- - GemCodebreaker.gemspec
124
137
  - Gemfile
125
138
  - Gemfile.lock
126
139
  - LICENSE.txt
127
140
  - README.md
128
141
  - bin/console
129
142
  - bin/setup
130
- - lib/GemCodebreaker/classes/codemaker.rb
131
- - lib/GemCodebreaker/classes/game.rb
132
- - lib/GemCodebreaker/classes/game_config.rb
133
- - lib/GemCodebreaker/classes/game_statistic.rb
134
- - lib/GemCodebreaker/classes/user.rb
135
- - lib/GemCodebreaker/config/i18n_locales.rb
136
- - lib/GemCodebreaker/errors/incorrect_length_error.rb
137
- - lib/GemCodebreaker/errors/name_length_error.rb
138
- - lib/GemCodebreaker/errors/no_attempts_error.rb
139
- - lib/GemCodebreaker/errors/no_hints_error.rb
140
- - lib/GemCodebreaker/errors/unknow_level_error.rb
141
- - lib/GemCodebreaker/errors/value_range_error.rb
142
- - lib/GemCodebreaker/errors/wrong_class_error.rb
143
- - lib/GemCodebreaker/gem_codebreaker.rb
144
- - lib/GemCodebreaker/modules/game_configurations.rb
145
- - lib/GemCodebreaker/modules/serializer_deserializer.rb
146
- - lib/GemCodebreaker/modules/validator.rb
147
- - lib/GemCodebreaker/version.rb
143
+ - gem_codebreaker.gemspec
144
+ - lib/gem_codebreaker/classes/code_maker.rb
145
+ - lib/gem_codebreaker/classes/game.rb
146
+ - lib/gem_codebreaker/classes/game_config.rb
147
+ - lib/gem_codebreaker/classes/game_statistic.rb
148
+ - lib/gem_codebreaker/classes/serializer_deserializer.rb
149
+ - lib/gem_codebreaker/classes/user.rb
150
+ - lib/gem_codebreaker/config/i18n_locales.rb
151
+ - lib/gem_codebreaker/errors/inclusion_error.rb
152
+ - lib/gem_codebreaker/errors/length_error.rb
153
+ - lib/gem_codebreaker/errors/no_attempts_error.rb
154
+ - lib/gem_codebreaker/errors/no_hints_error.rb
155
+ - lib/gem_codebreaker/errors/value_range_error.rb
156
+ - lib/gem_codebreaker/errors/wrong_class_error.rb
157
+ - lib/gem_codebreaker/gem_codebreaker.rb
158
+ - lib/gem_codebreaker/modules/validator.rb
159
+ - lib/gem_codebreaker/version.rb
148
160
  homepage: https://github.com/vasivaas/GemCodebreaker
149
161
  licenses:
150
162
  - MIT
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GemCodebreaker
4
- # Game class
5
- class Game
6
- LENGTH_OF_SECRET_CODE = 4
7
- DIGIT_RANGE = (1..6).freeze
8
-
9
- include GameConfigurations
10
- include Validator
11
- attr_reader :attempts, :hints, :secrete_code, :statistic, :matcher_hash
12
- attr_accessor :config
13
-
14
- def initialize(user, level)
15
- @config = GameConfig.new(user, level.to_sym)
16
- @attempts = @config.user_attempts
17
- @hints = @config.user_hints
18
- @statistic = []
19
- end
20
-
21
- def check_configuration
22
- validate_game_level(@config.difficulty)
23
- end
24
-
25
- def generate_secret_code
26
- @secrete_code = (1..LENGTH_OF_SECRET_CODE).map { rand DIGIT_RANGE }
27
- end
28
-
29
- def guess_valid?(user_code)
30
- validate_string(user_code)
31
- validate_guess_length if user_code.length != LENGTH_OF_SECRET_CODE
32
- validate_chars_range unless user_code[/\A[1-6]{4}\z/]
33
- true
34
- end
35
-
36
- def guess_start(input_code)
37
- validate_number_of_attempts if @attempts >= @config.max_attempts
38
-
39
- @attempts += 1
40
- user_code = convert_string_to_array(input_code)
41
- code_marker = CodeMaker.new(@secrete_code, user_code)
42
- code_marker.calculate_result_code
43
- @matcher_hash = { plus: code_marker.plus_match, minus: code_marker.minus_match, empty: code_marker.empty_match }
44
- end
45
-
46
- def win_game?
47
- @matcher_hash[:plus] == LENGTH_OF_SECRET_CODE
48
- end
49
-
50
- def game_over?
51
- (@attempts >= @config.max_attempts) && win_game? == false
52
- end
53
-
54
- def hints_used?
55
- @hints >= @config.max_hints
56
- end
57
-
58
- def hint
59
- validate_number_of_hints if hints_used?
60
-
61
- @hints += 1
62
- @secrete_code.sample
63
- end
64
-
65
- def reset
66
- @attempts = 0
67
- @hints = 0
68
- generate_secret_code
69
- end
70
-
71
- def save_user_statistic
72
- @statistic << current_user_statistic
73
- end
74
-
75
- private
76
-
77
- def current_user_statistic
78
- GameStatistic.new(self)
79
- end
80
-
81
- def convert_string_to_array(user_code)
82
- user_code.chars.map(&:to_i)
83
- end
84
- end
85
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GemCodebreaker
4
- # Configuration class for game
5
- class GameConfig
6
- include GameConfigurations
7
- attr_reader :user_attempts, :user_hints
8
- attr_accessor :user_nick_name, :difficulty, :max_attempts, :max_hints
9
-
10
- def initialize(user, level)
11
- @user_nick_name = user.nick_name
12
- @difficulty = level
13
- @max_attempts = GAME_LEVEL[level][:attempts]
14
- @max_hints = GAME_LEVEL[level][:hints]
15
- @user_attempts = 0
16
- @user_hints = 0
17
- end
18
- end
19
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GemCodebreaker
4
- # Error class to check the length of user code
5
- class IncorrectLengthError < StandardError
6
- def initialize
7
- super(I18n.t('errors.incorrect_length'))
8
- end
9
- end
10
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'GemCodebreaker/config/i18n_locales'
4
- require 'GemCodebreaker/version'
5
- require 'GemCodebreaker/errors/incorrect_length_error'
6
- require 'GemCodebreaker/errors/name_length_error'
7
- require 'GemCodebreaker/errors/no_attempts_error'
8
- require 'GemCodebreaker/errors/no_hints_error'
9
- require 'GemCodebreaker/errors/unknow_level_error'
10
- require 'GemCodebreaker/errors/value_range_error'
11
- require 'GemCodebreaker/errors/wrong_class_error'
12
- require 'GemCodebreaker/modules/validator'
13
- require 'GemCodebreaker/modules/serializer_deserializer'
14
- require 'GemCodebreaker/modules/game_configurations'
15
- require 'GemCodebreaker/classes/user'
16
- require 'GemCodebreaker/classes/codemaker'
17
- require 'GemCodebreaker/classes/game_config'
18
- require 'GemCodebreaker/classes/game_statistic'
19
- require 'GemCodebreaker/classes/game'
20
-
21
- module GemCodebreaker
22
- class Error < StandardError; end
23
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GemCodebreaker
4
- module GameConfigurations
5
- GAME_LEVEL = { easy:
6
- { attempts: 15,
7
- hints: 2 },
8
- medium:
9
- { attempts: 10,
10
- hints: 1 },
11
- hell:
12
- { attempts: 5,
13
- hints: 1 },
14
- strong_hell:
15
- { attempts: 1,
16
- hints: 0 } }.freeze
17
- end
18
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GemCodebreaker
4
- # Serialize and Deserialize data for game statistic
5
- module SerializerDeserializer
6
- FILE_NAME = 'game_statistic.yml'
7
- STATISTIC_DIR = 'data'
8
- STORAGE_PATH = File.expand_path("./#{STATISTIC_DIR}/#{FILE_NAME}")
9
-
10
- def data_dir_get
11
- data_directory = File.dirname(STORAGE_PATH)
12
- Dir.mkdir(data_directory) unless File.directory?(data_directory)
13
- end
14
-
15
- def load_game_statistic
16
- File.exist?(STORAGE_PATH) ? YAML.load_file(STORAGE_PATH) : []
17
- end
18
-
19
- def save_game_statistic(game_statistic)
20
- save_game_stat = game_statistic | load_game_statistic
21
- File.open(STORAGE_PATH, 'w') do |file|
22
- YAML.dump(save_game_stat, file)
23
- end
24
- end
25
- end
26
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GemCodebreaker
4
- # Validator
5
- module Validator
6
- def validate_game_level(game_level)
7
- level = %i[easy medium hell strong_hell]
8
- raise GemCodebreaker::UnknowLevelError unless level.include?(game_level)
9
- end
10
-
11
- def validate_number_of_hints
12
- raise GemCodebreaker::NoHintsError
13
- end
14
-
15
- def validate_number_of_attempts
16
- raise GemCodebreaker::NoAttemptsError
17
- end
18
-
19
- def validate_string(object)
20
- raise GemCodebreaker::WrongClassError unless object.is_a?(String)
21
- end
22
-
23
- def validate_guess_length
24
- raise GemCodebreaker::IncorrectLengthError
25
- end
26
-
27
- def validate_chars_range
28
- raise GemCodebreaker::ValueRangeError
29
- end
30
-
31
- def validate_nickname_length(nickname)
32
- raise GemCodebreaker::NameLengthError if nickname.length < 3 || nickname.length > 20
33
- end
34
- end
35
- end