code_brkr_game_training 0.7.2 → 0.9.2

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: b318c26b1c0fbbb3f410d204862100077cc1211f4a6fbd3f2c191e13e4418764
4
- data.tar.gz: 882dab2737baf0cdcb0c8d182f09b8a6a59612ed7b1fc1208336265b6f1d3ef2
3
+ metadata.gz: 8b837f5597a2519c21d96c308356ca46b0355b44cd663ad7b37bb170663353d8
4
+ data.tar.gz: 246fa97e39ea81dd95359fe7e3924cf7326aab07f7e8c10e7caace93bd7c325e
5
5
  SHA512:
6
- metadata.gz: 0b214b380fa55616ad912eb09f09c8cdb9c5796174af14dc17d837f78badf62720bb2b4e02bfb0455703be2f8e0f5f6f2795f186308036a1dc1073e4a5ed1eed
7
- data.tar.gz: 5fa53619996367d8de6a0befbf8477421e86bfcaddf31119d156774580c78e8ad9aa02c44011ea30c1dfdc93803b88cd5ad6a03439184ac1f67429f6f53087f6
6
+ metadata.gz: ed45190ae59db6543caf8b05189866fb5755920289dc04653715922fec64a2c7482e5e91382d84a0c478db63adf270bffee3229a2a81d0c52b4f253912f279fa
7
+ data.tar.gz: e628ce71dc943192feb7dfa8d26bd9a343d0660cfde56f11ccd233d828d2218cfb93160f2587ae868aa4a2ab9506f6569cc9db723f41fab35ff31d5c9eb389a8
data/.gitignore CHANGED
@@ -6,7 +6,8 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
- /code_brkr_game_training/data/
9
+ *.gem
10
+
10
11
 
11
12
 
