codebreaker_kirill 1.2.1 → 1.3.0
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/lib/codebreaker_kirill/autoload.rb +10 -8
- data/lib/codebreaker_kirill/code_generator.rb +5 -3
- data/lib/codebreaker_kirill/game.rb +26 -22
- data/lib/codebreaker_kirill/guess_handler.rb +27 -23
- data/lib/codebreaker_kirill/settings.rb +15 -13
- data/lib/codebreaker_kirill/stats.rb +12 -10
- data/lib/codebreaker_kirill/user.rb +18 -14
- data/lib/codebreaker_kirill/validations.rb +20 -16
- data/lib/codebreaker_kirill/version.rb +1 -1
- data/lib/codebreaker_kirill.rb +5 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 062f979cfbfa6fae7dafffd0050694e70e9437246fd70ff52105311a553f2c88
|
4
|
+
data.tar.gz: 74b6e47c51c165ba8d8e282e65e5f0fd78a87478087866e2a42a395e4c24a832
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9f476f9734a0aa99d1aebe9ff5205b647ae976939bf3b11322b56a638dfbb041d01f4ff5dccc4d47afdc4be272bc05debba1e83c57b4f2bd5fc4bff8b33fc78
|
7
|
+
data.tar.gz: 66ab34e34020fa4b49951f71b95928a26a62ba339c5a6a008a0369c30fe159e66e7cfcfceb1d85e96ade537e39bfb7b984e43953a0589740e556e30731304a31
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
9
|
-
require_relative '
|
10
|
-
require_relative '
|
3
|
+
module CodebreakerKirill
|
4
|
+
require 'yaml'
|
5
|
+
require_relative 'settings'
|
6
|
+
require_relative 'code_generator'
|
7
|
+
require_relative 'validations'
|
8
|
+
require_relative 'guess_handler'
|
9
|
+
require_relative 'user'
|
10
|
+
require_relative 'game'
|
11
|
+
require_relative 'stats'
|
12
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
4
|
-
|
5
|
-
|
3
|
+
module CodebreakerKirill
|
4
|
+
module CodeGenerator
|
5
|
+
def self.call
|
6
|
+
Array.new(Settings::CODE_LENGTH) { rand(Settings::RANDOM_RANGE) }
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
@@ -2,34 +2,38 @@
|
|
2
2
|
|
3
3
|
require_relative 'autoload'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
module CodebreakerKirill
|
6
|
+
class Game
|
7
|
+
include CodeGenerator
|
7
8
|
|
8
|
-
|
9
|
+
attr_reader :user
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def initialize(user)
|
12
|
+
@secret_code = CodeGenerator.call
|
13
|
+
@user = user
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
def give_a_hint
|
17
|
+
return nil if @user.hints_used >= @user.level[:hints]
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
@user.hints_used += 1
|
20
|
+
@secret_code.shuffle[@user.hints_used]
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
def respond_to_guess(input)
|
24
|
+
@user.attempts_used += 1
|
25
|
+
status = status(input, @secret_code)
|
26
|
+
resolved_code = GuessHandler.new(input, @secret_code).call
|
27
|
+
return { status: status, secret_code: @secret_code } if status == 'loss'
|
28
|
+
|
29
|
+
{ status: status, response: resolved_code, secret_code: @secret_code }
|
30
|
+
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
def status(input, code)
|
33
|
+
return 'loss' if @user.attempts_used >= @user.level[:attempts]
|
34
|
+
return 'win' if input.each_char.map(&:to_i) == code
|
32
35
|
|
33
|
-
|
36
|
+
'in_game'
|
37
|
+
end
|
34
38
|
end
|
35
39
|
end
|
@@ -2,35 +2,39 @@
|
|
2
2
|
|
3
3
|
require_relative 'autoload'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@input = input.each_char.map(&:to_i)
|
9
|
-
@code = code.clone
|
10
|
-
@result = []
|
11
|
-
end
|
5
|
+
module CodebreakerKirill
|
6
|
+
class GuessHandler
|
7
|
+
include Settings
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
def initialize(input, code)
|
10
|
+
Validations.validate_guess(input)
|
11
|
+
@input = input.each_char.map(&:to_i)
|
12
|
+
@code = code.clone
|
13
|
+
@result = []
|
14
|
+
end
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
def call
|
17
|
+
check_same_indexes
|
18
|
+
check_different_indexes
|
19
|
+
@result
|
20
|
+
end
|
21
|
+
|
22
|
+
def check_same_indexes
|
23
|
+
@input.each_index do |index|
|
24
|
+
next unless @input[index] == @code[index]
|
22
25
|
|
23
|
-
|
24
|
-
|
26
|
+
@result << Settings::POSITIVE_RESPONSE
|
27
|
+
@input[index], @code[index] = nil
|
28
|
+
end
|
25
29
|
end
|
26
|
-
end
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
def check_different_indexes
|
32
|
+
@input.each_with_index do |value, _index|
|
33
|
+
next unless !value.nil? && @code.include?(value)
|
31
34
|
|
32
|
-
|
33
|
-
|
35
|
+
@result << Settings::NEGATIVE_RESPONSE
|
36
|
+
@input[@input.find_index(value)], @code[@code.find_index(value)] = nil
|
37
|
+
end
|
34
38
|
end
|
35
39
|
end
|
36
40
|
end
|
@@ -2,17 +2,19 @@
|
|
2
2
|
|
3
3
|
require_relative 'autoload'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
5
|
+
module CodebreakerKirill
|
6
|
+
module Settings
|
7
|
+
DIFFICULTY = {
|
8
|
+
'easy' => { attempts: 15, hints: 2 },
|
9
|
+
'medium' => { attempts: 10, hints: 1 },
|
10
|
+
'hell' => { attempts: 5, hints: 1 }
|
11
|
+
}.freeze
|
12
|
+
CODE_LENGTH = 4
|
13
|
+
RANDOM_RANGE = (1..6).freeze
|
14
|
+
POSITIVE_RESPONSE = '+'
|
15
|
+
NEGATIVE_RESPONSE = '-'
|
16
|
+
NAME_MIN_LENGTH = 3
|
17
|
+
NAME_MAX_LENGTH = 20
|
18
|
+
GUESS_LENGTH = 4
|
19
|
+
end
|
18
20
|
end
|
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
require_relative 'autoload'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
module CodebreakerKirill
|
6
|
+
class Stats
|
7
|
+
def self.save_game(user)
|
8
|
+
@data = File.exist?('stats.yml') ? YAML.load_file('stats.yml') : []
|
9
|
+
@data << user
|
10
|
+
File.new('stats.yml', 'w') unless File.exist?('stats.yml')
|
11
|
+
File.open('stats.yml', 'w') { |file| file.write(@data.to_yaml) }
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
def self.show_stats
|
15
|
+
@data = File.exist?('stats.yml') ? YAML.load_file('stats.yml') : []
|
16
|
+
@data.sort_by! { |user| [user.level[:attempts], user.attempts_used, user.hints_used] }
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
@@ -2,21 +2,25 @@
|
|
2
2
|
|
3
3
|
require_relative 'autoload'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
module CodebreakerKirill
|
6
|
+
class User
|
7
|
+
include Settings
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
attr_accessor :attempts_used, :hints_used
|
10
|
+
attr_reader :difficulty, :name, :level
|
11
|
+
|
12
|
+
def initialize(name, difficulty)
|
13
|
+
validation(name, difficulty)
|
14
|
+
@difficulty = difficulty
|
15
|
+
@name = name
|
16
|
+
@level = Settings::DIFFICULTY[@difficulty]
|
17
|
+
@attempts_used = 0
|
18
|
+
@hints_used = 0
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
def validation(name, difficulty)
|
22
|
+
Validations.validate_name(name)
|
23
|
+
Validations.validate_difficulty(difficulty)
|
24
|
+
end
|
21
25
|
end
|
22
26
|
end
|
@@ -2,24 +2,28 @@
|
|
2
2
|
|
3
3
|
require_relative 'autoload'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
raise 'Name should be string' if name.class != String
|
9
|
-
raise 'Name should be at least 3 characters long' if name.length < Settings::NAME_MIN_LENGTH
|
10
|
-
raise "Name shouldn't be more than 20 characters long" if name.length > Settings::NAME_MAX_LENGTH
|
11
|
-
end
|
5
|
+
module CodebreakerKirill
|
6
|
+
class Validations
|
7
|
+
include Settings
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
def self.validate_name(name)
|
10
|
+
raise "Name shouldn't be empty" if name.empty?
|
11
|
+
raise 'Name should be string' if name.class != String
|
12
|
+
raise 'Name should be at least 3 characters long' if name.length < Settings::NAME_MIN_LENGTH
|
13
|
+
raise "Name shouldn't be more than 20 characters long" if name.length > Settings::NAME_MAX_LENGTH
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.validate_guess(guess)
|
17
|
+
raise "Guess shouldn't be empty" if guess.empty?
|
18
|
+
raise "Guess should be 4 characters. Got #{guess}" if guess.length < Settings::GUESS_LENGTH
|
19
|
+
raise 'Guess shouldn\'t be more than 4 characters long' if guess.length > Settings::GUESS_LENGTH
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
def self.validate_difficulty(difficulty)
|
23
|
+
raise "Input shouldn't be empty" if difficulty.empty?
|
24
|
+
return if Settings::DIFFICULTY.keys.include?(difficulty)
|
22
25
|
|
23
|
-
|
26
|
+
raise "You should enter one of the following options: #{Settings::DIFFICULTY.keys.join(', ')}"
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
data/lib/codebreaker_kirill.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'codebreaker_kirill/version'
|
4
|
-
require_relative 'codebreaker_kirill/game'
|
5
|
-
require_relative 'codebreaker_kirill/user'
|
6
|
-
require_relative 'codebreaker_kirill/guess_handler'
|
7
3
|
require_relative 'codebreaker_kirill/settings'
|
4
|
+
require_relative 'codebreaker_kirill/code_generator'
|
5
|
+
require_relative 'codebreaker_kirill/validations'
|
6
|
+
require_relative 'codebreaker_kirill/guess_handler'
|
7
|
+
require_relative 'codebreaker_kirill/user'
|
8
|
+
require_relative 'codebreaker_kirill/game'
|
8
9
|
require_relative 'codebreaker_kirill/stats'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codebreaker_kirill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kirill Dudchenko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|