codebreaker_paratskiy 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/lib/codebreaker_paratskiy/version.rb +3 -0
- data/lib/codebreaker_paratskiy.rb +9 -0
- data/lib/config/constants.rb +14 -0
- data/lib/console.rb +118 -0
- data/lib/dependencies.rb +17 -0
- data/lib/error.rb +1 -0
- data/lib/game.rb +48 -0
- data/lib/i18n_config.rb +1 -0
- data/lib/load_game.rb +6 -0
- data/lib/modules/output.rb +50 -0
- data/lib/modules/validating.rb +5 -0
- data/lib/services/matching_service.rb +41 -0
- data/lib/services/statistic_service.rb +22 -0
- data/lib/utils/db_utils.rb +12 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc88f1830d8e2791f5f3e8ea508fbb5f80799b1d988d078c1dcd00d29fd6a9d5
|
4
|
+
data.tar.gz: 80e9b346a177f00ba3db89d97cf28ad26e503db15b53f45d90581c13de806bd3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48dec98c1fb5c73da45dfe8364504ce608495fafec2cc6e2bcabf2ab252cc934ca36878911fa269a7c5043144d1758777a3b1803f2f48b2edae13c0147632e4d
|
7
|
+
data.tar.gz: 4fd5da4b654e8e7953853a10631f67140436ad176483b9fc6f81fa06c59cc76813b46439cc813b4ee923012cc5be464770ed9eef69a9d9ec6835a0faa5428a93
|
@@ -0,0 +1,14 @@
|
|
1
|
+
DB = 'stats.yml'.freeze
|
2
|
+
|
3
|
+
DIFFICULTIES = {
|
4
|
+
easy: { attempts: 15, hints: 2 },
|
5
|
+
medium: { attempts: 10, hints: 1 },
|
6
|
+
hell: { attempts: 5, hints: 1 }
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
MAIN_MENU_COMMANDS = {
|
10
|
+
'start' => :start,
|
11
|
+
'rules' => :show_rules,
|
12
|
+
'stats' => :show_stats,
|
13
|
+
'exit' => :exit
|
14
|
+
}.freeze
|
data/lib/console.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative 'codebreaker_paratskiy'
|
2
|
+
class Console
|
3
|
+
include CodebreakerParatskiy
|
4
|
+
include Validating
|
5
|
+
include Output
|
6
|
+
attr_accessor :user_code, :game
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@user_code = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
show_welcome
|
14
|
+
main_menu
|
15
|
+
end
|
16
|
+
|
17
|
+
def main_menu
|
18
|
+
show_main_menu
|
19
|
+
answer = user_enter
|
20
|
+
return process_answer_menu(answer) if MAIN_MENU_COMMANDS.include?(answer)
|
21
|
+
|
22
|
+
show_msg(:InvalidCommand)
|
23
|
+
main_menu
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def start
|
29
|
+
registration
|
30
|
+
game_scenario
|
31
|
+
end
|
32
|
+
|
33
|
+
def game_scenario
|
34
|
+
loop do
|
35
|
+
return lost if @game.lost?
|
36
|
+
|
37
|
+
show_msg(:AccompanyingMsg)
|
38
|
+
process_answer_game(user_enter)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_answer_game(answer)
|
43
|
+
case answer
|
44
|
+
when /^[1-6]{4}$/
|
45
|
+
return won if @game.won?(check_code(answer))
|
46
|
+
when 'hint' then request_of_hint
|
47
|
+
else show_msg(:InvalidCommand)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def process_answer_menu(answer)
|
52
|
+
send(MAIN_MENU_COMMANDS[answer])
|
53
|
+
main_menu if answer != 'start'
|
54
|
+
end
|
55
|
+
|
56
|
+
def request_of_hint
|
57
|
+
@game.hints.zero? ? show_msg(:HintsEnded) : (puts @game.give_hint)
|
58
|
+
end
|
59
|
+
|
60
|
+
def check_code(answer)
|
61
|
+
result = @game.result(answer)
|
62
|
+
puts result
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
def registration
|
67
|
+
@game = CodebreakerParatskiy.run_game(_get_name, _get_difficulty_level)
|
68
|
+
end
|
69
|
+
|
70
|
+
def _get_name
|
71
|
+
show_msg(:EnterName)
|
72
|
+
answer = user_enter
|
73
|
+
|
74
|
+
return answer if valid_name?(answer)
|
75
|
+
|
76
|
+
show_msg(:InvalidCommand)
|
77
|
+
_get_name
|
78
|
+
end
|
79
|
+
|
80
|
+
def _get_difficulty_level
|
81
|
+
show_msg(:EnterDifficulty)
|
82
|
+
answer = user_enter
|
83
|
+
return DIFFICULTIES[answer.to_sym] if DIFFICULTIES.include?(answer.to_sym)
|
84
|
+
|
85
|
+
show_msg(:InvalidCommand)
|
86
|
+
_get_difficulty_level
|
87
|
+
end
|
88
|
+
|
89
|
+
def save_result?
|
90
|
+
show_msg(:SaveResult)
|
91
|
+
user_enter == 'yes'
|
92
|
+
end
|
93
|
+
|
94
|
+
def won
|
95
|
+
show_msg(:Won)
|
96
|
+
@game.save_result if save_result?
|
97
|
+
main_menu
|
98
|
+
end
|
99
|
+
|
100
|
+
def lost
|
101
|
+
show_msg(:Loss)
|
102
|
+
puts @game.secret_code.join
|
103
|
+
main_menu
|
104
|
+
end
|
105
|
+
|
106
|
+
def user_enter
|
107
|
+
enter = gets.chomp.downcase
|
108
|
+
if exit?(enter)
|
109
|
+
show_msg(:Exit)
|
110
|
+
exit
|
111
|
+
end
|
112
|
+
enter
|
113
|
+
end
|
114
|
+
|
115
|
+
def exit?(answer)
|
116
|
+
answer == 'exit'
|
117
|
+
end
|
118
|
+
end
|
data/lib/dependencies.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
require 'yaml'
|
3
|
+
require 'command_line_reporter'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require_relative 'config/constants'
|
7
|
+
require_relative 'i18n_config'
|
8
|
+
require_relative 'error'
|
9
|
+
require_relative 'services/matching_service'
|
10
|
+
require_relative 'services/statistic_service'
|
11
|
+
require_relative 'game'
|
12
|
+
require_relative 'modules/validating'
|
13
|
+
require_relative 'modules/output'
|
14
|
+
require_relative 'codebreaker_paratskiy'
|
15
|
+
require_relative 'console'
|
16
|
+
require_relative 'utils/db_utils'
|
17
|
+
require_relative 'load_game'
|
data/lib/error.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
class Error < StandardError; end
|
data/lib/game.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative 'services/matching_service'
|
2
|
+
require_relative 'services/statistic_service'
|
3
|
+
class Game
|
4
|
+
attr_accessor :player_name, :secret_code, :user_code, :attempts, :hints, :difficulty_name
|
5
|
+
attr_reader :stats
|
6
|
+
def initialize(player_name, difficulty)
|
7
|
+
@stats = Statistic.stats
|
8
|
+
@player_name = player_name
|
9
|
+
@difficulty_name = DIFFICULTIES.key(difficulty).to_s
|
10
|
+
@attempts = difficulty[:attempts]
|
11
|
+
@hints = difficulty[:hints]
|
12
|
+
@db = DB
|
13
|
+
end
|
14
|
+
|
15
|
+
def give_hint
|
16
|
+
@hints -= 1
|
17
|
+
@secret_code.sample
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
@secret_code = generate_code
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate_code
|
25
|
+
Array.new(4) { rand(1..6) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def result(response)
|
29
|
+
@user_code = response.each_char.map(&:to_i)
|
30
|
+
@attempts -= 1
|
31
|
+
return '++++' if @secret_code == user_code
|
32
|
+
|
33
|
+
Matching.create_response(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
def save_result
|
37
|
+
@stats.push(Statistic.generate_stats(self))
|
38
|
+
DbUtils.add(@db, @stats)
|
39
|
+
end
|
40
|
+
|
41
|
+
def won?(result)
|
42
|
+
result == '++++'
|
43
|
+
end
|
44
|
+
|
45
|
+
def lost?
|
46
|
+
attempts.zero?
|
47
|
+
end
|
48
|
+
end
|
data/lib/i18n_config.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
I18n.load_path << Dir[File.expand_path('lib/config/locales') + '/*.yml']
|
data/lib/load_game.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module Output
|
2
|
+
include CommandLineReporter
|
3
|
+
|
4
|
+
def show_welcome
|
5
|
+
show_msg(:Welcome)
|
6
|
+
end
|
7
|
+
|
8
|
+
def show_main_menu
|
9
|
+
show_msg(:MainMenu)
|
10
|
+
end
|
11
|
+
|
12
|
+
def show_rules
|
13
|
+
show_msg(:Rules)
|
14
|
+
end
|
15
|
+
|
16
|
+
def show_stats(sorted_stats = Statistic.sort_stats)
|
17
|
+
table(border: true) do
|
18
|
+
generate_table_titles
|
19
|
+
generate_table_values(sorted_stats)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_table_titles
|
24
|
+
row do
|
25
|
+
column('Player name', width: 20)
|
26
|
+
column('Difficulty', width: 10)
|
27
|
+
column('Attempts total', width: 14)
|
28
|
+
column('Attempts used', width: 13)
|
29
|
+
column('Hints total', width: 11)
|
30
|
+
column('Hints used', width: 11)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_table_values(sorted_stats)
|
35
|
+
sorted_stats.each do |player|
|
36
|
+
row do
|
37
|
+
column(player[:name])
|
38
|
+
column(player[:difficulty])
|
39
|
+
column(player[:attempts_total])
|
40
|
+
column(player[:attempts_used])
|
41
|
+
column(player[:hints_total])
|
42
|
+
column(player[:hints_used])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def show_msg(type)
|
48
|
+
puts I18n.t(type)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Matching
|
2
|
+
def self.matches(game)
|
3
|
+
user_code_clone = game.user_code.clone
|
4
|
+
matches = game.secret_code.map do |number|
|
5
|
+
user_code_clone.find do |user_number|
|
6
|
+
user_code_clone.delete_at(user_code_clone.index(user_number)) if user_number == number
|
7
|
+
end
|
8
|
+
end
|
9
|
+
matches.compact! || matches
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create_response(game)
|
13
|
+
@pluses = ''
|
14
|
+
@minuses = ''
|
15
|
+
@spaces = ''
|
16
|
+
check_the_code(game)
|
17
|
+
"#{@pluses}#{@minuses}#{@spaces}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.check_the_code(game)
|
21
|
+
@secret_code_clone = game.secret_code.clone
|
22
|
+
(4 - matches(game).length).times { @spaces += ' ' }
|
23
|
+
matches(game).each do |match|
|
24
|
+
if same_position?(game, match)
|
25
|
+
@pluses += '+'
|
26
|
+
else
|
27
|
+
@minuses += '-'
|
28
|
+
end
|
29
|
+
remove_verified_number(match, game)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.same_position?(game, match)
|
34
|
+
[game.user_code[@secret_code_clone.index(match)], @secret_code_clone[game.user_code.index(match)]].include? match
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.remove_verified_number(number, game)
|
38
|
+
game.user_code[game.user_code.index(number)] = 0
|
39
|
+
@secret_code_clone[@secret_code_clone.index(number)] = 0
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative '../utils/db_utils'
|
2
|
+
require_relative '../config/constants'
|
3
|
+
module Statistic
|
4
|
+
def self.generate_stats(game)
|
5
|
+
{
|
6
|
+
name: game.player_name,
|
7
|
+
difficulty: game.difficulty_name,
|
8
|
+
attempts_total: DIFFICULTIES[game.difficulty_name.to_sym][:attempts],
|
9
|
+
attempts_used: DIFFICULTIES[game.difficulty_name.to_sym][:attempts] - game.attempts,
|
10
|
+
hints_total: DIFFICULTIES[game.difficulty_name.to_sym][:hints],
|
11
|
+
hints_used: DIFFICULTIES[game.difficulty_name.to_sym][:hints] - game.hints
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.sort_stats
|
16
|
+
stats.sort_by { |player| [player[:attempts_total], player[:attempts_used], player[:hints_used]] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.stats
|
20
|
+
DbUtils.get(DB)
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codebreaker_paratskiy
|
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
|
- Bogdan Paratskiy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -210,7 +210,21 @@ email:
|
|
210
210
|
executables: []
|
211
211
|
extensions: []
|
212
212
|
extra_rdoc_files: []
|
213
|
-
files:
|
213
|
+
files:
|
214
|
+
- lib/codebreaker_paratskiy.rb
|
215
|
+
- lib/codebreaker_paratskiy/version.rb
|
216
|
+
- lib/config/constants.rb
|
217
|
+
- lib/console.rb
|
218
|
+
- lib/dependencies.rb
|
219
|
+
- lib/error.rb
|
220
|
+
- lib/game.rb
|
221
|
+
- lib/i18n_config.rb
|
222
|
+
- lib/load_game.rb
|
223
|
+
- lib/modules/output.rb
|
224
|
+
- lib/modules/validating.rb
|
225
|
+
- lib/services/matching_service.rb
|
226
|
+
- lib/services/statistic_service.rb
|
227
|
+
- lib/utils/db_utils.rb
|
214
228
|
homepage: https://github.com/paratskiy/codebreaker
|
215
229
|
licenses:
|
216
230
|
- MIT
|