tobi-mastermind 1.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.
@@ -1,15 +1,15 @@
1
- module MasterMind
2
- module Tobi
3
- class GamePlay
4
- attr_reader :entry; attr_reader :correct_elements; attr_reader :correct_positions
5
-
6
- def initialize(entry, correct_elements, correct_positions)
7
- @entry = entry; @correct_elements = correct_elements; @correct_positions = correct_positions
8
- end
9
-
10
- def to_s
11
- "#{entry} ::: #{correct_elements} correct #{correct_elements > 1 ? 'elements' : 'element'} ::: #{correct_positions} in correct #{correct_positions > 1 ? 'positions' : 'position'}"
12
- end
13
- end
14
- end
1
+ module MasterMind
2
+ module Tobi
3
+ class GamePlay
4
+ attr_reader :entry; attr_reader :correct_elements; attr_reader :correct_positions
5
+
6
+ def initialize(entry, correct_elements, correct_positions)
7
+ @entry = entry; @correct_elements = correct_elements; @correct_positions = correct_positions
8
+ end
9
+
10
+ def to_s
11
+ "#{entry} ::: #{correct_elements} correct #{correct_elements > 1 ? 'elements' : 'element'} ::: #{correct_positions} in correct #{correct_positions > 1 ? 'positions' : 'position'}"
12
+ end
13
+ end
14
+ end
15
15
  end
@@ -1,38 +1,38 @@
1
- module MasterMind
2
- module Tobi
3
- class GameLogic
4
- attr_reader :level; attr_reader :length; attr_reader :color_array; attr_reader :sequence_type
5
-
6
- BEGINNER, INTERMEDIATE, ADVANCED = 0, 1, 2
7
- SEQUENCE_TYPES = ['a beginner', 'an intermediate', 'an advanced']
8
- COLORS = [['r', 'g', 'b', 'y'], ['r', 'g', 'b', 'y', 'o'], ['r', 'g', 'b', 'y', 'o', 'v']]
9
-
10
- def initialize(level)
11
- @level = level
12
- @color_array = COLORS[level]
13
- @length = color_array.length
14
- @sequence_type = SEQUENCE_TYPES[level]
15
- end
16
-
17
- def generate_sequence
18
- (color_array * (rand() * 1000).to_i).shuffle[0...color_array.length] # generate random combination of r/g/b/y
19
- end
20
-
21
- def self.check_input(sequence, input)
22
- verify_values(input.split(''), sequence, sequence[0..-1])
23
- end
24
-
25
- def self.verify_values(split_input, sequence, sequence_copy)
26
- result_values = {correct_elements: 0, correct_position: 0}
27
- split_input.each_with_index{ |element, index|
28
- result_values[:correct_position] += 1 if split_input[index] == sequence[index] # if element in correct position
29
- if sequence_copy.include?(element)
30
- result_values[:correct_elements] += 1
31
- sequence_copy.delete_at(sequence_copy.index(element)) # if in sequence, delete first occurrence so as to counter duplicates
32
- end
33
- }
34
- result_values
35
- end
36
- end
37
- end
1
+ module MasterMind
2
+ module Tobi
3
+ class GameLogic
4
+ attr_reader :level; attr_reader :length; attr_reader :color_array; attr_reader :sequence_type
5
+
6
+ BEGINNER, INTERMEDIATE, ADVANCED = 0, 1, 2
7
+ SEQUENCE_TYPES = ['a beginner', 'an intermediate', 'an advanced']
8
+ COLORS = [['r', 'g', 'b', 'y'], ['r', 'g', 'b', 'y', 'o'], ['r', 'g', 'b', 'y', 'o', 'v']]
9
+
10
+ def initialize(level)
11
+ @level = level
12
+ @color_array = COLORS[level]
13
+ @length = color_array.length
14
+ @sequence_type = SEQUENCE_TYPES[level]
15
+ end
16
+
17
+ def generate_sequence
18
+ (color_array * (rand() * 1000).to_i).shuffle[0...color_array.length] # generate random combination of r/g/b/y
19
+ end
20
+
21
+ def self.check_input(sequence, input)
22
+ verify_values(input.split(''), sequence, sequence[0..-1])
23
+ end
24
+
25
+ def self.verify_values(split_input, sequence, sequence_copy)
26
+ result_values = {correct_elements: 0, correct_position: 0}
27
+ split_input.each_with_index{ |element, index|
28
+ result_values[:correct_position] += 1 if split_input[index] == sequence[index] # if element in correct position
29
+ if sequence_copy.include?(element)
30
+ result_values[:correct_elements] += 1
31
+ sequence_copy.delete_at(sequence_copy.index(element)) # if in sequence, delete first occurrence so as to counter duplicates
32
+ end
33
+ }
34
+ result_values
35
+ end
36
+ end
37
+ end
38
38
  end
