codebreaker_kub 0.2.2 → 0.3.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: 051607a50601d334aa48d9d28785323e8d5c221c0aef317be4b4a5ceee34386e
4
- data.tar.gz: 6a7ef0f973f7f648ab9ec282631d77f18f62ab2b8d271fa1959e6a4d50286225
3
+ metadata.gz: 8c52f5d444aff492e925af1663df2b4900bb7b7148065772cbf6c50476a78b35
4
+ data.tar.gz: e5218e5898045bc0c36c7e462d54a83d97eb392cf00646b17b16ff029f437bd6
5
5
  SHA512:
6
- metadata.gz: a60a49f8ea3d902cc5455fba5e1acf75a1290d013bc4dda5ff4ca6cadabddd8795c8a8e25f697cfed92b1c10973e410b64070a5d48bc73e52afb252ec3c2da46
7
- data.tar.gz: 50d31ee1829a607075be8ec34df7b77eea7aa5c783ea62b5f12bfdc119f4c9df5db751b2d195a2c19970375422442f4a797e6e8326b327a2325765fbba717f99
6
+ metadata.gz: 1db8add5cb8637b435b06bc5b4a041255b567901724b1919fed6eb28d298836703e84ea7ae1c86357342097cc91191addf33f56b3b3663b0e5d4cef73b9d18e1
7
+ data.tar.gz: 65dfd444ec363d8527d29c214d7fe5b3f3c36cfbd3110e2490fce29a30c61306c94f0f7eaf7be9490243fd0c762d5a7db85087e1c4741659861dd091eae99a80
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  .rvmrc
2
2
  /coverage/
3
3
  .rspec_status
4
+ stats.yml
@@ -5,8 +5,7 @@ Style/Documentation:
5
5
  Enabled: false
6
6
 
7
7
  Layout/LineLength:
8
- Max: 110
8
+ Max: 120
9
9
 
10
10
  Metrics/BlockLength:
11
11
  Enabled: false
12
-
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- codebreaker_kub (0.2.1)
4
+ codebreaker_kub (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -61,6 +61,7 @@ PLATFORMS
61
61
  ruby
62
62
 
63
63
  DEPENDENCIES
64
+ bundler (~> 2.1)
64
65
  codebreaker_kub!
65
66
  fasterer (~> 0.8)
66
67
  i18n (~> 1.8)
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ['lib']
30
30
 
31
+ spec.add_development_dependency 'bundler', '~>2.1'
31
32
  spec.add_development_dependency 'fasterer', '~>0.8'
32
33
  spec.add_development_dependency 'i18n', '~>1.8'
33
34
  spec.add_development_dependency 'rake', '~> 12.0'
@@ -3,8 +3,5 @@
3
3
  require_relative 'codebreaker/guess_checker'
4
4
  require_relative 'codebreaker/game'
5
5
  require_relative 'codebreaker/loader'
6
- require_relative 'codebreaker/output'
7
- require_relative 'codebreaker/validation'
8
6
  require_relative 'codebreaker/version'
9
- require 'i18n'
10
7
  require 'yaml'
@@ -2,24 +2,25 @@
2
2
 
3
3
  module Codebreaker
4
4
  class Game
5
- include Codebreaker::GuessChecker
6
-
7
- attr_accessor :input_code, :code, :name, :difficulties, :difficulty, :hints_left, :attempts_left
8
- attr_reader :minuse, :plus, :none, :hints_code
5
+ attr_accessor :input_code, :code, :name, :difficulties, :difficulty, :hints_left, :attempts_left, :all_hints,
6
+ :all_attempts
7
+ attr_reader :hints_code
9
8
 
10
9
  CODE_LENGTH = 4
11
10
  CODE_RANGE = (1..6).freeze
12
11
 
13
- def initialize
14
- @difficulties = Codebreaker::Loader.load('difficulties')
12
+ def initialize(name, difficulty)
13
+ @difficulties = Loader.load('difficulties')
15
14
  @code = generate_code
16
15
  @hints_code = @code.chars.shuffle
17
- symbols
16
+ game_option(name, difficulty)
18
17
  end
19
18
 
20
19
  def game_option(name, difficulty)
21
20
  @name = name
22
- @difficulty = difficulty
21
+ @difficulty = difficulty.to_sym
22
+ @all_attempts = difficulty_option[:attempts]
23
+ @all_hints = difficulty_option[:hints]
23
24
  @attempts_left = difficulty_option[:attempts]
24
25
  @hints_left = difficulty_option[:hints]
25
26
  end
@@ -36,10 +37,11 @@ module Codebreaker
36
37
  end
37
38
 
38
39
  def input_operation(input_code)
40
+ @input_code = input_code
39
41
  return unless attempts_left?
40
42
 
41
43
  @attempts_left -= 1
42
- check_input(@code, input_code)
44
+ check_input(@code, @input_code)
43
45
  end
44
46
 
45
47
  def attempts_left?
@@ -50,8 +52,8 @@ module Codebreaker
50
52
  input_code == code
51
53
  end
52
54
 
53
- def save
54
- Codebreaker::Loader.save(to_h, 'stats')
55
+ def save(filename = 'stats')
56
+ Codebreaker::Loader.save(to_h, filename)
55
57
  end
56
58
 
57
59
  private
@@ -68,15 +70,22 @@ module Codebreaker
68
70
  @difficulties[@difficulty]
69
71
  end
70
72
 
73
+ def check_input(code, input)
74
+ guess_checker = Codebreaker::GuessChecker.new(code, input)
75
+ guess_checker.symbols
76
+ guess_checker.check_input
77
+ end
78
+
71
79
  def to_h
72
80
  {
73
81
  name: @name,
74
82
  difficulty: @difficulty,
75
- attempts: difficulty_option[:attempts],
76
- hints: difficulty_option[:hints],
83
+ attempts: @all_attempts,
84
+ hints: @all_hints,
77
85
  code: @code,
78
- used_attempts: difficulty_option[:attempts] - @attempts_left,
79
- used_hints: difficulty_option[:hints] - @hints_left
86
+ used_attempts: @all_attempts - @attempts_left,
87
+ used_hints: @all_hints - @hints_left,
88
+ date: Time.now
80
89
  }
81
90
  end
82
91
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Codebreaker
4
+ class GuessChecker
5
+ attr_accessor :inexact, :exact, :none
6
+
7
+ MINUSE = '-'
8
+ PLUS = '+'
9
+ NONE = ' '
10
+
11
+ def initialize(code, code_input)
12
+ @code = code.chars
13
+ @code_input = code_input.chars
14
+ end
15
+
16
+ def symbols(inexact = MINUSE, exact = PLUS, none = NONE)
17
+ @inexact = inexact
18
+ @exact = exact
19
+ @none = none
20
+ end
21
+
22
+ def check_input
23
+ raw_result = mismatched
24
+ matched(raw_result)
25
+ end
26
+
27
+ private
28
+
29
+ def mismatched
30
+ inexact = (@code & @code_input).map { |element| [@code.count(element), @code_input.count(element)].min }.sum
31
+ @inexact * inexact
32
+ end
33
+
34
+ def matched(result)
35
+ @code_input.each.with_index do |element, index|
36
+ result.sub!(@inexact, @exact) if element == @code[index]
37
+ end
38
+ return result unless result.empty?
39
+
40
+ @none
41
+ end
42
+ end
43
+ end
@@ -2,10 +2,9 @@
2
2
 
3
3
  module Codebreaker
4
4
  module Loader
5
- PATH = File.join(File.dirname(__FILE__), 'data/').freeze
6
5
  EXTENCTION = '.yml'
7
6
  def self.load(file_name)
8
- file_name = PATH + file_name + EXTENCTION.to_s
7
+ file_name = File.expand_path(file_name) + EXTENCTION.to_s
9
8
  if File.exist?(file_name)
10
9
  YAML.load_file(file_name)
11
10
  else
@@ -15,7 +14,7 @@ module Codebreaker
15
14
  end
16
15
 
17
16
  def self.save(obj, file_name)
18
- file_name = PATH + file_name + EXTENCTION.to_s
17
+ file_name = File.expand_path(file_name) + EXTENCTION.to_s
19
18
  stats = File.file?(file_name) && !File.zero?(file_name) ? YAML.load_file(file_name) : []
20
19
  stats << obj
21
20
  file = File.open(file_name, 'w')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Codebreaker
4
- VERSION = '0.2.2'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebreaker_kub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - katia kub
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-17 00:00:00.000000000 Z
11
+ date: 2020-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: fasterer
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -116,13 +130,11 @@ files:
116
130
  - bin/console
117
131
  - bin/setup
118
132
  - codebreaker.gemspec
133
+ - difficulties.yml
119
134
  - lib/codebreaker.rb
120
- - lib/codebreaker/data/difficulties.yml
121
- - lib/codebreaker/data/locales/en.yml
122
135
  - lib/codebreaker/game.rb
136
+ - lib/codebreaker/guess_checker.rb
123
137
  - lib/codebreaker/loader.rb
124
- - lib/codebreaker/output.rb
125
- - lib/codebreaker/validation.rb
126
138
  - lib/codebreaker/version.rb
127
139
  - pkg/codebreaker_kub-0.0.1.gem
128
140
  homepage: https://github.com/katiakub/gCodebreaker
@@ -1,29 +0,0 @@
1
- :en:
2
- hey: "Welcome to gCodebreaker!\n You can:
3
- - Start new game - puts 'start'\n
4
- - Check the rules - puts 'rules'\n
5
- - Load game statistics - puts 'stats'\n
6
- - Exit from game - puts 'exit'\n"
7
- goodbye: "Bye bye!\n"
8
- available_commands: "Enter 'start', 'rules', 'stats' or 'exit'"
9
- rules: "GAME RULES:\n
10
- # Codebreaker is a logic game in which a code-breaker tries to break a secret code created by a code-maker. The\n codemaker, which will be played by the application we’re going to write, creates a secret code.\n
11
- # The codebreaker gets some number of chances to break the code (depends on chosen difficulty). In each turn, the\n codebreaker makes a guess. The codemaker then marks the guess with special symbols.\n
12
- # If codebreaker inputs the exact number as a secret number - codebreaker wins the game. If all attempts are spent - codebreaker loses.\n
13
- # Codebreaker also has some number of hints(depends on chosen difficulty). If a user takes a hint - he receives back a\n
14
- separate digit of the secret code.\n
15
- # Good luck!"
16
- choose_name: "Enter you name: "
17
- wrong_name: "Enter valid name, please! Name must be min 3 and max 20 characters.\n"
18
- choose_difficulty: "Choose difficulty: 'easy', 'medium', 'hell'"
19
- wrong_difficulty: "There is no such level. Select from available, please"
20
- get_hint: "You can choose get hint - puts 'hint'"
21
- no_hints: "You have no hints"
22
- enter_guess: "Enter your guess, please"
23
- wrong_input: "Your input is invalid or there is no such command."
24
- win: "YOU WIN!"
25
- lose: "You lose, sorry("
26
- code: "The code was: "
27
- no_stats: "Sorry, you have not any statistic yet"
28
- save_result: "Do you want to save result y/n"
29
-
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Codebreaker
4
- class Output
5
- attr_reader :stats
6
- def initialize
7
- I18n.load_path << Dir[File.expand_path(File.join(File.dirname(__FILE__), 'data/locales/')) + '/*.yml']
8
- I18n.config.available_locales = :en
9
- @stats = Codebreaker::Loader.load('stats')
10
- end
11
-
12
- def greeting
13
- puts I18n.t(:hey)
14
- end
15
-
16
- def available_commands
17
- puts I18n.t(:available_commands)
18
- end
19
-
20
- def choose_name
21
- puts I18n.t(:choose_name)
22
- end
23
-
24
- def wrong_name
25
- puts I18n.t(:wrong_name)
26
- end
27
-
28
- def rules
29
- puts I18n.t(:rules)
30
- end
31
-
32
- def sort_stats
33
- @stats = @stats.sort_by do |game|
34
- [game[:attempts], game[:used_attempts],
35
- game[:used_hints]]
36
- end
37
- end
38
-
39
- def show_stats
40
- sort_stats
41
- @stats.each_with_index do |game, index|
42
- puts "Hey, #{game[:name]}
43
- Rating: #{index + 1}
44
- Attempts: #{game[:attempts]}
45
- Hints: #{game[:hints]}
46
- Chosen difficulty: #{game[:difficulty]}
47
- Used attempts: #{game[:used_attempts]}
48
- Used hints: #{game[:used_hints]}"
49
- end
50
- end
51
-
52
- def no_stats
53
- puts I18n.t(:no_stats)
54
- end
55
-
56
- def show_hint
57
- puts I18n.t(:get_hint)
58
- end
59
-
60
- def no_hints
61
- puts I18n.t(:no_hints)
62
- end
63
-
64
- def choose_difficulty
65
- puts I18n.t(:choose_difficulty)
66
- end
67
-
68
- def wrong_difficulty
69
- puts I18n.t(:wrong_difficulty)
70
- end
71
-
72
- def enter_guess
73
- puts I18n.t(:enter_guess)
74
- end
75
-
76
- def wrong_input
77
- puts I18n.t(:wrong_input)
78
- end
79
-
80
- def win
81
- puts I18n.t(:win)
82
- end
83
-
84
- def lose
85
- puts I18n.t(:lose)
86
- puts I18n.t(:code)
87
- end
88
-
89
- def save_result
90
- puts I18n.t(:save_result)
91
- end
92
-
93
- def goodbye
94
- puts I18n.t(:goodbye)
95
- end
96
- end
97
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Codebreaker
4
- module Validation
5
- MIN_NAME_LENGTH = 3
6
- MAX_NAME_LENGTH = 20
7
- def name_is_valid?(name)
8
- name.instance_of?(String) && name.length.between?(MIN_NAME_LENGTH, MAX_NAME_LENGTH)
9
- end
10
-
11
- def input_is_valid?(input)
12
- /^[1-6]{4}$/.match?(input)
13
- end
14
- end
15
- end