Mastermind Exercise

I’m stuck on a few places on this problem.
1st issue:
i’m very confused about what the[] method does, i think the suggestion is for the program to ask for a string for input, but for the [] method, SPEC is passing in Array and expect a return of string, so i wrote:
def
# @pegs[idx]
str = “”
str << @pegs[idx].to_s
str
end
as opposed to the solution:
def
@pegs[idx]
end
either way wouldn’t pass the SPEC.
And i dont know how to do save the input/ouput using IO method such a FILE == $PROGRAM_NAME…where can i read more about saving my data.
ALSO, another confusion i have is about the random method, is it to generate the secret code or is it to generate a random guess for the player?
Lastly, from reading the SPEC, i don’t think it’s using Game class to generate the secret code, but using code1, code_orange generated by Code class instead, then what’s the point of the game class? I dont see them correlating with each other regarding the secret code or getting answer using Game asking for an input…
Apologize for tons of questions and thanks in advance!

1 Like

and here’s my code:
class Code
PEGS = {“R” => :red, “Y” => :yellow, “G” => :green, “P” => :purple, “O” => :orange, “B” => :blue, “r” => :red, “y” => :yellow, “g” => :green, “p” => :purple, “o” => :orange, “b” => :blue }

attr_reader :pegs
def initialize(input)
raise “Please put in a guess” unless input
@pegs = input
end
def self.parse(input)
raise “input error” unless input.chars.all? {|el| PEGS.include?(el)}
Code.new(input)
end

def self.random
@random = “”
4.times {@random << %w(R Y G P O B).sample}
Code.new(@random)
end

def
# @pegs[idx]
str = “”
str << @pegs[idx].to_s
str
end

def ==(code)
return false unless code.class == Code
answer = []
4.times {|el| answer << (PEGS[@pegs[el]] == PEGS[code[el]])}
return true if answer.all? {|el| el == true}
end

def exact_matches(other_code)
black = 0
4.times {|idx| black +=1 if @pegs[idx] == other_code[idx]}
black
end

def near_matches(other_code)
white = 0
i = 0
group1 = self.pegs.dup.chars
group2 = other_code.pegs.dup.chars
while i < 4
j = 0
while j < 4
if group1[i] == group2[j] && i!=j
white+=1
p “MATCH i: #{i}, j: #{j}”
group1[i] = “gone1”
p group1
group2[j] = “gone2”
p group2
end
j+=1
end
i+=1
end
white - exact_matches(other_code)
end

end

class Game
attr_reader :secret_code
def initialize(secret_code = nil)

@secret_code = secret_code || @secret_code = Code.random
end
def play
10.times do |turn|
take_turn
break if won?
end
puts “Sorry, you lost…”
puts "The code was "
end
def get_guess
# try = 0
# guess = nil
# until guess == @secret_code || try == 10
puts “Please guess 4 colors, enter a four letter string, for example ‘RGPO’”

# try+=1
Code.parse(gets.chomp)
# end
# if guess == @secret_code
#   puts "Congratulations! You've cracked the code."
# else
#   puts "Sorry, you've ran out of tries!"
# end

end
def display_matches(code)
puts “near matches: #{@secret_code.near_matches(code)}”
puts “xxact matches: #{@secret_code.exact_matches(code)}”
end

end
if FILE == $PROGRAM_NAME
game = Game.new(Code.parse(“bbbb”))
game.play
end
I even tried to copy and solution video, doesn’t seem to be passing spec the way it does in the video.

I just developed a working mastermind code, i’ve played for quite a while, it would start another game by answering y when the game is over; however, it would only pass 6 specs.
class Code
PEGS = {“R” => :red, “Y” => :yellow, “G” => :green, “P” => :purple,
“O” => :orange, “B” => :blue, “r” => :red, “y” => :yellow, “g” => :green, “p” => :purple, “o” => :orange, “b” => :blue }

attr_reader :pegs
def initialize(input)
@pegs = input
end
def parse(input)
raise “input error” unless input.chars.all? {|el| PEGS.include?(el)}
Code.new(input)
end

def self.random
@random = “”
4.times {@random << %w(R Y G P O B).sample}
Code.new(@random)
end

def won?(code)
answer = []
4.times {|el| answer << (PEGS[@pegs[el]] == PEGS[code[el]])}
return true if answer.all? {|el| el == true}
end

def exact_matches(other_code)
black = 0
@group1 = self.pegs.to_s.dup.chars
@group2 = other_code.to_s.dup.chars
idx = 0
while idx < 4
if @group1[idx] == @group2[idx]
@group1[idx] = “exact_matched”
@group2[idx] = " #{@group2[idx]} (exact)"
black +=1
end
idx+=1
end
# p @group2
black
end

def near_matches(other_code)
white = 0
i = 0
while i < 4
j = 0
while j < 4
if @group1[i] == @group2[j] && i!=j
white+=1
@group1[i] = “near_matched”
@group1
@group2[j] = “#{@group2[j]} (near)”

      end
    j+=1
  end
  i+=1
end
p @group2
white #- exact_matches(other_code)

end

end

class Game
attr_reader :secret_code

def initialize(secret_code = nil)
@secret_code = secret_code || @secret_code = Code.random
#game is an instance of Code
end

def play
i = 0
while i < 10
get_guess
i+=1
if @secret_code.won?(@code)
puts “CONGRATS! YOU WON!!\n play again? y/n”
i = 10
elsif i == 10
puts “Sorry, you lost…”
puts “The code was #{secret_code.pegs}”
puts “play again? y/n”
end
end
answer = gets.chomp.to_s
continue = true
while continue
if answer == “y”
continue = false

      elsif answer == "n" 
    continue = false 
      exit 
      else
    "Sorry, invalid input, enter y to play again, n to exit the game"
      end 
    # end
end
game2 = Game.new 
game2.play 

end

def get_guess
puts %Q{Please guess 4 colors, enter a four letter string, for example YYYY, chose from R Y G P O B }
@code = gets.chomp.upcase
# puts @secret_code.pegs
# puts @code
puts “exact matches: #{@secret_code.exact_matches(@code)}”
puts “near matches: #{@secret_code.near_matches(@code)}”
end

def display_matches

# puts "\t #{get_guess[0]}"

end

end

Hi Xia,

Would you mind posting your code with proper indentations and wrapping it between a line that reads

```ruby

and a line that reads

```

As it stands, your code is very difficult to debug.