codebreaker_smn 0.1.1 → 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: 818dedfd723a81147690ad0ee563663536f138cc119ae7c05837ff593a518194
4
- data.tar.gz: 7a759cf89765076b62a5b51605400332bf74bc83800c8cf47224ec295b8cbc09
3
+ metadata.gz: 60a3274f3648ff487fb30920c98a724dc8721e770bb669a0847f002ff47d8a14
4
+ data.tar.gz: d5bf753a91bb8690b9c199d2312befdddd376720f2a822028fbaaeb0ea22812e
5
5
  SHA512:
6
- metadata.gz: 1d606c9062e04896f11c577867d69a4e33094d6d48b0e646e192df505b663ad124809a631a0c8693e6de4361699e9dcdd6339423567484196d00ccbf066e97e7
7
- data.tar.gz: e5f06e3439ac902bf1d4109bb075d72be8e83c28ab67d3e25b441376c30015d1d2fd2930ea82c43b399a7a20fd21649cb6e16c243a5c35c827e991daca9c8548
6
+ metadata.gz: 7f09e0fd84e11da945c853362701571d8235efd9c2d5d1134cf0f9fd0e81e9839e1d31219510f275ec6366d9e2efe9c78c977946095cb2357d22d6698a1f7bbf
7
+ data.tar.gz: 2f54e59132718e98c8b7fe06ecd4b9f63bbe97a87d32f5aa253a5d1ecac75d7b14509c92baa777c05094e011fcd91b59debda2eae1731d577e332a3fe5c5a94e
data/.rubocop.yml ADDED
@@ -0,0 +1,30 @@
1
+ require: rubocop-rspec
2
+
3
+ RSpec/MessageChain:
4
+ Enabled: false
5
+
6
+ RSpec/NestedGroups:
7
+ Max: 5
8
+
9
+ RSpec/MultipleExpectations:
10
+ Max: 5
11
+
12
+ RSpec/ExampleLength:
13
+ Max: 10
14
+
15
+ RSpec/MessageSpies:
16
+ Enabled: false
17
+
18
+ Metrics/BlockLength:
19
+ Exclude:
20
+ - 'Gemfile'
21
+ - 'spec/**/*.rb'
22
+
23
+ Metrics/LineLength:
24
+ Max: 120
25
+
26
+ Documentation:
27
+ Enabled: false
28
+
29
+ FrozenStringLiteralComment:
30
+ Enabled: false
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in codebreaker.gemspec
4
4
  gemspec
5
5
 
6
- gem 'simplecov', require: false, group: :test
6
+ gem 'simplecov', require: false, group: :test
data/Gemfile.lock CHANGED
@@ -1,43 +1,43 @@
1
- PATH
2
- remote: .
3
- specs:
4
- codebreaker_smn (0.1.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- diff-lcs (1.3)
10
- docile (1.3.2)
11
- json (2.2.0)
12
- rake (10.5.0)
13
- rspec (3.8.0)
14
- rspec-core (~> 3.8.0)
15
- rspec-expectations (~> 3.8.0)
16
- rspec-mocks (~> 3.8.0)
17
- rspec-core (3.8.2)
18
- rspec-support (~> 3.8.0)
19
- rspec-expectations (3.8.4)
20
- diff-lcs (>= 1.2.0, < 2.0)
21
- rspec-support (~> 3.8.0)
22
- rspec-mocks (3.8.1)
23
- diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.8.0)
25
- rspec-support (3.8.2)
26
- simplecov (0.16.1)
27
- docile (~> 1.1)
28
- json (>= 1.8, < 3)
29
- simplecov-html (~> 0.10.0)
30
- simplecov-html (0.10.2)
31
-
32
- PLATFORMS
33
- x64-mingw32
34
-
35
- DEPENDENCIES
36
- bundler (~> 2.0)
37
- codebreaker_smn!
38
- rake (~> 10.0)
39
- rspec (~> 3.0)
40
- simplecov
41
-
42
- BUNDLED WITH
43
- 2.0.2
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ codebreaker_smn (0.1.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ docile (1.3.2)
11
+ json (2.2.0)
12
+ rake (10.5.0)
13
+ rspec (3.8.0)
14
+ rspec-core (~> 3.8.0)
15
+ rspec-expectations (~> 3.8.0)
16
+ rspec-mocks (~> 3.8.0)
17
+ rspec-core (3.8.2)
18
+ rspec-support (~> 3.8.0)
19
+ rspec-expectations (3.8.4)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.8.0)
22
+ rspec-mocks (3.8.1)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.8.0)
25
+ rspec-support (3.8.2)
26
+ simplecov (0.16.1)
27
+ docile (~> 1.1)
28
+ json (>= 1.8, < 3)
29
+ simplecov-html (~> 0.10.0)
30
+ simplecov-html (0.10.2)
31
+
32
+ PLATFORMS
33
+ x64-mingw32
34
+
35
+ DEPENDENCIES
36
+ bundler (~> 2.0)
37
+ codebreaker_smn!
38
+ rake (~> 10.0)
39
+ rspec (~> 3.0)
40
+ simplecov
41
+
42
+ BUNDLED WITH
43
+ 2.0.2
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "codebreaker_smn"
3
+ require 'bundler/setup'
4
+ require 'codebreaker_smn'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "codebreaker_smn"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
@@ -1,40 +1,39 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "codebreaker_smn/version"
3
+ require 'codebreaker_smn/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "codebreaker_smn"
6
+ spec.name = 'codebreaker_smn'
8
7
  spec.version = CodebreakerSmn::VERSION
