codebreaker-rg-te 0.1.12 → 0.1.13

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
  SHA1:
3
- metadata.gz: 436e0b032eb6a771ebd9f04ae5771921a342e810
4
- data.tar.gz: 92b0a42323b4787184e8ad7e735b5aed80e8cfca
3
+ metadata.gz: 95180783a53441f9238daf38e89e7818b2eb51e2
4
+ data.tar.gz: 97dbc87d1f613e04071b3e8c1d419d796ebd7535
5
5
  SHA512:
6
- metadata.gz: d2d5d0218c3a5525236f0b866c74ba83d2d1bf44da7e1cdf3dd44596358b6efedce80e38051c073582bfc8828b6733bc279da74423b796c1d014e98e6a66efbf
7
- data.tar.gz: a2b66d0e87963c04450587d26652908d4dd259920c7c8e258098ee5fdb1cf80535bddd240d1127554da0bfef39d90c64e4bba87b896b666255b6cfac6ee4ea51
6
+ metadata.gz: b8bb7985bb6db6152e9ffadc330a7dd3f739b1ac53d63d3f2f36e199011cfacfe5cbcc1ce5565ce0ec91fc2bdea313da0e5882a0faaf2710f88deb2b331c0acb
7
+ data.tar.gz: 5cd985bf9e82107998fddb8275209b540ddf9fb32e1d465b3cac1a07895a647dd9df2146c318538447e9722f63971dd558d6d8867d1ce515608aa4894ba260f0
@@ -1,10 +1,10 @@
1
1
  require 'i18n'
2
2
  require 'yaml'
3
- require 'codebreaker/storage/StorageInterceptor.rb'
3
+ require 'codebreaker/storage/storage_interceptor.rb'
4
4
  require 'codebreaker/console.rb'
5
5
  require 'codebreaker/localization.rb'
6
6
  require 'codebreaker/validation.rb'
7
- require 'codebreaker/stats.rb'
7
+ require 'codebreaker/statistics.rb'
8
8
  require 'codebreaker/game.rb'
9
9
  require 'codebreaker.rb'
10
10
 
@@ -1,29 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Codebreaker
2
- class Console
3
- YES = 'yes'.freeze
4
- HINT = 'hint'.freeze
5
- START = 'start'.freeze
6
- RULES = 'rules'.freeze
7
- STATS = 'stats'.freeze
8
- EXIT = 'exit'.freeze
4
+ class Console
5
+ COMMANDS = {
6
+ start: 'start',
7
+ rules: 'rules',
8
+ stats: 'stats',
9
+ exit: 'exit'
10
+ }.freeze
9
11
 
10
- DIFFICULTIES = %w[easy medium hard].freeze
12
+ HINT = 'hint'
11
13
 
12
- def initialize
13
- @game = Codebreaker::Game.new
14
- @stat = Codebreaker::Stats.new
15
- end
14
+ ANSWERS = { yes: 'yes' }.freeze
16
15
 
17
16
  def launch
18
17
  loop do
19
18
  message(:start_game)
20
- message(:wel_instruct, start: START, rules: RULES, stats: STATS, exit: EXIT)
19
+ message(:wel_instruct, COMMANDS)
21
20
  @answer = read_from_console
22
- check_answer
21
+ return check_answer
23
22
  end
24
23
  end
25
24
 
26
25
  def start_game
26
+ @game = Codebreaker::Game.new
27
27
  enter_name
28
28
  enter_level
29
29
  @game.new_game
@@ -31,36 +31,30 @@ class Console
31
31
  end
32
32
 
33
33
  def round_game
34
- loop do
35
- return loose if @game.attempts.zero?
36
-
37
- message(:question_num, attempts: @game.attempts, hints: @game.hints)
38
- user_answer = read_from_console
39
- hint_show if user_answer == HINT
40
- next message(:invalid_number) unless @game.validate_answer(user_answer)
34
+ while @game.attempts.positive?
35
+ user_answer = message_game_read_console
36
+ next hint_show if user_answer == HINT
37
+ next message(:invalid_number) unless @game.validate_code(user_answer)
41
38
 
42
- @game.take_attempts
43
- @game.set_user_code(user_answer)
39
+ @game.handle_guess(user_answer)
44
40
  return win if @game.equal_codes?(user_answer)
45
41
 
46
- puts @game.game_result
42
+ message_game_result
47
43
  end
44
+ loose
48
45
  end
49
46
 
50
47
  def hint_show
51
- if @game.hints.zero?
52
- message(:over_hint)
53
- round_game
54
- end
48
+ return message(:over_hint) if @game.hints.zero?
49
+
55
50
  puts @game.show_hints
56
51
  @game.take_hints
57
- round_game
58
52
  end
59
53
 
60
54
  def win
61
55
  message(:win)