@@ -1,97 +1,98 @@
1
- require 'single_game'
2
- require 'logic'
3
- require 'ui'
4
- require 'io/console'
5
-
6
- module MasterMind
7
- module Tobi
8
- class MultiPlayer < SinglePlayer
9
- attr_reader :hide_guess
10
-
11
- def initialize(sequence, game_logic, hide_guess)
12
- super(sequence, game_logic)
13
- @hide_guess = hide_guess
14
- end
15
-
16
- def start_game
17
- number = num_of_players
18
- end_guess = 12*number + 1
19
-
20
- puts UI::GENERATE_MESSAGE % [game_logic.sequence_type, game_logic.length, UI::COLOR_STRINGS[game_logic.level]]
21
- history_hash = {}
22
- guesses_hash = {}
23
- (1..number).each {|x|
24
- history_hash[x] = []
25
- guesses_hash[x] = 0
26
- }
27
-
28
- multi_start_game(number, history_hash, guesses_hash)
29
- end
30
-
31
- def multi_start_game(number, history_hash, guesses_hash)
32
- total_guesses = 0 # total guesses of all players
33
- catch :player_wins do
34
- while total_guesses < (UI::GUESS_MAX * number) # until all players have exhausted their guesses
35
- for index in (1..number) # loop through to allow each player have a guess
36
- total_guesses += 1
37
- multi_helper(guesses_hash, index, history_hash)
38
- end
39
- end
40
- end
41
- puts UI::SORRY_MULTI_MESSAGE % sequence.join.upcase if total_guesses == UI::GUESS_MAX * number # guesses exhausted with no winner
42
- end
43
-
44
- def multi_helper(guesses_hash, index, history_hash)
45
- last_guess = guesses_hash[index] # to store player's last guess
46
- print "************"
47
- print UI::PLAYER_MESSAGE % index
48
- while guesses_hash[index] == last_guess # to counter situations where user enters invalid input, guess would still be same
49
- guesses_hash[index] = get_guess(history_hash, guesses_hash, index)
50
- throw(:player_wins) if guesses_hash[index] == end_guess # if there is a win
51
- end
52
- end
53
-
54
- def get_guess(history_hash, guesses_hash, index)
55
- input = hide_guess ? STDIN.noecho(&:gets).chomp : gets.chomp
56
-
57
- length_or_option = false
58
- length_or_option = invalid_length?(input) # invalid length for entry
59
-
60
- if !length_or_option
61
- length_or_option = treat_option?(input, history_hash[index]) # entry is a game option
62
- end
63
-
64
- if !length_or_option
65
- guesses_hash[index] = check_help(input, guesses_hash, history_hash, index)
66
- end
67
-
68
- guesses_hash[index]
69
- end
70
-
71
- def check_help(input, guesses_hash, history_hash, index)
72
- treat_guess(input, guesses_hash[index], history_hash[index]) # player enters a guess
73
- end
74
-
75
- def wrong_guess(sequence, guesses, input, history)
76
- result = GameLogic.check_input(sequence, input) # get results from input
77
- history << GamePlay.new(input, result[:correct_elements], result[:correct_position]) # add game play to history
78
-
79
- puts UI::INFO_MESSAGE % [hide_guess ? "Your Guess" : input.upcase, result[:correct_elements], result[:correct_position]]
80
- puts UI::GUESSES_MESSAGE % [guesses, guesses > 1 ? "guesses" : "guess"]
81
- print UI::INPUT_PROMPT
82
- end
83
-
84
- def num_of_players
85
- print UI::MULTI_START_MESSAGE
86
- input = gets.chomp
87
-
88
- while (input.to_i <= 1)
89
- print UI::INVALID_MESSAGE
90
- input = gets.chomp
91
- end
92
-
93
- return input.to_i
94
- end
95
- end
96
- end
97
- end
1
+ require 'single_game'
2
+ require 'logic'
3
+ require 'ui'
4
+ require 'io/console'
5
+
6
+ module MasterMind
7
+ module Tobi
8
+ class MultiPlayer < SinglePlayer
9
+ attr_reader :hide_guess
10
+
11
+ def initialize(sequence, game_logic, hide_guess)
12
+ super(sequence, game_logic)
13
+ @hide_guess = hide_guess
14
+ end
15
+
16
+ def start_game
17
+ number = num_of_players
18
+ end_guess = 12*number + 1
19
+
20
+ puts UI::GENERATE_MESSAGE % [game_logic.sequence_type, game_logic.length, UI::COLOR_STRINGS[game_logic.level]]
21
+ history_hash = {}
22
+ guesses_hash = {}
23
+ (1..number).each {|x|
24
+ history_hash[x] = []
25
+ guesses_hash[x] = 0
26
+ }
27
+
28
+ multi_start_game(number, history_hash, guesses_hash)
29
+ end
30
+
31
+ def multi_start_game(number, history_hash, guesses_hash)
32
+ total_guesses = 0 # total guesses of all players
33
+ catch :player_wins do
34
+ while total_guesses < (UI::GUESS_MAX * number) # until all players have exhausted their guesses
35
+ for index in (1..number) # loop through to allow each player have a guess
36
+ total_guesses += 1
37
+ multi_helper(guesses_hash, index, history_hash)
38
+ end
39
+ end
40
+ end
41
+ puts UI::SORRY_MULTI_MESSAGE % sequence.join.upcase if total_guesses == UI::GUESS_MAX * number # guesses exhausted with no winner
42
+ total_guesses
43
+ end
44
+
45
+ def multi_helper(guesses_hash, index, history_hash)
46
+ last_guess = guesses_hash[index] # to store player's last guess
47
+ print "************"
48
+ print UI::PLAYER_MESSAGE % index
49
+ while guesses_hash[index] == last_guess # to counter situations where user enters invalid input, guess would still be same
50
+ guesses_hash[index] = get_guess(history_hash, guesses_hash, index)
51
+ throw(:player_wins) if guesses_hash[index] == end_guess # if there is a win
52
+ end
53
+ end
54
+
55
+ def get_guess(history_hash, guesses_hash, index)
56
+ input = hide_guess ? STDIN.noecho(&:gets).chomp : gets.chomp
57
+
58
+ length_or_option = false
59
+ length_or_option = invalid_length?(input) # invalid length for entry
60
+
61
+ if !length_or_option
62
+ length_or_option = treat_option?(input, history_hash[index]) # entry is a game option
63
+ end
64
+
65
+ if !length_or_option
66
+ guesses_hash[index] = check_help(input, guesses_hash, history_hash, index)
67
+ end
68
+
69
+ guesses_hash[index]
70
+ end
71
+
72
+ def check_help(input, guesses_hash, history_hash, index)
73
+ treat_guess(input, guesses_hash[index], history_hash[index]) # player enters a guess
74
+ end
75
+
76
+ def wrong_guess(sequence, guesses, input, history)
77
+ result = GameLogic.check_input(sequence, input) # get results from input
78
+ history << GamePlay.new(input, result[:correct_elements], result[:correct_position]) # add game play to history
79
+
80
+ puts UI::INFO_MESSAGE % [hide_guess ? "Your Guess" : input.upcase, result[:correct_elements], result[:correct_position]]
81
+ puts UI::GUESSES_MESSAGE % [guesses, guesses > 1 ? "guesses" : "guess"]
82
+ print UI::INPUT_PROMPT
83
+ end
84
+
85
+ def num_of_players
86
+ print UI::MULTI_START_MESSAGE
87
+ input = gets.chomp
88
+
89
+ while (input.to_i <= 1)
90
+ print UI::INVALID_MESSAGE
91
+ input = gets.chomp
92
+ end
93
+
94
+ return input.to_i
95
+ end
96
+ end
97
+ end
98
+ end
@@ -1,21 +1,21 @@
1
- require 'timehelper'
2
-
3
- module MasterMind
4
- module Tobi
5
- class Player
6
- attr_reader :name
7
- attr_reader :sequence
8
- attr_reader :time
9
- attr_reader :guesses
10
- include TimeHelper
11
-
12
- def initialize(name, sequence, time, guesses)
13
- @name = name; @sequence = sequence; @time = time; @guesses = guesses
14
- end
15
-
16
- def to_s
17
- "%s solved '%s' in %s %s over %s" % [name, sequence.join.upcase, guesses, guesses > 1 ? "guesses" : "guess", time_convert(time)]
18
- end
19
- end
20
- end
1
+ require 'timehelper'
2
+
3
+ module MasterMind
4
+ module Tobi
5
+ class Player
6
+ attr_reader :name
7
+ attr_reader :sequence
8
+ attr_reader :time
9
+ attr_reader :guesses
10
+ include TimeHelper
11
+
12
+ def initialize(name, sequence, time, guesses)
13
+ @name = name; @sequence = sequence; @time = time; @guesses = guesses
14
+ end
15
+
16
+ def to_s
17
+ "%s solved '%s' in %s %s over %s" % [name, sequence.join.upcase, guesses, guesses > 1 ? "guesses" : "guess", time_convert(time)]
18
+ end
19
+ end
20
+ end
21
21
  end
