i'm trying to make a simple coin-flipping program. once either 'heads' or 'tails' has reached 3, the coin-flipping while loop closes. it made sense to use a random integer from sample() to generate either a 1 or a 2 to add to the tally of either heads or tails.
The problem is that the coin_flip doesn't seem to change on subsequent iterations of the while loop. So my question: how can i make it so that:
Many thanks Rohan
This is my code
heads <- 0
tails <- 0
coin_flip <- sample(1:2, 1)
print(coin_flip)
while (heads < 3 & tails < 3) {
coin_flip
print(coin_flip)
if (coin_flip <- 1) {
print ('Heads!')
heads = heads + 1 }
if (coin_flip <- 2) {
print ('Tails!')
tails = tails + 1}
}
You've got 2 problems:
The value of coin_flip
is only changed when you assign a new value to it, coin_flip <- ...
. The only time you assign a random value is before the loop. If you want to get a new random value each time through the loop, that needs to happen inside the loop.
Related, we use <-
to assign a value, and ==
to test equality. You are using <-
inside your if()
statement so you are assigning a value. We need to use ==
there instead to test for equality.
Your code, if (coin_flip <- 1)
is the same as coin_flip <- 1; if(coin_flip)
, and if()
will consider any non-zero number as TRUE
.
Fixing those, we get this:
heads <- 0
tails <- 0
while (heads < 3 & tails < 3) {
coin_flip <- sample(1:2, 1)
print(coin_flip)
if (coin_flip == 1) {
print ('Heads!')
heads = heads + 1 }
if (coin_flip == 2) {
print ('Tails!')
tails = tails + 1}
}
# [1] 2
# [1] "Tails!"
# [1] 1
# [1] "Heads!"
# [1] 2
# [1] "Tails!"
# [1] 1
# [1] "Heads!"
# [1] 1
# [1] "Heads!"
If we wanted to simplify a little bit, I would say there's no reason to sample numbers when we could sample from "Heads" and "Tails" directly. I also generally prefer message()
to print()
for single-line notes about how code is running. This would let us remove some unnecessary bits like this:
heads <- 0
tails <- 0
while (heads < 3 & tails < 3) {
coin_flip <- sample(c("Heads", "Tails"), 1)
message(coin_flip)
if (coin_flip == "Heads") {
heads = heads + 1
}
if (coin_flip == "Tails") {
tails = tails + 1
}
}
# Heads
# Tails
# Heads
# Heads
Here's a little more concise, using a named vector for the results instead of two separate objects. This lets us skip the if()
statements entirely, using the result as a name to increment the correct value.
results = c("Heads" = 0, "Tails" = 0)
while (all(results < 3)) {
coin_flip <- sample(c("Heads", "Tails"), 1)
message(coin_flip)
results[coin_flip] <- results[coin_flip] + 1
}