codebreaker_sn 0.1.0 → 0.1.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: 8b4bc64fa02fe1525021ca41c2f25989ad79ef13c7f52df4e54f272b6526c2d3
4
- data.tar.gz: ac89230e4c36e093aa783dace5d1f9c7e12d380107a55f7d450f531eddbe2843
3
+ metadata.gz: a9b1441a0483d35cfbd56b0ed3c0a6dd3ec3501b4cae97770e5f7a765211de03
4
+ data.tar.gz: 55ce5e6e368e9cad3c1ea50b21440813ca3c84164c0daaf4b3ab2928a573358e
5
5
  SHA512:
6
- metadata.gz: 3002e08c2f92d7bbe4813389ebde8fc31a123c15c919b823d33ee719320e9f1455c8f40e8350c9ec7e65567aa999998b9ce33a25a2f7f349274ca62b265a6af6
7
- data.tar.gz: 034aa1c0516dc53a557f5f672028bb13a57a706f349dc5f19473bf7d746761629195ff36fbdeddd90694afd02fd1ac7ff0c72e05a4c9030a674d2e42d3875f4d
6
+ metadata.gz: 5162f080fef1f3280d08e12ec005505e294df53388a1526e7a1794ec1e93a92441344bfa67844a8a6d1bedf3586fd5063327fe0d5832615c01ef50cf8c9c7157
7
+ data.tar.gz: bdf5faf548352291c6eb15ab222582f1829d5c04c73ab8b30635eff9a85b10ddff2d9d5291951e06952b5337049a85513745ad707dc47ebae62b52406a7c7130
@@ -19,7 +19,7 @@ commands:
19
19
  keys:
20
20
  - *bundle_cache_full
21
21
  - *bundle_cache
22
- - run: bundle config set path 'vendor/bundle'
22
+ - run: bundle install --path vendor/bundle
23
23
  - save_cache:
24
24
  key: *bundle_cache_full
25
25
  paths:
@@ -1,4 +1,2 @@
1
- speedups:
2
- each_with_index_vs_while: false
3
1
  exclude_paths:
4
2
  - "vendor/**/*.rb"
@@ -1,6 +1,8 @@
1
- require: rubocop-rspec
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rspec
2
4
 
3
5
  Style/Documentation:
4
6
  Enabled: false
