andrii_codebreaker 0.1.0 → 0.1.4

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: e1607581ffecd6cfb9a39facf2faac691b9e0a202fb84beb49abf204cada9cb7
4
- data.tar.gz: 48026a23d738ca88f541744730a7d815c8a3e79d4c71126855783c20bf817203
3
+ metadata.gz: f3027085006ffe0d292e9f98fab0592e60bad72a65891bdc88636462c02a0467
4
+ data.tar.gz: 3e9ccb14889cd81faa40b812b586c8e82467d94eb0ec110c800c3981c4c96cf1
5
5
  SHA512:
6
- metadata.gz: d6d0086e5960049a94be3964254e615b78c5af76212d435dd8b9e162522b4af4e8969ffc5af04cc11be887884205ee1809034a0c14f233989897db2d61b21488
7
- data.tar.gz: eaba1452c2d889ebf2fc2a992aa2d6a4671449b4d6e5851ba1f99732a3565e032d4278f822d221f12c10db48d210994cfad31c43793c842c76704c710f75edd7
6
+ metadata.gz: b3ed0df86dc3ddb50e0111996dfa8ad431cc1d4b7e30900ad1cc2ff43b4a153da0a153cf77c53f232e40623ba7b1ee22a7b28e79130bad79728b51ed4e1e259f
7
+ data.tar.gz: 9e3ec45080ac93dfa06cb58cf70acaa5707bbacbfcaeeb04408f1738c4afca10a10e4065ba4d52ab633bf2389b3d082677b4d1a7e8f5c5ef8e8b75005fa86a13
@@ -0,0 +1,62 @@
1
+
2
+ version: 2.1
3
+
4
+ executors:
5
+ default:
6
+ working_directory: ~/repo
7
+ description: The official CircleCI Ruby Docker image
8
+ docker:
9
+ - image: circleci/ruby:2.7.2
10
+
11
+ cashes:
12
+ - &bundle_caches_full v2-repo-{{ checksum "Gemfile.lock" }}
13
+ - &bundle_cache v2-repo-
14
+
15
+ commands:
16
+ defaults:
17
+ steps:
18
+ - checkout
19
+ - restore_cache:
20
+ keys:
21
+ - *bundle_caches_full
22
+ - *bundle_cache
23
+ - run: bundle install --path vendor/bundle
24
+ - save_cache:
25
+ key: *bundle_caches_full
26
+ paths:
27
+ - vendor/bundle
28
+ run_linters:
29
+ description: command to start linters
30
+ steps:
31
+ - run:
32
+ name: rubucop
33
+ command: bundle exec rubocop
34
+ - run:
35
+ name: fasterer
36
+ command: bundle exec fasterer lib/
37
+ run_specs:
38
+ steps:
39
+ - run:
40
+ name: run specs
41
+ command: bundle exec rspec
42
+
43
+ jobs:
44
+ lintering:
45
+ executor: default
46
+ steps:
47
+ - defaults
48
+ - run_linters
49
+ run_specs:
50
+ executor: default
51
+ steps:
52
+ - defaults
53
+ - run_specs
54
+
55
+ workflows:
56
+ version: 2.1
57
+ build:
58
+ jobs:
59
+ - lintering
60
+ - run_specs:
61
+ requires:
62
+ - lintering
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ /.bundle/
2
+ /coverage/
3
+ .rspec_status
data/.rubocop.yml CHANGED
@@ -1,3 +1,5 @@
1
+ require: rubocop-rspec
2
+
1
3
  AllCops:
2
4
  NewCops: enable
3
5
  SuggestExtensions: false
@@ -5,12 +7,12 @@ AllCops:
5
7
  Style/Documentation:
6
8
  Enabled: false
7
9
 
8
- Style/FrozenStringLiteralComment:
9
- Enabled: false
10
-
11
10
  Metrics/LineLength:
12
11
  Max: 120
13
12
 
13
+ RSpec/AnyInstance:
14
+ Enabled: false
15
+
14
16
  Metrics/BlockLength:
15
17
  Exclude:
16
18
  - 'Rakefile'
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,19 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- andrii_codebreaker (0.1.0)
5
- simplecov
4
+ andrii_codebreaker (0.1.4)
6
5
 
7
6
  GEM
8
7
  remote: https://rubygems.org/
9
8
  specs:
10
9
  ast (2.4.2)
11
10
  colorize (0.8.1)
11
+ concurrent-ruby (1.1.9)
12
12
  diff-lcs (1.4.4)
13
13
  docile (1.4.0)
14
14
  fasterer (0.9.0)
15
15
  colorize (~> 0.7)
16
16
  ruby_parser (>= 3.14.1)
17
+ i18n (1.8.11)
18
+ concurrent-ruby (~> 1.0)
17
19
  parallel (1.21.0)
18
20
  parser (3.0.2.0)
19
21
  ast (~> 2.4.1)
@@ -34,7 +36,7 @@ GEM
34
36
  diff-lcs (>= 1.2.0, < 2.0)
35
37
  rspec-support (~> 3.10.0)
36
38
  rspec-support (3.10.2)
37
- rubocop (1.22.2)
39
+ rubocop (1.22.3)
38
40
  parallel (~> 1.10)
39
41
  parser (>= 3.0.0.0)
40
42
  rainbow (>= 2.2.2, < 4.0)
@@ -45,10 +47,12 @@ GEM
45
47
  unicode-display_width (>= 1.4.0, < 3.0)
46
48
  rubocop-ast (1.12.0)
47
49
  parser (>= 3.0.1.1)
50
+ rubocop-rspec (2.5.0)
51
+ rubocop (~> 1.19)
48
52
  ruby-progressbar (1.11.0)
49
- ruby_parser (3.17.0)
50
- sexp_processor (~> 4.15, >= 4.15.1)
51
- sexp_processor (4.15.3)
53
+ ruby_parser (3.18.0)
54
+ sexp_processor (~> 4.16)
55
+ sexp_processor (4.16.0)
52
56
  simplecov (0.21.2)
53
57
  docile (~> 1.1)
54
58
  simplecov-html (~> 0.11)
@@ -63,9 +67,12 @@ PLATFORMS
63
67
  DEPENDENCIES
64
68
  andrii_codebreaker!
65
69
  fasterer
70
+ i18n
66
71
  rake
67
72
  rspec
68
73
  rubocop
74
+ rubocop-rspec
75
+ simplecov
69
76
 
70
77
  BUNDLED WITH
71
78
  2.2.29
