2015-12-06 11 views
9

Randomise Ich habe eine RPS-Funktion erstellt, die die Bewegung des Computers für eine Runde randomisiert. Zum Beispiel, wenn Sie rps ("Rock") eingeben, spuckt die Funktion zufällig Stein, Papier, Schere zusammen mit dem Ergebnis aus (Gewinn, Verlust, Gleichstand).Versuchen, ein Spiel von Stein, Papier, Schere in R

rps = function(move){ 
    options = c("rock", "paper", "scissors") 
    comp.move = sample(options, size = 1) 
    if(move == "rock" & comp.move == "rock"){ 
    names(comp.move) = "tie" 
}else 
if(move == "rock" & comp.move == "scissors"){ 
    names(comp.move) = "loss" 
}else 
if(move == "rock" & comp.move == "paper"){ 
    names(comp.move) = "win" 
}else 
if(move == "paper" & comp.move == "paper"){ 
    names(comp.move) = "tie" 
}else 
if(move == "paper" & comp.move == "scissors"){ 
    names(comp.move) = "win" 
}else 
if(move == "paper" & comp.move == "rock"){ 
    names(comp.move) = "loss" 
}else 
if(move == "scissors" & comp.move == "scissors"){ 
    names(comp.move) = "tie" 
}else 
if(move == "scissors" & comp.move == "rock"){ 
    names(comp.move) = "win" 
}else 
if(move == "scissors" & comp.move == "paper"){ 
    names(comp.move) = "loss" 
} 
    return(comp.move) 
} 

Jetzt möchte ich eine Version des Spiels spielen, wo dies 50 Mal passiert. Ich habe bereits einen Vektor der Länge 50 erstellt, der die zuvor aufgenommenen menschlichen Bewegungen enthält.

human.move = c("rock", "paper", "scissors", "paper", "paper", "rock", "scissors", "rock", "rock", "paper", "paper", "scissors", "rock", "rock", "paper", "paper", "paper", "scissors", "paper", "rock", "paper", "rock", "rock", "scissors", "scissors", "paper", "rock", "paper", "scissors", "rock", "paper", "paper", "scissors", "rock", "paper", "rock", "paper", "paper", "scissors", "scissors", "paper", "rock", "rock", "scissors", "scissors", "rock", "paper", "scissors", "scissors", "rock") 

Wie erhalte ich den Computer, um die rps Funktion für jedes Element in diesem Vektor zu laufen, und geben Sie mir die Ergebnisse? Momentan benutzt meine Funktion nur das erste Element meines menschlichen Bewegungsvektors (welches Rock ist) und vergleicht nur seine zufälligen Bewegungen damit.

rps.random=function(move,n=50){ 
comp.moves = vector("character") 

for(i in human.move){ 
comp.move=rps(move[i]) 
comp.moves = append(comp.moves,comp.move, after = length(comp.moves)) 
} 
return(comp.moves) 
} 
+0

Viele der Antworten unten groß sind, und beinhalten viel von der ursprünglichen OP des Codes neu zu schreiben. Die Frage lautete jedoch: "Wie bekomme ich den Computer dazu, die rps-Funktion für jedes Element in diesem Vektor auszuführen und mir die Ergebnisse zu geben?" –

+1

@GaryWeissman - Das ist richtig, aber manchmal kann es besser sein, Verbesserungen der aktuellen Methoden des OP anzubieten. –

+0

@RichardScriven das ist auch wahr. –

Antwort

8

Hier sind ein paar Vorschläge. Zuerst ein Update für Ihre Funktion. Sie können alle diese if() Aussagen mit ein paar "oder" Anweisungen mit dem | Operator für entweder gewinnen oder Verlust und die identical() Funktion für eine Krawatte reduzieren. Es ist auch mein Verständnis, dass randomisierte Spiele wie dieses eine Runde nacheinander gespielt werden sollten und für mehr als eine Runde repliziert wurden. Daher prüft diese Funktion auf einen Vektor mit einer einzigen Länge, der in move angegeben ist.

rps <- function (move) { 
    opts <- c("rock", "paper", "scissors") 
    stopifnot(length(move) == 1L, move %in% opts) 
    cpu <- sample(opts, 1) 
    names(cpu) <- if (identical(move, cpu)) { 
     "tie" 
    } 
    else if (move == "rock" & cpu == "scissors" | move == "paper" & 
     cpu == "rock" | move == "scissors" & cpu == "paper") { 
     "win" 
    } 
    else { 
     "loss" 
    } 
    cpu 
} 

Hier sind ein paar Beispiel läuft -

rps("paper") 
# win 
# "rock" 
rps("rock") 
# loss 
# "paper" 

Jetzt manuell Sie nicht brauchen, um einen Vektor von 50 Elementen zu erstellen. Wir können den Prozess einfach 50 Mal replizieren, indem wir ein Beispiel in dem Argument move verwenden.

replicate(50, rps(sample(c("rock", "paper", "scissors"), 1))) 
#  win  win  loss  win  loss  tie  tie 
# "scissors" "paper" "paper" "paper"  "rock" "paper" "scissors" 
#  win  loss  loss  tie  loss  win  win 
#  "rock" "paper" "paper" "paper" "paper" "scissors" "scissors" 
#  tie  loss  tie  win  win  tie  loss 
# "scissors"  "rock" "scissors" "paper" "paper" "scissors"  "rock" 
#  tie  tie  loss  tie  win  win  win 
#  "rock" "scissors" "scissors" "scissors"  "rock" "scissors" "scissors" 
#  win  win  loss  win  tie  tie  win 
# "scissors" "scissors" "paper" "paper" "paper" "paper" "paper" 
#  win  tie  win  tie  tie  win  win 
# "paper"  "rock"  "rock" "paper" "scissors" "paper" "scissors" 
#  loss  tie  tie  loss  tie  win  win 
#  "rock"  "rock" "paper" "scissors" "scissors"  "rock"  "rock" 
#  win 
# "paper" 

