codebreaker_vukolov_edition 0.1.0 → 0.1.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: e6495897950114c08c140eeee8ea424097445661
4
- data.tar.gz: c1e980080c361c301a3051b916a6aa0b7cb301f0
3
+ metadata.gz: bf336e1325d91902eed033fcfa76c165c6ae67f5
4
+ data.tar.gz: '0399cabf25a22df600ce4a33fefe3f2cba9c9b98'
5
5
  SHA512:
6
- metadata.gz: a546eb98d82e3aad7d1afca838e484892052b81be1aa418b271c7d90607ac4cd161cf9b8f013d63d8cf9252c1bad1268d21897dc75c0682870e3dedd80c8e340
7
- data.tar.gz: b85e8961b89481544898a4a268bb0f07b20f652b98dcdad00a8ffbbe78e738c3b06fc2fe42001733504867037095af3eb0f750a5668021342396248b0bd59f1f
6
+ metadata.gz: e0cede4d0212af980e67ae1810ac4cf0a4e71835ecd878188e617c65c2f22cfdfd904d7462d46f6334a5944e9a8ce7ce2fd361014efd999aeb666ba316aab15a
7
+ data.tar.gz: 31eebfbae302407cd0bebe4e3c51a3519de610f893c25ddcf92665f67c3d43de557f47bae834503d0e38f461c029672cfa250d1e7c398a1821eb855a53ecd2dc
data/.gitignore CHANGED
@@ -11,4 +11,4 @@
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
13
 