12
13
  # rspec failure tracking
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- code_brkr_game_training (0.7.2)
4
+ code_brkr_game_training (0.9.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
+ require 'date'
4
5
 
5
6
  require_relative '../version'
6
7
  require_relative '../modules/file_operations'
@@ -9,6 +10,7 @@ require_relative '../modules/validator'
9
10
 
10
11
  require_relative '../entities/user'
11
12
  require_relative '../entities/difficulty_controller'
13
+ require_relative '../entities/code_comparator'
12
14
  require_relative '../entities/code'
13
15
  require_relative '../modules/statistics'
14
16
  require_relative '../entities/game'
@@ -4,12 +4,10 @@
4
4
  module CodeBrkrGameTraining
5
5
  # Class class for storage and operations with secret code
6
6
  class Code
7
- include Validator
8
-
9
7
  GAME_NUMBERS = { from: 1, to: 6, count: 4 }.freeze
10
8
 
11
9
  def initialize
12
- @secret_digit_arr = code_generator
10
+ @secret_digit_arr = generate_code
13
11
  end
14
12
 
15
13
  def to_s
@@ -17,43 +15,18 @@ module CodeBrkrGameTraining
17
15
  end
18
16
 
19
17
  def code_check(user_digits_arr)
20
- check_array_code_format(user_digits_arr)
21
- alg_result = code_check_algorithm(@secret_digit_arr.clone, user_digits_arr)
22
- result = {
23
- in_position: GAME_NUMBERS[:count] - alg_result[:miss_indexes].length,
24
- out_of_position: alg_result[:out_of_positions].length
25
- }
26
- result[:not_guessed] = GAME_NUMBERS[:count] - result[:in_position] - result[:out_of_position]
27
- result
18
+ CodeComparator.new(@secret_digit_arr, user_digits_arr).compare_codes
28
19
  end
29
20
 
30
- def random_secret_digit_according_indexes(exclude_indexes)
21
+ def random_digit(exclude_indexes)
31
22
  rand_index = @secret_digit_arr.each_index.reject { |index| exclude_indexes.include? index }.sample
32
23
  { index: rand_index, digit: @secret_digit_arr[rand_index] }
33
24
  end
34
25
 
35
26
  private
36
27
 
37
- def code_generator
28
+ def generate_code
38
29
  Array.new(GAME_NUMBERS[:count]) { rand(GAME_NUMBERS[:from]..GAME_NUMBERS[:to]) }
39
30
  end
40
-
41
- def check_array_code_format(code_arr)
42
- check_type(code_arr, Array)
43
- raise GameError, 'incorrect_code_format' unless code_arr.size == GAME_NUMBERS[:count]
44
-
45
- digits_range_arr = (GAME_NUMBERS[:from]..GAME_NUMBERS[:to]).to_a
46
- code_arr.each { |digit| raise GameError, 'incorrect_code_format' unless digits_range_arr.member? digit }
47
- end
48
-
49
- def code_check_algorithm(system_arr, user_arr)
50
- miss_indexes_arr = user_arr.each_index.reject { |user_index| user_arr[user_index] == system_arr[user_index] }
51
- system_arr.select!.with_index { |_, sys_index| miss_indexes_arr.include? sys_index }
52
- out_of_positions = miss_indexes_arr.collect do |miss_index|
53
- found = system_arr.find_index { |sys_num| user_arr[miss_index] == sys_num }
54
- found.nil? ? nil : system_arr.delete_at(found)
55
- end
56
- { miss_indexes: miss_indexes_arr, out_of_positions: out_of_positions.compact }
57
- end
58
31
  end
59
32
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Main Gem module
4
+ module CodeBrkrGameTraining
5
+ # Class for comparing the hidden code and the code entered by the user
6
+ class CodeComparator
7
+ include Validator
8
+
9
+ def initialize(secret_code, user_code)
10
+ check_code_format(user_code)
11
+
12
+ @secret_code = secret_code
13
+ @user_code = user_code
14
+ end
15
+
16
+ def compare_codes
17
+ {
18
+ in_positions: check_in_positions,
19
+ out_of_positions: check_out_positions,
20
+ not_guessed: check_not_guessed
21
+ }
22
+ end
23
+
24
+ private
25
+
26
+ def check_code_format(code)
27
+ check_type(code, Array)
28
+ raise GameError, 'incorrect_code_format' unless code.size == Code::GAME_NUMBERS[:count]
29
+
30
+ digits_range_array = (Code::GAME_NUMBERS[:from]..Code::GAME_NUMBERS[:to]).to_a
31
+ code.each { |digit| raise GameError, 'incorrect_code_format' unless digits_range_array.member? digit }
32
+ end
33
+
34
+ def check_miss_indexes
35
+ @check_miss_indexes ||= Code::GAME_NUMBERS[:count].times.reject do |user_index|
36
+ @user_code[user_index] == @secret_code[user_index]
37
+ end
38
+ end
39
+
40
+ def check_in_positions
41
+ @check_in_positions ||= Code::GAME_NUMBERS[:count] - check_miss_indexes.length
42
+ end
43
+
44
+ def check_out_positions
45
+ return @check_out_positions if @check_out_positions
46
+
47
+ miss_indexes = check_miss_indexes
48
+ system_digits = @secret_code.select.with_index { |_, system_index| miss_indexes.include? system_index }
49
+ @check_out_positions = miss_indexes.collect do |miss_index|
50
+ found = system_digits.find_index { |system_num| @user_code[miss_index] == system_num }
51
+ found.nil? ? nil : system_digits.delete_at(found)
52
+ end.compact.length
53
+ end
54
+
55
+ def check_not_guessed
56
+ Code::GAME_NUMBERS[:count] - check_in_positions - check_out_positions
57
+ end
58
+ end
59
+ end
@@ -7,25 +7,18 @@ module CodeBrkrGameTraining
7
7
  include Validator
8
8
 
9
9
  GAME_DIFFICULTIES = {
10
- easy: { name: 'easy', attempts: 15, hints: 2 },
10
+ hell: { name: 'hell', attempts: 5, hints: 1 },
11
11
  medium: { name: 'medium', attempts: 10, hints: 1 },
12
- hell: { name: 'hell', attempts: 5, hints: 1 }
12
+ easy: { name: 'easy', attempts: 15, hints: 2 }
13
13
  }.freeze
14
14
 
15
15
  attr_reader :init_values, :actual_values
16
16
 
17
- def self.difficulty_levels_order
18
- GAME_DIFFICULTIES
19
- .values
20
- .sort_by { |difficulty| [difficulty[:attempts], difficulty[:hints]] }
21
- .collect { |difficulty| difficulty[:name] }
22
- end
23
-
24
- def initialize(dfclt_val)
25
- @value_name = dfclt_val
17
+ def initialize(difficulty_value)
18
+ @value_name = difficulty_value
26
19
  validate
27
20
 
28
- @init_values = GAME_DIFFICULTIES[dfclt_val.to_sym]
21
+ @init_values = GAME_DIFFICULTIES[difficulty_value.to_sym]
29
22
  @actual_values = @init_values.clone
30
23
  end
31
24
 
@@ -22,9 +22,9 @@ module CodeBrkrGameTraining
22
22
  end
23
23
 
24
24
  def code_guessing_attempt(digits_arr)
25
- @difficulty.guessing_attempts_decrement!
26
25
  result = @code.code_check(digits_arr)
27
- if result[:in_position] == Code::GAME_NUMBERS[:count]
26
+ @difficulty.guessing_attempts_decrement!
27
+ if result[:in_positions] == Code::GAME_NUMBERS[:count]
28
28
  result = { win: true }
29
29
  elsif !@difficulty.guessing_attempts_available?
30
30
  result = { loss: true, сorrect_answer: @code.to_s }
@@ -34,7 +34,7 @@ module CodeBrkrGameTraining
34
34
 
35
35
  def game_hint
36
36
  @difficulty.hints_decrement!
37
- hint = @code.random_secret_digit_according_indexes(@hints_indexes)
37
+ hint = @code.random_digit(@hints_indexes)
38
38
  @hints_indexes << hint[:index]
39
39
  hint[:digit]
40
40
  end
@@ -4,14 +4,16 @@
4
4
  module CodeBrkrGameTraining
5
5
  # Module for file operations
6
6
  module FileOperations
7
- def save_to_file(data, path)
8
- yml = YAML.dump(data)
9
- File.open(path, 'a') { |yml_file| yml_file.write(yml) }
7
+ def save_to_file(**args)
8
+ ensuring_directory_availability args[:directory]
9
+
10
+ yml = YAML.dump(args[:data])
11
+ File.open(File.join(args[:directory], args[:file]), 'a') { |yml_file| yml_file.write(yml) }
10
12
  end
11
13
 
12
- def load_from_file(path)
14
+ def load_from_file(directory, file)
13
15
  begin
14
- yml_data = File.open(path, &:read)
16
+ yml_data = File.open(File.join(directory, file), &:read)
15
17
  rescue Errno::ENOENT
16
18
  yml_data = ''
17
19
  end
@@ -20,5 +22,11 @@ module CodeBrkrGameTraining
20
22
  yml_data
21
23
  )
