codebreaker_paratskiy 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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