andrii_codebreaker 0.1.2 → 0.1.3

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: d4ca52214a921ea9b0fc78992ef7d0da364089eaabc37c822ec6684df7246d70
4
- data.tar.gz: '089d9d9c55bab90acbb98810ee30fb98d7f25fe5871364afa928fae5c370db5e'
3
+ metadata.gz: e172f73161a1701928e49af4747bcb8f85867ef2c9a135fb04488774b542b9b0
4
+ data.tar.gz: e30f119ccda4eeafdb8b9904b9f20e3b748bcbdbaa5456429c2d18a012ae00b5
5
5
  SHA512:
6
- metadata.gz: ade917c605ff8db3c1f8f29b601773787b0c696f3c09eedb861692700407449849dee930e7bcef60d5457b449f9198fc6617d612a61bb6cbf7283f39f55733eb
7
- data.tar.gz: a31d77642798e00747a315979bb2e544e0a66ac56574edc596711809d9b3865625fefda5b02bd1a22ab3cb19975e2fbd4ed736d98bdda13b1423f6ae4f5a7e98
6
+ metadata.gz: d6b1f4b5af1f965f5bce17e022948005851bfd688c1b2a9de73d69f135a0be932cd15c9e1793da4772abdb62a2f97e31c89f967b0b37a86cd66bae093291fa6b
7
+ data.tar.gz: c0a7e048a4d875e0d65166de7354f5e67d439a929f0763b67ec3b9c40f88c9b89b77299a2d5618a06a024d914cefaf4f60062671897aa375d30f3778ecfd2e1a
data/.gitignore CHANGED
@@ -1,10 +1,3 @@
1
1
  /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
2
  /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
3
  .rspec_status
data/.rubocop.yml CHANGED
@@ -7,9 +7,6 @@ AllCops:
7
7
  Style/Documentation:
8
8
  Enabled: false
9
9
 
10
- Style/FrozenStringLiteralComment:
11
- Enabled: false
12
-
13
10
  Metrics/LineLength:
14
11
  Max: 120
