aboutsummaryrefslogtreecommitdiff
path: root/doc/codewalk/pig.go
diff options
context:
space:
mode:
Diffstat (limited to 'doc/codewalk/pig.go')
-rw-r--r--doc/codewalk/pig.go121
1 files changed, 0 insertions, 121 deletions
diff --git a/doc/codewalk/pig.go b/doc/codewalk/pig.go
deleted file mode 100644
index 941daaed16..0000000000
--- a/doc/codewalk/pig.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "fmt"
- "math/rand"
-)
-
-const (
- win = 100 // The winning score in a game of Pig
- gamesPerSeries = 10 // The number of games per series to simulate
-)
-
-// A score includes scores accumulated in previous turns for each player,
-// as well as the points scored by the current player in this turn.
-type score struct {
- player, opponent, thisTurn int
-}
-
-// An action transitions stochastically to a resulting score.
-type action func(current score) (result score, turnIsOver bool)
-
-// roll returns the (result, turnIsOver) outcome of simulating a die roll.
-// If the roll value is 1, then thisTurn score is abandoned, and the players'
-// roles swap. Otherwise, the roll value is added to thisTurn.
-func roll(s score) (score, bool) {
- outcome := rand.Intn(6) + 1 // A random int in [1, 6]
- if outcome == 1 {
- return score{s.opponent, s.player, 0}, true
- }
- return score{s.player, s.opponent, outcome + s.thisTurn}, false
-}
-
-// stay returns the (result, turnIsOver) outcome of staying.
-// thisTurn score is added to the player's score, and the players' roles swap.
-func stay(s score) (score, bool) {
- return score{s.opponent, s.player + s.thisTurn, 0}, true
-}
-
-// A strategy chooses an action for any given score.
-type strategy func(score) action
-
-// stayAtK returns a strategy that rolls until thisTurn is at least k, then stays.
-func stayAtK(k int) strategy {
- return func(s score) action {
- if s.thisTurn >= k {
- return stay
- }
- return roll
- }
-}
-
-// play simulates a Pig game and returns the winner (0 or 1).
-func play(strategy0, strategy1 strategy) int {
- strategies := []strategy{strategy0, strategy1}
- var s score
- var turnIsOver bool
- currentPlayer := rand.Intn(2) // Randomly decide who plays first
- for s.player+s.thisTurn < win {
- action := strategies[currentPlayer](s)
- s, turnIsOver = action(s)
- if turnIsOver {
- currentPlayer = (currentPlayer + 1) % 2
- }
- }
- return currentPlayer
-}
-
-// roundRobin simulates a series of games between every pair of strategies.
-func roundRobin(strategies []strategy) ([]int, int) {
- wins := make([]int, len(strategies))
- for i := 0; i < len(strategies); i++ {
- for j := i + 1; j < len(strategies); j++ {
- for k := 0; k < gamesPerSeries; k++ {
- winner := play(strategies[i], strategies[j])
- if winner == 0 {
- wins[i]++
- } else {
- wins[j]++
- }
- }
- }
- }
- gamesPerStrategy := gamesPerSeries * (len(strategies) - 1) // no self play
- return wins, gamesPerStrategy
-}
-
-// ratioString takes a list of integer values and returns a string that lists
-// each value and its percentage of the sum of all values.
-// e.g., ratios(1, 2, 3) = "1/6 (16.7%), 2/6 (33.3%), 3/6 (50.0%)"
-func ratioString(vals ...int) string {
- total := 0
- for _, val := range vals {
- total += val
- }
- s := ""
- for _, val := range vals {
- if s != "" {
- s += ", "
- }
- pct := 100 * float64(val) / float64(total)
- s += fmt.Sprintf("%d/%d (%0.1f%%)", val, total, pct)
- }
- return s
-}
-
-func main() {
- strategies := make([]strategy, win)
- for k := range strategies {
- strategies[k] = stayAtK(k + 1)
- }
- wins, games := roundRobin(strategies)
-
- for k := range strategies {
- fmt.Printf("Wins, losses staying at k =% 4d: %s\n",
- k+1, ratioString(wins[k], games-wins[k]))
- }
-}