andrii_codebreaker 0.1.2 → 0.1.6

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: 850117beac1f8b9441630a8a0f97ef5a6c374e671dce56bedc85d9f43b74d828
4
+ data.tar.gz: c52fce0dcceb07cb99bb0ce693b7e38469b380e4310c990e9783cf53acb4fbb7
5
5
  SHA512:
6
- metadata.gz: ade917c605ff8db3c1f8f29b601773787b0c696f3c09eedb861692700407449849dee930e7bcef60d5457b449f9198fc6617d612a61bb6cbf7283f39f55733eb
7
- data.tar.gz: a31d77642798e00747a315979bb2e544e0a66ac56574edc596711809d9b3865625fefda5b02bd1a22ab3cb19975e2fbd4ed736d98bdda13b1423f6ae4f5a7e98
6
+ metadata.gz: 614863a6b0e5d83c2e3752d5244146fc8aaebf1452dcdb367172da66bb8c6c9c6a838fc347e4af237d57792b76676b30dc55224acf1d7cc963cc0a746aa5e00a
7
+ data.tar.gz: 32267d352720c6009cd3b4bff6f3c130e1dae175f6b90b423c1b4ff8ac42459f9b252b0934d55c2fc0e4a22118d2c89f72637083c8ee4a9def75b16ae6331dc0
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,18 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- andrii_codebreaker (0.1.1)
4
+ andrii_codebreaker (0.1.6)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
10
  colorize (0.8.1)
11
+ concurrent-ruby (1.1.9)
11
12
  diff-lcs (1.4.4)
12
13
  docile (1.4.0)
13
14
  fasterer (0.9.0)
14
15
  colorize (~> 0.7)
15
16
  ruby_parser (>= 3.14.1)
17
+ i18n (1.8.11)
18
+ concurrent-ruby (~> 1.0)
16
19
  parallel (1.21.0)
17
20
  parser (3.0.2.0)
18
21
  ast (~> 2.4.1)
@@ -64,6 +67,7 @@ PLATFORMS
64
67
  DEPENDENCIES
65
68
  andrii_codebreaker!
66
69
  fasterer
70
+ i18n
67
71
  rake
68
72
  rspec
69
73
  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
Binary file
@@ -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__)
@@ -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,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
4
  class Game
3
5
  include Validate
4
- include Model
5
6
  include Statistic
6
- attr_reader :secret_code
7
- attr_accessor :secret_code_copy
7
+ include Constant
8
+
9
+ attr_reader :player_name, :difficulty, :attempts_total, :hints_total, :secret_code
10
+ attr_accessor :hints_left, :attempts_left, :secret_code_copy
8
11
 
9
12
  CONST_COMMAND = {
10
13
  start: 'start',
@@ -13,75 +16,68 @@ module AndriiCodebreaker
13
16
  exit: 'exit'
14
17
  }.freeze
15
18
 
16
- WIN_MATRIX = ['+', '+', '+', '+'].freeze
17
-
18
- def initialize
19
- @secret_code = generate_code
20
- @secret_code_copy = @secret_code.dup
19
+ def initialize(player_name, difficulty)
20
+ @player_name = player_name
21
+ @difficulty = difficulty
22
+ @attempts_left = 0
23
+ @hints_left = 0
24
+ initialize_class
21
25
  end
22
26
 
23
- def hints(user)
24
- return unless user.hints_total > user.hints_now
25
-
26
- user.hints_now += 1
27
- @secret_code_copy.pop
27
+ def initialize_class
28
+ difficult = DIFFICULTY[@difficulty.to_sym]
29
+ @hints_total = difficult[:hints]
30
+ @attempts_total = difficult[:attempts]
31
+ @secret_code = generate_code
32
+ @secret_code_copy = @secret_code.dup.chars
28
33
  end
29
34
 
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)
35
+ def show_hints
36
+ hints_left
33
37
  end
34
38
 
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
39
+ def compare_codes(guess)
40
+ return '++++' if exact_match(guess)
41
41
 
42
- def save_result(user, file)
43
- save(user, file)
42
+ ('+' * pluses(guess)) + ('-' * minuses(guess))
44
43
  end
45
44
 
46
45
  private
