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 +4 -4
- data/.rubocop.yml +30 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +43 -43
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/codebreaker_smn.gemspec +18 -19
- data/lib/codebreaker_smn/config/setup.rb +5 -0
- data/lib/codebreaker_smn/helpers/code_handler.rb +30 -0
- data/lib/codebreaker_smn/helpers/validation_helper.rb +15 -12
- data/lib/codebreaker_smn/version.rb +1 -1
- data/lib/codebreaker_smn.rb +45 -98
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60a3274f3648ff487fb30920c98a724dc8721e770bb669a0847f002ff47d8a14
|
4
|
+
data.tar.gz: d5bf753a91bb8690b9c199d2312befdddd376720f2a822028fbaaeb0ea22812e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/Gemfile.lock
CHANGED
@@ -1,43 +1,43 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
codebreaker_smn (0.1.
|
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
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
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
|
13
|
+
require 'irb'
|
14
14
|
IRB.start(__FILE__)
|
data/codebreaker_smn.gemspec
CHANGED
@@ -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
|
3
|
+
require 'codebreaker_smn/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'codebreaker_smn'
|
8
7
|
spec.version = CodebreakerSmn::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
8
|
+
spec.authors = ['Someone443']
|
9
|
+
spec.email = ['kostyan.12@ukr.net']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
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[
|
19
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
21
20
|
|
22
|
-
spec.metadata[
|
23
|
-
spec.metadata[
|
24
|
-
spec.metadata[
|
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
|
27
|
-
|
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(
|
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 =
|
34
|
+
spec.bindir = 'exe'
|
36
35
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
-
spec.require_paths = [
|
36
|
+
spec.require_paths = ['lib']
|
38
37
|
|
39
38
|
spec.required_ruby_version = '~> 2.5'
|
40
39
|
|
@@ -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
|
11
|
-
|
12
|
-
|
9
|
+
def valid_difficulty?(level, difficulty_array)
|
10
|
+
difficulty_array.include?(level)
|
11
|
+
end
|
13
12
|
|
14
|
-
|
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) && !
|
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
|
-
|
30
|
+
(input.is_a? Integer) && input.positive?
|
28
31
|
end
|
29
32
|
|
30
33
|
def valid_guess_length(input)
|
31
|
-
|
34
|
+
input.size.eql?(4)
|
32
35
|
end
|
33
36
|
|
34
37
|
def valid_digits(input)
|
35
|
-
|
38
|
+
input.match(/[1-6]+/)
|
36
39
|
end
|
37
|
-
end
|
40
|
+
end
|
data/lib/codebreaker_smn.rb
CHANGED
@@ -1,31 +1,20 @@
|
|
1
|
-
require_relative './codebreaker_smn/
|
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
|
-
|
19
|
-
|
20
|
-
|
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 :
|
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
|
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
|
-
|
82
|
-
|
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
|
-
|
103
|
-
|
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
|
-
|
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
|
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
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
146
|
-
|
83
|
+
def get_hint
|
84
|
+
result = @hint_code || generate_hint
|
85
|
+
if @hints.positive? && @state == :started
|
147
86
|
@hints -= 1
|
148
|
-
|
87
|
+
result.pop
|
149
88
|
else
|
150
89
|
'No hints left!'
|
151
90
|
end
|
152
91
|
end
|
153
92
|
|
154
|
-
def
|
155
|
-
|
156
|
-
|
157
|
-
|
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
|
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.
|
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-
|
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
|