data/Rakefile CHANGED
@@ -1,12 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require 'rubocop/rake_task'
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[spec rubocop]
4
+ task default: :spec
Binary file
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/andrii_codebreaker/version'
4
+ lib = File.expand_path('lib', __dir__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'andrii_codebreaker'
9
+ spec.version = AndriiCodebreaker::VERSION
10
+ spec.authors = ['Andrii']
11
+ spec.email = ['andrii.okhrimets@rubygarage.org']
12
+
13
+ spec.summary = 'Game in Codebreaker'
14
+ spec.description = 'Game in Codebreaker'
15
+ spec.homepage = 'https://github.com/Andrii-RubyGarage/Codebreker-Gem'
16
+ spec.license = 'MIT'
17
+ spec.required_ruby_version = '>= 2.7.2'
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = spec.homepage
21
+
22
+ spec.add_development_dependency 'fasterer'
23
+ spec.add_development_dependency 'i18n'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'rubocop'
27
+ spec.add_development_dependency 'rubocop-rspec'
28
+ spec.add_development_dependency 'simplecov'
29
+
30
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
32
+ end
33
+
34
+ spec.bindir = 'bin'
35
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ['lib']
37
+ end
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,11 +1,13 @@
1
- require_relative '../andrii_codebreaker'
1
+ # frozen_string_literal: true
2
+
2
3
  module AndriiCodebreaker
3
4
  class Game
4
5
  include Validate
5
- include Model
6
6
  include Statistic
7
- attr_reader :secret_code
8
- 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
9
11
 
10
12
  CONST_COMMAND = {
11
13
  start: 'start',
@@ -14,75 +16,67 @@ module AndriiCodebreaker
14
16
  exit: 'exit'
15
17
  }.freeze
16
18
 
17
- WIN_MATRIX = ['+', '+', '+', '+'].freeze
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
25
+ end
18
26
 
19
- def initialize
27
+ def initialize_class
28
+ difficult = DIFFICULTY[@difficulty.to_sym]
29
+ @hints_total = difficult[:hints]
30
+ @attempts_total = difficult[:attempts]
20
31
  @secret_code = generate_code
21
- @secret_code_copy = @secret_code.dup
22
32
  end
23
33
 
24
- def save_result(user, file)
25
- save(user, file)
34
+ def show_hints
35
+ hints_left
26
36
  end
27
37
 
28
- def hints(user)
29
- return unless user.hints_total > user.hints_now
30
-
31
- user.hints_now += 1
32
- @secret_code_copy.pop
33
- end
38
+ def compare_codes(guess)
39
+ return '++++' if exact_match(guess)
34
40
 
35
- def compare_codes(user_code)
36
- matches, user_code, code_copy = right_place(user_code)
37
- number_secret_code(user_code, matches, code_copy)
41
+ ('+' * pluses(guess)) + ('-' * minuses(guess))
38
42
  end
39
43
 
40
44
  private
41
45
 
42
- def string_to_integer(input_code)
43
- array_int = []
44
- array_chars = input_code.chars
45
- array_chars.each { |i| array_int << i.to_i }
46
- array_int
46
+ def exact_match(guess)
47
+ @secret_code == guess
47
48
  end
48
49
 
49
- def right_place(user_code)
50
- code_copy = @secret_code.dup
51
- matches = []
52
- user_code.each_index do |i|
53
- next unless @secret_code[i] == user_code[i]
54
-
55
- matches.unshift('+')
56
- user_code[i] = nil
57
- code_copy[i] = false
58
- end
59
- [matches, user_code, code_copy]
50
+ def pluses(guess)
51
+ zipped(guess)
52
+ .select { |el| el[0] == el[1] }
53
+ .count
60
54
  end
61
55
 
62
- def number_secret_code(user_code, matches, code_copy)
63
- amount_numbers_secret = Hash.new(0)
64
- amount_numbers_now = Hash.new(0)
65
- code_copy.each { |number| amount_numbers_secret[number.to_s] += 1 }
66
- user_code.each do |element|
67
- next unless include_element?(code_copy, element) &&
68
- amount_of_element?(amount_numbers_now, amount_numbers_secret, element)
56
+ def minuses(guess)
57
+ return 0 if exact_match(guess)
58
+
59
+ arr = delete_pairs(guess)
60
+ arr[1].each do |number|
61
+ next unless arr[0].include?(number)
69
62
 
70
- matches.push('-')
71
- amount_numbers_now[element.to_s] += 1
63
+ arr[0].delete_at(arr[0].index(number))
72
64
  end
73
- matches
65
+ arr[1].size - arr[0].size
74
66
  end
75
67
 
76
- def include_element?(given_array, element)
77
- given_array.include? element
68
+ def zipped(guess)
69
+ @secret_code.chars.zip(guess.chars)
78
70
  end
79
71
 
80
- def amount_of_element?(amount_numbers_now, amount_numbers_secret, element)
81
- amount_numbers_now[element.to_s] < amount_numbers_secret[element.to_s]
72
+ def delete_pairs(guess)
73
+ zipped(guess)
74
+ .delete_if { |el| el[0] == el[1] }
75
+ .transpose
82
76
  end
83
77
 
84
78
  def generate_code
85
- Array.new(4) { rand(1..6) }
79
+ (Array.new(CODE_LENGTH_COUNT) { rand(CODE_START_LENGTH..CODE_LENGTH) }).join.to_s
86
80
  end
87
81
  end
88
82
  end
@@ -1,22 +1,21 @@
1
- require 'yaml'
2
- module AndriiCodebreaker
3
- module Model
4
- def load_file(file)
5
- return nil if File.empty?(file)
1
+ # frozen_string_literal: true
6
2
 
7
- save_data(file)
8
- rescue Errno::ENOENT
9
- nil
10
- end
3
+ module AndriiCodebreaker
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
11
11
 
12
- def save_data(file)
13
- File.open(file, 'r') do |filename|
14
- YAML.safe_load(filename)
12
+ def save(user, path)
13
+ File.open(path, 'a') { |f| YAML.dump(user, f) }
15
14
  end
16
- end
17
15
 
18
- def save(user, file)
19
- File.open(file, 'a') { |f| YAML.dump(user, f) }
16
+ def load_file_stats(path)
17
+ YAML.load_stream(File.open(path))
18
+ end
20
19
  end
21
20
  end
22
21
  end
@@ -1,8 +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
- data.sort_by { |item| [item.difficulty, -item.attempts_now, item.hints_now] }.reverse
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] }
6
10
  end
