GemCodebreaker 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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