codebreaker_smn 0.1.2 → 0.1.3
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/.rspec +0 -2
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile.lock +6 -0
- data/codebreaker_smn.gemspec +3 -0
- data/lib/codebreaker_smn.rb +91 -46
- data/lib/codebreaker_smn/helpers/code_handler.rb +31 -23
- data/lib/codebreaker_smn/helpers/validation_helper.rb +25 -35
- data/lib/codebreaker_smn/version.rb +1 -1
- metadata +46 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3ffd0c70f709b3a838da9da77894735120773d9dd83e18368bc516c9d9c2a21
|
4
|
+
data.tar.gz: 3dd3f1fd8dd6ee5ffd3a41121e7409119d3dd6e174b6de516fe75401c53653aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 519c949f7c607d2c75d18210b2c73e2beb5b5a96118d56ac82b15634ca1e20d337557a0594ff7195d7dc99b9f979d1d042bd45fbbd21602a99e43fc934cc9c07
|
7
|
+
data.tar.gz: 7cb62f5fe76526c8ecfce4616443cbab702462d3c1822e3fee1d2810b6ee2f5b25e03c0b9a8cd848c4c674345da0aeaab46436813af5c0493400715719e85f5f
|
data/.rspec
CHANGED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
codebreaker_smn
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.5.1
|
data/Gemfile.lock
CHANGED
@@ -6,9 +6,14 @@ PATH
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
coderay (1.1.2)
|
9
10
|
diff-lcs (1.3)
|
10
11
|
docile (1.3.2)
|
11
12
|
json (2.2.0)
|
13
|
+
method_source (0.9.2)
|
14
|
+
pry (0.12.2)
|
15
|
+
coderay (~> 1.1.0)
|
16
|
+
method_source (~> 0.9.0)
|
12
17
|
rake (10.5.0)
|
13
18
|
rspec (3.8.0)
|
14
19
|
rspec-core (~> 3.8.0)
|
@@ -35,6 +40,7 @@ PLATFORMS
|
|
35
40
|
DEPENDENCIES
|
36
41
|
bundler (~> 2.0)
|
37
42
|
codebreaker_smn!
|
43
|
+
pry
|
38
44
|
rake (~> 10.0)
|
39
45
|
rspec (~> 3.0)
|
40
46
|
simplecov
|
data/codebreaker_smn.gemspec
CHANGED
@@ -40,4 +40,7 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
41
41
|
spec.add_development_dependency 'rake', '~> 10.0'
|
42
42
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
43
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.4'
|
44
|
+
spec.add_development_dependency 'rubocop', '~> 0.71.0'
|
45
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.33'
|
43
46
|
end
|
data/lib/codebreaker_smn.rb
CHANGED
@@ -5,13 +5,25 @@ module CodebreakerSmn
|
|
5
5
|
include ValidationHelper
|
6
6
|
|
7
7
|
DIFFICULTIES = {
|
8
|
-
|
8
|
+
hell: { attempts: 5, hints: 1 },
|
9
9
|
medium: { attempts: 10, hints: 1 },
|
10
|
-
|
10
|
+
easy: { attempts: 15, hints: 2 }
|
11
11
|
}.freeze
|
12
12
|
|
13
|
+
CODE_RULES = {
|
14
|
+
size: 4,
|
15
|
+
digits: 1..6
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
USERNAME_RULES = {
|
19
|
+
min_length: 3,
|
20
|
+
max_length: 20
|
21
|
+
}
|
22
|
+
|
23
|
+
WIN_RESULT = '++++'.freeze
|
24
|
+
|
13
25
|
attr_reader :code, :state, :difficulty, :username
|
14
|
-
attr_accessor :attempts, :hints
|
26
|
+
attr_accessor :attempts, :hints
|
15
27
|
|
16
28
|
def initialize
|
17
29
|
new_game
|
@@ -27,61 +39,28 @@ module CodebreakerSmn
|
|
27
39
|
@state = :started
|
28
40
|
end
|
29
41
|
|
30
|
-
def
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
def game_over
|
35
|
-
@state = :game_over
|
36
|
-
end
|
37
|
-
|
38
|
-
def high_scores
|
39
|
-
attempts_total = DIFFICULTIES[@difficulty.to_sym][:attempts]
|
42
|
+
def statistics
|
43
|
+
attempts_total = DIFFICULTIES[@difficulty][:attempts]
|
40
44
|
attempts_used = attempts_total - @attempts
|
41
|
-
hints_total = DIFFICULTIES[@difficulty
|
45
|
+
hints_total = DIFFICULTIES[@difficulty][:hints]
|
42
46
|
hints_used = hints_total - @hints
|
43
|
-
{ name: @username, difficulty: @difficulty,
|
47
|
+
{ name: @username, difficulty: @difficulty.to_s,
|
44
48
|
attempts_total: attempts_total, attempts_used: attempts_used,
|
45
49
|
hints_total: hints_total, hints_used: hints_used,
|
46
50
|
date: Date.today }
|
47
51
|
end
|
48
52
|
|
49
|
-
def generate_code
|
50
|
-
@code = Array.new(4) { rand(1..6) }
|
51
|
-
end
|
52
|
-
|
53
|
-
def generate_hint
|
54
|
-
@hint_code = @code.sample(DIFFICULTIES[@difficulty.to_sym][:hints])
|
55
|
-
end
|
56
|
-
|
57
53
|
def guess_code(input)
|
58
54
|
return unless valid_guess?(input)
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
result = CodeHandler.process_guess(@code, input)
|
64
|
-
select_winner(result, @attempts)
|
65
|
-
elsif @attempts == 1 && @state == :started
|
66
|
-
@attempts -= 1
|
67
|
-
result = CodeHandler.process_guess(@code, input)
|
68
|
-
select_winner(result, @attempts)
|
69
|
-
else
|
70
|
-
game_over
|
71
|
-
end
|
72
|
-
result
|
73
|
-
end
|
74
|
-
|
75
|
-
def select_winner(result, attempts)
|
76
|
-
if attempts.positive?
|
77
|
-
win if result == '++++'
|
78
|
-
else
|
79
|
-
result == '++++' ? win : game_over
|
56
|
+
CodeHandler.process_guess(@code, input) do |result|
|
57
|
+
select_winner(result)
|
58
|
+
take_attempt
|
80
59
|
end
|
81
60
|
end
|
82
61
|
|
83
62
|
def get_hint
|
84
|
-
result =
|
63
|
+
result = hint_code
|
85
64
|
if @hints.positive? && @state == :started
|
86
65
|
@hints -= 1
|
87
66
|
result.pop
|
@@ -97,9 +76,9 @@ module CodebreakerSmn
|
|
97
76
|
end
|
98
77
|
|
99
78
|
def difficulty=(level)
|
100
|
-
return unless valid_difficulty?(level, DIFFICULTIES.keys
|
79
|
+
return unless valid_difficulty?(level.to_sym, DIFFICULTIES.keys)
|
101
80
|
|
102
|
-
@difficulty = level
|
81
|
+
@difficulty = level.to_sym
|
103
82
|
@attempts = DIFFICULTIES[level.to_sym][:attempts]
|
104
83
|
@hints = DIFFICULTIES[level.to_sym][:hints]
|
105
84
|
end
|
@@ -108,8 +87,74 @@ module CodebreakerSmn
|
|
108
87
|
|
109
88
|
attr_writer :code, :state
|
110
89
|
|
90
|
+
def win
|
91
|
+
@state = :win
|
92
|
+
end
|
93
|
+
|
94
|
+
def game_over
|
95
|
+
@state = :game_over
|
96
|
+
end
|
97
|
+
|
98
|
+
def generate_code
|
99
|
+
@code = Array.new(CODE_RULES[:size]) { rand(CODE_RULES[:digits]) }
|
100
|
+
end
|
101
|
+
|
102
|
+
def hint_code
|
103
|
+
@hint_code ||= @code.sample(DIFFICULTIES[@difficulty][:hints])
|
104
|
+
end
|
105
|
+
|
106
|
+
def select_winner(result)
|
107
|
+
if many_attempts?
|
108
|
+
win if winner?(result)
|
109
|
+
elsif last_attempt?
|
110
|
+
winner?(result) ? win : game_over
|
111
|
+
else
|
112
|
+
game_over
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def take_attempt
|
117
|
+
@attempts -= 1
|
118
|
+
end
|
119
|
+
|
120
|
+
def many_attempts?
|
121
|
+
@attempts > 1 && @state == :started
|
122
|
+
end
|
123
|
+
|
124
|
+
def last_attempt?
|
125
|
+
@attempts == 1 && @state == :started
|
126
|
+
end
|
127
|
+
|
128
|
+
def winner?(result)
|
129
|
+
result == WIN_RESULT
|
130
|
+
end
|
131
|
+
|
111
132
|
def reset_params
|
112
133
|
@username, @difficulty, @hint_code = nil
|
113
134
|
end
|
135
|
+
|
136
|
+
def valid_name?(username)
|
137
|
+
not_empty_string(username) &&
|
138
|
+
valid_length(
|
139
|
+
input: username,
|
140
|
+
from: USERNAME_RULES[:min_length],
|
141
|
+
to: USERNAME_RULES[:max_length]
|
142
|
+
)
|
143
|
+
end
|
144
|
+
|
145
|
+
def valid_difficulty?(level, difficulty_array)
|
146
|
+
difficulty_array.include?(level)
|
147
|
+
end
|
148
|
+
|
149
|
+
def valid_guess?(input)
|
150
|
+
not_empty_string(input) &&
|
151
|
+
positive_integers(input.split('').map(&:to_i)) &&
|
152
|
+
valid_digits(input.split('').map(&:to_i), CODE_RULES[:digits]) &&
|
153
|
+
valid_length(
|
154
|
+
input: input,
|
155
|
+
from: CODE_RULES[:size],
|
156
|
+
to: CODE_RULES[:size]
|
157
|
+
)
|
158
|
+
end
|
114
159
|
end
|
115
160
|
end
|
@@ -1,30 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module CodebreakerSmn
|
4
|
+
class CodeHandler
|
5
|
+
def self.process_guess(code, input)
|
6
|
+
temp_code = code.clone
|
7
|
+
input = input.split('').map(&:to_i)
|
7
8
|
|
8
|
-
|
9
|
-
end
|
9
|
+
result = plus(temp_code, input) + minus(temp_code, input)
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
yield(result)
|
12
|
+
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def self.plus(code, input)
|
19
|
+
input.collect.with_index do |char, index|
|
20
|
+
if code.include?(char) && (code[index] == char)
|
21
|
+
input[index], code[index] = nil
|
22
|
+
'+'
|
23
|
+
end
|
24
|
+
end.join
|
25
|
+
end
|
19
26
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
def self.minus(code, input)
|
28
|
+
input.compact!
|
29
|
+
code.compact!
|
30
|
+
code.collect.with_index do |char, index|
|
31
|
+
if input.include?(char)
|
32
|
+
code[index], input[input.index(char)] = nil
|
33
|
+
'-'
|
34
|
+
end
|
35
|
+
end.join
|
36
|
+
end
|
29
37
|
end
|
30
38
|
end
|
@@ -1,40 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Validate parameters
|
4
|
-
module
|
5
|
-
|
6
|
-
not_empty_string(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
positive_integers(input)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
(input
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def positive_integer(input)
|
30
|
-
(input.is_a? Integer) && input.positive?
|
31
|
-
end
|
32
|
-
|
33
|
-
def valid_guess_length(input)
|
34
|
-
input.size.eql?(4)
|
35
|
-
end
|
36
|
-
|
37
|
-
def valid_digits(input)
|
38
|
-
input.match(/[1-6]+/)
|
4
|
+
module CodebreakerSmn
|
5
|
+
module ValidationHelper
|
6
|
+
def not_empty_string(input)
|
7
|
+
(input.is_a? String) && !input.empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid_length(input:, from:, to:)
|
11
|
+
input.size.between?(from, to)
|
12
|
+
end
|
13
|
+
|
14
|
+
def positive_integers(input)
|
15
|
+
input.all? { |char| positive_integer(char) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def positive_integer(input)
|
19
|
+
(input.is_a? Integer) && input.positive?
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_digits(input, range)
|
23
|
+
input.all? { |digit| valid_digit(digit, range) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_digit(digit, range)
|
27
|
+
range.include?(digit)
|
28
|
+
end
|
39
29
|
end
|
40
30
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Someone443
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,48 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.71.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.71.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: '1.33'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.33'
|
55
97
|
description: Codebreaker is a logic game in which a code-breaker tries to break a
|
56
98
|
secret code created by a code-maker.
|
57
99
|
email:
|
@@ -63,6 +105,8 @@ files:
|
|
63
105
|
- ".gitignore"
|
64
106
|
- ".rspec"
|
65
107
|
- ".rubocop.yml"
|
108
|
+
- ".ruby-gemset"
|
109
|
+
- ".ruby-version"
|
66
110
|
- ".travis.yml"
|
67
111
|
- Gemfile
|
68
112
|
- Gemfile.lock
|