Class: RavCodebreaker::Game

Inherits:
Object
  • Object
show all
Defined in:
lib/rav_codebreaker/game.rb

Constant Summary collapse

TURNS_COUNT =
{expert: 10, master: 15, beginner: 20}
HINTS_COUNT =
{expert: 0, master: 1, beginner: 2}
SCORES_FILE_NAME =
'./score.dat'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(level = :expert) ⇒ Game

Returns a new instance of Game.



9
10
11
12
13
14
# File 'lib/rav_codebreaker/game.rb', line 9

def initialize(level = :expert)
  @secret_code = ''
  @turns_left = 0
  TURNS_COUNT.keys.include?(level) ? @level = level : @level = :expert
  @score = []
end

Instance Attribute Details

#hints_leftObject (readonly)

Returns the value of attribute hints_left.



7
8
9
# File 'lib/rav_codebreaker/game.rb', line 7

def hints_left
  @hints_left
end

#offerObject (readonly)

Returns the value of attribute offer.



7
8
9
# File 'lib/rav_codebreaker/game.rb', line 7

def offer
  @offer
end

#turns_leftObject (readonly)

Returns the value of attribute turns_left.



7
8
9
# File 'lib/rav_codebreaker/game.rb', line 7

def turns_left
  @turns_left
end

Instance Method Details

#again?Boolean

Returns:

  • (Boolean)


41
42
43
44
# File 'lib/rav_codebreaker/game.rb', line 41

def again?
  puts 'Do you want to play again (Y or N)'
  gets =~ /y|Y/
end

#decode_offerObject



63
64
65
66
67
68
69
70
# File 'lib/rav_codebreaker/game.rb', line 63

def decode_offer
  code = @secret_code.split('')
  offer = @offer.split('')
  4.times{|i| code[i] = offer[i] = nil if @secret_code[i] == @offer[i]}
  offer.compact!
  offer.each{|num| code[code.index(num)] = '-' if code.include? num}
  '+' * code.count(nil) + '-' * code.count('-')
end

#exit?Boolean

Returns:

  • (Boolean)


89
90
91
# File 'lib/rav_codebreaker/game.rb', line 89

def exit?
  @offer =~ /^[qQ]$/
end

#format_error?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/rav_codebreaker/game.rb', line 85

def format_error?
  @offer !~ /^[1-6]{4}$/ && @offer !~ /^[hH]$/
end

#game_over?Boolean

Returns:

  • (Boolean)


93
94
95
# File 'lib/rav_codebreaker/game.rb', line 93

def game_over?
  @turns_left < 1
end

#get_offerObject



72
73
74
# File 'lib/rav_codebreaker/game.rb', line 72

def get_offer
  @offer = gets.chomp
end

#incorrect_messageObject



59
60
61
# File 'lib/rav_codebreaker/game.rb', line 59

def incorrect_message
  "\nincorrect number format, try again, please..."
end

#invitation_messageObject



54
55
56
57
# File 'lib/rav_codebreaker/game.rb', line 54

def invitation_message
  "Try to guess the secret code! You have #{@turns_left} attempts and #{@hints_left} hints. Good luck!" +
  "\nEnter you four numbers code (from 1 to 6), please (or Q - for exit, H - for hint):"
end

#load_scores_from_fileObject



117
118
119
120
121
122
# File 'lib/rav_codebreaker/game.rb', line 117

def load_scores_from_file
  return unless File.exist? SCORES_FILE_NAME
  File.open(SCORES_FILE_NAME) do |file|
    @score = Marshal.load(file)
  end
end

#playObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rav_codebreaker/game.rb', line 23

def play
  start
  welcome_message
  loop do
    puts format_error? ? incorrect_message : invitation_message
    get_offer
    exit if exit?
    next if show_hint? || format_error?
    test_offer
    show_winner_message if win?
    show_game_over_message if game_over?
    break if win? || game_over?
  end
  load_scores_from_file
  save_results
  show_results
end

#save_resultsObject



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/rav_codebreaker/game.rb', line 144

def save_results
  puts '"Do you want to save your results (Y/N)?'
  return if gets !~ /y|Y/
  player = {}
  begin
    puts 'Enter your name, please...'
    player[:name] = gets.chomp
  end while player[:name].empty?
  player[:level] = @level
  player[:turns] = TURNS_COUNT[@level] - @turns_left
  player[:hints] = HINTS_COUNT[@level] - @hints_left
  @score << player
  save_scores_to_file
end

#save_scores_to_fileObject



124
125
126
127
128
# File 'lib/rav_codebreaker/game.rb', line 124

def save_scores_to_file
  File.open(SCORES_FILE_NAME, 'w+') do |file|
    Marshal.dump(@score, file)
  end
end

#show_game_over_messageObject



97
98
99
# File 'lib/rav_codebreaker/game.rb', line 97

def show_game_over_message
  puts "Sorry, you lose the game :(\nThe secret code was #{@secret_code}."
end

#show_hint?Boolean

Returns:

  • (Boolean)


105
106
107
108
109
110
111
112
113
114
115
# File 'lib/rav_codebreaker/game.rb', line 105

def show_hint?
  return false unless @offer =~ /^[hH]$/
  if @hints_left < 1
    puts 'Sorry, but you have not any hints :('
  else
    @hints_left -= 1
    pos = rand(4)
    puts "I exactly know that a number #{@secret_code[pos]} is at position ##{pos} (remember, it starts from 0)."
  end
  true
end

#show_resultsObject



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/rav_codebreaker/game.rb', line 130

def show_results
  @score.sort_by!{|player| player[:turns]}
  format_str = "| %02s | %12s | %10s | %5s | %5s |"
  format_str_length = 50
  puts '-' * format_str_length
  puts format_str % %w(## player\ name game\ level turns hints)
  puts '-' * format_str_length
  @score.each_with_index do |player, index|
    arr = [index + 1] + player.values
    puts format_str % arr
  end
  puts '-' * format_str_length
end

#show_winner_messageObject



101
102
103
# File 'lib/rav_codebreaker/game.rb', line 101

def show_winner_message
  puts 'We congratulate you on your victory!!!'
end

#startObject



16
17
18
19
20
21
# File 'lib/rav_codebreaker/game.rb', line 16

def start
  @secret_code = Array.new(4){rand(1..6)}*''
  @turns_left = TURNS_COUNT[@level]
  @hints_left = HINTS_COUNT[@level]
  @offer = '6666'
end

#test_offerObject



76
77
78
79
# File 'lib/rav_codebreaker/game.rb', line 76

def test_offer
  @turns_left -= 1
  puts "You result is \"#{decode_offer}\"!"
end

#welcome_messageObject

private



48
49
50
51
52
# File 'lib/rav_codebreaker/game.rb', line 48

def welcome_message
  puts '='*80
  puts 'Welcome to play the CodeBreaker Game!!!'
  puts '='*80
end

#win?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/rav_codebreaker/game.rb', line 81

def win?
  decode_offer == '++++'
end