Random coin flipping while loop in

43 Views Asked by At

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:

  1. coin_flip actually changes on subsequent iterations of the while loop
  2. I don't receive both 'Heads!' and 'Tails' on each iteration of the while loop

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}
} 
1

There are 1 best solutions below

2
Gregor Thomas On BEST ANSWER

You've got 2 problems:

  1. 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.

  2. 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
}