Task

Implement the classic children's game Rock-paper-scissors, as well as a simple predictive   AI   (artificial intelligence)   player.

Rock Paper Scissors is a two player game.

Each player chooses one of rock, paper or scissors, without knowing the other player's choice.

The winner is decided by a set of rules:

   Rock beats scissors
   Scissors beat paper
   Paper beats rock


If both players choose the same thing, there is no winner for that round.

For this task, the computer will be one of the players.

The operator will select Rock, Paper or Scissors and the computer will keep a record of the choice frequency, and use that information to make a weighted random choice in an attempt to defeat its opponent.



Extra credit

Support additional choices   additional weapons.




package main
 
import (
    "fmt"
    "math/rand"
    "strings"
    "time"
)
 
const rps = "rps"
 
var msg = []string{
    "Rock breaks scissors",
    "Paper covers rock",
    "Scissors cut paper",
}
 
func main() {
    rand.Seed(time.Now().UnixNano())
    fmt.Println("Rock Paper Scissors")
    fmt.Println("Enter r, p, or s as your play.  Anything else ends the game.")
    fmt.Println("Running score shown as <your wins>:<my wins>")
    var pi string // player input
    var aScore, pScore int
    sl := 3               // for output alignment
    pcf := make([]int, 3) // pcf = player choice frequency
    var plays int
    aChoice := rand.Intn(3) // ai choice for first play is completely random
    for {
        // get player choice
        fmt.Print("Play: ")
        _, err := fmt.Scanln(&pi)  // lazy
        if err != nil || len(pi) != 1 {
            break
        }
        pChoice := strings.Index(rps, pi)
        if pChoice < 0 {
            break
        }
        pcf[pChoice]++
        plays++
 
        // show result of play
        fmt.Printf("My play:%s%c.  ", strings.Repeat(" ", sl-2), rps[aChoice])
        switch (aChoice - pChoice + 3) % 3 {
        case 0:
            fmt.Println("Tie.")
        case 1:
            fmt.Printf("%s.  My point.\n", msg[aChoice])
            aScore++
        case 2:
            fmt.Printf("%s.  Your point.\n", msg[pChoice])
            pScore++
        }
 
        // show score
        sl, _ = fmt.Printf("%d:%d  ", pScore, aScore)
 
        // compute ai choice for next play
        switch rn := rand.Intn(plays); {
        case rn < pcf[0]:
            aChoice = 1
        case rn < pcf[0]+pcf[1]:
            aChoice = 2
        default:
            aChoice = 0
        }
    }
}