@@ -1,117 +1,118 @@
1
- require 'ui'
2
- require 'timehelper'
3
- require 'player'
4
- require 'yaml'
5
- require 'gameplay'
6
- require 'gamemethods'
7
-
8
- module MasterMind
9
- module Tobi
10
- class SinglePlayer
11
- include GameMethods
12
- include TimeHelper
13
-
14
- attr_reader :start_time
15
- attr_reader :history
16
- attr_reader :sequence
17
- attr_reader :game_logic
18
- attr_accessor :end_guess
19
-
20
- ALLOWED = ['c', 'h', 'q', 'cheat', 'history', 'quit']
21
-
22
- def initialize(sequence, game_logic)
23
- @start_time = Time.now
24
- @history = []
25
- @sequence = sequence
26
- @game_logic = game_logic
27
- @end_guess = 13
28
- end
29
-
30
- # generate game sequence and start game play
31
- def start_game
32
- print UI::GENERATE_MESSAGE % [game_logic.sequence_type, game_logic.length, UI::COLOR_STRINGS[game_logic.level]]
33
- print UI::INPUT_PROMPT
34
-
35
- # allow the user guess up to twelve times before ending game
36
- guesses = 0
37
- while guesses < UI::GUESS_MAX
38
- guesses = process_input(guesses, history)
39
- end
40
- puts UI::SORRY_SINGLE_MESSAGE % sequence.join.upcase if guesses == UI::GUESS_MAX
41
- end
42
-
43
- def process_input(guesses, history)
44
- input = gets.chomp.downcase
45
- length_or_option = false
46
-
47
- length_or_option = invalid_length?(input)
48
-
49
- if !length_or_option
50
- length_or_option = treat_option?(input, history)
51
- end
52
-
53
- if !length_or_option
54
- guesses = treat_guess(input, guesses, history)
55
- end
56
- guesses
57
- end
58
-
59
- # check if user's guess is longer or fewer than the required length
60
- def invalid_length?(input)
61
- if input.length < game_logic.length && !(ALLOWED.include?(input))
62
- print UI::INPUT_SHORT_MESSAGE
63
- return true
64
-
65
- elsif input.length > game_logic.length && !(ALLOWED.include?(input))
66
- print UI::INPUT_LONG_MESSAGE
67
- return true
68
- end
69
-
70
- return false
71
- end
72
-
73
- # check if user selects an option
74
- def treat_option?(input, history)
75
- case input
76
- when "h", "history" then print_history(history)
77
- when "q", "quit" then exit(0)
78
- when "c", "cheat" then print UI::SEQUENCE_MESSAGE % sequence.join.upcase
79
- else return false
80
- end
81
- return true
82
- end
83
-
84
- # treat guesses entered by user
85
- def treat_guess(input, guesses, history)
86
- guesses += 1
87
- if input == sequence.join # right guess entered
88
- right_guess(start_time, sequence, guesses)
89
- guesses = end_guess # sentinel value to end guess loop
90
- else
91
- wrong_guess(sequence, guesses, input, history) # wrong guess entered
92
- end
93
-
94
- return guesses
95
- end
96
-
97
- def right_guess(start_time, sequence, guesses)
98
- time_elapsed = (Time.now - start_time).to_i # time used by user in seconds
99
- current_player = store_game(sequence, guesses, time_elapsed) # store user data to top-scores file
100
-
101
- puts UI::CONGRATS_MESSAGE % [current_player.name, sequence.join.upcase, guesses, guesses > 1 ? "guesses" : "guess",
102
- time_convert(time_elapsed) << '.']
103
- print_top_ten(current_player)
104
- end
105
-
106
- def wrong_guess(sequence, guesses, input, history)
107
- result = GameLogic.check_input(sequence, input) # get results from input
108
- history << GamePlay.new(input, result[:correct_elements], result[:correct_position]) # add game play to history
109
-
110
- puts UI::INFO_MESSAGE % [input.upcase, result[:correct_elements], result[:correct_position]]
111
- puts UI::GUESSES_MESSAGE % [guesses, guesses > 1 ? "guesses" : "guess"]
112
- print UI::INPUT_PROMPT
113
- end
114
-
115
- end
116
- end
1
+ require 'ui'
2
+ require 'timehelper'
3
+ require 'player'
4
+ require 'yaml'
5
+ require 'gameplay'
6
+ require 'gamemethods'
7
+
8
+ module MasterMind
9
+ module Tobi
10
+ class SinglePlayer < GameMethods
11
+ #include GameMethods
12
+ include TimeHelper
13
+
14
+ attr_reader :start_time
15
+ attr_reader :history
16
+ attr_reader :sequence
17
+ attr_reader :game_logic
18
+ attr_accessor :end_guess
19
+
20
+ ALLOWED = ['c', 'h', 'q', 'cheat', 'history', 'quit']
21
+
22
+ def initialize(sequence, game_logic)
23
+ @start_time = Time.now
24
+ @history = []
25
+ @sequence = sequence
26
+ @game_logic = game_logic
27
+ @end_guess = 13
28
+ end
29
+
30
+ # generate game sequence and start game play
31
+ def start_game
32
+ print UI::GENERATE_MESSAGE % [game_logic.sequence_type, game_logic.length, UI::COLOR_STRINGS[game_logic.level]]
33
+ print UI::INPUT_PROMPT
34
+
35
+ # allow the user guess up to twelve times before ending game
36
+ guesses = 0
37
+ while guesses < UI::GUESS_MAX
38
+ guesses = process_input(guesses, history)
39
+ end
40
+ puts UI::SORRY_SINGLE_MESSAGE % sequence.join.upcase if guesses == UI::GUESS_MAX
41
+ guesses
42
+ end
43
+
44
+ def process_input(guesses, history)
45
+ input = gets.chomp.downcase
46
+ length_or_option = false
47
+
48
+ length_or_option = invalid_length?(input)
49
+
50
+ if !length_or_option
51
+ length_or_option = treat_option?(input, history)
52
+ end
53
+
54
+ if !length_or_option
55
+ guesses = treat_guess(input, guesses, history)
56
+ end
57
+ guesses
58
+ end
59
+
60
+ # check if user's guess is longer or fewer than the required length
61
+ def invalid_length?(input)
62
+ if input.length < game_logic.length && !(ALLOWED.include?(input))
63
+ print UI::INPUT_SHORT_MESSAGE
64
+ return true
65
+
66
+ elsif input.length > game_logic.length && !(ALLOWED.include?(input))
67
+ print UI::INPUT_LONG_MESSAGE
68
+ return true
69
+ end
70
+
71
+ return false
72
+ end
73
+
74
+ # check if user selects an option
75
+ def treat_option?(input, history)
76
+ case input
77
+ when "h", "history" then print_history(history)
78
+ when "q", "quit" then exit(0)
79
+ when "c", "cheat" then print UI::SEQUENCE_MESSAGE % sequence.join.upcase
80
+ else return false
81
+ end
82
+ return true
83
+ end
84
+
85
+ # treat guesses entered by user
86
+ def treat_guess(input, guesses, history)
87
+ guesses += 1
88
+ if input == sequence.join # right guess entered
89
+ right_guess(start_time, sequence, guesses)
90
+ guesses = end_guess # sentinel value to end guess loop
91
+ else
92
+ wrong_guess(sequence, guesses, input, history) # wrong guess entered
93
+ end
94
+
95
+ return guesses
96
+ end
97
+
98
+ def right_guess(start_time, sequence, guesses)
99
+ time_elapsed = (Time.now - start_time).to_i # time used by user in seconds
100
+ current_player = store_game(sequence, guesses, time_elapsed) # store user data to top-scores file
101
+
102
+ puts UI::CONGRATS_MESSAGE % [current_player.name, sequence.join.upcase, guesses, guesses > 1 ? "guesses" : "guess",
103
+ time_convert(time_elapsed) << '.']
104
+ print_top_ten(current_player)
105
+ end
106
+
107
+ def wrong_guess(sequence, guesses, input, history)
108
+ result = GameLogic.check_input(sequence, input) # get results from input
109
+ history << GamePlay.new(input, result[:correct_elements], result[:correct_position]) # add game play to history
110
+
111
+ puts UI::INFO_MESSAGE % [input.upcase, result[:correct_elements], result[:correct_position]]
112
+ puts UI::GUESSES_MESSAGE % [guesses, guesses > 1 ? "guesses" : "guess"]
113
+ print UI::INPUT_PROMPT
114
+ end
115
+
116
+ end
117
+ end
117
118
  end