alex_codebreaker 0.1.6 → 0.1.7

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: 31e7f606c615b97cc6f49e74138d611a9cbbff08e356bdda31b14c07d587d786
4
- data.tar.gz: f8407fce826a3cc5be2ca8bb9faeee67df6b1dd121e62ce6d153d1417ff84865
3
+ metadata.gz: 9906ea2d8ba009f676ae54c4e40fe92a6c32c2027e925c75b2cc578139d0c0d0
4
+ data.tar.gz: e1b386d362478ee47deb158c476ed73fe38c33a85f7a2991967552009e399782
5
5
  SHA512:
6
- metadata.gz: 43a221a965ad118e17e4a2356a89475a7d42480951c371251f1e8d236cba18f3bccf1f9b6008fbacbf4c2db959a383d198c6edb6c879b49b26a01d98f98735f0
7
- data.tar.gz: 8c561f6bcdd0400b081b50c4607add61bf24c02391a2544f3fe5f6b35250b11563e488f031a8de4220d1ac5d2875585233639d77c1703d50e7f38e7a2472b96f
6
+ metadata.gz: b3bf4021bf22dbbfb4bde1d3e8a73898adc68eb7607c0c05511576e41661eb2032588a3a38cc5895f0be61ea19861c4487e294c97bf1f4fba101e243c11e1856
7
+ data.tar.gz: 61c34662972de0c1e127c3740a04e12b33f4ac2fba86c834661f85c55f8321fddcfda9ac97f749a88ef10d1645bbac0e0bca5491b0fa46226aa83ba868a77e4b
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Codebreaker
2
2
 
3
- This pearl contains the business logic for codebreaker game.
3
+ This gem contains the business logic for codebreaker game.
4
4
 
5
5
  ## Installation
6
6
 
@@ -4,8 +4,9 @@ require_relative 'alex_codebreaker/version'
4
4
  require_relative 'alex_codebreaker/modules/files'
5
5
  require_relative 'alex_codebreaker/modules/settings'
6
6
  require_relative 'alex_codebreaker/modules/difficulty_levels'
7
- require_relative 'alex_codebreaker/modules/validators/validators'
8
- require_relative 'alex_codebreaker/modules/validators/arguments_validation'
7
+ require_relative 'alex_codebreaker/modules/validators'
8
+ require_relative 'alex_codebreaker/modules/arguments_validation'
9
+ require_relative 'alex_codebreaker/secret_code_generator'
9
10
  require_relative 'alex_codebreaker/players_rating'
10
11
  require_relative 'alex_codebreaker/session'
11
12
  require_relative 'alex_codebreaker/game'
@@ -1,87 +1,72 @@
1
- require_relative 'modules/validators/arguments_validation'
1
+ module AlexCodebreaker
2
+ class Game
3
+ include AlexCodebreaker::Modules::ArgumentsValidation
2
4
 
3
- class Game
4
- include ArgumentsValidation
5
+ attr_reader :secret_code, :session, :win_status
5
6
 
6
- attr_reader :session, :win_status
7
-
8
- def initialize
9
- @secret_code = Array.new(Settings::CODE_LENGTH) { rand(Settings::CODE_MIN_DIGIT..Settings::CODE_MAX_DIGIT) }
10
- @session = Session.new
11
- @win_status = false
12
- end
13
-
14
- def add_player_name(given_name)
15
- name_validation(given_name) ? @session.player_name = given_name : false
16
- end
17
-
18
- def choose_difficulty(chosen_difficulty)
19
- @session.difficulty_manager(chosen_difficulty.to_sym)
20
- end
21
-
22
- def hint
23
- return false if @session.hints_used >= @session.hints_total
24
-
25
- @session.hints_used += 1
26
- @secret_code_for_hint ||= @secret_code.clone.uniq
27
- @secret_code_for_hint.delete(@secret_code_for_hint.sample)
28
- end
29
-
30
- def guess(user_input)
31
- return false if !guess_validation(user_input) || check_attempts
7
+ def initialize
8
+ @secret_code = AlexCodebreaker::SecretCodeGenerator.new.secret_code
9
+ @secret_code_for_hint = @secret_code.clone.uniq
10
+ @session = Session.new
11
+ end
32
12
 