15
12
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
data/Gemfile.lock CHANGED
@@ -1,21 +1,29 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- andrii_codebreaker (0.1.1)
4
+ andrii_codebreaker (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
+ coderay (1.1.3)
10
11
  colorize (0.8.1)
12
+ concurrent-ruby (1.1.9)
11
13
  diff-lcs (1.4.4)
12
14
  docile (1.4.0)
13
15
  fasterer (0.9.0)
14
16
  colorize (~> 0.7)
15
17
  ruby_parser (>= 3.14.1)
18
+ i18n (1.8.11)
19
+ concurrent-ruby (~> 1.0)
20
+ method_source (1.0.0)
16
21
  parallel (1.21.0)
17
22
  parser (3.0.2.0)
18
23
  ast (~> 2.4.1)
24
+ pry (0.14.1)
25
+ coderay (~> 1.1)
26
+ method_source (~> 1.0)
19
27
  rainbow (3.0.0)
20
28
  rake (13.0.6)
21
29
  regexp_parser (2.1.1)
@@ -64,6 +72,8 @@ PLATFORMS
64
72
  DEPENDENCIES
65
73
  andrii_codebreaker!
66
74
  fasterer
75
+ i18n
76
+ pry
67
77
  rake
68
78
  rspec
69
79
  rubocop
data/Rakefile CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  task default: :spec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require './lib/andrii_codebreaker/version'
2
4
  lib = File.expand_path('lib', __dir__)
3
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
@@ -18,6 +20,7 @@ Gem::Specification.new do |spec|
18
20
  spec.metadata['source_code_uri'] = spec.homepage
19
21
 
20
22
  spec.add_development_dependency 'fasterer'
23
+ spec.add_development_dependency 'i18n'
21
24
  spec.add_development_dependency 'rake'
22
25
  spec.add_development_dependency 'rspec'
23
26
  spec.add_development_dependency 'rubocop'
data/bin/console CHANGED
@@ -1,15 +1,5 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
1
  require 'bundler/setup'
5
2
  require 'andrii_codebreaker'
6
3
 
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
4
  require 'irb'
15
5
  IRB.start(__FILE__)
data/config/i18n.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ I18n.config.load_path << Dir[File.expand_path('config/locales').concat('/*.yml')]
@@ -0,0 +1,5 @@
1
+ en:
2
+ start: start
3
+ rules: rules
4
+ stats: stats
5
+ exit: exit
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AndriiCodebreaker
4
+ module Constant
5
+ NAME_MIN_LENGTH = 3
6
+ NAME_MAX_LENGTH = 20
7
+ CODE_START_LENGTH = 1
8
+ CODE_LENGTH = 6
9
+ CODE_LENGTH_COUNT = 4
10
+ DIFFICULTY = {
11
+ easy: { attempts: 15, hints: 2 },
12
+ medium: { attempts: 10, hints: 1 },
13
+ hell: { attempts: 5, hints: 1 }
14
+ }.freeze
15
+ DIFFICULTY_SORT = { easy: 1, medium: 2, hell: 3 }.freeze
16
+ end
17
+ end
@@ -1,87 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../andrii_codebreaker'
4
+ require_relative '../../config/i18n'
5
+
1
6
  module AndriiCodebreaker
2
7
  class Game
3
8
  include Validate
4
- include Model
5
9
  include Statistic
6
- attr_reader :secret_code
7
- attr_accessor :secret_code_copy
10
+ include Constant
11
+
12
+ attr_reader :player_name, :difficulty, :attempts_total, :hints_total, :secret_code
13
+ attr_accessor :hints_left, :attempts_left
8
14
 
9
15
  CONST_COMMAND = {
10
- start: 'start',
11
- rules: 'rules',
12
- stats: 'stats',
13
- exit: 'exit'
16
+ start: I18n.t('start'),
17
+ rules: I18n.t('rules'),
18
+ stats: I18n.t('stats'),
19
+ exit: I18n.t('exit')
14
20
  }.freeze
15
21
 
16
- WIN_MATRIX = ['+', '+', '+', '+'].freeze
17
-
18
- def initialize
19
- @secret_code = generate_code
20
- @secret_code_copy = @secret_code.dup
22
+ def initialize(player_name, difficulty)
23
+ @player_name = player_name
24
+ @difficulty = difficulty
25
+ @attempts_left = 0
26
+ @hints_left = 0
27
+ initialize_class
21
28
  end
22
29
 
23
- def hints(user)
24
- return unless user.hints_total > user.hints_now
25
-
26
- user.hints_now += 1
27
- @secret_code_copy.pop
30
+ def initialize_class
31
+ difficult = DIFFICULTY[@difficulty.to_sym]
32
+ @hints_total = difficult[:hints]
33
+ @attempts_total = difficult[:attempts]
34
+ @secret_code = generate_code
28
35
  end
29
36
 
30
- def compare_codes(user_code)
31
- matches, user_code, code_copy = right_place(user_code)
32
- number_secret_code(user_code, matches, code_copy)
37
+ def show_hints
38
+ hints_left
33
39
  end
34
40
 
35
- def string_to_integer(input_code)
36
- array_int = []
37
- array_chars = input_code.chars
38
- array_chars.each { |i| array_int << i.to_i }
39
- array_int
40
- end
41
+ def compare_codes(guess)
42
+ return '++++' if exact_match(guess)
41
43
 
42
- def save_result(user, file)
43
- save(user, file)
44
+ ('+' * pluses(guess)) + ('-' * minuses(guess))
44
45
  end
45
46
 
46
47
  private
47
48
 
48
- def right_place(user_code)
49
- code_copy = @secret_code.dup
50
- matches = []
51
- user_code.each_index do |i|
52
- next unless @secret_code[i] == user_code[i]
49
+ def exact_match(guess)
50
+ @secret_code == guess
51
+ end
53
52
 
54
- matches.unshift('+')
55
- user_code[i] = nil
56
- code_copy[i] = false
57
- end
58
- [matches, user_code, code_copy]
53
+ def pluses(guess)
54
+ zipped(guess)
55
+ .select { |el| el[0] == el[1] }
56
+ .count
59
57
  end
60
58
 
61
- def number_secret_code(user_code, matches, code_copy)
62
- amount_numbers_secret = Hash.new(0)
63
- amount_numbers_now = Hash.new(0)
64
- code_copy.each { |number| amount_numbers_secret[number.to_s] += 1 }
65
- user_code.each do |element|
66
- next unless include_element?(code_copy, element) &&
67
- amount_of_element?(amount_numbers_now, amount_numbers_secret, element)
59
+ def minuses(guess)
60
+ return 0 if exact_match(guess)
61
+
62
+ arr = delete_pairs(guess)
63
+ arr[1].each do |number|
64
+ next unless arr[0].include?(number)
68
65
 
69
- matches.push('-')
70
- amount_numbers_now[element.to_s] += 1
66
+ arr[0].delete_at(arr[0].index(number))
71
67
  end
72
- matches
68
+ arr[1].size - arr[0].size
73
69
  end
74
70
 
75
- def include_element?(given_array, element)
76
- given_array.include? element
71
+ def zipped(guess)
72
+ @secret_code.chars.zip(guess.chars)
77
73
  end
78
74
 
79
- def amount_of_element?(amount_numbers_now, amount_numbers_secret, element)
80
- amount_numbers_now[element.to_s] < amount_numbers_secret[element.to_s]
75
+ def delete_pairs(guess)
76
+ zipped(guess)
77
+ .delete_if { |el| el[0] == el[1] }
78
+ .transpose
81
79
  end
82
80
 
83
81
  def generate_code
84
- Array.new(4) { rand(1..6) }
82
+ (Array.new(CODE_LENGTH_COUNT) { rand(CODE_START_LENGTH..CODE_LENGTH) }).join.to_s
85
83
  end
86
84
  end
87
85
  end
@@ -1,18 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
- module Model
3
- def load_file(file)
4
- save_data(file)
5
- rescue Errno::ENOENT
6
- nil
7
- end
4
+ class DbYaml
5
+ class << self
6
+ def load_file(path)
7
+ File.open(path, 'r') do |filename|
8
+ YAML.safe_load(filename)
9
+ end
10
+ end
8
11
 
9
- def save(user, file)
10
- File.open(file, 'a') { |f| YAML.dump(user, f) }
11
- end
12
+ def save(user, path)
13
+ File.open(path, 'a') { |f| YAML.dump(user, f) }
14
+ end
12
15
 
13
- def save_data(file)
14
- File.open(file, 'r') do |filename|
15
- YAML.safe_load(filename)
16
+ def load_file_stats(path)
17
+ YAML.load_stream(File.open(path))
16
18
  end
17
19
  end
18
20
  end
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
4
  module Statistic
5
+ include Constant
6
+
3
7
  def statistics
4
- data = YAML.load_stream(File.open('result.yml'))
5
- hash = { easy: 1, medium: 2, hell: 3 }
6
- data.sort_by { |item| [-hash[item.difficulty.to_sym], item.attempts_now, item.hints_now] }
8
+ data = DbYaml.load_file_stats('result.yml')
9
+ data.sort_by { |item| [-DIFFICULTY_SORT[item.difficulty.to_sym], item.attempts_left, item.hints_left] }
7
10
  end
8
11
  end
9
12
  end
@@ -1,28 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
4
  class User
3
- DIFFICULTY = {
4
- easy: { attempts: 15, hints: 2 },
5
- medium: { attempts: 10, hints: 1 },
6
- hell: { attempts: 5, hints: 1 }
7
- }.freeze
5
+ include AndriiCodebreaker::Validate
8
6
 
9
- attr_reader :name, :difficulty, :attempts_total, :hints_total
10
- attr_accessor :hints_now, :attempts_now
7
+ attr_reader :name
11
8
 
12
- def initialize(name, difficulty)
9
+ def initialize(name)
13
10
  @name = name
14
- @difficulty = difficulty
15
- @attempts_now = 0
16
- @hints_now = 0
17
- set_count_attempt
11
+ validate_name
12
+ end
13
+
14
+ def hints(user)
15
+ return unless user.hints_total > user.hints_left
16
+
17
+ user.hints_left += 1
18
18
  end
19
19
 
20
20
  private
21
21
 
22
- def set_count_attempt
23
- difficult = DIFFICULTY[@difficulty.to_sym]
24
- @hints_total = difficult[:hints]
25
- @attempts_total = difficult[:attempts]
22
+ def validate_name
23
+ @name = validates_name(name)
26
24
  end
27
25
  end
28
26
  end
@@ -1,12 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../constants'
4
+
1
5
  module AndriiCodebreaker
2
6
  module Validate
7
+ include Constant
8
+
3
9
  def validates_name(name)
4
10
  name if valid_name?(name)
5
11
  end
6
12
 
7
13
  def validate_guess(code)
8
14
  code = string_to_integer(code)
9
- code if check_code_length?(code) && check_numbers?(code)
15
+ true if check_code_length?(code) && check_numbers?(code)
10
16
  end
11
17
 
12
18
  private
@@ -19,15 +25,15 @@ module AndriiCodebreaker
19
25
  end
20
26
 
21
27
  def valid_name?(name)
22
- name.length >= 3 && name.length <= 20
28
+ name.length >= NAME_MIN_LENGTH && name.length <= NAME_MAX_LENGTH
23
29
  end
24
30
 
25
31
  def check_code_length?(code)
26
- code.length == 4
32
+ code.length == CODE_LENGTH_COUNT
27
33
  end
28
34
 
29
35
  def check_numbers?(code)
30
- code.all? { |value| value.between?(1, 6) }
36
+ code.all? { |value| value.between?(CODE_START_LENGTH, CODE_LENGTH) }
31
37
  end
32
38
  end
33
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
- VERSION = '0.1.2'.freeze
4
+ VERSION = '0.1.3'
3
5
  end
@@ -1,8 +1,11 @@
1
- require 'yaml'
1
+ # frozen_string_literal: true
2
2
 
3
+ require 'yaml'
4
+ require 'i18n'
5
+ require_relative 'andrii_codebreaker/validate/validate'
3
6
  require_relative 'andrii_codebreaker/model'
4
7
  require_relative 'andrii_codebreaker/user'
5
- require_relative 'andrii_codebreaker/validate/validate'
6
8
  require_relative 'andrii_codebreaker/statistic'
7
9
  require_relative 'andrii_codebreaker/version'
8
10
  require_relative 'andrii_codebreaker/game'
11
+ require_relative 'andrii_codebreaker/constants'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: andrii_codebreaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrii
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-03 00:00:00.000000000 Z
11
+ date: 2021-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fasterer
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: i18n
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -116,7 +130,10 @@ files:
116
130
  - andrii_codebreaker.gemspec
117
131
  - bin/console
118
132
  - bin/setup
133
+ - config/i18n.rb
134
+ - config/locales/en.yml
119
135
  - lib/andrii_codebreaker.rb
136
+ - lib/andrii_codebreaker/constants.rb
120
137
  - lib/andrii_codebreaker/game.rb
121
138
  - lib/andrii_codebreaker/model.rb
122
139
  - lib/andrii_codebreaker/statistic.rb