62
56
  message(:progress)
63
- @game.save if read_from_console.eql? YES
57
+ @game.save if read_from_console.eql? ANSWERS[:yes]
64
58
  continue_game? ? start_game : exit
65
59
  end
66
60
 
@@ -71,20 +65,19 @@ class Console
71
65
 
72
66
  def continue_game?
73
67
  message(:new_game)
74
- read_from_console.eql? YES
68
+ read_from_console.eql? ANSWERS[:yes]
75
69
  end
76
70
 
77
71
  def stats_show
78
- data = @stat.stats
79
-
80
- return message(:empty_stat) unless data
72
+ @stat = Codebreaker::Statistics.new
73
+ return message(:empty_stat) unless data = @stat.stats
81
74
 
82
75
  message(:stats)
83
76
  message(:col_table)
84
- data.each_with_index do |val, index|
77
+ data.each_with_index do |row, index|
85
78
  print "#{index}\t"
86
- val.each do |_key, value|
87
- print "#{value}\t"
79
+ row.each do |_key, cell|
80
+ print "#{cell}\t"
88
81
  end
89
82
  print "\n"
90
83
  end
@@ -94,10 +87,10 @@ class Console
94
87
 
95
88
  def check_answer
96
89
  case @answer
97
- when START then start_game
98
- when RULES then message(:rulegame)
99
- when STATS then stats_show
100
- when EXIT then exit
90
+ when COMMANDS[:start] then start_game
91
+ when COMMANDS[:rules] then message(:rulegame)
92
+ when COMMANDS[:stats] then stats_show
93
+ when COMMANDS[:exit] then exit
101
94
  end
102
95
  end
103
96
 
@@ -109,17 +102,25 @@ class Console
109
102
  gets.chomp
110
103
  end
111
104
 
105
+ def message_game_read_console
106
+ message(:question_num, attempts: @game.attempts, hints: @game.hints)
107
+ read_from_console
108
+ end
109
+
110
+ def message_game_result
111
+ puts @game.game_result
112
+ end
113
+
112
114
  def enter_name
113
115
  message(:username)
114
- name = read_from_console
115
- return enter_name unless @game.enter_name(name)
116
+ return enter_name unless @game.enter_name(read_from_console)
116
117
 
117
- message(:hello, name: name)
118
+ message(:hello, name: @game.name)
118
119
  end
119
120
 
120
121
  def enter_level
121
- message(:choose_difficulty, difficulties: DIFFICULTIES.join(' '))
122
- return input_level unless @game.enter_level(read_from_console)
122
+ message(:choose_difficulty, difficulties: Codebreaker::Game::GAME_LEVELS.keys.join(' '))
123
+ return enter_level unless @game.enter_level(read_from_console)
123
124
  end
124
125
  end
125
126
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Codebreaker
3
4
  class Game
4
5
  include Validation
@@ -13,29 +14,27 @@ module Codebreaker
13
14
  hard: { attempts: 10, hints: 1, level_num: 2 }
14
15
  }.freeze
15
16
 
17
+ COUNTS_OF_HINTS = (0..3).freeze
16
18
  DIGITS_COUNT = 4
19
+ USER_ANSWER_REX = /^[1-6]{4}$/.freeze
17
20
 
18
21
  def new_game
19
22
  @secret_code = Array.new(DIGITS_COUNT) { rand(RANGE) }
20
23
  end
21
24
 
22
- def set_user_code(enter_code)
23
- @user_code = enter_code.each_char.map(&:to_i)
24
- end
25
-
26
25
  def enter_level(level)
27
- return unless validate_level(level)
26
+ return unless GAME_LEVELS.key?(level.to_sym)
28
27
 
29
28
  @level = level
30
29
 
31
30
  @attempts = GAME_LEVELS.dig(level.to_sym, :attempts)
32
31
  @hints = GAME_LEVELS.dig(level.to_sym, :hints)
33
32
  @level_num = GAME_LEVELS.dig(level.to_sym, :level_num)
34
- @hints_index = (0..3).to_a.sample @hints
33
+ @hints_index = COUNTS_OF_HINTS.to_a.sample @hints
35
34
  end
36
35
 
37
36
  def enter_name(name)
38
- return unless validate_name(name)
37
+ return unless validate_length(name)
39
38
 
40
39
  @name = name
41
40
  end
@@ -56,27 +55,48 @@ module Codebreaker
56
55
  secret_code[hints_index.shift]
57
56
  end
58
57
 
58
+ def set_user_code(enter_code)
59
+ @user_code = enter_code.each_char.map(&:to_i)
60
+ end
61
+
62
+ def handle_guess(user_answer)
63
+ take_attempts
64
+ set_user_code(user_answer)
65
+ end
66
+
59
67
  def game_result