22
24
  end
25
+
26
+ private
27
+
28
+ def ensuring_directory_availability(directory)
29
+ Dir.mkdir(directory) unless Dir.exist?(directory)
30
+ end
23
31
  end
24
32
  end
@@ -4,27 +4,29 @@
4
4
  module CodeBrkrGameTraining
5
5
  # Module for game stats
6
6
  module Statistics
7
- STATISTICS_FILE_PATH = File.dirname(File.expand_path(__FILE__)) + '/../data/game_stats.yml'
7
+ # STATISTICS_FILE_PATH = File.dirname(File.expand_path(__FILE__)) + '/../data/game_stats.yml'
8
+ SAVE_DIRECTORY = 'data'
9
+ SAVE_FILE = 'game_stats.yml'
8
10
 
9
11
  def save_game_results!(user, difficulty)
10
12
  difficulty_init = difficulty.init_values
11
13
  difficulty_actual = difficulty.actual_values
12
14
  game_session = {
13
- name: user.name, difficulty: difficulty_init[:name],
15
+ name: user.name, time: DateTime.now, difficulty: difficulty_init[:name],
14
16
  attempts_total: difficulty_init[:attempts], hints_total: difficulty_init[:hints]
15
17
  }
16
18
  game_session[:attempts_used] = game_session[:attempts_total] - difficulty_actual[:attempts]
17
19
  game_session[:hints_used] = game_session[:hints_total] - difficulty_actual[:hints]
18
- save_to_file(game_session, STATISTICS_FILE_PATH)
20
+ save_to_file(data: game_session, directory: SAVE_DIRECTORY, file: SAVE_FILE)
19
21
  end
20
22
 
21
23
  def full_statistics
22
- games_array = load_from_file(STATISTICS_FILE_PATH)
24
+ games_array = load_from_file(SAVE_DIRECTORY, SAVE_FILE)
23
25
  return games_array if games_array.empty?
24
26
 
25
- difficulty_order = DifficultyController.difficulty_levels_order
27
+ difficulty_order = DifficultyController::GAME_DIFFICULTIES.keys
26
28
  games_array.sort_by do |game|
27
- [difficulty_order.index(game[:difficulty]), game[:attempts_used], game[:hints_used]]
29
+ [difficulty_order.index(game[:difficulty].to_sym), game[:attempts_used], game[:hints_used]]
28
30
  end
29
31
  end
30
32
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # The main module is re-opened here for declaring gem version
4
4
  module CodeBrkrGameTraining
5
- VERSION = '0.7.2'
5
+ VERSION = '0.9.2'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_brkr_game_training
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-25 00:00:00.000000000 Z
11
+ date: 2020-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fasterer
@@ -131,8 +131,8 @@ files:
131
131
  - lefthook.yml
132
132
  - lib/code_brkr_game_training.rb
133
133
  - lib/code_brkr_game_training/bootstrap/autoloader.rb
134
- - lib/code_brkr_game_training/data/.keep
135
134
  - lib/code_brkr_game_training/entities/code.rb
135
+ - lib/code_brkr_game_training/entities/code_comparator.rb
136
136
  - lib/code_brkr_game_training/entities/difficulty_controller.rb
137
137
  - lib/code_brkr_game_training/entities/game.rb
138
138
  - lib/code_brkr_game_training/entities/user.rb
File without changes