14
- results.txt
14
+ results.yml
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.4.0
@@ -1,3 +1,3 @@
1
1
  module CodebreakerVukolovEdition
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/controller.rb ADDED
@@ -0,0 +1,93 @@
1
+ require_relative 'codebreaker_vukolov_edition/version'
2
+ require_relative 'game'
3
+ require_relative 'messages'
4
+ require_relative 'services'
5
+ require 'yaml'
6
+
7
+ module CodebreakerVukolovEdition
8
+ class Controller
9
+ AVAILIABLE_VALUES = %w[hint yes no]
10
+ attr_accessor :game, :services
11
+
12
+ def initialize
13
+ @game = Game.new
14
+ @messages = Messages.new
15
+ @services = Services.new
16
+ end
17
+
18
+ def play
19
+ return total_result(:lose) if @game.turns == Game::MAX_TURNS
20
+ @messages.before_round_info(@game.turns)
21
+ show_hint
22
+ guess = provided_guess
23
+ result = @game.round_result(guess)
24
+ round_info(result)
25
+ @game.add_new_turn
26
+ play
27
+ end
28
+
29
+ def round_info(result)
30
+ return total_result(:won) if result == :won
31
+ @messages.show_messages(:round_result, result)
32
+ end
33
+
34
+ def show_hint
35
+ return @messages.print_hint(@game.hint) if @game.hint[:used]
36
+ @messages.hint_info
37
+ end
38
+
39
+ def next_step(decision, *option)
40
+ if decision == 'yes'
41
+ yield
42
+ elsif decision == 'no' && option.include?('save_result')
43
+ @messages.show_messages(:game_unsaved)
44
+ else
45
+ abort
46
+ end
47
+ end
48
+
49
+ def total_result(state)
50
+ @messages.total_game_info(state, @game.turns, @game.secret_code)
51
+ next_step(make_a_decision(:save_result), 'save_result') do
52
+ username = get_action(:name)
53
+ @services.write_result_to_file(username, state, @game.turns, @game.hint, @game.secret_code)
54
+ end
55
+ next_step(make_a_decision(:new_game)) do
56
+ game = CodebreakerVukolovEdition::Controller.new
57
+ game.play
58
+ end
59
+ end
60
+
61
+ def make_a_decision(option)
62
+ decision = validate(get_action(option))
63
+ return decision unless decision.nil?
64
+ @messages.show_messages(:instruction)
65
+ make_a_decision(option)
66
+ end
67
+
68
+ def get_action(*question)
69
+ @messages.show_messages(question.first) if question
70
+ value = gets.chomp
71
+ value.empty? ? get_action(*question) : value
72
+ end
73
+
74
+ def provided_guess
75
+ input = validate(get_action(:input))
76
+ if input.nil?
77
+ @messages.show_messages(:input_warning)
78
+ provided_guess
79
+ elsif input == 'hint'
80
+ @game.use_hint
81
+ play
82
+ else
83
+ input
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ def validate(input)
90
+ input if (input.to_i.positive? && input.length == 4) || AVAILIABLE_VALUES.include?(input)
91
+ end
92
+ end
93
+ end
data/lib/game.rb ADDED
@@ -0,0 +1,60 @@
1
+ require_relative 'controller'
2
+
3
+ module CodebreakerVukolovEdition
4
+ class Game
5
+ SECRET_CODE_VALID_VALUES = (1..6)
6
+ SECRET_CODE_LENGTH = 4
7
+ MAX_TURNS = 15
8
+ attr_accessor :turns, :secret_code, :hint
9
+
10
+ def initialize
11
+ @secret_code = new_code
12
+ @turns = 0
13
+ @hint = { used: false, value: @secret_code.sample }
14
+ end
15
+
16
+ def add_new_turn
17
+ @turns += 1
18
+ end
19
+
20
+ def use_hint
21
+ @hint[:used] = true
22
+ end
23
+
24
+ def round_result(guess)
25
+ result = checker(guess)
26
+ return :won if result == '++++'
27
+ result
28
+ end
29
+
30
+ def checker(guess)
31
+ guess_arr = guess.split('').map(&:to_i)
32
+ temp = @secret_code.zip(guess_arr)
33
+ get_plusses(temp) + get_minuses(temp)
34
+ end
35
+
36
+ private
37
+
38
+ def new_code
39
+ Array.new(SECRET_CODE_LENGTH).map { rand(SECRET_CODE_VALID_VALUES) }
40
+ end
41
+
42
+ def count_plusses(temp)
43
+ temp.select { |el| el.uniq.size == 1 }
44
+ end
45
+
46
+ def get_plusses(temp)
47
+ '+' * count_plusses(temp).size
48
+ end
49
+
50
+ def get_minuses(temp)
51
+ minuses = ''
52
+ code = (temp - count_plusses(temp)).transpose.first
53
+ user_guess = (temp - count_plusses(temp)).transpose.last
54
+ code&.each do |code_value|
55
+ user_guess.delete_at(user_guess.index(code_value) || user_guess.length) && minuses << '-' if user_guess.include?(code_value)
56
+ end
57
+ minuses
58
+ end
59
+ end
60
+ end
data/lib/messages.rb ADDED
@@ -0,0 +1,46 @@
1
+ require_relative 'controller'
2
+
3
+ module CodebreakerVukolovEdition
4
+ class Messages
5
+ INFO_MESSAGES = {
6
+ new_game: '(?) Would you like to play new game? [yes/no]',
7
+ save_result: '(?) Would you like to save result of your game? [yes/no]',
8
+ input: '> Please provide your guess',
9
+ input_warning: "(!) The input should be exactly four digits or 'hint' word",
10
+ name: 'What is your name?',
11
+ instruction: "(!) Please follow to instruction. You can type only 'yes' or 'no'",
12
+ result_saved: 'Result of your game was written to file: ',
13
+ game_unsaved: 'Ok, nobody will know about your fail LoL, azaza!!!!!!!11)',
14
+ round_result: 'Your result is: '
15
+ }
16
+
17
+ def before_round_info(turns)
18
+ puts "====================== round ##{turns + 1} ======================
19
+ You have #{CodebreakerVukolovEdition::Game::MAX_TURNS - turns} turns for breaking this code"
20
+ end
21
+
22
+ def print_hint(hint)
23
+ puts "HINT: #{hint[:value]}"
24
+ end
25
+
26
+ def hint_info
27
+ puts "(*) Also, you can use hint (the system reveals one of the numbers in the secret code). If you need a hint, please put 'hint'"
28
+ end
29
+
30
+ def total_game_info(state, turns, secret_code)
31
+ case state
32
+ when :won
33
+ puts "
34
+ Congratulation!!!!
35
+ You have hacked this code by #{turns} turns, the code is #{secret_code.join('')}"
36
+ when :lose
37
+ puts "Unfortunately you spent all your turns (#{turns}) and didn't brake the code. Code was #{secret_code.join('')}"
38
+ end
39
+ end
40
+
41
+ def show_messages(symbol, *arg)
42
+ message = arg.empty? ? INFO_MESSAGES[symbol] : INFO_MESSAGES[symbol] + arg.first
43
+ puts message
44
+ end
45
+ end
46
+ end
data/lib/services.rb ADDED
@@ -0,0 +1,16 @@
1
+ require_relative 'messages'
2
+
3
+ module CodebreakerVukolovEdition
4
+ class Services
5
+ def initialize
6
+ @messages = Messages.new
7
+ end
8
+
9
+ def write_result_to_file(username, state, turns, hint, secret_code)
10
+ filename = 'results.yml'
11
+ string = "#{Time.now.strftime('%F %T')} | #{username} | #{state} | #{turns} of #{CodebreakerVukolovEdition::Game::MAX_TURNS} | hint #{hint[:used] ? 'used' : 'did not use'} | code was #{secret_code.join('')}"
12
+ File.open(filename, 'a') {|f| f.write string.to_yaml }
13
+ @messages.show_messages(:result_saved, filename)
14
+ end
15
+ end
16
+ end
data/start.rb ADDED
@@ -0,0 +1,4 @@
1
+ require_relative 'lib/controller'
2
+
3
+ game = CodebreakerVukolovEdition::Controller.new
4
+ game.play
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebreaker_vukolov_edition
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-06 00:00:00.000000000 Z
11
+ date: 2017-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -64,6 +64,7 @@ extra_rdoc_files: []
64
64
  files:
65
65
  - ".gitignore"
66
66
  - ".rspec"