33
- @session.attempts_used += 1
34
- @win_status = true if user_input.to_i == @secret_code.join.to_i
35
- comparator(user_input)
36
- end
13
+ def hint
14
+ return unless @session.check_hints
37
15
 
38
- def check_attempts
39
- @session.attempts_used >= @session.attempts_total
40
- end
16
+ hint_processing
17
+ end
41
18
 
42
- def save_game
43
- @session.save_session_statistic if @win_status
44
- end
19
+ def guess(user_input)
20
+ return unless guess_validation(user_input) && @session.check_attempts
45
21
 
46
- def show_secret_code
47
- @secret_code.join
48
- end
22
+ comparator(user_input)
23
+ end
49
24
 
50
- private
25
+ private
51
26
 
52
- def comparator(user_input)
53
- user_input = user_input.chars.map!(&:to_i)
54
- @secret_code_for_comparison = @secret_code.clone
55
- user_input = matching_numbers_and_indexes(user_input)
27
+ def hint_processing
28
+ return @secret_code_for_hint.first if @secret_code_for_hint.one?
56
29
 
57
- user_input = matching_only_numbers(user_input).sort
30
+ @secret_code_for_hint.delete(@secret_code_for_hint.sample)
31
+ end
58
32
 
59
- user_input.rotate(user_input.count(Settings::MATCHING[:absent])).join
60
- end
33
+ def comparator(user_input)
34
+ user_input = user_input.chars.map!(&:to_i)
35
+ secret_code_for_comparison = @secret_code.clone
36
+ user_input = matching_numbers_and_indexes(user_input, secret_code_for_comparison).compact
37
+ user_input = matching_only_numbers(user_input, secret_code_for_comparison).compact
38
+ matching_absent(user_input)
39
+ end
61
40
 
62
- def matching_numbers_and_indexes(user_input)
63
- user_input.map.with_index do |value, index|
64
- if value == @secret_code_for_comparison[index]
65
- @secret_code_for_comparison[index] = nil
66
- Settings::MATCHING[:place]
67
- elsif !@secret_code_for_comparison.include?(value)
68
- Settings::MATCHING[:absent]
69
- else
70
- value
41
+ def matching_numbers_and_indexes(user_input, secret_code_for_comparison)
42
+ user_input.map.with_index do |value, index|
43
+ if value == secret_code_for_comparison[index]
44
+ secret_code_for_comparison[index] = nil
45
+ AlexCodebreaker::Modules::Settings::MATCHING[:place]
46
+ else
47
+ value
48
+ end
71
49
  end
72
50
  end
73
- end
74
51
 
75
- def matching_only_numbers(user_input)
76
- user_input.map do |value|
77
- if @secret_code_for_comparison.include?(value)
78
- @secret_code_for_comparison.delete_at(@secret_code_for_comparison.index(value))
79
- Settings::MATCHING[:presence]
80
- elsif [Settings::MATCHING[:place], Settings::MATCHING[:absent]].include?(value)
81
- value
82
- else
83
- Settings::MATCHING[:absent]
52
+ def matching_only_numbers(user_input, secret_code_for_comparison)
53
+ user_input.map do |value|
54
+ if secret_code_for_comparison.include?(value)
55
+ secret_code_for_comparison.delete_at(secret_code_for_comparison.index(value))
56
+ AlexCodebreaker::Modules::Settings::MATCHING[:presence]
57
+ elsif value == AlexCodebreaker::Modules::Settings::MATCHING[:place]
58
+ value
59
+ end
84
60
  end
85
61
  end
62
+
63
+ def matching_absent(user_input)
64
+ AlexCodebreaker::Modules::Settings::MATCHING[:place] *
65
+ user_input.count(AlexCodebreaker::Modules::Settings::MATCHING[:place]) +
66
+ AlexCodebreaker::Modules::Settings::MATCHING[:presence] *
67
+ user_input.count(AlexCodebreaker::Modules::Settings::MATCHING[:presence]) +
68
+ AlexCodebreaker::Modules::Settings::MATCHING[:absent] *
69
+ (AlexCodebreaker::Modules::Settings::CODE_LENGTH - user_input.length)
70
+ end
86
71
  end
