andrii_codebreaker 0.1.1 → 0.1.5

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: 4fe12dfef9d161e80cd13690272a4a293527bc887c3dfaddd868b6c21ad01f52
4
- data.tar.gz: 53f29bacf46db43b1a9cc122107c040279d087f80c6a40219c08c808c9683fe6
3
+ metadata.gz: 1743f315c3e1b74182843039b68e4a94274b9b32d29e4006ab50bc40a1b9bef2
4
+ data.tar.gz: 4562d14615ea91676b026d3fa4038c3542c5293cbc3c1e12bc159b08002e9bef
5
5
  SHA512:
6
- metadata.gz: ba3d0da4107f56f16f0957b4fe4b553d206823fd397edfa1421d1a562e7ba4500f670fa1ca74f04a54d0391b8a27833b7ec97f292765a0097d6de4ac6610979e
7
- data.tar.gz: a298375c0632b26d4c4ab7264bc9a7677231ce375bb67be24d3b3c9a2282fae1282d524c044404e49a458f9c69c6aff5d672741a53d6d4b7c46f263bde71e6ea
6
+ metadata.gz: 53365788f599671f07b0b59725ebb0d2e080ec7d62117052807c2995c384f3b7da63cafd4c8b99a0cc486fcfaa78f6e1d83f151c6f15a62d869659907cd32aef
7
+ data.tar.gz: b28fda65ac98bdcf8c5385c068620d5e66fde3ae818a6fe3c044dc85e9cd1b25b432b2cd4167fa06237c842c5d05189ec251f88e299ed7c9ddf9438bee2ea12d
@@ -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,6 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
- RSpec::Core::RakeTask.new(:spec)
4
- require 'rubocop/rake_task'
5
- RuboCop::RakeTask.new
6
- task default: %i[spec rubocop]
4
+ task default: :spec
@@ -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, :secret_code_cope
9
11
 
10
12
  CONST_COMMAND = {
11
13
  start: 'start',
@@ -14,75 +16,68 @@ module AndriiCodebreaker
14
16
  exit: 'exit'
15
17
  }.freeze
16
18
 
17
- WIN_MATRIX = ['+', '+', '+', '+'].freeze
18
-
19
- def initialize
20
- @secret_code = generate_code
21
- @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
22
25
  end
23
26
 
24
- def hints(user)
25
- return unless user.hints_total > user.hints_now
26
-
27
- user.hints_now += 1
28
- @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_cope = @secret_code.dup
29
33
  end
30
34
 
31
- def compare_codes(user_code)
32
- matches, user_code, code_copy = right_place(user_code)
33
- number_secret_code(user_code, matches, code_copy)
35
+ def show_hints
36
+ hints_left
34
37
  end
35
38
 
36
- def string_to_integer(input_code)
37
- array_int = []
38
- array_chars = input_code.chars
39
- array_chars.each { |i| array_int << i.to_i }
40
- array_int
41
- end
39
+ def compare_codes(guess)
40
+ return '++++' if exact_match(guess)
42
41
 
43
- def save_result(user, file)
44
- save(user, file)
42
+ ('+' * pluses(guess)) + ('-' * minuses(guess))
45
43
  end
46
44
 
47
45
  private
48
46
 
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]
47
+ def exact_match(guess)
48
+ @secret_code == guess
49
+ end
54
50
 
55
- matches.unshift('+')
56
- user_code[i] = nil
57
- code_copy[i] = false
58
- end
59
- [matches, user_code, code_copy]
51
+ def pluses(guess)
52
+ zipped(guess)
53
+ .select { |el| el[0] == el[1] }
54
+ .count
60
55
  end
61
56
 
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)
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)
69
63
 
70
- matches.push('-')
71
- amount_numbers_now[element.to_s] += 1
64
+ arr[0].delete_at(arr[0].index(number))
72
65
  end
73
- matches
66
+ arr[1].size - arr[0].size
74
67
  end
75
68
 
76
- def include_element?(given_array, element)
77
- given_array.include? element
69
+ def zipped(guess)
70
+ @secret_code.chars.zip(guess.chars)
78
71
  end
79
72
 
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]
73
+ def delete_pairs(guess)
74
+ zipped(guess)
75
+ .delete_if { |el| el[0] == el[1] }
76
+ .transpose
82
77
  end
83
78
 
84
79
  def generate_code
85
- Array.new(4) { rand(1..6) }
80
+ (Array.new(CODE_LENGTH_COUNT) { rand(CODE_START_LENGTH..CODE_LENGTH) }).join.to_s
86
81
  end
87
82
  end
88
83
  end
@@ -1,21 +1,20 @@
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(user, file)
13
- File.open(file, 'a') { |f| YAML.dump(user, f) }
14
- end
12
+ def save(user, path)
13
+ File.open(path, 'a') { |f| YAML.dump(user, f) }
14
+ end
15
15
 
16
- def save_data(file)
17
- File.open(file, 'r') do |filename|
18
- YAML.safe_load(filename)
16
+ def load_file_stats(path)
17
+ YAML.load_stream(File.open(path))
19
18
  end
20
19
  end
21
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_cope.chars.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,17 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AndriiCodebreaker
2
4
  module Validate
3
- def validate_guess(code)
4
- code.match(/^[1-6]{4}$/)
5
- end
5
+ include Constant
6
6
 
7
- def valide_name(name)
7
+ def validates_name(name)
8
8
  name if valid_name?(name)
9
9
  end
10
10
 
11
+ def validate_guess(code)
12
+ code = string_to_integer(code)
13
+ true if check_code_length?(code) && check_numbers?(code)
14
+ end
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.1'.freeze
4
+ VERSION = '0.1.5'
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
9
  require_relative 'andrii_codebreaker/version'
6
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.1
4
+ version: 0.1.5
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-28 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,11 @@ files:
97
127
  - LICENSE.txt
98
128
  - README.md
99
129
  - Rakefile
130
+ - andrii_codebreaker.gemspec
100
131
  - bin/console
101
132
  - bin/setup
102
133
  - lib/andrii_codebreaker.rb
134
+ - lib/andrii_codebreaker/constants.rb
103
135
  - lib/andrii_codebreaker/game.rb
104
136
  - lib/andrii_codebreaker/model.rb
105
137
  - lib/andrii_codebreaker/statistic.rb