67
+ - ".ruby-version"
67
68
  - ".travis.yml"
68
69
  - CODE_OF_CONDUCT.md
69
70
  - Gemfile
@@ -74,8 +75,12 @@ files:
74
75
  - bin/setup
75
76
  - circle.yml
76
77
  - codebreaker_vukolov_edition.gemspec
77
- - lib/codebreaker_vukolov_edition.rb
78
78
  - lib/codebreaker_vukolov_edition/version.rb
79
+ - lib/controller.rb
80
+ - lib/game.rb
81
+ - lib/messages.rb
82
+ - lib/services.rb
83
+ - start.rb
79
84
  homepage: https://github.com/vatnajokull/
80
85
  licenses:
81
86
  - MIT
@@ -1,137 +0,0 @@
1
- require "codebreaker_vukolov_edition/version"
2
-
3
- module CodebreakerVukolovEdition
4
- class Game
5
- MAX_TURNS = 15
6
- attr_accessor :turns, :secret_code, :max_turns, :hint
7
-
8
- def initialize
9
- @turns = 0
10
- @secret_code = new_code
11
- @hint = { used: false, value: @secret_code.sample }
12
- end
13
-
14
- def play
15
- if @turns < MAX_TURNS
16
- puts "====================== round ##{turns + 1} ======================
17
- You have #{MAX_TURNS - @turns} turns for breaking this code"
18
- show_hint
19
- guess = provided_guess
20
- result = checker(guess)
21
- calculation(result)
22
- play
23
- else
24
- result('lose')
25
- end
26
- end
27
-
28
- def show_hint
29
- if @hint[:used]
30
- puts "HINT: #{@hint[:value]}"
31
- else
32
- puts "(*) Also, you can use hint (the system reveals one of the numbers in the secret code). If you need a hint, please put 'hint'"
33
- end
34
- end
35
-
36
- def result(state)
37
- case state
38
- when 'win'
39
- puts "
40
- Congratulation #{@user}!!!!
41
- You have hacked this code by #{@turns} turns, the code is #{@secret_code.join('')}"
42
- when 'lose'
43
- puts "#{@user}, unfortunately you spent all your turns (#{@turns}) and didn't brake the code. Code was #{@secret_code.join('')}"
44
- end
45
- save_result(state, make_a_decision('save result'))
46
- play_new_game(make_a_decision('play new game'))
47
- end
48
-
49
- def make_a_decision(option)
50
- decision = get_action("(?) Would you like to #{option}? [yes/no]")
51
- if decision == 'yes' || decision == 'no'
52
- decision
53
- else
54
- puts "(!) Please follow to instruction. You can type only 'yes' or 'no'"
55
- make_a_decision(option)
56
- end
57
- end
58
-
59
- def get_action(*question)
60
- puts question
61
- value = gets.chomp
62
- value.empty? ? get_action : value
63
- end
64
-
65
- def save_result(state, decision)
66
- case decision
67
- when 'yes'
68
- username = get_action('What is your name?')
69
- write_result_to_file(state, username)
70
- when 'no'
71
- puts 'Ok, nobody will know about your fail LoL, azaza!!!!!!!11)'
72
- end
73
- end
74
-
75
- def play_new_game(decision)
76
- case decision
77
- when 'yes'
78
- game = CodebreakerVukolovEdition::Game.new
79
- game.play
80
- when 'no' then abort
81
- end
82
- end
83
-
84
- def write_result_to_file(state, username)
85
- filename = 'results.txt'
86
- File.open(filename, 'a') do |file|
87
- string = "#{Time.now.strftime('%F %T')} | #{username} | #{state} | #{@turns} of #{MAX_TURNS} | hint #{@hint[:used]? 'used' : 'did not use'} | code was #{@secret_code.join('')}"
88
- file.write("\n#{string}")
89
- end
90
- puts "Result of your game was written to: #{filename}"
91
- end
92
-
93
- def new_code
94
- secret_code = []
95
- 4.times { secret_code.push(rand(1..6)) }
96
- secret_code
97
- end
98
-
99
- def provided_guess
100
- input = get_action('> Please provide your guess')
101
- if input == 'hint'
102
- @hint[:used] = true
103
- elsif input.to_i > 0 && input.length == 4
104
- add_new_turn
105
- else
106
- puts "(!) The input should be exactly four digits or 'hint' word"
107
- provided_guess
108
- end
109
- input
110
- end
111
-
112
- def add_new_turn
113
- @turns += 1
114
- end
115
-
116
- def checker(guess)
117
- guess_arr = guess.split('').map(&:to_i)
118
- result = []
119
- guess_arr.each_with_index do |number, index|
120
- if number == @secret_code[index]
121
- result.unshift('+')
122
- elsif @secret_code.include?(number)
123
- result.push('-')
124
- end
125
- end
126
- result.join('')
127
- end
128
-
129
- def calculation(result)
130
- if result == '++++'
131
- result('win')
132
- else
133
- puts "Your result is: #{result}"
134
- end
135
- end
136
- end
137
- end