87
72
  end
@@ -0,0 +1,17 @@
1
+ module AlexCodebreaker
2
+ module Modules
3
+ module ArgumentsValidation
4
+ include AlexCodebreaker::Modules::Validators
5
+ def name_validation(name)
6
+ argument_min_length_check(name, AlexCodebreaker::Modules::Settings::MIN_PLAYER_NAME_LENGTH) &&
7
+ argument_max_length_check(name, AlexCodebreaker::Modules::Settings::MAX_PLAYER_NAME_LENGTH)
8
+ end
9
+
10
+ def guess_validation(guess)
11
+ argument_length_check(guess, AlexCodebreaker::Modules::Settings::CODE_LENGTH) &&
12
+ digits_check(guess, AlexCodebreaker::Modules::Settings::CODE_MIN_DIGIT,
13
+ AlexCodebreaker::Modules::Settings::CODE_MAX_DIGIT)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,22 +1,26 @@
1
- module DifficultyLevels
2
- DIFFICULTY_LEVELS = {
3
- Easy: {
4
- name: :Easy,
5
- level: 0,
6
- attempts_total: 15,
7
- hints_total: 2
8
- },
9
- Medium: {
10
- name: :medium,
11
- level: 1,
12
- attempts_total: 10,
13
- hints_total: 1
14
- },
15
- Hell: {
16
- name: :hell,
17
- level: 2,
18
- attempts_total: 5,
19
- hints_total: 1
20
- }
21
- }.freeze
1
+ module AlexCodebreaker
2
+ module Modules
3
+ module DifficultyLevels
4
+ DIFFICULTY_LEVELS = {
5
+ easy: {
6
+ name: 'Easy',
7
+ level: 0,
8
+ attempts_total: 15,
9
+ hints_total: 2
10
+ },
11
+ medium: {
12
+ name: 'Medium',
13
+ level: 1,
14
+ attempts_total: 10,
15
+ hints_total: 1
16
+ },
17
+ hell: {
18
+ name: 'Hell',
19
+ level: 2,
20
+ attempts_total: 5,
21
+ hints_total: 1
22
+ }
23
+ }.freeze
24
+ end
25
+ end
22
26
  end
@@ -1,3 +1,7 @@
1
- module Files
2
- STATS_FILE = 'stats.yml'.freeze
1
+ module AlexCodebreaker
2
+ module Modules
3
+ module Files
4
+ STATS_FILE = 'stats.yml'.freeze
5
+ end
6
+ end
3
7
  end
@@ -1,8 +1,12 @@
1
- module Settings
2
- MATCHING = { place: '+', presence: '-', absent: ' ' }.freeze
3
- CODE_MIN_DIGIT = 1
4
- CODE_MAX_DIGIT = 6
5
- CODE_LENGTH = 4
6
- MIN_PLAYER_NAME_LENGTH = 3
7
- MAX_PLAYER_NAME_LENGTH = 20
1
+ module AlexCodebreaker
2
+ module Modules
3
+ module Settings
4
+ MATCHING = { place: '+', presence: '-', absent: ' ' }.freeze
5
+ CODE_MIN_DIGIT = 1
6
+ CODE_MAX_DIGIT = 6
7
+ CODE_LENGTH = 4
8
+ MIN_PLAYER_NAME_LENGTH = 3
9
+ MAX_PLAYER_NAME_LENGTH = 20
10
+ end
11
+ end
8
12
  end