7
11
  end
8
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
- @hints_now = 0
16
- @attempts_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,17 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
4
  module Validate
3
- def valide_name(name)
5
+ include Constant
6
+
7
+ def validates_name(name)
4
8
  name if valid_name?(name)
5
9
  end
6
10
 
7
11
  def validate_guess(code)
8
- code.match(/^[1-6]{4}$/)
12
+ code = string_to_integer(code)
13
+ true if check_code_length?(code) && check_numbers?(code)
9
14
  end
10
15
 
11
16
  private
12
17
 
18
+ def string_to_integer(input_code)
19
+ array_int = []
20
+ array_chars = input_code.chars
21
+ array_chars.each { |i| array_int << i.to_i }
22
+ array_int
23
+ end
24
+
13
25
  def valid_name?(name)
14
- name.length >= 3 && name.length <= 20
26
+ name.length >= NAME_MIN_LENGTH && name.length <= NAME_MAX_LENGTH
27
+ end
28
+
29
+ def check_code_length?(code)
30
+ code.length == CODE_LENGTH_COUNT
31
+ end
32
+
33
+ def check_numbers?(code)
34
+ code.all? { |value| value.between?(CODE_START_LENGTH, CODE_LENGTH) }
15
35
  end
16
36
  end
17
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
- VERSION = '0.1.0'.freeze
4
+ VERSION = '0.1.4'
3
5
  end
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative 'andrii_codebreaker/constants'
5
+ require_relative 'andrii_codebreaker/validate/validate'
1
6
  require_relative 'andrii_codebreaker/model'
2
7
  require_relative 'andrii_codebreaker/user'
3
- require_relative 'andrii_codebreaker/validate/validate'
4
8
  require_relative 'andrii_codebreaker/statistic'
5
- require_relative 'andrii_codebreaker/game'
6
9
  require_relative 'andrii_codebreaker/version'
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.0
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrii
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-26 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
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: simplecov
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -73,7 +101,7 @@ dependencies:
73
101
  - - ">="
74
102
  - !ruby/object:Gem::Version
75
103
  version: '0'
76
- type: :runtime
104
+ type: :development
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
@@ -87,7 +115,9 @@ executables: []
87
115
  extensions: []
88
116
  extra_rdoc_files: []
89
117
  files:
118
+ - ".circleci/config.yml"
90
119
  - ".fasterer.yml"
120
+ - ".gitignore"
91
121
  - ".rspec"
92
122
  - ".rubocop.yml"
93
123
  - ".ruby-gemset"
@@ -97,9 +127,12 @@ files:
97
127
  - LICENSE.txt
98
128
  - README.md
99
129
  - Rakefile
130
+ - andrii_codebreaker-0.1.3.gem
131
+ - andrii_codebreaker.gemspec
100
132
  - bin/console
101
133
  - bin/setup
102
134
  - lib/andrii_codebreaker.rb
135
+ - lib/andrii_codebreaker/constants.rb
103
136
  - lib/andrii_codebreaker/game.rb
104
137
  - lib/andrii_codebreaker/model.rb
105
138
  - lib/andrii_codebreaker/statistic.rb