codebreaker_dmitriev 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7953790376d20c4c0fdeea17496564434f344fa0f3db29ad7a875eadfb1bba1
4
- data.tar.gz: 0dbcab1cde0637f14b8a6b452e97f6b5cbc1be34ee0232458c8fce1ae77bbede
3
+ metadata.gz: 05e12443dab6ab9acbfea4d6893c727ac640e9d8b6348579031db4078d3e2151
4
+ data.tar.gz: abdd9f4dd78c96dcdf61c658ca561d818c6b5f63389ce91b373814b0d9467b32
5
5
  SHA512:
6
- metadata.gz: 39324fb095949394bf296666f1259df7beb9312aac005836ece4cad63cb115546b2a6b0ae3683aa82b6f45ad78d7aa948dae0870bdc8a0f143f9a2aa79f4e1c5
7
- data.tar.gz: 2ab28acfefe83253fa745bcc20c9dc04601f1f00d3c9262630d49c9e040270fa598ff5fdbbf9ae6f6133ddf6c96fcbc6af2908b4bb3e2cc5913805c34145192a
6
+ metadata.gz: 60a57b275110c7f12362b7d4b94108463c156f3c0d8164ad5b3131f1e1da456a67d1d6e0f7be66845d6fd2e3202a7ed93cdd61ac285b989844d164277d8ad046
7
+ data.tar.gz: e26e5e638abae5019e61a067597b3d93b8b60dcf310f09de77666f33a806810a7e471c994fa37fb17adb3385d8f2c3e72c119dc878290988e751afb2038d770f
data/.rubocop.yml CHANGED
@@ -12,11 +12,5 @@ Style/FrozenStringLiteralComment:
12
12
  Metrics/BlockLength:
13
13
  ExcludedMethods: ['describe']
14
14
 
15
- Metrics/AbcSize:
16
- Max: 30
17
-
18
- Metrics/MethodLength:
19
- Max: 15
20
-
21
15
  RSpec/MessageSpies:
22
16
  Enabled: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- codebreaker_dmitriev (0.1.0)
4
+ codebreaker_dmitriev (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/autoload.rb CHANGED
@@ -1,2 +1,3 @@
1
+ require_relative './lib/codebreaker/constants'
1
2
  require_relative './lib/codebreaker/validation'
2
3
  require_relative './lib/codebreaker/game'
@@ -3,11 +3,11 @@ en:
3
3
  goodbye: "Goodbye!"
4
4
  rules: "You need to guess a number that the computer generated.\nYou have some attempts and some hints.\nGood luck :)"
5
5
  menu: "Please, choose one:\n* start\n* rules\n* stats\n* exit"
6
- difficult: "* Easy - 15 attempts, 2 hints\n* Medium - 10 attempts, 1 hint\n* Hell - 5 attempts, 1 hint"
7
- set_name: "Choose name (min 3 characters):"
6
+ difficult: "* Easy\n* Medium\n* Hell"
7
+ set_name: "Choose name (min %{min} characters):"
8
8
  set_difficult: "Choose level:"
9
9
  unknown_command: "Wrong command!"
10
- name_error: "Name must be between 3 and 20 characters!"
10
+ name_error: "Name must be between %{min} and %{max} characters!"
11
11
  difficult_error: "Wrong difficult!"
12
12
  hint_error: "Sorry, but you don`t have a hints :("
13
13
  win: "Congratz. You win!"
@@ -21,8 +21,8 @@ en:
21
21
  show_stats: "Rating: %{rating};
22
22
  Name: %{name};
23
23
  Difficult: %{difficult};
24
- Attempts total: %{a};
25
- Attempts used: %{a_used};
26
- Hints total: %{h};
27
- Hints used: %{h_used};"
24
+ Attempts total: %{attempts};
25
+ Attempts used: %{attempts_used};
26
+ Hints total: %{hints};
27
+ Hints used: %{hints_used};"
28
28
  stats_error: "Statistics is empty."
@@ -0,0 +1,24 @@
1
+ module Constants
2
+ PLUS = '+'.freeze
3
+ MINUS = '-'.freeze
4
+
5
+ DIFFICULTS = {
6
+ easy: {
7
+ name: 'easy',
8
+ attempts: 15,
9
+ hints: 2
10
+ },
11
+ medium: {
12
+ name: 'medium',
13
+ attempts: 10,
14
+ hints: 1
15
+ },
16
+ hell: {
17
+ name: 'hell',
18
+ attempts: 5,
19
+ hints: 1
20
+ }
21
+ }.freeze
22
+
23
+ WIN_RESULT = '++++'.freeze
24
+ end
@@ -2,18 +2,15 @@ module Codebreaker
2
2
  include Validation
3
3
 
4
4
  class Game
5
- PLUS = '+'.freeze
6
- MINUS = '-'.freeze
5
+ include Constants
7
6
 
8
- attr_reader :name, :difficult, :secret, :attempts, :hints, :hints_used, :attempts_used
7
+ attr_reader :name, :difficult, :secret, :attempts, :hints
9
8
 
10
9
  def initialize(name, difficult)
11
10
  @name = name
12
11
  @difficult = difficult
13
12
  @attempts = get_attempts(difficult)
14
13
  @hints = get_hints(difficult)
15
- @attempts_used = 0
16
- @hints_used = 0
17
14
 
18
15
  generate_secret
19
16
  @secret_chars = @secret.chars.shuffle
@@ -22,56 +19,73 @@ module Codebreaker
22
19
  def decrement_attempts
23
20
  return false if @attempts.zero?
24
21
 
25
- @attempts_used += 1
26
22
  @attempts -= 1
27
23
  end
28
24
 
29
25
  def use_hint
30
26
  return false if @hints.zero?
31
27
 
32
- @hints_used += 1
33
28
  @hints -= 1
34
29
  @secret_chars.pop
35
30
  end
36
31
 
37
32
  def win?(matches)
38
- matches == '++++'
33
+ matches == WIN_RESULT
34
+ end
35
+
36
+ def used_attempts
37
+ get_attempts(@difficult) - @attempts
38
+ end
39
+
40
+ def used_hints
41
+ get_hints(@difficult) - @hints
39
42
  end
40
43
 
41
44
  def check_number(guess, secret_code = @secret)
42
45
  secret = secret_code.chars
43
46
  input = guess.chars
44
47
 
45
- grouped = secret.zip(input).group_by { |values| values.first == values.last }
46
- grouped.default = []
48
+ grouped = group_arrays(secret, input)
47
49
 
48
50
  plus = grouped[true].size
49
- return PLUS * plus if plus == 4
51
+ return result(plus) if plus == 4
50
52
 
51
- secret, input = grouped[false].transpose
52
- minus = (secret & input).inject(0) { |count, number| count + [secret.count(number), input.count(number)].min }
53
- PLUS * plus << MINUS * minus
53
+ minus = get_minuses_count(grouped)
54
+ result(plus, minus)
54
55
  end
55
56
 
56
57
  private
57
58
 
59
+ def result(plus, minus = 0)
60
+ PLUS * plus << MINUS * minus
61
+ end
62
+
63
+ def get_minuses_count(grouped)
64
+ secret, input = grouped[false].transpose
65
+ (secret & input).inject(0) do |count, number|
66
+ count + [secret.count(number), input.count(number)].min
67
+ end
68
+ end
69
+
70
+ def group_arrays(secret, input)
71
+ grouped = secret
72
+ .zip(input)
73
+ .group_by { |values| values.first == values.last }
74
+ grouped.default = []
75
+
76
+ grouped
77
+ end
78
+
58
79
  def generate_secret
59
80
  @secret = (1..4).map { rand(1..6) }.join
60
81
  end
61
82
 
62
- def get_attempts(difficult)
63
- case difficult
64
- when 'easy' then 15
65
- when 'medium' then 10
66
- when 'hell' then 5
67
- end
83
+ def get_attempts(level)
84
+ DIFFICULTS[level.to_sym][:attempts]
68
85
  end
69
86
 
70
- def get_hints(difficult)
71
- case difficult
72
- when 'easy' then 2
73
- else 1
74
- end
87
+ def get_hints(level)
88
+ DIFFICULTS[level.to_sym][:hints]
75
89
  end
76
90
  end
77
91
  end
@@ -1,10 +1,4 @@
1
1
  module Validation
2
- DIFFICULTS = {
3
- easy: 'easy',
4
- medium: 'medium',
5
- hell: 'hell'
6
- }.freeze
7
-
8
2
  def name_valid?(name)
9
3
  name.length.between? 3, 20
10
4
  end
@@ -13,7 +7,7 @@ module Validation
13
7
  /^[1-6]{4}$/.match? guess
14
8
  end
15
9
 
16
- def difficult_valid?(difficult)
17
- DIFFICULTS.values.include? difficult.downcase
10
+ def difficult_valid?(level)
11
+ !Constants::DIFFICULTS[level.to_sym].nil?
18
12
  end
19
13
  end
@@ -1,3 +1,3 @@
1
1
  module Codebreaker
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -17,7 +17,6 @@ class Console
17
17
  Messages.show_greeting
18
18
 
19
19
  loop do
20
- print '~> '
21
20
  case gets.chomp.downcase
22
21
  when COMMANDS[:start] then return register
23
22
  when COMMANDS[:rules] then Messages.show_rules
@@ -35,9 +34,9 @@ class Console
35
34
  name: game.name,
36
35
  difficult: @difficult,
37
36
  attempts: game.attempts,
38
- attempts_used: game.attempts_used,
37
+ attempts_used: game.used_attempts,
39
38
  hints: game.hints,
40
- hints_used: game.hints_used
39
+ hints_used: game.used_hints
41
40
  }
42
41
  end
43
42
 
@@ -50,7 +49,12 @@ class Console
50
49
 
51
50
  def start_game(game)
52
51
  Messages.game_commands
52
+ game_process(game)
53
+ start_new_game
54
+ end
53
55
 
56
+ def game_process(game)
57
+ puts game.secret
54
58
  loop do
55
59
  break Messages.lose if game.attempts.zero?
56
60
 
@@ -63,8 +67,6 @@ class Console
63
67
  result = get_result(game, guess)
64
68
  break win_game(game) if result
65
69
  end
66
-
67
- start_new_game
68
70
  end
69
71
 
70
72
  def start_new_game
@@ -1,33 +1,21 @@
1
- require_relative './errors/errors'
2
-
3
1
  class Difficult
4
- include Errors
5
-
6
- DIFFICULTS = {
7
- easy: 'easy',
8
- medium: 'medium',
9
- hell: 'hell'
10
- }.freeze
11
-
12
2
  attr_reader :level
13
3
 
14
4
  def initialize(level)
15
- raise WrongDifficultError unless valid? level
16
-
17
5
  @level = level.downcase
18
6
  end
19
7
 
20
8
  def to_i
21
- case @level.downcase
22
- when DIFFICULTS[:hell] then 1
23
- when DIFFICULTS[:medium] then 2
24
- when DIFFICULTS[:easy] then 3
9
+ case @level
10
+ when name('hell') then 1
11
+ when name('medium') then 2
12
+ when name('easy') then 3
25
13
  end
26
14
  end
27
15
 
28
16
  private
29
17
 
30
- def valid?(level)
31
- level.is_a?(String) && DIFFICULTS.values.include?(level.downcase)
18
+ def name(difficult)
19
+ Codebreaker::Game::DIFFICULTS[difficult.to_sym][:name]
32
20
  end
33
21
  end
@@ -12,9 +12,14 @@ module Output
12
12
  end
13
13
 
14
14
  def show_stats(stat)
15
- puts I18n.t(:show_stats, rating: stat[:rating], name: stat[:name], difficult: stat[:difficult].level,
16
- a: (stat[:attempts] + stat[:attempts_used]), a_used: stat[:attempts_used],
17
- h: (stat[:hints] + stat[:hints_used]), h_used: stat[:hints_used])
15
+ puts I18n.t(:show_stats,
16
+ rating: stat[:rating],
17
+ name: stat[:name],
18
+ difficult: stat[:difficult].level,
19
+ attempts: (stat[:attempts] + stat[:attempts_used]),
20
+ attempts_used: stat[:attempts_used],
21
+ hints: (stat[:hints] + stat[:hints_used]),
22
+ hints_used: stat[:hints_used])
18
23
  end
19
24
 
20
25
  def show_greeting
@@ -52,7 +57,7 @@ module Output
52
57
  end
53
58
 
54
59
  def show_name
55
- puts I18n.t :set_name
60
+ puts I18n.t :set_name, min: 3
56
61
  print ARROW
57
62
  end
58
63
 
@@ -75,7 +80,7 @@ module Output
75
80
  end
76
81
 
77
82
  def name_error
78
- puts I18n.t :name_error
83
+ puts I18n.t :name_error, min: 3, max: 20
79
84
  end
80
85
 
81
86
  def lose
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebreaker_dmitriev
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Dmitriev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-18 00:00:00.000000000 Z
11
+ date: 2019-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -162,13 +162,13 @@ files:
162
162
  - config/i18n.rb
163
163
  - config/locales/en.yml
164
164
  - lib/codebreaker.rb
165
+ - lib/codebreaker/constants.rb
165
166
  - lib/codebreaker/game.rb
166
167
  - lib/codebreaker/validation.rb
167
168
  - lib/codebreaker/version.rb
168
169
  - lib/console_app/console.rb
169
170
  - lib/console_app/database.rb
170
171
  - lib/console_app/difficult.rb
171
- - lib/console_app/errors/errors.rb
172
172
  - lib/console_app/output.rb
173
173
  - main.rb
174
174
  homepage: https://github.com/legendado/codebreaker
@@ -1,7 +0,0 @@
1
- module Errors
2
- class WrongDifficultError < StandardError
3
- def initialize
4
- super('Wrong difficult!')
5
- end
6
- end
7
- end