@@ -0,0 +1,21 @@
1
+ module AlexCodebreaker
2
+ module Modules
3
+ module Validators
4
+ def argument_length_check(arg, length)
5
+ arg.to_s.length == length
6
+ end
7
+
8
+ def argument_max_length_check(arg, max)
9
+ arg.length <= max
10
+ end
11
+
12
+ def argument_min_length_check(arg, min)
13
+ arg.length >= min
14
+ end
15
+
16
+ def digits_check(arg, min_digit, max_digit)
17
+ arg.split('').all? { |value| value.to_i.between?(min_digit, max_digit) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,26 +1,29 @@
1
- class PlayersRating
2
- attr_accessor :stats
1
+ module AlexCodebreaker
2
+ class PlayersRating
3
+ attr_accessor :stats
3
4
 
4
- def initialize
5
- stats_loader
6
- end
5
+ def initialize
6
+ @stats = []
7
+ stats_loader
8
+ end
7
9
 
8
- private
10
+ private
9
11
 
10
- def stats_loader
11
- return @stats = false unless File.exist?(Files::STATS_FILE)
12
+ def stats_loader
13
+ return unless File.exist?(AlexCodebreaker::Modules::Files::STATS_FILE)
12
14
 
13
- load_stats
14
- sort_players_rating
15
- end
15
+ load_stats
16
+ sort_players_rating
17
+ end
16
18
 
17
- def load_stats
18
- File.open(Files::STATS_FILE) do |file|
19
- @stats = Array.new(Psych.load_stream(file))
19
+ def load_stats
20
+ File.open(AlexCodebreaker::Modules::Files::STATS_FILE) do |file|
21
+ @stats = Array.new(Psych.load_stream(file))
22
+ end
20
23
  end
21
- end
22
24
 
23
- def sort_players_rating
24
- @stats.sort_by! { |value| [-value.difficulty_level, value.attempts_used, value.hints_used] }
25
+ def sort_players_rating
26
+ @stats.sort_by! { |value| [-value.difficulty_level, value.attempts_used, value.hints_used] }
27
+ end
25
28
  end
26
29
  end
@@ -0,0 +1,17 @@
1
+ module AlexCodebreaker
2
+ class SecretCodeGenerator
3
+ attr_reader :secret_code
4
+
5
+ def initialize
6
+ @secret_code = generate_secret_code
7
+ end
8
+
9
+ private
10
+
11
+ def generate_secret_code
12
+ Array.new(AlexCodebreaker::Modules::Settings::CODE_LENGTH) do
13
+ rand(AlexCodebreaker::Modules::Settings::CODE_MIN_DIGIT..AlexCodebreaker::Modules::Settings::CODE_MAX_DIGIT)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,34 +1,47 @@
1
- class Session
2
- INITIAL_ATTEMPTS_USED = 0
3
- INITIAL_HINTS_USED = 0
1
+ module AlexCodebreaker
2
+ class Session
3
+ include AlexCodebreaker::Modules::ArgumentsValidation
4
4
 
5
- attr_accessor :player_name, :attempts_used, :hints_used, :hints_total,
5
+ INITIAL_ATTEMPTS_USED = 0
6
+ INITIAL_HINTS_USED = 0
7
+
8
+ attr_reader :hints_used, :attempts_used, :player_name, :hints_total,
6
9
  :difficulty_name, :attempts_total, :difficulty_level
7
10
 
8
- def initialize
9
- @attempts_used = INITIAL_ATTEMPTS_USED
10
- @hints_used = INITIAL_HINTS_USED
11
- end
11
+ def initialize
12
+ @attempts_used = INITIAL_ATTEMPTS_USED
13
+ @hints_used = INITIAL_HINTS_USED
14
+ end
12
15
 
13
- def difficulty_manager(difficulty)
14
- if DifficultyLevels::DIFFICULTY_LEVELS.include?(difficulty)
15
- add_difficulty(DifficultyLevels::DIFFICULTY_LEVELS[difficulty])
16
+ def add_name(given_name)
17
+ @player_name = given_name if name_validation(given_name)
16
18
  end
17
- return false unless DifficultyLevels::DIFFICULTY_LEVELS.include?(difficulty)
18
- end
19
19
 
20
- def save_session_statistic
21
- File.open(Files::STATS_FILE, 'a') do |file|
22
- file.write(to_yaml)
20
+ def add_difficulty(difficulty)
21
+ return unless AlexCodebreaker::Modules::DifficultyLevels::DIFFICULTY_LEVELS.include?(difficulty.downcase.to_sym)
22
+
23
+ difficulty(AlexCodebreaker::Modules::DifficultyLevels::DIFFICULTY_LEVELS[difficulty.downcase.to_sym])
23
24
  end
24
- end
25
25
 
26
- private
26
+ def check_hints
27
+ @hints_used += 1 if @hints_used < @hints_total
28
+ end
27
29
 
28
- def add_difficulty(difficulty)
29
- @difficulty_name = difficulty[:name]
30
- @difficulty_level = difficulty[:level]
31
- @attempts_total = difficulty[:attempts_total]
32
- @hints_total = difficulty[:hints_total]
30
+ def check_attempts
31
+ @attempts_used += 1 if @attempts_used < @attempts_total - 1
32
+ end
33
+
34
+ def save_statistic
35
+ File.open(AlexCodebreaker::Modules::Files::STATS_FILE, 'a') { |file| file.write(to_yaml) }
36
+ end
37
+
38
+ private
39
+
40
+ def difficulty(difficulty)
41
+ @difficulty_name = difficulty[:name]
42
+ @difficulty_level = difficulty[:level]
43
+ @attempts_total = difficulty[:attempts_total]
44
+ @hints_total = difficulty[:hints_total]
45
+ end
33
46
  end
34
47
  end
@@ -1,3 +1,5 @@
1
1
  module AlexCodebreaker
2
- VERSION = '0.1.6'.freeze
2
+ module Version
3
+ VERSION = '0.1.7'.freeze
4
+ end
3
5
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alex_codebreaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleksandr Loza
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-09 00:00:00.000000000 Z
11
+ date: 2019-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: i18n
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.7'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.7'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +136,20 @@ dependencies:
150
136
  - - "~>"
151
137
  - !ruby/object:Gem::Version
152
138
  version: 0.17.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: solargraph
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.38.0
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.38.0
153
153
  description: Codebreaker game business logic
154
154
  email:
155
155
  - alexwebq@gmail.com
@@ -161,12 +161,13 @@ files:
161
161
  - README.md
162
162
  - lib/alex_codebreaker.rb
163
163
  - lib/alex_codebreaker/game.rb
164
+ - lib/alex_codebreaker/modules/arguments_validation.rb
164
165
  - lib/alex_codebreaker/modules/difficulty_levels.rb
165
166
  - lib/alex_codebreaker/modules/files.rb
166
167
  - lib/alex_codebreaker/modules/settings.rb
167
- - lib/alex_codebreaker/modules/validators/arguments_validation.rb
168
- - lib/alex_codebreaker/modules/validators/validators.rb
168
+ - lib/alex_codebreaker/modules/validators.rb
169
169
  - lib/alex_codebreaker/players_rating.rb
170
+ - lib/alex_codebreaker/secret_code_generator.rb
170
171
  - lib/alex_codebreaker/session.rb
171
172
  - lib/alex_codebreaker/version.rb
172
173
  homepage: https://github.com/Alexwell/codebreaker/tree/feature/initial-gem-settings
@@ -1,13 +0,0 @@
1
- module ArgumentsValidation
2
- include Validators
3
-
4
- def name_validation(name)
5
- argument_min_length_check(name, Settings::MIN_PLAYER_NAME_LENGTH) && \
6
- argument_max_length_check(name, Settings::MAX_PLAYER_NAME_LENGTH)
7
- end
8
-
9
- def guess_validation(guess)
10
- argument_fixed_length_check(guess, Settings::CODE_LENGTH) && \
11
- digits_check(guess, min_digit: Settings::CODE_MIN_DIGIT, max_digit: Settings::CODE_MAX_DIGIT)
12
- end
13
- end
@@ -1,17 +0,0 @@
1
- module Validators
2
- def argument_fixed_length_check(arg, fixed_length)
3
- arg.to_s.length == fixed_length
4
- end
5
-
6
- def argument_max_length_check(arg, max)
7
- arg.length <= max
8
- end
9
-
10
- def argument_min_length_check(arg, min)
11
- arg.length >= min
12
- end
13
-
14
- def digits_check(arg, min_digit: 1, max_digit: 6)
15
- arg.to_s.split('').map { |value| value unless value.to_i.between?(min_digit, max_digit) }.compact.empty?
16
- end
17
- end