alex_codebreaker 0.1.6 → 0.1.7

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