简体   繁体   中英

How to use a while() loop within a for() loop in R

I'm new to R, so most of my code is most likely wrong. However, I was wondering how to use a while() loop within a for() loop. I'm trying to simulate rolling a pair of dice several times if the total 2,3,7,11,or 12 then I stop. If the total 4,5,6,8,9, or 10 then I continue to the roll the dice until the initial total appears or 7. I'm trying to find the average number of rolls it take to end the game

count = 0
x = NULL
for (i in 1:10) {
  x[i] = c(sample(1:6,1) +sample(1:6,1))
  if(x[i] == c(2||3||7||11||12)) {
    if(TRUE) {count = count +1}
  } else { while(x[i] == c(4||5||6||8||9||10)) {
    x[i +1] = c(sample(1:6,1)+sample(1:6,1))
    if(x[i+1] == c(x[i]||7)) {
      if(TRUE){count = count + x[i+1]}
    }
  }
  }
}
print(count)

I think there are a few issues with your logic. I'm not quite sure what you're trying to do in your code, but this is my interpretation of your description of your problem ... this only runs a single round of your game -- it should work if you embed it in a for loop though (just don't reset count or reset the random-number seed in side your loop -- then count will give you the total number of rolls, and you can divide by the number of rounds to get the average)

Setup:

count = 0
sscore <- c(2,3,7,11,12)
set.seed(101)
debug = TRUE

Running a single round:

x = sample(1:6,1) +sample(1:6,1)  ## initial roll
count = count + 1
if (x %in% sscore) {
    ## don't need to do anything if we hit,
    ## as the roll has already been counted
    if (debug) cat("hit",x[i],"\n")  
} else {
    ## initialize while loop -- try one more time
    y = c(sample(1:6,1)+sample(1:6,1))
    count = count + 1
    if (debug) cat("initial",x,"next",y,"\n")
    while(!(y %in% c(x,7))) {
        y = c(sample(1:6,1)+sample(1:6,1))
        count = count+1
        if (debug) cat("keep trying",y,"\n")

    }  ## end while
}  ## end if-not-hit
print(count)

I tried embedding this in a for loop and got a mean of 3.453 for 1000 rounds, close to @PawelP's answer.

PS I hope this isn't homework, as I prefer not to answer homework questions ...

EDIT: I had a bug - forgot to remove if negation. Now the below seems to be 100% true to your description of the problem.

This is my implementation of the game you've described. It calculates the average number of rolls it took to end the game over a TOTAL_GAMES many games.

TOTAL_GAMES = 1000
counts = rep(0, TOTAL_GAMES)
x = NULL
for (i in 1:TOTAL_GAMES) {
    x_start = c(sample(1:6,1) +sample(1:6,1))
    counts[i] = counts[i] + 1
    x = x_start
    if(x %in% c(2, 3, 7, 11, 12)){
       next
    }

    repeat {
        x = c(sample(1:6,1)+sample(1:6,1))
            counts[i] = counts[i] + 1
        if(x %in% c(x_start, 7)){
            break
        }
    }
}

print(mean(counts))

It seems that the average number of rolls is around 3.38

Here's one approach to this question - I made a function that runs a single trial, and another function which conducts a variable number of these trials and returns the cumulative average.

## Single trial
rollDice <- function(){
  init <- sample(1:6,1)+sample(1:6,1)
  rolls <- 1
  if( init %in% c(2,3,7,11,12) ){
    return(1)
  } else {
    Flag <- TRUE
    while( Flag ){
      roll <- sample(1:6,1)+sample(1:6,1)
      rolls <- rolls + 1
      if( roll %in% c(init,7) ){
        Flag <- FALSE
      }
      rolls
    }
  }
  return(rolls)
}
## Multiple trials
simAvg <- function(nsim = 100){
  x <- replicate(nsim,rollDice())
  Reduce("+",x)/nsim
}
##
## Testing 
nTrial <- seq(1,1000,25)
Results <- sapply(nTrial, function(X){ simAvg(X) })
##
## Plot over varying number of simulations
plot(x=nTrial,y=Results,pch=20)

As @Ben Bolker pointed out, you had a couple of syntax errors with || , which is understandable for someone new to R. Also, you'll probably hear it a thousand times, but for and while loops are pretty inefficient in R so you generally want to avoid them if possible. In the case of the while loop in the above rollDice() function, it probably isn't a big deal because the probability of the loop executing a large number of times is very low. I used the functions Reduce and replicate to serve the role of a for loop in the second function. Good question though, it was fun to work on.

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM