codebreaker_artem 0.2.1 → 0.3.1

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: 7e4829afb9df99eb2ac625338df6ceeae94f1e34
4
- data.tar.gz: 9b9953345abfd00827efa6d5f82309cc1c05c527
3
+ metadata.gz: '056680463d26bc82bcde45002724db966ed5fc50'
4
+ data.tar.gz: 4c394660eb8fbca917bafb022f630c64d84d8dd8
5
5
  SHA512:
6
- metadata.gz: db318b9fd9e7d1f01f8ed754a2b89d0cc933fd9d99208cfe15f8b087af6cbdce3b527f6074816fba52706883a9e560e968ba1d89c297d41832d3d253061cb944
7
- data.tar.gz: a4cc6e09ce4674517fdde87f0353eadfe3cdc57500a035d747cce7f169a1f66cbdcc882dc84044fa3eee510dc7fb221c2aa994eb2341557532686e9a67ff2a92
6
+ metadata.gz: 8047618ac8da41e254767769c12cc0fbfa7a3019e86304748cebd4ba03cab7a7908f2d4b256c9e41ca8b9defae99fb4419251350af61e316f5c23a6b9c4694bf
7
+ data.tar.gz: 3743e9b166af684ce964de77d433adc0638cb26e45b782cae69df1998c9b0c3a32384cc522e38fcb0ed1d0f62f8fd4170833de4ecd3fbcce6e2c8b2a4249af2c
data/README.md CHANGED
@@ -24,8 +24,7 @@ Or install it yourself as:
24
24
  ```ruby
25
25
  require 'codebreaker_artem'
26
26
 
27
- game = CodebreakerArtem::Game.new
28
- game.play
27
+ CodebreakerArtem::Starter.start
29
28
  ```
30
29
 
31
30
  The code-maker, which will be played by the application, creates a secret code of four numbers between 1 and 6.
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = CodebreakerArtem::VERSION
9
9
  spec.licenses = ['MIT']
10
10
  spec.authors = ["b-artem"]
11
- spec.email = ["ba.artyom@gmail.com"]
11
+ spec.email = ["artemb.dev@gmail.com"]
12
12
 
13
13
  spec.summary = %q{Codebreaker game.}
14
14
  spec.description = %q{Codebreaker is a logic game in which a code-breaker
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
  which will be played by the application, creates a secret code of four
17
17
  numbers between 1 and 6.}
18
18
  spec.homepage = "https://github.com/b-artem/codebreaker_artem"
19
+ spec.required_ruby_version = ">=1.9.3"
19
20
 
20
21
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
21
22
  # to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -36,4 +37,5 @@ Gem::Specification.new do |spec|
36
37
  spec.add_development_dependency "bundler", "~> 1.15"
37
38
  spec.add_development_dependency "rake", "~> 10.0"
38
39
  spec.add_development_dependency "rspec", "~> 3.0"
40
+ spec.add_development_dependency 'pry', "~> 0.10.0"
39
41
  end
@@ -0,0 +1,115 @@
1
+ require_relative 'validator'
2
+
3
+ module CodebreakerArtem
4
+ class CLI
5
+ class << self
6
+ def welcome_msg(max_guess_number)
7
+ puts %(
8
+ Welcome to the Codebreaker Game!
9
+ New secret code has just been generated
10
+ You have #{max_guess_number} attempts
11
+ Type 'hint' to take a hint
12
+ Type 'exit' to exit the game
13
+ )
14
+ end
15
+
16
+ def guess_prompt(guess_count)
17
+ print "Please enter your guess no. #{guess_count + 1}: "
18
+ end
19
+
20
+ def submit_guess
21
+ guess = $stdin.gets.chomp
22
+ exit?(guess)
23
+ return :hint if guess =~ /^hint$/i
24
+ return wrong_code_pattern unless Validator.code_valid?(guess)
25
+ guess
26
+ end
27
+
28
+ def show_hint(number = nil, position = nil)
29
+ return one_hint_only unless number && position
30
+ puts "HINT: Number #{number} is in position #{position + 1}"
31
+ end
32
+
33
+ def show_mark(mark)
34
+ puts mark
35
+ end
36
+
37
+ def win(code, score)
38
+ win_msg
39
+ finish_game(code, score)
40
+ end
41
+
42
+ def lose(code, score, max_guess_number)
43
+ lose_msg(max_guess_number)
44
+ finish_game(code, score)
45
+ end
46
+
47
+ def win_msg
48
+ puts "\nCONGRATULATIONS! YOU'VE WON the Codebreaker game!\n"
49
+ end
50
+
51
+ def lose_msg(max_guess_number)
52
+ puts "GAME OVER. You've used all #{max_guess_number} attempts\n"
53
+ end
54
+
55
+ def finish_game(code, score)
56
+ reveal_code(code)
57
+ save_score(score)
58
+ end
59
+
60
+ def reveal_code(code)
61
+ puts "The secret code was #{code}\n"
62
+ end
63
+
64
+ def one_hint_only
65
+ puts 'You have only one hint!'
66
+ end
67
+
68
+ def wrong_code_pattern
69
+ puts 'Code must contain 4 numbers from 1 to 6. Please try again'
70
+ end
71
+
72
+ def exit?(input)
73
+ exit if input =~ /^exit$/i
74
+ end
75
+
76
+ def save_score(score)
77
+ return false unless yes? { 'Do you want to save your score? [y/n]: ' }
78
+ begin
79
+ Dir.mkdir('./score') unless File.exist?('./score')
80
+ file = File.new('./score/score.txt', 'a')
81
+ rescue
82
+ puts "Can't create file './score/score.txt'"
83
+ return
84
+ end
85
+ write_score_to_file(file, score)
86
+ file.close
87
+ end
88
+
89
+ def write_score_to_file(file, score)
90
+ print 'Please enter your name: '
91
+ name = $stdin.gets.chomp
92
+ file << "Name: #{name}\n"
93
+ file << "Time: #{Time.now}\n"
94
+ file << "Score: #{score}\n\n"
95
+ puts "Your score was added to a file #{file.path}"
96
+ end
97
+
98
+ def play_again
99
+ exit unless yes? { 'Would you like to play one more time? [y/n]: ' }
100
+ true
101
+ end
102
+
103
+ def yes?
104
+ print yield if block_given?
105
+ loop do
106
+ answer = $stdin.gets.chomp
107
+ exit?(answer)
108
+ return false if answer =~ /^n/i
109
+ return true if answer =~ /^y/i
110
+ puts "Please enter 'y' or 'n': "
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -1,37 +1,40 @@
1
- require_relative 'game_utils'
1
+ require_relative 'validator'
2
2
 
3
3
  module CodebreakerArtem
4
4
  class Game
5
- include GameUtils
6
5
  MAX_GUESS_NUMBER = 10
7
6
 
8
- attr_reader :secret_code
7
+ attr_reader :secret_code, :guess_count, :score
9
8
 
10
9
  def initialize
11
10
  initial_values_set
12
11
  end
13
12
 
14
- def play
15
- start
16
- loop do
17
- guess_prompt
18
- mark_guess(submit_guess)
19
- return lose if @guess_count >= MAX_GUESS_NUMBER
20
- end
21
- end
22
-
23
- private
24
-
25
13
  def start
26
14
  initial_values_set
27
15
  generate_secret_code
28
- welcome_msg
29
16
  end
30
17
 
18
+ def mark_guess(guess)
19
+ return false unless Validator.code_valid? guess
20
+ @guess_count += 1
21
+ counts = plus_minus_count(guess)
22
+ score_set(counts[0], counts[1])
23
+ '' << ('+' * counts[0]) << ('-' * counts[1])
24
+ end
25
+
26
+ def hint
27
+ return unless hint_available?
28
+ @hint_available = false
29
+ position = rand(0..3)
30
+ [@secret_code[position], position]
31
+ end
32
+
33
+ private
34
+
31
35
  def initial_values_set
32
36
  @guess_count = 0
33
37
  @score = 0
34
- @numbers_guess_count = [0, 0, 0, 0]
35
38
  @hint_available = true
36
39
  end
37
40
 
@@ -40,53 +43,28 @@ module CodebreakerArtem
40
43
  4.times { @secret_code << rand(1..6).to_s }
41
44
  end
42
45
 
43
- def mark_guess(guess)
44
- return false unless guess
45
- counts = plus_minus_count(guess)
46
- score_set(counts[0], counts[1])
47
- puts mark = '' << ('+' * counts[0]) << ('-' * counts[1])
48
- return win if mark == '++++'
49
- mark
46
+ def plus_minus_count(guess)
47
+ zipped = @secret_code.split('').zip(guess.split(''))
48
+ not_plus = zipped.delete_if { |item| item.uniq.one? }
49
+ return [4, 0] if not_plus.empty?
50
+ plus_count = 4 - not_plus.count
51
+ [plus_count, minus_count(not_plus)]
50
52
  end
51
53
 
52
- def plus_minus_count(guess)
53
- plus_count = 0
54
- minus_count = 0
55
- guess.each_char.with_index do |number, index|
56
- if number == @secret_code[index]
57
- plus_count += 1
58
- @numbers_guess_count[index] += 1
59
- elsif @secret_code.include? number
60
- minus_count += 1
61
- end
62
- end
63
- [plus_count, minus_count]
54
+ def minus_count(not_plus)
55
+ code = not_plus.transpose[0]
56
+ guess = not_plus.transpose[1]
57
+ guess.each { |item| code.delete_at(code.index(item) || code.length) }
58
+ not_plus.count - code.size
64
59
  end
65
60
 
66
61
  def score_set(plus_count, minus_count)
67
62
  @score = (plus_count * 3) + (minus_count * 1) +
68
- (MAX_GUESS_NUMBER - @guess_count + 1)
63
+ (MAX_GUESS_NUMBER - @guess_count)
69
64
  end
70
65
 
71
66
  def hint_available?
72
- return one_hint_only unless @hint_available
73
- true
74
- end
75
-
76
- def win
77
- win_msg
78
- finish_game
79
- end
80
-
81
- def lose
82
- lose_msg
83
- finish_game
84
- end
85
-
86
- def finish_game
87
- reveal_code
88
- save_score
89
- play_again
67
+ @hint_available
90
68
  end
91
69
  end
92
70
  end
@@ -0,0 +1,31 @@
1
+ require_relative 'game'
2
+ require_relative 'cli'
3
+
4
+ module CodebreakerArtem
5
+ class Starter
6
+ MAX = CodebreakerArtem::Game::MAX_GUESS_NUMBER
7
+
8
+ def self.start
9
+ game = CodebreakerArtem::Game.new
10
+ game.start
11
+ CLI.welcome_msg(MAX)
12
+ play(game)
13
+ start if CLI.play_again
14
+ end
15
+
16
+ def self.play(game)
17
+ loop do
18
+ CLI.guess_prompt(game.guess_count)
19
+ case input = CLI.submit_guess
20
+ when nil then next
21
+ when :hint then CLI.show_hint(*game.hint)
22
+ else
23
+ mark = game.mark_guess(input)
24
+ CLI.show_mark(mark)
25
+ return CLI.win(input, game.score) if mark == '++++'
26
+ end
27
+ return CLI.lose(game.secret_code, game.score, MAX) if game.guess_count >= MAX
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ module Validator
2
+ def self.code_valid?(input)
3
+ true if input =~ /^[1-6]{4}$/
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module CodebreakerArtem
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebreaker_artem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - b-artem
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-12 00:00:00.000000000 Z
11
+ date: 2017-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,13 +52,27 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.10.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.10.0
55
69
  description: |-
56
70
  Codebreaker is a logic game in which a code-breaker
57
71
  tries to break a secret code created by a code-maker. The code-maker,
58
72
  which will be played by the application, creates a secret code of four
59
73
  numbers between 1 and 6.
60
74
  email:
61
- - ba.artyom@gmail.com
75
+ - artemb.dev@gmail.com
62
76
  executables: []
63
77
  extensions: []
64
78
  extra_rdoc_files: []
@@ -74,8 +88,10 @@ files:
74
88
  - bin/setup
75
89
  - codebreaker_artem.gemspec
76
90
  - lib/codebreaker_artem.rb