Natürlich, wenn Sie haben einen Eingangsvektor haben wir es durch sapply() laufen die gleichen Ergebnisse wie oben (mit oder ohne den Eingangsvektor in dem Namen) zu sehen.

sapply(c("rock", "paper", "scissors"), rps) 
# rock.loss paper.win scissors.tie 
#  "paper"  "rock" "scissors" 
sapply(c("rock", "paper", "scissors"), rps, USE.NAMES = FALSE) 
#  tie  loss  win 
# "rock" "scissors" "paper" 

Update: es mir gerade aufgegangen, dass Sie keine Ahnung haben, was die Eingabe in den oben genannten Fällen war, dass wir von replicate() bekamen, hier so eine Lösung. Wenn wir die letzte Zeile ändern, wenn die Funktion zu einer Matrix (oder einer Liste) gehört, können wir auch angeben, was die Eingabe war. Wir können so etwas wie dies für die letzte Zeile verwenden =

matrix(c(move, cpu), 1, dimnames = list(wlt, c("move", "cpu"))) 

Dann würden wir die folgenden für Ergebnisse erhalten -

rps("paper") 
#  move cpu  
# loss "paper" "scissors" 
rps("paper") 
#  move cpu  
# tie "paper" "paper" 

Jetzt wissen wir, was wir als Input setzen in, ohne zusätzliche Arbeit. Und wir können Replikationen mit unserem alten Freund do.call(rbind, ...) in eine Matrix zusammenbringen.

2

können Sie die apply Familie von Funktionen nutzen. Versuchen Sie in Ihrem Fall:

lapply(human.move, rps) 
6

Wie Gary vorgeschlagen hat, können Sie für jede Funktion, die an "einer Sache" funktioniert, lapply oder sapply verwenden, damit es für viele Dinge funktioniert.

Aber ich würde sagen, das ist nicht wirklich hier notwendig, weil, was in rps ist bereits die Situation behandelt, wenn move länger als 1. Sie würden nur sample(options, size = 1)-sample(options, size = length(move), replace = TRUE) ändern müssen.

Google "Sampling mit Ersatz", wenn Sie nicht sicher sind über die replace = TRUE Teil.

Ich denke, es gibt auch einen einfacheren Weg herauszufinden, ob es ein Gewinn, Verlust oder Gleichstand war.

rps = function(move){ 

    # possible selections 
    options = c("rock", "paper", "scissors") 

    # the sample function is already vectorised, so it will work when 
    # move is longer than one 
    comp.move = sample(options, size = length(move), replace = TRUE) 

    #create a result vector that defaults to 'loss' 
    results <- rep('loss', length(move)) 

    # update the rest of the results (these are vectorised too) 
    results[move == comp.move]        <- 'tie' 
    results[move == 'rock'  & comp.move == 'scissors'] <- 'win' 
    results[move == 'paper'  & comp.move == 'rock']  <- 'win' 
    results[move == 'scissors' & comp.move == 'paper'] <- 'win' 

    # set the names 
    names(comp.move) <- results 

    # return the vector 
    comp.move 
} 

Dann können Sie es wie verwenden, so

> rps(human.move) 
     loss  win  win  loss  loss  win  loss  tie  loss  loss  loss  loss  win  win 
    "paper"  "rock" "paper" "scissors" "scissors" "scissors"  "rock"  "rock" "paper" "scissors" "scissors"  "rock" "scissors" "scissors" 
     loss  loss  loss  loss  tie  tie  loss  tie  tie  loss  tie  win  tie  tie 
"scissors" "scissors" "scissors"  "rock" "paper"  "rock" "scissors"  "rock"  "rock"  "rock" "scissors"  "rock"  "rock" "paper" 
     tie  win  loss  loss  win  loss  loss  win  loss  tie  tie  tie  win  loss 
"scissors" "scissors" "scissors" "scissors" "paper" "paper" "scissors" "scissors" "scissors" "paper" "scissors" "scissors"  "rock" "paper" 
     tie  win  tie  tie  loss  tie  tie  tie 
    "rock" "paper" "scissors"  "rock" "scissors" "scissors" "scissors"  "rock" 
5

kek

rps <- function(player) { 
    p <- c('rock','paper','scissors') 
    player <- if (missing(player)) 
    sample(p, 1) else match.arg(player, p, FALSE) 
    computer <- sample(p, 1) 
    message(sprintf('Computer picks %s', computer)) 
    message(sprintf('You chose %s', player)) 
    plays <- cbind(expand.grid(p = p, c = p), 
       result = I(c('tie','win','loss','loss','tie','win','win','loss','tie'))) 

    res <- plays[plays$p %in% player & plays$c %in% computer, 'result'] 
    if (res == 'tie') 
    return(res) 

    for (ii in 1:10) { 
    par(mar = c(0,0,0,0), bg = sample(colors(), 1)) 
    plot(1:10, ann = FALSE, axes = FALSE, type = 'n') 
    text(runif(1, 1, 10), runif(1, 1, 10), toupper(res), srt = sample(0:360, 1), 
     font = 3, cex = 4, col = sample(colors(), 1)) 
    Sys.sleep(.1) 
    } 
    graphics.off() 
    res 
} 

rps() 
Verwandte Themen