Class: Mastermind::Game

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/mastermind/game.rb,
lib/mastermind/extensions/extensions.rb,
lib/mastermind/extensions/continue_later.rb

Constant Summary collapse

ALLOWED_TRIALS =
12
@@all_colors_hash =
{ 'R' => '(r)ed',
  'G' => '(g)reen',
  'B' => '(b)lue',
  'Y' => '(y)ellow'
}
@@color_array =

%w{ R G B Y }

@@all_colors_hash.keys

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper

#get_input, #send_message

Constructor Details

#initialize(response, character_count = 4, top_ten_record: TopTen.new) ⇒ Game

Returns a new instance of Game.



13
14
15
16
17
# File 'lib/mastermind/game.rb', line 13

def initialize(response, character_count = 4, top_ten_record: TopTen.new)
  @response = response
  @character_count = character_count
  @top_ten_record = top_ten_record
end

Instance Attribute Details

#character_countObject (readonly)

Returns the value of attribute character_count.



4
5
6
# File 'lib/mastermind/game.rb', line 4

def character_count
  @character_count
end

#colorsObject (readonly)

Returns the value of attribute colors.



4
5
6
# File 'lib/mastermind/game.rb', line 4

def colors
  @colors
end

#game_save_dataObject (readonly)

Returns the value of attribute game_save_data.



4
5
6
# File 'lib/mastermind/extensions/continue_later.rb', line 4

def game_save_data
  @game_save_data
end

#levelObject (readonly)

Returns the value of attribute level.



27
28
29
# File 'lib/mastermind/extensions/extensions.rb', line 27

def level
  @level
end

#playerObject (readonly)

Returns the value of attribute player.



4
5
6
# File 'lib/mastermind/game.rb', line 4

def player
  @player
end

#responseObject (readonly)

Returns the value of attribute response.



4
5
6
# File 'lib/mastermind/game.rb', line 4

def response
  @response
end

#top_ten_recordObject (readonly)

Returns the value of attribute top_ten_record.



4
5
6
# File 'lib/mastermind/game.rb', line 4

def top_ten_record
  @top_ten_record
end

#trial_countObject (readonly)

Returns the value of attribute trial_count.



4
5
6
# File 'lib/mastermind/game.rb', line 4

def trial_count
  @trial_count
end

Instance Method Details

#actionsObject



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

def actions
  action_s = {
    'q' => 'quit_game',
    'quit' => 'quit_game',
    'i' => 'instructions',
    'instructions' => 'instructions',
    'c' => 'cheat',
    'cheat' => 'cheat'
  }

  supported_actions = {'p' => 'play', 'play' => 'play', 'top_players' => 'top_players', 't' => 'top_players'}
  action_s = action_s.merge(supported_actions) if @trial_count >= ALLOWED_TRIALS || @response.status == :won

  action_s
end

#analyze_guess(current_guess) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/mastermind/game.rb', line 56

def analyze_guess(current_guess)
  current_guess = current_guess.upcase.split('')
  current_sprint = Hash.new(0)
  current_guess.each_with_index{ |value, index|
    if value == @colors[index]
      current_sprint[:match_position] += 1
    elsif @colors.include? value
      # near matches should be a counter that
      # counts the unique elements in the colors array
      current_sprint[:almost_match] += 1
    end
  }
  current_sprint
end

#cheatObject



178
179
180
181
# File 'lib/mastermind/game.rb', line 178

def cheat
  send_message(@response.cheat(@colors.join).message)
  @response.message
end

#check_correct?(analysis) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
124
125
126
# File 'lib/mastermind/game.rb', line 121

def check_correct?(analysis)
  if analysis[:match_position] == @character_count
    won(@time_started)
    true
  end
end

#check_if_user_has_saved_gameObject



13
14
15
16
17
18
19
20
# File 'lib/mastermind/extensions/continue_later.rb', line 13