91
+ - lib/codebreaker_artem/cli.rb
77
92
  - lib/codebreaker_artem/game.rb
78
- - lib/codebreaker_artem/game_utils.rb
93
+ - lib/codebreaker_artem/starter.rb
94
+ - lib/codebreaker_artem/validator.rb
79
95
  - lib/codebreaker_artem/version.rb
80
96
  homepage: https://github.com/b-artem/codebreaker_artem
81
97
  licenses:
@@ -90,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
106
  requirements:
91
107
  - - ">="
92
108
  - !ruby/object:Gem::Version
93
- version: '0'
109
+ version: 1.9.3
94
110
  required_rubygems_version: !ruby/object:Gem::Requirement
95
111
  requirements:
96
112
  - - ">="
@@ -1,107 +0,0 @@
1
- require_relative 'game'
2
-
3
- module GameUtils
4
- include CodebreakerArtem
5
-
6
- def welcome_msg
7
- print "Welcome to the Codebreaker Game!\n" \
8
- "New secret code has just been generated\n" \
9
- "You have #{Game::MAX_GUESS_NUMBER} attempts\n" \
10
- "Type 'hint' to take a hint\n" \
11
- "Type 'exit' to exit the game\n\n"
12
- end
13
-
14
- def guess_prompt
15
- print "Please enter your guess no. #{@guess_count}: "
16
- end
17
-
18
- def submit_guess
19
- guess = $stdin.gets.chomp
20
- exit?(guess)
21
- return false if take_hint(guess)
22
- return wrong_code_length unless guess.length == 4
23
- return wrong_code_numbers unless guess =~ /[1-6]{4}/
24
- @guess_count += 1
25
- guess
26
- end
27
-
28
- def save_score
29
- return false unless yes? { 'Do you want to save your score? (y/n): ' }
30
- begin
31
- Dir.mkdir('./score') unless File.exist?('./score')
32
- file = File.new('./score/score.txt', 'a')
33
- rescue
34
- puts "Can't create file './score/score.txt'"
35
- return
36
- end
37
- write_score_to_file file
38
- file.close
39
- end
40
-
41
- def write_score_to_file(file)
42
- print 'Please enter your name: '
43
- name = $stdin.gets.chomp
44
- file << "Name: #{name}\n"
45
- file << "Time: #{Time.now}\n"
46
- file << "Score: #{@score}\n\n"
47
- puts "Your data was added to a file #{file.path}"
48
- end
49
-
50
- def take_hint(input = nil)
51
- return false unless input =~ /hint/i
52
- return false unless hint_available?
53
- position = @numbers_guess_count.index(@numbers_guess_count.min)
54
- secret_number = @secret_code[position]
55
- puts "HINT: Number #{secret_number} is in position #{position + 1}"
56
- @hint_available = false
57
- secret_number
58
- end
59
-
60
- def one_hint_only
61
- puts 'You have only one hint'
62
- end
63
-
64
- def play_again
65
- exit unless yes? { 'Would you like to play one more time? (y/n): ' }
66
- start
67
- end
68
-
69
- def exit?(input)
70
- exit if input =~ /exit/
71
- false
72
- end
73
-
74
- def yes?
75
- print yield if block_given?
76
- loop do
77
- answer = $stdin.gets.chomp
78
- exit?(answer)
79
- return false if answer =~ /^n/i
80
- return true if answer =~ /^y/i
81
- puts "Please enter 'y' or 'n': "
82
- end
83
- end
84
-
85
- def wrong_code_length
86
- puts 'Code contains 4 numbers, please try again'
87
- false
88
- end
89
-
90
- def wrong_code_numbers
91
- puts 'All numbers are between 1 and 6, please try again'
92
- false
93
- end
94
-
95
- def win_msg
96
- puts "\nCONGRATULATIONS! You've won the Codebreaker game!"
97
- end
98
-
99
- def lose_msg
100
- puts "You've used all your attempts (#{Game::MAX_GUESS_NUMBER})" \
101
- " and LOST THE GAME\n"
102
- end
103
-
104
- def reveal_code
105
- puts "The secret code was #{@secret_code}\n"
106
- end
107
- end