9
- spec.authors = ["Someone443"]
10
- spec.email = ["kostyan.12@ukr.net"]
8
+ spec.authors = ['Someone443']
9
+ spec.email = ['kostyan.12@ukr.net']
11
10
 
12
- spec.summary = "Codebreaker game"
13
- spec.description = "Codebreaker is a logic game in which a code-breaker tries to break a secret code created by a code-maker."
14
- spec.homepage = "https://github.com/Someone443/codebreaker"
15
- spec.license = "MIT"
11
+ spec.summary = 'Codebreaker game'
12
+ spec.description = 'Codebreaker is a logic game in which a code-breaker tries to break a secret code created by a code-maker.'
13
+ spec.homepage = 'https://github.com/Someone443/codebreaker'
14
+ spec.license = 'MIT'
16
15
 
17
16
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
17
  # to allow pushing to a single host or delete this section to allow pushing to any host.
19
18
  if spec.respond_to?(:metadata)
20
- spec.metadata["allowed_push_host"] = "https://rubygems.org/"
19
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
21
20
 
22
- spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = "https://github.com/Someone443/codebreaker"
24
- spec.metadata["changelog_uri"] = "https://github.com/Someone443/codebreaker"
21
+ spec.metadata['homepage_uri'] = spec.homepage
22
+ spec.metadata['source_code_uri'] = 'https://github.com/Someone443/codebreaker'
23
+ spec.metadata['changelog_uri'] = 'https://github.com/Someone443/codebreaker'
25
24
  else
26
- raise "RubyGems 2.0 or newer is required to protect against " \
27
- "public gem pushes."
25
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
26
+ 'public gem pushes.'
28
27
  end
29
28
 
30
29
  # Specify which files should be added to the gem when it is released.
31
30
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
33
32
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
33
  end
35
- spec.bindir = "exe"
34
+ spec.bindir = 'exe'
36
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
- spec.require_paths = ["lib"]
36
+ spec.require_paths = ['lib']
38
37
 
39
38
  spec.required_ruby_version = '~> 2.5'
40
39
 
@@ -0,0 +1,5 @@
1
+ require_relative '../../codebreaker_smn/version.rb'
2
+ require_relative '../../codebreaker_smn/helpers/validation_helper.rb'
3
+ require_relative '../../codebreaker_smn/helpers/code_handler.rb'
4
+ require 'yaml'
5
+ require 'date'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CodeHandler
4
+ def self.process_guess(code, input)
5
+ temp_code = code.clone
6
+ input = input.split('').map(&:to_i)
7
+
8
+ plus(temp_code, input) + minus(temp_code, input)
9
+ end
10
+
11
+ def self.plus(code, input)
12
+ input.collect.with_index do |char, index|
13
+ if code.include?(char) && (code[index] == char)
14
+ input[index], code[index] = nil
15
+ '+'
16
+ end
17
+ end.join
18
+ end
19
+
20
+ def self.minus(code, input)
21
+ input.compact!
22
+ code.compact!
23
+ code.collect.with_index do |char, index|
24
+ if input.include?(char)
25
+ code[index], input[input.index(char)] = nil
26
+ '-'
27
+ end
28
+ end.join
29
+ end
30
+ end
@@ -2,36 +2,39 @@
2
2
 
3
3
  # Validate parameters
4
4
  module ValidationHelper
5
-
6
5
  def valid_name?(username)
7
6
  not_empty_string(username) && valid_username_length(username)
8
7
  end
9
8
 
10
- def validate_guess(input)
11
-
12
- input.split("").each { |char| positive_integer(char.to_i) }
9
+ def valid_difficulty?(level, difficulty_array)
10
+ difficulty_array.include?(level)
11
+ end
13
12
 
14
- valid_guess_length(input)
15
- valid_digits(input)
13
+ def valid_guess?(input)
14
+ positive_integers(input) && valid_guess_length(input) && valid_digits(input)
16
15
  end
17
-
16
+
18
17
  def not_empty_string(input)