68
+ return '++++' if equal_codes?(@user_code.join)
69
+
60
70
  result = ''
61
- (0..3).each do |index|
62
- result += '+' if @user_code[index] == @secret_code[index]
71
+ @secret_code_clone = @secret_code.clone
72
+ @user_code.each_with_index do |digit, index|
73
+ next unless digit == @secret_code_clone[index]
74
+
75
+ result += '+'
76
+ @secret_code_clone[index] = nil
77
+ @user_code[index] = nil
63
78
  end
64
- return result if result.eql?('++++')
65
79
 
66
- (0..3).each do |index|
67
- result += '-' if @secret_code.include?(@user_code[index]) && @user_code[index] != @secret_code[index]
80
+ @user_code.compact.each_with_index do |digit, _index|
81
+ next unless @secret_code_clone.include?(digit)
82
+
83
+ result += '-'
84
+ @secret_code_clone[@secret_code_clone.index(digit)] = nil
68
85
  end
69
86
  result
70
87
  end
71
88
 
72
- def save
73
- di = StorageInterceptor.new
74
- codebreaker_data = di.read_database || []
89
+ def storage_data(codebreaker_data)
75
90
  attempts_used = GAME_LEVELS.dig(level.to_sym, :attempts) - attempts
76
91
  hints_used = GAME_LEVELS.dig(level.to_sym, :hints) - hints
77
92
  hash_stat = { name: @name, level: @level, level_num: @level_num, attempts: @attempts, attempts_used: attempts_used, hints: @hints, hints_used: hints_used }
78
93
  codebreaker_data << hash_stat
79
- di.write_database(codebreaker_data)
94
+ end
95
+
96
+ def save
97
+ storage = StorageInterceptor.new
98
+ codebreaker_data = storage.read_database || []
99
+ storage.write_database(storage_data(codebreaker_data))
80
100
  end
81
101
  end
82
- end
102
+ end
@@ -1,10 +1,8 @@
1
1
  module Codebreaker
2
- class Stats
2
+ class Statistics
3
3
  def stats
4
- di = StorageInterceptor.new
5
- codebreaker_data = di.read_database
6
-
7
- return unless codebreaker_data
4
+ storage = StorageInterceptor.new
5
+ return unless codebreaker_data = storage.read_database
8
6
 
9
7
  codebreaker_data.sort_by! { |stat| [stat[:level_num], stat[:hints], stat[:attempts]] }
10
8
  codebreaker_data.each { |stat| stat.delete_if { |key, _value| key == :level_num } }
@@ -1,5 +1,5 @@
1
1
  module Codebreaker
2
- class StorageInterceptor
2
+ class StorageInterceptor
3
3
  DEFAULT_PATH_TO_FILE = './data/stat.yml'.freeze
4
4
 
5
5
  def initialize(path_to_file = DEFAULT_PATH_TO_FILE)
@@ -10,8 +10,8 @@ class StorageInterceptor
10
10
  YAML.load_file(@path_to_file) if File.exist?(@path_to_file)
11
11
  end
12
12
 
13
- def write_database(library)
14
- File.open(@path_to_file, 'w') { |file| file.write(library.to_yaml) }
13
+ def write_database(data)
14
+ File.open(@path_to_file, 'w') { |file| file.write(data.to_yaml) }
15
15
  end
16
16
  end
17
17
  end
@@ -1,15 +1,9 @@
1
1
  module Validation
2
- USER_ANSWER_REX = /^[1-6]{4}$/
3
-
4
- def validate_name(name)
5
- name.size > 2 && name.size < 21
6
- end
7
-
8
- def validate_level(level)
9
- %w[easy medium hard].include? level
2
+ def validate_length(word)
3
+ word.size > 2 && word.size < 21
10
4
  end
11
5
 
12
- def validate_answer(user_answer)
13
- user_answer =~ USER_ANSWER_REX
6
+ def validate_code(code)
7
+ code =~ Codebreaker::Game::USER_ANSWER_REX
14
8
  end
15
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebreaker-rg-te
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eugene Tereschenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-06 00:00:00.000000000 Z
11
+ date: 2019-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.1
19
+ version: 1.16.1
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.1
26
+ version: 1.16.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: fasterer
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -161,8 +161,8 @@ files:
161
161
  - lib/codebreaker/console.rb
162
162
  - lib/codebreaker/game.rb
163
163
  - lib/codebreaker/localization.rb
164
- - lib/codebreaker/stats.rb
165
- - lib/codebreaker/storage/StorageInterceptor.rb
164
+ - lib/codebreaker/statistics.rb
165
+ - lib/codebreaker/storage/storage_interceptor.rb
166
166
  - lib/codebreaker/validation.rb
167
167
  homepage: https://github.com/EugeneTereschenko/codebreaker
168
168
  licenses: []