Skip to content

Commit b4cd45a

Browse files
committed
finished project
1 parent 72e6fc2 commit b4cd45a

File tree

3 files changed

+521
-0
lines changed

3 files changed

+521
-0
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
# ruby_oop
22
The ruby oop project for the odin project.
3+
Includes:
4+
1. Tictactoe command line game
5+
2. Mastermind command line game
6+
7+
Link to project page: http://www.theodinproject.com/ruby-programming/oop

mastermind.rb

+357
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,357 @@
1+
class Mastermind
2+
LETTERS = ["R", "B", "Y", "G", "O", "P"]
3+
attr_accessor :guess
4+
def initialize
5+
@mode = 0
6+
@guess = []
7+
@hint = []
8+
@code = []
9+
@human_player = HumanPlayer.new
10+
@computer_player = ComputerPlayer.new
11+
end
12+
13+
# This method allows the user to choose the mode they want to play
14+
# they can either be the code breaker or code maker
15+
def set_up_game
16+
system 'clear'
17+
@human_player.get_name
18+
choose_mode
19+
if @mode == 1
20+
play_as_codebreaker
21+
elsif @mode == 2
22+
play_as_codemaker
23+
end
24+
end
25+
26+
27+
28+
# This method makes shows the mode options and makes sure that the mode that the user
29+
# chooses is valid.
30+
def choose_mode
31+
valid = false
32+
while valid == false
33+
puts "Hi #{@human_player.name} do you want to be the code maker or"
34+
puts "the code breaker?"
35+
puts "1. for code breaker"
36+
puts "2. for code maker"
37+
puts
38+
print "Please choose an option: "
39+
@mode = gets.chomp.to_i
40+
41+
if @mode > 0 && @mode <= 2
42+
valid = true
43+
else
44+
system 'clear'
45+
puts "Invalid selection, please choose either option 1 or 2."
46+
end
47+
end
48+
end
49+
50+
# This method will be run if the user chooses the code maker mode.
51+
# it asks the user to enter a 4 letter code and makes sure it is valid
52+
# the computer then makes a random intial guess from the letters array
53+
# the results of this guess will be shown
54+
# the computer then takes the hints into consideration for its next guess
55+
# if the hints contain any exacts, the computer will keep these
56+
# if the the hints contain any nears, they will keep them but put them in
57+
# another random posistion.
58+
# if they have any nopes they wont use them again
59+
# this will repeat until the computer has guessed the code directly
60+
# or if the iteration runs out.
61+
def play_as_codemaker
62+
system 'clear'
63+
puts "Letters to choose from: #{LETTERS.inspect}"
64+
print "Please enter your guess for the four letter code: \n"
65+
@code = @human_player.enter_code
66+
67+
puts
68+
i = 1
69+
while i < 11
70+
if i == 1
71+
@guess = @computer_player.intial_guess
72+
else
73+
@guess = @computer_player.final_array
74+
@computer_player.temp = []
75+
end
76+
puts "Guess Number: #{i}"
77+
get_results
78+
79+
80+
puts "The computer player is making his guess #{i}: "
81+
3.times do
82+
print (".")
83+
sleep(1)
84+
end
85+
show_result
86+
@computer_player.logic(@hint, @guess)
87+
@computer_player.any_nil?
88+
@computer_player.final_array
89+
if win?
90+
puts "The computer has won!"
91+
play_again?
92+
end
93+
94+
i += 1
95+
end
96+
puts "You have won!"
97+
play_again?
98+
99+
100+
101+
102+
end
103+
104+
105+
106+
# This method detemines the hints from the guess array and
107+
# fills the hints array with the following:
108+
# The hint will be exact if the guess is the same letter as the code and in the same position
109+
# the hint will be near if the guess is just the same letter but not in the same position as the code
110+
# the hint will be nope if the guess letter is not in the code
111+
def get_results
112+
i = 0
113+
while i < @guess.length
114+
if @guess[i] == @code[i]
115+
@hint[i] = "Exact"
116+
elsif @code.include?(@guess[i])
117+
@hint[i] = "Near"
118+
else
119+
@hint[i] = "Nope"
120+
end
121+
i += 1
122+
end
123+
return @hint
124+
end
125+
126+
127+
# This method outputs the results of the guess to the screen
128+
# It shows the guess and the coresponding hints below it
129+
def show_result
130+
puts "\n"
131+
puts "\t Choice 1 \t Choice 2\t Choice 3\t Choice 4"
132+
puts "-" * 70
133+
puts "Guess |\t#{@guess[0]}\t #{@guess[1]}\t\t #{@guess[2]}\t\t #{@guess[3]}"
134+
puts "Result |\t#{@hint[0]} \t #{@hint[1]} \t #{@hint[2]} \t #{@hint[3]}"
135+
puts "\n"
136+
end
137+
138+
139+
# This method runs when the user chooses the code breaker mode
140+
# It first gets the computer to generate a random code from the letters array
141+
# it then starts a loop, each time it asks for the user to enter thier guess
142+
# and it will output the results to the screen.
143+
# it will stop when the user guesses the code correctly or when the iteration reaches 10
144+
def play_as_codebreaker
145+
system 'clear'
146+
i = 1
147+
@code = @computer_player.generate_code
148+
while i < 11
149+
puts "\n"
150+
puts "Letters to choose from: #{LETTERS}"
151+
puts "\n"
152+
print "Please enter your guess for the four letter code: \n"
153+
@guess = @human_player.enter_guess
154+
get_results
155+
puts "\n"
156+
puts "Guess Number: #{i}"
157+
show_result
158+
159+
160+
if win?
161+
puts "You have Won!"
162+
play_again?
163+
end
164+
165+
i += 1
166+
end
167+
puts "You have lost!"
168+
play_again?
169+
end
170+
171+
172+
# This method checks to see if all the elements in the hint array
173+
# equal 'Exact' when they do, the method will return true
174+
def win?
175+
@hint.all? {|a| a == "Exact"}
176+
end
177+
178+
# This gives the user the option to play again by going by to
179+
# the set up game method. It also checks to ensure the user has
180+
# entered a valid option
181+
def play_again?
182+
again = false
183+
while again == false
184+
print "Do you want to play again? (y/n): "
185+
input = gets.chomp.downcase
186+
if input == "y"
187+
again = true
188+
load './mastermind.rb'
189+
system 'clear'
190+
set_up_game
191+
elsif input == "n"
192+
again = true
193+
exit
194+
else
195+
puts "Invalid input, Please enter either 'y' or 'n'."
196+
end
197+
end
198+
end
199+
200+
201+
202+
203+
204+
205+
206+
207+
class HumanPlayer
208+
attr_accessor :name
209+
def initialize
210+
@name = nil
211+
end
212+
213+
def get_name
214+
print "What is your name: "
215+
@name = gets.chomp
216+
end
217+
218+
def enter_guess
219+
guess = []
220+
i = 0
221+
while i < 4
222+
print "Letter #{i + 1}: "
223+
guess[i] = gets.chomp.upcase
224+
if LETTERS.include?(guess[i])
225+
i += 1
226+
else
227+
puts "Invalid letter please choose again"
228+
end
229+
end
230+
return guess
231+
end
232+
233+
def enter_code
234+
code = []
235+
i = 0
236+
237+
while i < 4
238+
print "Letter #{i + 1}: "
239+
code[i] = gets.chomp.upcase
240+
if LETTERS.include?(code[i])
241+
i += 1
242+
else
243+
puts "Invalid letter please choose again"
244+
end
245+
end
246+
return code
247+
end
248+
end
249+
250+
251+
class ComputerPlayer
252+
attr_accessor :final_array, :temp, :possible_letters
253+
def initialize
254+
@temp = Array.new(4)
255+
@intial_guess = []
256+
@free_indexes = []
257+
@final_array = []
258+
@possible_letters = LETTERS
259+
end
260+
261+
262+
# This method generates a random code from the letters array
263+
def generate_code
264+
LETTERS.sample(4)
265+
end
266+
267+
# This method makes the computers intial guess, 4 random letters from the letters array
268+
def intial_guess
269+
while @intial_guess.size < 4
270+
@intial_guess << LETTERS[rand(LETTERS.size)]
271+
@intial_guess.uniq!
272+
end
273+
return @intial_guess
274+
end
275+
276+
277+
# This method contains the logic for the computers guesses
278+
# It first checks if any of the hints returned are "Exact"
279+
# if there any, it will add these to a temp array and then
280+
# check for any hints that are equal to "near" if there are
281+
# any it will keep them and put them in a different position
282+
# in the temp array. It will then check if there are any
283+
# "nope" hints. If there are any it will delete them from the
284+
# array of possible letters. The final array is then made from
285+
# the temp array and is returned. This will be used as the
286+
# computers next guess
287+
def logic(hint, guess)
288+
i = 0
289+
while i < hint.size
290+
if hint[i] == "Exact"
291+
@temp[i] = guess[i]
292+
@possible_letters.delete(guess[i])
293+
elsif hint[i] == "Near"
294+
if @temp.count(guess[i]) > 1 || @final_array.count(guess[1]) > 1
295+
find_empty_indexes
296+
@temp[@new_index] = choose_random_letter(guess[i])
297+
else
298+
find_empty_indexes
299+
@temp[@new_index] = guess[i]
300+
end
301+
elsif hint[i] == "Nope"
302+
@possible_letters.delete(guess[i])
303+
@temp[i] = @possible_letters[rand(@possible_letters.size)]
304+
end
305+
i += 1
306+
end
307+
@final_array = @temp
308+
return @final_array
309+
end
310+
311+
312+
# This method checks to see if any elements in the temp array are equal to nil
313+
# if they are, they will be assigned a new random letter.
314+
def any_nil?
315+
i = 0
316+
while i < 4
317+
if @temp[i] == nil
318+
@temp[i] = @possible_letters[rand(@possible_letters.length)]
319+
end
320+
i += 1
321+
end
322+
@final_array = @temp
323+
return @final_array
324+
end
325+
326+
327+
# This method chooses a random letter from the possible_letters array
328+
def choose_random_letter(letter)
329+
new_letter = letter
330+
331+
while new_letter == letter
332+
new_letter = @possible_letters[rand(@possible_letters.size)]
333+
end
334+
return new_letter
335+
end
336+
337+
338+
# This method finds any empty indexes in the temp array
339+
def find_empty_indexes
340+
i = 0
341+
@free_indexes.clear
342+
while i < 4
343+
if @temp[i] == nil
344+
@free_indexes << i
345+
end
346+
i += 1
347+
end
348+
@new_index = @free_indexes[rand(@free_indexes.size)]
349+
return @new_index
350+
end
351+
end
352+
end
353+
354+
355+
356+
mastermind = Mastermind.new
357+
mastermind.set_up_game

0 commit comments

Comments
 (0)