19
- (input.is_a? String) && !(input.empty?)
18
+ (input.is_a? String) && !input.empty?
20
19
  end
21
20
 
22
21
  def valid_username_length(username)
23
22
  username.size.between?(3, 20)
24
23
  end
25
24
 
25
+ def positive_integers(input)
26
+ not_empty_string(input) && input.split('').all? { |char| positive_integer(char.to_i) }
27
+ end
28
+
26
29
  def positive_integer(input)
27
- raise ValidationError unless (input.is_a? Integer) && (input.positive?)
30
+ (input.is_a? Integer) && input.positive?
28
31
  end
29
32
 
30
33
  def valid_guess_length(input)
31
- raise ValidationError if !(input.size.eql?(4))
34
+ input.size.eql?(4)
32
35
  end
33
36
 
34
37
  def valid_digits(input)
35
- raise ValidationError if !(input.match(/[1-6]+/))
38
+ input.match(/[1-6]+/)
36
39
  end
37
- end
40
+ end
@@ -1,3 +1,3 @@
1
1
  module CodebreakerSmn
2
- VERSION = "0.1.1"
2
+ VERSION = '0.1.2'.freeze
3
3
  end
@@ -1,31 +1,20 @@
1
- require_relative './codebreaker_smn/version.rb'
2
- require_relative './codebreaker_smn/helpers/validation_helper.rb'
3
- require_relative './codebreaker_smn/helpers/errors/validation_error.rb'
4
- require 'yaml'
1
+ require_relative './codebreaker_smn/config/setup.rb'
5
2
 
6
3
  module CodebreakerSmn
7
4
  class Game
8
5
  include ValidationHelper
9
- # Codebreaker class
10
- # Codemaker class
11
- # DB Helper class/module
12
- # Stats class
13
- # Output class -> logic regarding returning messages on errors/hints/help/etc.
14
- # Validation class
15
- # Custom errors class
16
6
 
17
7
  DIFFICULTIES = {
18
- easy: {attempts: 15, hints: 2},
19
- medium: {attempts: 10, hints: 1},
20
- hell: {attempts: 5, hints: 1}
21
- }
8
+ easy: { attempts: 15, hints: 2 },
9
+ medium: { attempts: 10, hints: 1 },
10
+ hell: { attempts: 5, hints: 1 }
11
+ }.freeze
22
12
 
23
- attr_reader :code, :state, :difficulty
24
- attr_accessor :username, :attempts, :hints, :results
13
+ attr_reader :code, :state, :difficulty, :username
14
+ attr_accessor :attempts, :hints, :hint_code
25
15
 
26
16
  def initialize
27
17
  new_game
28
- @results = load_results
29
18
  end
30
19
 
31
20
  def new_game
@@ -46,123 +35,81 @@ module CodebreakerSmn
46
35
  @state = :game_over
47
36
  end
48
37
 
49
- def load_results # TODO!!!! db path should be provided from Console
50
- YAML.load_file('./db/results.yml')
51
- rescue SystemCallError
52
- []
53
- end
54
-
55
- def save_results # TODO!!!!
56
- if @state == :win
57
-
58
- attempts_total = DIFFICULTIES[@difficulty.to_sym][:attempts]
59
- attempts_used = attempts_total - @attempts
60
- hints_total = DIFFICULTIES[@difficulty.to_sym][:hints]
61
- hints_used = hints_total - @hints
62
-
63
- @results << {name: @username,
64
- difficulty: @difficulty,
65
- attempts_total: attempts_total,
66
- attempts_used: attempts_used,
67
- hints_total: hints_total,
68
- hints_used: hints_used,
69
- date: Date.today}
70
-
71
- File.write('./db/results.yml', @results.to_yaml)
72
- end
73
- end
74
-
75
- def high_scores # TODO!!!!
38
+ def high_scores
76
39
  attempts_total = DIFFICULTIES[@difficulty.to_sym][:attempts]
77
40
  attempts_used = attempts_total - @attempts
78
41
  hints_total = DIFFICULTIES[@difficulty.to_sym][:hints]
79
42
  hints_used = hints_total - @hints