def check_if_user_has_saved_game
  @game_save_data ||= SaveGame.new
  player = @game_save_data.fetch_player(@player.name)
  if player
    input = get_input(@response.message_if_user_has_saved_game.message)
    continue_saved_game(player) if ['y', 'yes'].include? input
  end
end

#continue_saved_game(player) ⇒ Object



22
23
24
25
# File 'lib/mastermind/extensions/continue_later.rb', line 22

def continue_saved_game(player)
  @player = player
  load_saved_game
end

#convert_level(level = 1) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/mastermind/extensions/extensions.rb', line 40

def convert_level(level = 1)
  # @character_count = 4 + (2 * (level - 1))
  color_count = 4 + (1 * (level - 1))
  #this ought not be, however useful for the simple gem
  #which basically uses the generates colors based on the arrays
  #if colors were repeated the commented method above would have been better

  @character_count = color_count
  additional_colors = {'O' => '(o)range',
                      'P' => '(p)urple',
                      'C' => '(c)yan',
                      'V' => '(v)iolet',
                      'I' => '(i)ndigo',
                      'A' => '(a)mber'
                      }
  @@all_colors_hash.merge!(additional_colors)
  @@color_array = @@all_colors_hash.keys.sample(color_count)
end

#game_processObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/mastermind/game.rb', line 39

def game_process
  until @response.status == :won || @response.status == :lost || @trial_count >= ALLOWED_TRIALS
    input = get_game_input
    if actions.keys.include? input
      method(actions[input]).call
      break unless actions[input] =~ /instructions/
    else
      next if the_input_is_too_long_or_too_short?(input)
      @trial_count += 1
      analyzed = analyze_guess(input)
      break if check_correct?(analyzed)
      send_message(@response.analyzed_guess(analyzed[:match_position], analyzed[:almost_match]).message)
    end
  end
  what_do_you_want_to_do_next
end

#generate_colorsObject



29
30
31
32
# File 'lib/mastermind/game.rb', line 29

def generate_colors
  @colors = @@color_array.sample(@character_count)
  shuffle_colors_hash
end

#get_game_inputObject



104
105
106
107
# File 'lib/mastermind/game.rb', line 104

def get_game_input
  input = get_input(@response.trial_count(@trial_count, @colors.join, @color_values_from_all_colors_array).message)
  input
end

#get_playerObject



71
72
73
74
75
76
77
78
79
# File 'lib/mastermind/game.rb', line 71

def get_player
  @player ||= Player.new
  player = Hash.new(nil)
  while player[:name].nil? || player[:name].empty?
    player_name = get_input(@response.player.message)
    player[:name] = player_name
    @player.set_attr player
  end
end

#instructionsObject



144
145
146
147
# File 'lib/mastermind/game.rb', line 144

def instructions
  send_message(@response.instructions(@color_values_from_all_colors_array).message)
  @response.message
end

#load_saved_gameObject



40
41
42
43
44
45
46
47
48
# File 'lib/mastermind/extensions/continue_later.rb', line 40

def load_saved_game
  @trial_count = @player.guesses_at_pause_count
  @colors = @player.color_combo
  @character_count = @colors.length
  time_used = @player.time_started - @player.time_at_game_save
  @time_started = Time.now.to_i - time_used
  shuffle_colors_hash
  instructions
end

#loser_play_again_or_quitObject



109
110
111
112
# File 'lib/mastermind/game.rb', line 109

def loser_play_again_or_quit
  input = get_game_input
  method(actions[input]).call if actions.keys.include? input
end

#lostObject



167
168
169
# File 'lib/mastermind/game.rb', line 167

def lost

end

#old_actionsObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/mastermind/extensions/continue_later.rb', line 3

def actions
  action_s = {
    'q' => 'quit_game',
    'quit' => 'quit_game',
    'i' => 'instructions',
    'instructions' => 'instructions',
    'c' => 'cheat',
    'cheat' => 'cheat'
  }

  supported_actions = {'p' => 'play', 'play' => 'play', 'top_players' => 'top_players', 't' => 'top_players'}
  action_s = action_s.merge(supported_actions) if @trial_count >= ALLOWED_TRIALS || @response.status == :won

  action_s
