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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5845b0ae8445f8f083f9ab06d31eec8e288ed0b2595f7bc95ad74a181bb0644d
4
- data.tar.gz: 47af900845abafbb455ffc006d80aa0a357782ab7e7987fd250c249ce03d9765
3
+ metadata.gz: bc88f1830d8e2791f5f3e8ea508fbb5f80799b1d988d078c1dcd00d29fd6a9d5
4
+ data.tar.gz: 80e9b346a177f00ba3db89d97cf28ad26e503db15b53f45d90581c13de806bd3
5
5
  SHA512:
6
- metadata.gz: b42dbc44bf8032ff948846f6a4d4202dead79ec21cd6a440a12f801b7c27d84f7c2bfe2c2ff5459ab090ba350801331ba0da1443d6091f027748420b17001351
7
- data.tar.gz: 4b5d19cf315523b53d732dc683d5ba5adef93384852bdb51b4b3aaa8d132847dc2434829b51bedc70cacd8d44e6f020cc56675500a37a8122ab9adac67a1cea4
6
+ metadata.gz: 48dec98c1fb5c73da45dfe8364504ce608495fafec2cc6e2bcabf2ab252cc934ca36878911fa269a7c5043144d1758777a3b1803f2f48b2edae13c0147632e4d
7
+ data.tar.gz: 4fd5da4b654e8e7953853a10631f67140436ad176483b9fc6f81fa06c59cc76813b46439cc813b4ee923012cc5be464770ed9eef69a9d9ec6835a0faa5428a93
@@ -0,0 +1,3 @@
1
+ module CodebreakerParatskiy
2
+ VERSION = '0.1.3'.freeze
3
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'game'
2
+ module CodebreakerParatskiy
3
+ def self.run_game(name, difficulty)
4
+ game = Game.new(name, difficulty)
5
+ game.run
6
+ game
7
+ end
8
+ end
9
+ # game = CodebreakerParatskiy.run_game('asdf', { attempts: 5, hints: 1})
@@ -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
@@ -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
@@ -0,0 +1 @@
1
+ I18n.load_path << Dir[File.expand_path('lib/config/locales') + '/*.yml']
data/lib/load_game.rb ADDED
@@ -0,0 +1,6 @@
1
+ require_relative 'dependencies'
2
+ module LoadGame
3
+ def self.start
4
+ Console.new.run
5
+ end
6
+ end
@@ -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,5 @@
1
+ module Validating
2
+ def valid_name?(name = '')
3
+ name.length.between?(4, 20) && name[/^[a-zа-яё]+$/i]
4
+ end
5
+ 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
@@ -0,0 +1,12 @@
1
+ require 'yaml'
2
+ module DbUtils
3
+ def self.add(path, element)
4
+ File.open(path, 'w') do |file|
5
+ file.write(element.to_yaml)
6
+ end
7
+ end
8
+
9
+ def self.get(path)
10
+ YAML.load_file(path)
11
+ end
12
+ 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.2
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-28 00:00:00.000000000 Z
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