80
-
81
- { name: @username,
82
- difficulty: @difficulty,
83
- attempts_total: attempts_total,
84
- attempts_used: attempts_used,
85
- hints_total: hints_total,
86
- hints_used: hints_used,
43
+ { name: @username, difficulty: @difficulty,
44
+ attempts_total: attempts_total, attempts_used: attempts_used,
45
+ hints_total: hints_total, hints_used: hints_used,
87
46
  date: Date.today }
88
-
89
- # This method should combine and sort stat inside @results var and just return this @results var
90
- # We should return @results from just last game -> Console or Web app should form Stat on its own
91
- #puts 'Name, Difficulty, Attempts Total, Attempts Used, Hints Total, Hints Used'
92
- #@results.each do |result|
93
- # puts %Q(#{result[:name]} #{result[:difficulty]} #{result[:attempts_total].to_s} #{result[:attempts_used].to_s} #{result[:hints_total].to_s} #{result[:hints_used].to_s})
94
- #end
95
47
  end
96
48
 
97
49
  def generate_code
98
50
  @code = Array.new(4) { rand(1..6) }
99
51
  end
100
52
 
53
+ def generate_hint
54
+ @hint_code = @code.sample(DIFFICULTIES[@difficulty.to_sym][:hints])
55
+ end
56
+
101
57
  def guess_code(input)
102
- validate_guess(input)
103
- result = ""
58
+ return unless valid_guess?(input)
59
+
60
+ result = ''
104
61
  if @attempts > 1 && @state == :started
105
62
  @attempts -= 1
106
- result = process_guess(input)
107
- win if result == "++++"
63
+ result = CodeHandler.process_guess(@code, input)
64
+ select_winner(result, @attempts)
108
65
  elsif @attempts == 1 && @state == :started
109
66
  @attempts -= 1
110
- result = process_guess(input)
111
- result == "++++" ? win : game_over
67
+ result = CodeHandler.process_guess(@code, input)
68
+ select_winner(result, @attempts)
112
69
  else
113
70
  game_over
114
71
  end
115
72
  result
116
73
  end
117
74
 
118
- def process_guess(input)
119
- temp_code = @code.clone
120
- input = input.split("")
121
- result = ""
122
- exclude_indexes = []
123
- input.each_with_index do |char, index|
124
- if temp_code.include?(char.to_i) && (temp_code[index] == char.to_i)
125
- result << "+"
126
- exclude_indexes << index
127
- end
128
- end
129
-
130
- exclude_indexes.reverse_each do |index|
131
- input.delete_at(index)
132
- temp_code.delete_at(index)
133
- end
134
-
135
- temp_code.each_with_index do |char, index|
136
- if input.include?(char.to_s) # input.uniq.include? or temp_code.uniq.include?
137
- result << "-"
138
- temp_code[index] = nil # We have to check if char is one in the input or several -> count of matches in input
139
- end # code = 1455, input = 5133
75
+ def select_winner(result, attempts)
76
+ if attempts.positive?
77
+ win if result == '++++'
78
+ else
79
+ result == '++++' ? win : game_over
140
80
  end
141
-
142
- result
143
81
  end
144
82
 
145
- def get_hint # TODO!
146
- if @hints > 0 && @state == :started
83
+ def get_hint
84
+ result = @hint_code || generate_hint
85
+ if @hints.positive? && @state == :started
147
86
  @hints -= 1
148
- code.sample
87
+ result.pop
149
88
  else
150
89
  'No hints left!'
151
90
  end
152
91
  end
153
92
 
154
- def set_difficulty(level)
155
- @difficulty = level
156
- @attempts = DIFFICULTIES[level.to_sym][:attempts]
157
- @hints = DIFFICULTIES[level.to_sym][:hints]
93
+ def username=(username)
94
+ return unless valid_name?(username)
95
+
96
+ @username = username
97
+ end
98
+
99
+ def difficulty=(level)
100
+ return unless valid_difficulty?(level, DIFFICULTIES.keys.map(&:to_s))
101
+
102
+ @difficulty = level
103
+ @attempts = DIFFICULTIES[level.to_sym][:attempts]
104
+ @hints = DIFFICULTIES[level.to_sym][:hints]
158
105
  end
159
106
 
160
107
  private
161
108
 
162
- attr_writer :code, :state, :difficulty
109
+ attr_writer :code, :state
163
110
 
164
111
  def reset_params
165
- @username, @difficulty = nil
112
+ @username, @difficulty, @hint_code = nil
166
113
  end
167
114
  end
168
115
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebreaker_smn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Someone443
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-22 00:00:00.000000000 Z
11
+ date: 2019-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -62,6 +62,7 @@ extra_rdoc_files: []
62
62
  files:
63
63
  - ".gitignore"
64
64
  - ".rspec"
65
+ - ".rubocop.yml"
65
66
  - ".travis.yml"
66
67
  - Gemfile
67
68
  - Gemfile.lock
@@ -72,6 +73,8 @@ files:
72
73
  - bin/setup
73
74
  - codebreaker_smn.gemspec
74
75
  - lib/codebreaker_smn.rb
76
+ - lib/codebreaker_smn/config/setup.rb
77
+ - lib/codebreaker_smn/helpers/code_handler.rb
75
78
  - lib/codebreaker_smn/helpers/errors/validation_error.rb
76
79
  - lib/codebreaker_smn/helpers/validation_helper.rb
77
80
  - lib/codebreaker_smn/version.rb