I'm having trouble with my code here what it's supposed to do is generate a number from 1 to 6 and than ask you who you think the imposter is after it asks you it waits for input and than checks for the input and the random number that was generated if the input is Red and the random number was 1 it would say that red is the imposter and so on with Orange and 2 Green and 3 Yelow and 4 Cyan with 5 and Black with 6 but the problem is that if you put anything that isn't red EX: Orange it just stops for no reason. What did I do wrong with the code? Please help.
susas = rand (1..6)
puts "Who is the imposter?"
sleep (1)
puts "Is it Red, Orange, Green, Yellow, Cyan, Or Black (use capital format EX:Red)"
answr = gets.chomp
if answr == "Red" && susas == 1
puts "Red was the imposter"
elsif answr == "Red" && susas != 1
puts "Red was not the imposter you failed"
if answr == "Orange" && susas == 2
puts "Orange was the imposter"
elsif answr == "Orange" && susas != 2
puts "Orange was not the imposter you failed"
if answr == "Green" && susas == 3
puts "Green was the imposter"
elsif answr == "Green" && susas != 3
puts "Green was not the imposter you failed"
if answr == "Yellow" && susas == 4
puts "Yellow was the imposter"
elsif answr == "Yellow" && susas != 4
puts "Yellow was not the imposter you failed"
if answr == "Cyan" && susas == 5
puts "Cyan was the imposter"
elsif answr == "Cyan" && susas != 5
puts "Cyan was not the imposter you failed"
if answr == "Black" && susas == 6
puts "Black was the imposter"
elsif answr == "Black" && susas != 6
puts "Black was not the imposter you failed"
end
end
end
end
end
end
Here is a repl.it link https://repl.it/#Student_Aiden_K/SmoothFaithfulComputerscience#main.rb
if you put anything that isn't red EX: Orange it just stops for no reason. What did I do wrong with the code?
You have two main branches:
if answr == "Red" && susas == 1
puts "Red was the imposter"
elsif answr == "Red" && susas != 1
puts "Red was not the imposter you failed"
# anything else
end
The other colors are all under the elsif branch but Ruby will not reach them because answr == "Red" will be false for all colors beside red.
What you want is more elsif's on the same level:
if answr == "Red" && susas == 1
puts "Red was the imposter"
elsif answr == "Red" && susas != 1
puts "Red was not the imposter you failed"
elsif answr == "Orange" && susas == 2
puts "Orange was the imposter"
elsif answr == "Orange" && susas != 2
puts "Orange was not the imposter you failed"
# ...
end
Needless to say, there's a lot of repetition in your code. You should try to reduce that.
You could for example add a hash to map color names to numbers:
colors = {
'Red' => 1, 'Orange' => 2, 'Green' => 3,
'Yellow' => 4, 'Cyan' => 5, 'Black' => 6
}
Then fetch the number for the given answer:
answer = gets.chomp
number = colors[answer]
And have just one if to check whether it is correct or not:
if number == susas
puts "#{answer} was the imposter"
else
puts "#{answer} was not the imposter you failed"
end
Related
What I am trying to do is have a random generator generate 9 cremates and 1 impostor but what happens when it generates them is one of the cremates isn't generated and its just a blank space in between the other string values when I display the values on cmd so idk why it doesn't but I feel it may be to do with the player so there is 10 crews and 1 impostor.
impgen = rand (1..10)
deadgen = rand (1..9)
if impgen == 2
impot = 'Red'
elsif impgen == 3
impot = 'Orange'
elsif impgen == 4
impot = 'Yellow'
elsif impgen == 5
impot = 'Green'
end
if impgen == 6
impot = 'Dark Green'
elsif impgen == 7
impot = 'Blue'
elsif impgen == 8
impot = 'Purple'
elsif impgen == 9
impot = 'Black'
elsif impgen == 10
impot = 'Cyan'
end
if impgen != 2
crew1 = 'Red'
if impgen != 3
crew2 = 'Orange'
end
if impgen != 4
crew3 = 'Yellow'
if impgen != 5
crew4 = 'Green'
end
if impgen != 6
crew5 = 'Dark Green'
if impgen != 7
crew6 = 'Blue'
end
if impgen != 8
crew7 = 'Purple'
if impgen != 9
crew8 = 'Black'
end
if impgen != 10
crew9 = 'Cyan'
end
end
end
end
end
puts "Enter Name"
un = gets.chomp
puts "Ok " + un + " let's play Among Us"
sleep (1)
if impgen == 1
puts "You are an imposter!"
else impgen
puts "You are a crewmate there is 1 imposter among us!"
sleep (1.5)
puts "The other players are Red, Orange, Yellow, Green, Dark Green, Blue, Purple, Black, and Cyan you are Lime"
sleep (4)
puts impot
puts crew1
puts crew2
puts crew3
puts crew4
puts crew5
puts crew6
puts crew7
puts crew8
puts crew9
end
I think the biggest issue becomes apparent when you indent your code:
if impgen != 2
crew1 = 'Red'
if impgen != 3
crew2 = 'Orange'
end
if impgen != 4
crew3 = 'Yellow'
if impgen != 5
crew4 = 'Green'
end
if impgen != 6
crew5 = 'Dark Green'
if impgen != 7
crew6 = 'Blue'
end
if impgen != 8
crew7 = 'Purple'
if impgen != 9
crew8 = 'Black'
end
if impgen != 10
crew9 = 'Cyan'
end
end
end
end
end
There is a major bug here. For example, if impgen == 2, then none of the following code will get executed, and none of the crew variables will be assigned. You probably don't want to use nested if statements here, but instead do something like this:
if impgen != 2
crew1 = 'Red'
end
if impgen != 3
crew2 = 'Orange'
end
if impgen != 4
crew3 = 'Yellow'
end
if impgen != 5
crew4 = 'Green'
end
if impgen != 6
crew5 = 'Dark Green'
end
if impgen != 7
crew6 = 'Blue'
end
if impgen != 8
crew7 = 'Purple'
end
if impgen != 9
crew8 = 'Black'
end
if impgen != 10
crew9 = 'Cyan'
end
If you just make this change, you'll see that there is a consistent empty line that appears in the output. The reasoning is pretty clear, the imposter's crew member variable isn't getting assigned when impgen is a certain value. For example, if impgen is 2, impgen != 2 evaluates to false, and crew1 = 'Red' doesn't get executed.
If this behavior is undesirable, you can just drop the if statements completely:
crew1 = 'Red'
crew2 = 'Orange'
crew3 = 'Yellow'
crew4 = 'Green'
crew5 = 'Dark Green'
crew6 = 'Blue'
crew7 = 'Purple'
crew8 = 'Black'
crew9 = 'Cyan'
Edit:
You may want to consider refactoring this code. I'm not sure how you plan to use your crew mate variables, but it might be easier to keep track of each member in an array:
crew_members = ["Red", "Orange", "Yellow", "Green", "Dark Green", "Blue", "Purple", "Black", "Cyan"]
player = crew_members.sample
imposter = crew_members.sample
puts "Enter Name"
un = gets.chomp
puts "Ok " + un + " let's play Among Us"
sleep (1)
if player == imposter
puts "You are an imposter!"
else
puts "You are a crewmate there is 1 imposter among us!"
sleep (1.5)
puts "The other players are #{(crew_members - [player]).join(", ")} you are #{player}"
end
This question already has answers here:
How do I pick randomly from an array?
(7 answers)
Closed 4 years ago.
Im pretty new to programming and I'm trying to make a basic rock paper scissors program.
I've already made this program using 1 = rock, 2 = paper, 3 = scissors. but now I want to try doing it with actual words instead of numbers. How can I make ruby choose randomly from my array, mine?
Thanks!
mine = ["Rock", "Paper", "Scissors"]
mine.sample(1 + rand(mine.count))
puts 'Write your choice, Rock, Paper, or Scissors'
yours = gets.chomp.to_s
if yours == "Rock"
puts 'Your choice is Rock'
elsif yours == "Paper"
puts 'Your choice is Paper'
else yours == "Scissors"
puts 'Your choice is Scissors'
end
puts "--------------------------"
if mine == "Rock"
puts 'Computer: My choice is Rock'
elsif mine == "Paper"
puts 'Computer: My choice is Paper'
else mine == "Scissors"
puts 'Computer: My choice is Scissors'
end
print 'Computer: My choice was: '
print mine
puts
if mine == "Rock" && yours == "Paper"
puts "==========="
puts "Paper Wins!"
puts "==========="
elsif mine == "Paper" && yours == "Rock"
puts "==========="
puts "Paper Wins!"
puts "==========="
elsif mine == "Paper" && yours == "Scissors"
puts "=============="
puts "Scissors Wins!"
puts "=============="
elsif mine == "Scissors" && yours == "Paper"
puts "=============="
puts "Scissors Wins!"
puts "=============="
elsif mine == "Scissors" && yours == "Rock"
puts "=========="
puts "Rock Wins!"
puts "=========="
elsif mine == "Rock" && yours == "Scissors"
puts "=============="
puts "Rock Wins!"
puts "=============="
else
puts "======================"
puts "It's a tie! TRY AGAIN!"
puts "======================"
end
You can use sample:
[1, 2, 3].sample #=> 1
[1, 2, 3].sample(2) #=> [3, 1]
Documentation
I'm trying to build a rock, paper, scissors game. Could someone please tell me or point me in the right direction of where I'm going wrong with this code?
I want the players_score and cpu_score variables to increment by 1 each time either one wins a round.
choice = ["rock", "paper", "Scissors"]
players_score = 0
cpu_score = 0
def win_lose(a,b,c,d)
if a == "rock" && b == "scissors"
c+=1
puts "YOU WIN!!"
elsif a == "scissors" && b == "rock"
d+=1
puts "YOU LOSE!!"
elsif a =="paper" && b == "rock"
c+=1
puts "YOU WIN!!"
elsif a =="rock" && b == "paper"
d+=1
puts "YOU LOSE!!"
elsif a == "scissors" && b == "paper"
c+=1
puts "YOU WIN!!"
elsif a == "paper" && b == "scissors"
d+=1
puts "YOU LOSE!!"
else a == b
puts "Its a Draw this time!!"
end
end
while players_score < 2 && cpu_score < 2
print "Lets play. Plese choose rock, paper or scissors: "
players = gets.chomp.downcase
puts "You have #{players}"
cpu = choice.sample.downcase
puts "Computer has #{cpu}"
win_lose(players, cpu, players_score, cpu_score)
puts "scores are player #{players_score} , cpu #{cpu_score}"
end
Return a value from win_lose, and use that to determine increment the variable, e.g.:
def win_lose(a,b,c,d)
if a == "rock" && b == "scissors"
c+=1
winner = 'player'
elsif a == "scissors" && b == "rock"
d+=1
winner = 'computer'
# [.. etc ..]
else a == b
winner = 'draw'
end
return winner
end
player_score = 0
cpu_score = 0
choice = ["rock", "paper", "Scissors"]
while players_score < 2 && cpu_score < 2
print "Lets play. Plese choose rock, paper or scissors: "
players = gets.chomp.downcase
puts "You have #{players}"
cpu = choice.sample.downcase
puts "Computer has #{cpu}"
winner = win_lose(players, cpu, players_score, cpu_score)
if winner == 'player'
player_score += 1
puts "YOU WIN!!"
elsif winner == 'computer'
cpu_score += 1
puts "YOU LOSE!!"
else
puts "It's a draw"
end
puts "scores are player #{players_score} , cpu #{cpu_score}"
end
As you can see, this also allows you to not repeat the same "YOU WIN!!" sentence over and over again. I moved that outside the win_lose function so that this function does only one thing: determine the winner or loser, rather than two things: determine the winner or loser, and inform them of this.
This distinction is perhaps not important for such a small program, but as your programs grow it will be critical to keep your program understandable.
Earlier I asked about adding points to a RPS game I created, that problem is fixed, but now I have a new problem.. Every time the user rolls for their item (rock, paper, or scissors) it's a draw. I've tried adding a percentage to the array 33.5% for two and 33% for one which adds to 100 and it still comes up as a draw every time.
def welcome
puts "Welcome to Rock, Paper, Scissors. To begin press 'S'.
To learn how to play press 'I'. To quit the game press 'Q'"
input = gets.chomp
if input =~ /s/i
start_game
elsif input =~ /i/i
instructions
else
exit
end
end
def start_game
start_points_P1 = 0
start_points_P2 = 0
choice = ['Rock', 'Paper', 'Scissors']
choice2 = ['Rock', 'Paper', 'Scissors']
player1 = choice.sample
player2 = choice2.sample
puts "Press 'R' to roll for Player 1"
input = gets.chomp!
puts "Player 1 has recieved #{player1}"
puts "Press 'E' to roll for Player 2!"
input = gets.chomp!
puts "Player 2 has recieved #{player2}"
if player1 == player2
puts "Draw!"
start_game
elsif player1 == 'Paper' && player2 == 'Scissors'
start_points_P2 += 10
puts "Player 2 has won with #{player2}. You now have #{start_points_P2} points and opponent has #{start_points_P1} points"
elsif player1 == 'Scissors' && player2 == 'Paper'
start_points_P1 += 10
puts "Player 1 has won with #{player1}. You know have #{start_points_P1} points and opponent has #{start_points_P2} points"
elsif player1 == 'Rock' && player2 == 'Paper'
start_points_P2 += 10
puts "Player 2 has won with #{player2}. You now have #{start_points_P2} points and opponent has #{start_points_P1} points"
elsif player1 == 'Paper' && player2 == 'Rock'
start_points_P1 += 10
puts "Player 1 has won with #{player1}. You know have #{start_points_P1} points and opponent has #{start_points_P2} points"
elsif player1 == 'Scissors' && player2 == 'Rock'
start_points_P2 += 10
puts "Player 2 has won with #{player2}. You now have #{start_points_P2} points and opponent has #{start_points_P1} points"
elsif player1 == 'Rock' && player2 == 'Scissors'
start_points_P1 += 10
puts "Player 1 has won with #{player1}. You know have #{start_points_P1} points and opponent has #{start_points_P2} points"
end
end
welcome
Am I missing something here, why does it keep showing up as a draw if I have set the players into separate arrays and only called .sample once?
After a good 10 minutes of trying to come up with a more informative title, I ran out of ideas.
I have 2 prolems. The first is that whenever I try to input a position for pos_in, it registers as nul when run through the case statement that determines what m_index will be for that turn.
The second is that whenever the AI takes a turn, it always selects 1 1.
My question is: is there some way to fix this? I've tried switching the input types to no avail and I'm completely clueless on what to do.
My code:
$moves = ["x", "o"]
$move = 1
m_index = 0
$spots = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
possiblesx = (1..3)
possiblesy = (1..3)
def board
puts """
TicTacToe 1.5 by Touka
#{$spots[0]}|#{$spots[1]}|#{$spots[2]}
-----
#{$spots[3]}|#{$spots[4]}|#{$spots[5]}
-----
#{$spots[6]}|#{$spots[7]}|#{$spots[8]}
move: #{$c_move}
"""
end
def ai_move
if $spots[3, 6] == "x" || $spots[4, 8] == "x" || $spots[1, 2] == "x"
pos_in = "1 1"
elsif $spots[1, 3] == "x" || $spots[4, 7] == "x"
pos_in = "1 2"
elsif $spots[0, 1] == "x" || $spots[6, 4] == "x" || $spots[5, 8] == "x"
pos_in = "1 3"
elsif $spots[0, 6] == "x" || $spots[4, 5] == "x"
pos_in = "2 1"
elsif $spots[0, 8] == "x" || $spots[1, 7] == "x" || $spots[2, 6] == "x" || $spots[5, 3] == "x"
pos_in = "2 2"
elsif $spots[2, 8] == "x" || $spots[3, 4] == "x"
pos_in = "2 3"
elsif $spots[0, 3] == "x" || $spots[2, 4] == "x" || $spots[7, 8] == "x"
pos_in = "3 1"
elsif $spots[1, 4] == "x" || $spots[6, 8] == "x"
pos_in = "3 2"
elsif $spots[6, 7] == "x" || $spots[0, 4] == "x" || $spots[2, 5] == "x"
pos_in = "3 3"
else
aimx = possiblesx.to_a.sample
aimy = possiblesy.to_a.sample
pos_in = "#{aimx} #{aimy}"
end
end
def game
system "cls"
if $move == 1
$move = 0
else
$move = 1
end
$c_move = $moves[$move]
board
if $opp == 2 && $c_move == "o"
ai_move
else
puts "Enter move coordinates (ex \"1 1\"):"
pos_in = gets.chomp
end
case pos_in
when ["1 1"]
m_index = 0
when ["1 2"]
m_index = 1
when ["1 3"]
m_index = 2
when ["2 1"]
m_index = 3
when ["2 2"]
m_index = 4
when ["2 3"]
m_index = 5
when ["3 1"]
m_index = 6
when ["3 2"]
m_index = 7
when ["3 3"]
m_index = 8
end
if $spots[m_index] == " "
$spots[m_index] = "#{$c_move}"
else
if $opp == 2 && $c_move == "o"
$move = $c_move
game
end
system "cls"
puts "
Error.
Re-enter $move."
sleep(3)
system "cls"
$move = c_$move
game
end
system "cls"
game
end
puts "Play vs. [1]Friend or [2]AI"
$opp = gets.to_i
game
The problem you had was with your scoping, along with the fact you were trying to match a string to an array as Piotr Kruczek pointed out.
Make the pos_in variable global and change the when statements from an array input to a string.
Here is the working version of your code:
$moves = ["x", "o"]
$move = 1
m_index = 0
$spots = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
$pos_in = nil
def board
puts """
TicTacToe 1.5 by Touka
#{$spots[0]}|#{$spots[1]}|#{$spots[2]}
-----
#{$spots[3]}|#{$spots[4]}|#{$spots[5]}
-----
#{$spots[6]}|#{$spots[7]}|#{$spots[8]}
move: #{$c_move}
"""
end
def ai_move
if $spots[3, 6] == "x" || $spots[4, 8] == "x" || $spots[1, 2] == "x"
$pos_in = "1 1"
elsif $spots[1, 3] == "x" || $spots[4, 7] == "x"
$pos_in = "1 2"
elsif $spots[0, 1] == "x" || $spots[6, 4] == "x" || $spots[5, 8] == "x"
$pos_in = "1 3"
elsif $spots[0, 6] == "x" || $spots[4, 5] == "x"
$pos_in = "2 1"
elsif $spots[0, 8] == "x" || $spots[1, 7] == "x" || $spots[2, 6] == "x" || $spots[5, 3] == "x"
$pos_in = "2 2"
elsif $spots[2, 8] == "x" || $spots[3, 4] == "x"
$pos_in = "2 3"
elsif $spots[0, 3] == "x" || $spots[2, 4] == "x" || $spots[7, 8] == "x"
$pos_in = "3 1"
elsif $spots[1, 4] == "x" || $spots[6, 8] == "x"
$pos_in = "3 2"
elsif $spots[6, 7] == "x" || $spots[0, 4] == "x" || $spots[2, 5] == "x"
$pos_in = "3 3"
else
aimx = (1..3).to_a.sample
aimy = (1..3).to_a.sample
$pos_in = "#{aimx} #{aimy}"
end
end
def game
m_index = nil
system "cls"
if $move == 1
$move = 0
else
$move = 1
end
$c_move = $moves[$move]
board
if $opp == 2 && $c_move == "o"
ai_move
else
puts "Enter move coordinates (ex \"1 1\"):"
$pos_in = gets.chomp
end
case $pos_in
when "1 1"
p m_index = 0
when "1 2"
p m_index = 1
when "1 3"
p m_index = 2
when "2 1"
p m_index = 3
when "2 2"
p m_index = 4
when "2 3"
p m_index = 5
when "3 1"
p m_index = 6
when "3 2"
p m_index = 7
when "3 3"
p m_index = 8
end
if $spots[m_index] == " "
$spots[m_index] = "#{$c_move}"
else
if $opp == 2 && $c_move == "o"
$move = $c_move
game
end
system "cls"
puts "
Error.
Re-enter $move."
sleep(3)
system "cls"
$move = c_$move
game
end
system "cls"
game
end
puts "Play vs. [1]Friend or [2]AI"
$opp = gets.to_i
game
You assign
pos_in = "1 1"
as a String, while in you case statement you check for Array
case pos_in
when ["1 1"]
As Stated by Piotr and Menelik, there were a few obvious errors in this. Oddly enough, the structure of ai_move was one of those. The working code is as follows. It's not the cleanest thing ever and there are some bugs to iron out but it does it's job.
$moves = ["x", "o"]
$move = 1
m_index = 0
$spots = Array.new(9, " ")
$possiblesx = [1, 2, 3]
$possiblesy = [1, 2, 3]
def board
puts """
TicTacToe 1.5 by Touka
#{$spots[0]}|#{$spots[1]}|#{$spots[2]}
-----
#{$spots[3]}|#{$spots[4]}|#{$spots[5]}
-----
#{$spots[6]}|#{$spots[7]}|#{$spots[8]}
move: #{$c_move}
"""
end
def ai_move
if $spots[3] == "x" && $spots[6] == "x"
$pos_in = "1 1"
elsif $spots[4] == "x" && $spots[8] == "x"
$pos_in = "1 1"
elsif $spots[1] == "x" && $spots[2] == "x"
$pos_in = "1 1"
elsif $spots[1] == "x" && $spots[3] == "x"
$pos_in = "1 2"
elsif $spots[4] == "x" && $spots[7] == "x"
$pos_in = "1 2"
elsif $spots[0] == "x" && $spots[1] == "x"
$pos_in = "1 3"
elsif $spots[6] == "x" && $spots[4] == "x"
$pos_in = "1 3"
elsif $spots[5] == "x" && $spots[8] == "x"
$pos_in = "1 3"
elsif $spots[0] == "x" && $spots[6] == "x"
$pos_in = "2 1"
elsif $spots[4] == "x" && $spots[5] == "x"
$pos_in = "2 1"
elsif $spots[0] == "x" && $spots[8] == "x"
$pos_in = "2 2"
elsif $spots[1] == "x" && $spots[7] == "x"
$pos_in = "2 2"
elsif $spots[2] == "x" && $spots[6] == "x"
$pos_in = "2 2"
elsif $spots[5] == "x" && $spots[3] == "x"
$pos_in = "2 2"
elsif $spots[2] == "x" && $spots[8] == "x"
$pos_in = "2 3"
elsif $spots[3] == "x" && $spots[4] == "x"
$pos_in = "2 3"
elsif $spots[0] == "x" && $spots[3] == "x"
$pos_in = "3 1"
elsif $spots[2] == "x" && $spots[4] == "x"
$pos_in = "3 1"
elsif $spots[7] == "x" && $spots[8] == "x"
$pos_in = "3 1"
elsif $spots[1] == "x" && $spots[4] == "x"
$pos_in = "3 2"
elsif $spots[6] == "x" && $spots[8] == "x"
$pos_in = "3 2"
elsif $spots[6] == "x" && $spots[7] == "x"
$pos_in = "3 3"
elsif $spots[0] == "x" && $spots[4] == "x"
$pos_in = "3 3"
elsif $spots[2] == "x" && $spots[5] == "x"
$pos_in = "3 3"
else
aimx = $possiblesx.sample
aimy = $possiblesy.sample
$pos_in = "#{aimx} #{aimy}"
end
end
def game
system "cls"
if $move == 1
$move = 0
else
$move = 1
end
$c_move = $moves[$move]
board
if $opp == 2 && $c_move == "o"
ai_move
else
puts "Enter move coordinates (ex \"1 1\"):"
$pos_in = gets.chomp
end
case $pos_in
when "1 1"
m_index = 0
when "1 2"
m_index = 1
when "1 3"
m_index = 2
when "2 1"
m_index = 3
when "2 2"
m_index = 4
when "2 3"
m_index = 5
when "3 1"
m_index = 6
when "3 2"
m_index = 7
when "3 3"
m_index = 8
end
if $spots[m_index] == " "
$spots[m_index] = "#{$c_move}"
else
if $opp == 2 && $c_move == "o"
$move = $c_move
game
end
system "cls"
puts "
Error.
Re-enter move."
sleep(3)
system "cls"
$move = $c_move
game
end
system "cls"
game
end
puts "Play vs. [1]Friend [2]AI"
$opp = gets.to_i
game