5
- Metrics/MethodLength:
6
- Max: 12
7
+ Metrics/BlockLength:
8
+ ExcludedMethods: ['describe', 'context']
data/Gemfile CHANGED
@@ -2,5 +2,4 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- # Specify your gem's dependencies in codebreaker.gemspec
6
5
  gemspec
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- codebreaker (0.1.0)
4
+ codebreaker_sn (0.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -44,6 +44,8 @@ GEM
44
44
  unicode-display_width (>= 1.4.0, < 2.0)
45
45
  rubocop-ast (0.1.0)
46
46
  parser (>= 2.7.0.1)
47
+ rubocop-performance (1.7.1)
48
+ rubocop (>= 0.82.0)
47
49
  rubocop-rspec (1.41.0)
48
50
  rubocop (>= 0.68.1)
49
51
  ruby-progressbar (1.10.1)
@@ -60,11 +62,12 @@ PLATFORMS
60
62
  ruby
61
63
 
62
64
  DEPENDENCIES
63
- codebreaker!
65
+ codebreaker_sn!
64
66
  fasterer
65
67
  rake
66
68
  rspec
67
69
  rubocop
70
+ rubocop-performance
68
71
  rubocop-rspec
69
72
  simplecov
70
73
 
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency 'rake'
26
26
  spec.add_development_dependency 'rspec'
27
27
  spec.add_development_dependency 'rubocop'
28
+ spec.add_development_dependency 'rubocop-performance'
28
29
  spec.add_development_dependency 'rubocop-rspec'
29
30
  spec.add_development_dependency 'simplecov'
30
31
  end
Binary file
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative 'codebreaker/version'
5
+ require_relative 'moduls/validations'
6
+ require_relative 'codebreaker/game'
7
+ require_relative 'codebreaker/user'
8
+ require_relative 'codebreaker/codemaker'
9
+ require_relative 'codebreaker/codechecker'
10
+ require_relative 'codebreaker/guess'
11
+ require_relative 'codebreaker/statistic'
12
+ require_relative 'codebreaker/sorter'
13
+ require_relative 'errors/validation_error'
14
+ require_relative 'errors/length_error'
15
+ require_relative 'errors/presence_error'
16
+ require_relative 'errors/out_of_range_error'
17
+ require_relative 'errors/class_type_error'
18
+ require_relative 'errors/inclusion_error'
@@ -1,23 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RANGE_OF_NUMBERS = (1..6).freeze
4
- AMOUNT_OF_NUMBERS = 4
5
- DIFF_ARRAY = %w[hell medium easy].freeze
6
- RESULTS_FILE = 'lib/files/results_file.csv'
7
- RULES_FILE = 'lib/files/rules.txt'
3
+ require_relative 'autoload'
8
4
 
9
5
  module Codebreaker
10
- require 'csv'
11
- require 'codebreaker/version'
12
- require 'moduls/validations'
13
- require 'codebreaker/game'
14
- require 'codebreaker/user'
15
- require 'codebreaker/codemaker'
16
- require 'codebreaker/guess'
17
- require 'errors/validation_error'
18
- require 'errors/length_error'
19
- require 'errors/presence_error'
20
- require 'errors/out_of_range_error'
21
- require 'errors/class_type_error'
22
- require 'errors/inclusion_error'
23
6
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Codebreaker
4
+ class Codechecker
5
+ attr_reader :guess_array, :secret_code_array, :response
6
+
7
+ def initialize(guess_array, secret_code_array)
8
+ @guess_array = guess_array
9
+ @secret_code_array = secret_code_array
10
+ @response = { in_plase: 0, out_of_place: 0 }
11
+ end
12
+
13
+ def call
14
+ in_plase_check
15
+ out_of_place_check
16
+ end
17
+
18
+ private
19
+
20
+ def in_plase_check
21
+ index = 0
22
+ while index < guess_array.size
23
+ if guess_array[index] == secret_code_array[index]
24
+ response[:in_plase] += 1
25
+ guess_array[index] = nil
26
+ secret_code_array[index] = nil
27
+ end
28
+ index += 1
29
+ end
30
+ end
31
+
32
+ def out_of_place_check
33
+ guess_array.each do |number|
34
+ if !number.nil? && secret_code_array.include?(number)
35
+ response[:out_of_place] += 1
36
+ secret_code_array[secret_code_array.index(number)] = nil
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -2,37 +2,15 @@
2
2
 
3
3
  module Codebreaker
4
4
  class Codemaker
5
- NON_OCCURRING_VALUE_FIRST = 'X'
6
- NON_OCCURRING_VALUE_SECOND = 'Y'
7
- NON_OCCURRING_VALUE_THIRD = 'Z'
5
+ RANGE_OF_NUMBERS = (1..6).freeze
6
+ AMOUNT_OF_NUMBERS = 4
8
7
 
9
- attr_reader :secret_code, :response
10
-
11
- def initialize
12
- @secret_code = ''
13
- @response = { in_plase: 0, out_of_place: 0 }
14
- end
8
+ attr_reader :secret_code
15
9
 
16
10
  def generate_secret_code(amout = AMOUNT_OF_NUMBERS, range = RANGE_OF_NUMBERS)
17
11
  array_of_numbers = []
18
12
  amout.times { array_of_numbers << rand(range) }
19
13
  @secret_code = array_of_numbers.join.to_i
20
14
  end
21
-
22
- def check(guess_array, secret_code_array)
23
- guess_array.each_with_index do |number, index|
24
- next unless number == secret_code_array[index]
25
-
26
- @response[:in_plase] += 1
27
- guess_array[index] = NON_OCCURRING_VALUE_FIRST
28
- secret_code_array[index] = NON_OCCURRING_VALUE_SECOND
29
- end
30
- guess_array.each do |number|
31
- if secret_code_array.include?(number)
32
- @response[:out_of_place] += 1
33
- secret_code_array[secret_code_array.index(number)] = NON_OCCURRING_VALUE_THIRD
34
- end
35
- end
36
- end
37
15
  end
38
16
  end
@@ -2,15 +2,16 @@
2
2
 
3
3
  module Codebreaker
4
4
  class Game
5
- include Validations
6
-
7
5
  DIFFICULTY_HASH = { easy: { attempts: 15, hints: 2 },
8
6
  medium: { attempts: 10, hints: 1 },
9
7
  hell: { attempts: 5, hints: 1 } }.freeze
10
8
 
11
- validate :difficulty, :inclusion, %i[easy medium hell]
9
+ include Validations
10
+
11
+ validate :difficulty, :inclusion, DIFFICULTY_HASH.keys
12
12
 
13
- attr_reader :user, :difficulty, :secret_code
13
+ attr_reader :user, :difficulty, :secret_code, :hints_used
14
+ attr_accessor :attempts_used
14
15
 
15
16
  def initialize(user, difficulty, secret_code)
16
17
  @user = user
@@ -22,45 +23,36 @@ module Codebreaker
22
23
  end
23
24
 
24
25
  def check(guess)
25
- @attempts_used += 1
26
+ self.attempts_used += 1
26
27
 
27
- guess_array = guess.to_s.split('').map(&:to_i)
28
- secret_code_array = @secret_code.to_s.split('').map(&:to_i)
28
+ guess_array = guess.digits.reverse
29
+ secret_code_array = secret_code.digits.reverse
29
30
 
30
- codemaker = Codebreaker::Codemaker.new
31
- codemaker.check(guess_array, secret_code_array)
32
- codemaker.response
31
+ codechecker = Codechecker.new(guess_array, secret_code_array)
32
+ codechecker.call
33
+ codechecker.response
33
34
  end
34
35
 
35
36
  def any_hints_left?
36
- DIFFICULTY_HASH[@difficulty][:hints] > @hints_used.count
37
+ DIFFICULTY_HASH[difficulty][:hints] > hints_used.count
37
38
  end
38
39
 
39
40
  def take_hint
40
- secret_code_array = @secret_code.to_s.split('').map(&:to_i)
41
- @hints_used.each do |hint_used|
41
+ secret_code_array = secret_code.digits.reverse
42
+ hints_used.each do |hint_used|
42
43
  secret_code_array.delete_at(secret_code_array.index(hint_used))
43
44
  end
44
- random_element = secret_code_array.sample
45
- @hints_used << random_element
46
- random_element
45
+ hint = secret_code_array.sample
46
+ hints_used << hint
47
+ hint
47
48
  end
48
49
 
49
50
  def win?(guess)
50
- guess == @secret_code
51
+ guess == secret_code
51
52
  end
52
53
 
53
54
  def lose?
54
- @attempts_used >= DIFFICULTY_HASH[@difficulty][:attempts]
55
- end
56
-
57
- def save_result
58
- data = "#{@user.name},#{@difficulty},"
59
- data += "#{DIFFICULTY_HASH[@difficulty][:attempts]},#{@attempts_used},"
60
- data += "#{DIFFICULTY_HASH[@difficulty][:hints]},#{@hints_used.count}"
61
- File.open(RESULTS_FILE, 'a') do |file|
62
- file.puts data
63
- end
55
+ attempts_used >= DIFFICULTY_HASH[difficulty][:attempts]
64
56
  end
65
57
  end
66
58
  end
@@ -8,8 +8,8 @@ module Codebreaker
8
8
 
9
9
  validate :numbers, :presence
10
10
  validate :numbers, :type, Integer
11
- validate :numbers, :length, AMOUNT_OF_NUMBERS
12
- validate :numbers, :range, RANGE_OF_NUMBERS
11
+ validate :numbers, :length, Codebreaker::Codemaker::AMOUNT_OF_NUMBERS
12
+ validate :numbers, :range, Codebreaker::Codemaker::RANGE_OF_NUMBERS
13
13
 
14
14
  def initialize(numbers)
15
15
  @numbers = numbers
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Codebreaker
4
+ class Sorter
5
+ CONDITIONAL_ARRAY = %i[hell medium easy].freeze
6
+
7
+ attr_reader :data
8
+
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
13
+ def call
14
+ sorted = sort_by_hints(data)
15
+ sorted = sort_by_attempts(sorted)
16
+ sorted = sort_by_difficulties(sorted)
17
+ sorted
18
+ end
19
+
20
+ private
21
+
22
+ def sort_by_hints(data)
23
+ data.sort_by { |row| row[:hints_used] }
24
+ end
25
+
26
+ def sort_by_attempts(data)
27
+ data.sort_by { |row| row[:attempts_used] }
28
+ end
29
+
30
+ def sort_by_difficulties(data)
31
+ data.sort_by { |row| CONDITIONAL_ARRAY.index(row[:difficulty]) }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Codebreaker
4
+ class Statistic
5
+ attr_reader :file_path
6
+
7
+ def initialize(file_path)
8
+ @file_path = file_path
9
+ end
10
+
11
+ def save(game)
12
+ data = File.file?(file_path) && !File.zero?(file_path) ? read : []
13
+ data << new_record(game)
14
+ file = File.open(file_path, 'w')
15
+ file.write(data.to_yaml)
16
+ file.close
17
+ end
18
+
19
+ def read
20
+ YAML.load_file(file_path)
21
+ end
22
+
23
+ private
24
+
25
+ def new_record(game)
26
+ user = game.user.name
27
+ attempts_total = Codebreaker::Game::DIFFICULTY_HASH[game.difficulty][:attempts]
28
+ attempts_used = game.attempts_used
29
+ hints_total = Codebreaker::Game::DIFFICULTY_HASH[game.difficulty][:hints]
30
+ hints_used = game.hints_used.size
31
+ { user: user, difficulty: game.difficulty, attempts_total: attempts_total,
32
+ attempts_used: attempts_used, hints_total: hints_total, hints_used: hints_used }
33
+ end
34
+ end
35
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Codebreaker
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.2'
5
5
  end
@@ -30,9 +30,7 @@ module Validations
30
30
  end
31
31
 
32
32
  def validate_range(value, name, range)
33
- return unless value.to_s.split('').map(&:to_i).any? { |number| !range.include?(number) }
34
-
35
- raise OutOfRangeError, "#{name} must be in #{range}"
33
+ raise OutOfRangeError, "#{name} must be in #{range}" if out_of_range?(value, range)
36
34
  end
37
35
 
38
36
  def validate_type(value, name, type_class)
@@ -54,5 +52,9 @@ module Validations
54
52
  length.member?(count)
55
53
  end
56
54
  end
55
+
56
+ def out_of_range?(value, range)
57
+ value.digits.reverse.any? { |number| !range.include?(number) }
58
+ end
57
59
  end
58
60
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebreaker_sn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-08 00:00:00.000000000 Z
11
+ date: 2020-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fasterer
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-performance
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rubocop-rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -117,10 +131,15 @@ files:
117
131
  - bin/console
118
132
  - bin/setup
119
133
  - codebreaker.gemspec
134
+ - codebreaker_sn-0.1.0.gem
135
+ - lib/autoload.rb
120
136
  - lib/codebreaker.rb
137
+ - lib/codebreaker/codechecker.rb
121
138
  - lib/codebreaker/codemaker.rb
122
139
  - lib/codebreaker/game.rb
123
140
  - lib/codebreaker/guess.rb
141
+ - lib/codebreaker/sorter.rb
142
+ - lib/codebreaker/statistic.rb
124
143
  - lib/codebreaker/user.rb
125
144
  - lib/codebreaker/version.rb
126
145
  - lib/errors/class_type_error.rb
@@ -129,8 +148,6 @@ files:
129
148
  - lib/errors/out_of_range_error.rb
130
149
  - lib/errors/presence_error.rb
131
150
  - lib/errors/validation_error.rb
132
- - lib/files/results_file.csv
133
- - lib/files/rules.txt
134
151
  - lib/moduls/validations.rb
135
152
  homepage: https://github.com/sergeynakul/codebreaker
136
153
  licenses:
@@ -153,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
170
  - !ruby/object:Gem::Version
154
171
  version: '0'
155
172
  requirements: []
156
- rubygems_version: 3.1.2
173
+ rubygems_version: 3.0.4
157
174
  signing_key:
158
175
  specification_version: 4
159
176
  summary: Codebreaker game
File without changes
@@ -1,14 +0,0 @@
1
- Game Rules
2
- Codebreaker is a logic game in which a code-breaker tries to break a secret code created by a code-maker. The codemaker, which will be played by the application we’re going to write, creates a secret code of four numbers between 1 and 6.
3
- The codebreaker gets some number of chances to break the code (depends on chosen difficulty). In each turn, the codebreaker makes a guess of 4 numbers. The codemaker then marks the guess with up to 4 signs - + or - or empty spaces.
4
- A + indicates an exact match: one of the numbers in the guess is the same as one of the numbers in the secret code and in the same position. For example:
5
- Secret number - 1234
6
- Input number - 6264
7
- Number of pluses - 2 (second and fourth position)
8
- A - indicates a number match: one of the numbers in the guess is the same as one of the numbers in the secret code but in a different position. For example:
9
- Secret number - 1234
10
- Input number - 6462
11
- Number of minuses - 2 (second and fourth position)
12
- An empty space indicates that there is not a current digit in a secret number.
13
- If codebreaker inputs the exact number as a secret number - codebreaker wins the game. If all attempts are spent - codebreaker loses.
14
- Codebreaker also has some number of hints(depends on chosen difficulty). If a user takes a hint - he receives back a separate digit of the secret code.