end

#old_get_playerObject



5
6
7
8
9
10
11
12
13
# File 'lib/mastermind/extensions/continue_later.rb', line 5

def get_player
  @player ||= Player.new
  player = Hash.new(nil)
  while player[:name].nil? || player[:name].empty?
    player_name = get_input(@response.player.message)
    player[:name] = player_name
    @player.set_attr player
  end
end

#old_playObject

alias_method :old_initialize, :initialize



30
31
32
33
34
35
36
37
38
# File 'lib/mastermind/extensions/extensions.rb', line 30

def play
  generate_colors
  @trial_count = 0
  get_player if @player.nil?
  @response.start.message
  @time_started = Time.now.to_i

  game_process
end

#play(level = 1) ⇒ Object Also known as: new_old_play



19
20
21
22
23
24
25
26
27
# File 'lib/mastermind/game.rb', line 19

def play
  generate_colors
  @trial_count = 0
  get_player if @player.nil?
  @response.start.message
  @time_started = Time.now.to_i

  game_process
end

#play_laterObject



36
37
38
# File 'lib/mastermind/extensions/continue_later.rb', line 36

def play_later
  @player.save_game(@time_started, @colors, @trial_count)
end

#quit_gameObject



149
150
151
152
153
154
# File 'lib/mastermind/game.rb', line 149

def quit_game
  @trial_count = 0
  @colors = []
  send_message(@response.exit_game.message)
  @response.message
end

#save_if_top_tenObject



171
172
173
174
175
176
# File 'lib/mastermind/game.rb', line 171

def save_if_top_ten
  game_attr = {time_taken: @time_taken, guesses: @trial_count, date_played: Date.today}
  @player.set_attr game_attr

  @top_ten_record.add_record(@player)
end

#shuffle_colors_hashObject



34
35
36
37
# File 'lib/mastermind/game.rb', line 34

def shuffle_colors_hash
  @color_values_from_all_colors_array = @colors.map{|color| @@all_colors_hash[color] }
  @color_values_from_all_colors_array.shuffle!
end

#the_input_is_too_long_or_too_short?(input) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/mastermind/game.rb', line 95

def the_input_is_too_long_or_too_short?(input)
  true if too_long?(input) || too_short?(input)
end

#too_long?(input) ⇒ Boolean

Returns:

  • (Boolean)


88
89
90
91
92
93
# File 'lib/mastermind/game.rb', line 88

def too_long?(input)
  if input.length > @character_count
    send_message(@response.longer_input.message)
    true
  end
end

#too_short?(input) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
# File 'lib/mastermind/game.rb', line 81

def too_short?(input)
  if input.length < @character_count
    send_message(@response.shorter_input.message)
    true
  end
end

#top_playersObject



183
184
185
186
187
188
189
# File 'lib/mastermind/game.rb', line 183

def top_players
  @top_ten_record.fetch_all.each{ |player|
    send_message(player.winner_response)
  }

  game_process
end

#what_do_you_want_to_do_nextObject



99
100
101
102
# File 'lib/mastermind/game.rb', line 99

def what_do_you_want_to_do_next
  loser_play_again_or_quit if @response.status == :lost || @trial_count >= ALLOWED_TRIALS
  winner_play_again_or_quit if @response.status == :won
end

#winner_play_again_or_quitObject



114
115
116
117
118
119
# File 'lib/mastermind/game.rb', line 114

def winner_play_again_or_quit
  if @response.status == :won
    input = get_input(@response.message)
    method(actions[input]).call if actions.keys.include? input
  end
end

#won(start_time) ⇒ Object



156
157
158
159
160
161
162
163
164
165
# File 'lib/mastermind/game.rb', line 156

def won(start_time)
  @time_taken = Time.now.to_i - start_time
  time = {}
  time[:mins] = @time_taken/60
  time[:secs] = @time_taken%60

  save_if_top_ten

  @response.won(@trial_count, time)
end