47
46
 
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]
47
+ def exact_match(guess)
48
+ @secret_code == guess
49
+ end
53
50
 
54
- matches.unshift('+')
55
- user_code[i] = nil
56
- code_copy[i] = false
57
- end
58
- [matches, user_code, code_copy]
51
+ def pluses(guess)
52
+ zipped(guess)
53
+ .select { |el| el[0] == el[1] }
54
+ .count
59
55
  end
60
56
 
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)
57
+ def minuses(guess)
58
+ return 0 if exact_match(guess)
59
+
60
+ arr = delete_pairs(guess)
61
+ arr[1].each do |number|
62
+ next unless arr[0].include?(number)
68
63
 
69
- matches.push('-')
70
- amount_numbers_now[element.to_s] += 1
64
+ arr[0].delete_at(arr[0].index(number))
71
65
  end
72
- matches
66
+ arr[1].size - arr[0].size
73
67
  end
74
68
 
75
- def include_element?(given_array, element)
76
- given_array.include? element
69
+ def zipped(guess)
70
+ @secret_code.chars.zip(guess.chars)
77
71
  end
78
72
 
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]
73
+ def delete_pairs(guess)
74
+ zipped(guess)
75
+ .delete_if { |el| el[0] == el[1] }
76
+ .transpose
81
77
  end
82
78
 
83
79
  def generate_code
84
- Array.new(4) { rand(1..6) }
80
+ (Array.new(CODE_LENGTH_COUNT) { rand(CODE_START_LENGTH..CODE_LENGTH) }).join.to_s
85
81
  end
86
82
  end
87
83
  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,27 @@
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(game)
15
+ return unless game.hints_total > game.hints_left
16
+
17
+ game.hints_left += 1
18
+ game.secret_code_copy.pop
18
19
  end
19
20
 
20
21
  private
21
22
 
22
- def set_count_attempt
23
- difficult = DIFFICULTY[@difficulty.to_sym]
24
- @hints_total = difficult[:hints]
25
- @attempts_total = difficult[:attempts]
23
+ def validate_name
24
+ @name = validates_name(name)
26
25
  end
27
26
  end
28
27
  end
@@ -1,12 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
4
  module Validate
5
+ include Constant
6
+
3
7
  def validates_name(name)
4
8
  name if valid_name?(name)
5
9
  end
6
10
 
7
11
  def validate_guess(code)
8
12
  code = string_to_integer(code)
9
- code if check_code_length?(code) && check_numbers?(code)
13
+ true if check_code_length?(code) && check_numbers?(code)
10
14
  end
11
15
 
12
16
  private
@@ -19,15 +23,15 @@ module AndriiCodebreaker
19
23
  end
20
24
 
21
25
  def valid_name?(name)
22
- name.length >= 3 && name.length <= 20
26
+ name.length >= NAME_MIN_LENGTH && name.length <= NAME_MAX_LENGTH
23
27
  end
24
28
 
25
29
  def check_code_length?(code)
26
- code.length == 4
30
+ code.length == CODE_LENGTH_COUNT
27
31
  end
28
32
 
29
33
  def check_numbers?(code)
30
- code.all? { |value| value.between?(1, 6) }
34
+ code.all? { |value| value.between?(CODE_START_LENGTH, CODE_LENGTH) }
31
35
  end
32
36
  end
33
37
  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.6'
3
5
  end
@@ -1,8 +1,10 @@
1
- require 'yaml'
1
+ # frozen_string_literal: true
2
2
 
3
+ require 'yaml'
4
+ require_relative 'andrii_codebreaker/constants'
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'
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.6
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
@@ -113,10 +127,12 @@ files:
113
127
  - LICENSE.txt
114
128
  - README.md
115
129
  - Rakefile
130
+ - andrii_codebreaker-0.1.5.gem
116
131
  - andrii_codebreaker.gemspec
117
132
  - bin/console
118
133
  - bin/setup
119
134
  - lib/andrii_codebreaker.rb
135
+ - lib/andrii_codebreaker/constants.rb
120
136
  - lib/andrii_codebreaker/game.rb
121
137
  - lib/andrii_codebreaker/model.rb
122
138
  - lib/andrii_codebreaker/statistic.rb