{
  "id": "P035",
  "slug": "pig-dice-game",
  "key": "P035-pig-dice-game",
  "title": "Pig (dice game)",
  "summary": "The dice game Pig for two players or against the computer: roll as often as you like, every roll adds to the turn, a 1 loses the whole turn, and holding banks it - first to the target wins. The computer holds at 20; the dice come from a random generator written in EML, so a seed always gives the same game, and a tally shows how often each face came up.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P035 - Pig (dice game)\n\nThe dice game Pig, for two players or one against the computer. On a turn you\nroll a die as often as you like: every roll adds to the turn, but a 1 loses\nthe whole turn, and holding banks it. The first to the target - 100 unless it\nis changed - wins; a turn that reaches the target is banked at once. The dice\ncome from a random generator written in EML, so a seed always gives the same\nrolls, and a tally shows how often each face has come up.\n\n- `main.eml` - the menu, the names, the target and the seed, a turn at the\n  keyboard and the game\n- `pig.eml` - the computer's strategy and its turn\n- `rng.eml` - the random generator of P008 (number guessing), with a die\n- `tally.eml` - how often each face came up, with a bar for each\n\nHow each part works:\n\n- The computer holds at 20, or as soon as its turn would win. A roll at turn\n  total t loses t one time in six and otherwise adds 4 on average\n  ((2 + 3 + 4 + 5 + 6) / 5), so it is worth (20 - t) / 6 points on average:\n  rolling pays while the turn is below 20. Worked out exactly over a whole\n  turn, holding at 20 gives the most points per turn, 8.14 on average (so\n  does 21: at 20 one more roll gains nothing on average). That is the best\n  rule for points per turn; winning a game is a different question - near\n  the end, the score still needed matters more - and the computer looks at\n  that only to stop when its turn would win.\n- The generator is a linear congruential one with the constants of the C\n  standard's example rand(), its state below 2^31; a die is 1 plus the high\n  bits of the state (the state divided by 65536) modulo 6. The constants meet\n  the conditions for the full period, so in one period every state comes\n  once and each face comes up exactly as often as its share of the 32,768\n  high-bit values: 5,462 for faces 1 and 2 and 5,461 for the others - a sixth,\n  to within 0.012%.\n- Python's random module is not used: a session is checked byte for byte in\n  CPython and in the EML interpreter, and both must see the same rolls.\n- The tally counts every roll of the run, the computer's too, as in the\n  corpus case `dice-roll-tally`: a count for each face, the face that came up\n  most often (the lowest on a tie) and the share a fair die would give.\n\nWhat is checked: names of 1 to 12 letters, different in any case, and not\nComputer when playing the computer; r, h or q on a turn, in either case, and\nno hold before the first roll; a target from 10 to 500; a seed of up to 9\ndigits. An empty answer cancels.\n\nSessions: `sessions/basic.in` sets the target to 40. Ana and Bo play: Bo holds\nonce his turn reaches 12 and Ana at 15; Ana loses four turns to a 1 before\nher first hold, and Bo wins 43 to 32 with a single 4 that takes him past 40.\nThen Cy plays the computer, which holds once with 21 and loses three turns to\na 1; Cy wins 41 to 21. The tally of the 57 rolls ends the session.\n`sessions/bad-input.in` gives menu choices 0 and x, the tally before any\nroll, targets 5, 501 and x, seeds x and 1234567890, a name with a digit, a\nname of 13 letters, the same name in capitals, a hold before rolling, x and\nroll as moves, R in capitals, q to stop the game, Computer as a name and two\ncancelled games; then it sets seed 7 twice, and both games start with 5, 3\nand 3 - the same seed gives the same rolls.\n\nBuilt on the verified corpus case `dice-roll-tally` (a tally of dice faces,\nwith the most frequent face found by comparison).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P035 dice game Pig: two players, or one against the computer. On a turn\n# you roll a die as often as you like - every roll adds to the turn, but a 1\n# loses the whole turn - and holding banks it. The first to the target wins.\n# The dice come from a random generator written in EML, so the same seed\n# always gives the same rolls, and a tally shows how often each face came up.\nimport pig\nimport rng\nimport tally\n\n12 => longest_name\n\ndef trim(s):\n    0 => i\n    len(s) => j\n    while i < j and s[i] == \" \":\n        i + 1 => i\n    while j > i and s[j - 1] == \" \":\n        j - 1 => j\n    return s[i:j]\n\ndef lower(s):\n    \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" => big\n    \"abcdefghijklmnopqrstuvwxyz\" => small\n    \"\" => out\n    for c in s:\n        0 => k\n        while k < 26 and big[k] != c:\n            k + 1 => k\n        if k < 26:\n            out + small[k] => out\n        else:\n            out + c => out\n    return out\n\ndef number(s):\n    # The value of 1 to 9 digits, otherwise -1.\n    if s == \"\" or len(s) > 9:\n        return -1\n    0 => n\n    for c in s:\n        if not (c in \"0123456789\"):\n            return -1\n        n * 10 + int(c) => n\n    return n\n\ndef ask_name(prompt, taken):\n    # A name of 1 to 12 letters, not taken (in any case); \"\" when the\n    # answer is empty.\n    while True:\n        trim(input(prompt)) => name\n        if name == \"\":\n            return \"\"\n        True => letters\n        for c in name:\n            if not (c in \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"):\n                False => letters\n        if not letters or len(name) > longest_name:\n            (\"A name is 1 to \" + str(longest_name) + \" letters.\") ^0\n        else:\n            \"\" => clash\n            for t in taken:\n                if lower(t) == lower(name):\n                    t => clash\n            if clash == \"\":\n                return name\n            (clash + \" is already playing.\") ^0\n\ndef human_turn(r, name, score, target):\n    # One turn at the keyboard. Returns [how it ended, points, rolls], where\n    # it ends \"lost\", \"held\", \"won\" or \"stopped\".\n    0 => turn\n    [] => rolls\n    while True:\n        lower(trim(input(name + \" (turn \" + str(turn) + \")> \"))) => answer\n        if answer == \"r\":\n            r.die() => d\n            rolls + [d] => rolls\n            if d == 1:\n                (name + \" rolls 1 - the turn is lost.\") ^0\n                return [\"lost\", 0, rolls]\n            turn + d => turn\n            if score + turn >= target:\n                (name + \" rolls \" + str(d) + \" - turn \" + str(turn) + \", score \" + str(score + turn) + \".\") ^0\n                return [\"won\", turn, rolls]\n            (name + \" rolls \" + str(d) + \" - turn \" + str(turn) + \".\") ^0\n        elif answer == \"h\":\n            if turn == 0:\n                \"Roll at least once before holding.\" ^0\n            else:\n                (name + \" holds: \" + str(turn) + \", score \" + str(score + turn) + \".\") ^0\n                return [\"held\", turn, rolls]\n        elif answer == \"q\":\n            return [\"stopped\", 0, rolls]\n        else:\n            \"Type r to roll, h to hold or q to stop the game.\" ^0\n\ndef computer_turn(r, score, target):\n    # The computer's turn, shown on one line. Returns [how it ended, points,\n    # rolls] like human_turn.\n    pig.computer_turn(r, score, target) => rolls\n    if rolls[len(rolls) - 1] == 1:\n        (\"Computer rolls \" + pig.listed(rolls) + \" - the turn is lost.\") ^0\n        return [\"lost\", 0, rolls]\n    0 => turn\n    for d in rolls:\n        turn + d => turn\n    if score + turn >= target:\n        (\"Computer rolls \" + pig.listed(rolls) + \" - turn \" + str(turn) + \", score \" + str(score + turn) + \".\") ^0\n        return [\"won\", turn, rolls]\n    (\"Computer rolls \" + pig.listed(rolls) + \" and holds: \" + str(turn) + \", score \" + str(score + turn) + \".\") ^0\n    return [\"held\", turn, rolls]\n\ndef play(r, names, computer, target, counts):\n    # One game; the first name starts. Returns the tally with this game's\n    # rolls added.\n    [0, 0] => scores\n    0 => p\n    \"Type r to roll, h to hold, q to stop the game.\" ^0\n    if computer:\n        \"The computer holds at 20, or as soon as its turn would win.\" ^0\n    while True:\n        (names[0] + \" \" + str(scores[0]) + \", \" + names[1] + \" \" + str(scores[1]) + \" - \" + names[p] + \" to play.\") ^0\n        if computer and p == 1:\n            computer_turn(r, scores[1], target) => t\n        else:\n            human_turn(r, names[p], scores[p], target) => t\n        tally.counted(counts, t[2]) => counts\n        if t[0] == \"stopped\":\n            \"Game stopped.\" ^0\n            return counts\n        scores[p] + t[1] => scores[p]\n        if t[0] == \"won\":\n            (names[p] + \" wins, \" + str(scores[p]) + \" to \" + str(scores[1 - p]) + \"!\") ^0\n            return counts\n        1 - p => p\n\ndef new_game(r, computer, target, counts):\n    if computer:\n        ask_name(\"your name> \", [\"Computer\"]) => a\n        if a == \"\":\n            \"Cancelled.\" ^0\n            return counts\n        return play(r, [a, \"Computer\"], True, target, counts)\n    ask_name(\"player 1> \", []) => a\n    if a == \"\":\n        \"Cancelled.\" ^0\n        return counts\n    ask_name(\"player 2> \", [a]) => b\n    if b == \"\":\n        \"Cancelled.\" ^0\n        return counts\n    return play(r, [a, b], False, target, counts)\n\n100 => target\n2026 => seed\nrng.Rng(seed) => r\n[0, 0, 0, 0, 0, 0] => counts\nTrue => running\nwhile running:\n    \"\" ^0\n    (\"== Pig (first to \" + str(target) + \", seed \" + str(seed) + \") ==\") ^0\n    \"1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\" ^0\n    trim(input(\"choice> \")) => choice\n    if choice == \"1\":\n        new_game(r, False, target, counts) => counts\n    elif choice == \"2\":\n        new_game(r, True, target, counts) => counts\n    elif choice == \"3\":\n        trim(input(\"target (10 to 500)> \")) => answer\n        number(answer) => n\n        if answer == \"\":\n            \"Cancelled.\" ^0\n        elif n >= 10 and n <= 500:\n            n => target\n            (\"The first to \" + str(target) + \" wins.\") ^0\n        else:\n            (\"The target stays \" + str(target) + \": type a number from 10 to 500.\") ^0\n    elif choice == \"4\":\n        trim(input(\"seed> \")) => answer\n        number(answer) => s\n        if answer == \"\":\n            \"Cancelled.\" ^0\n        elif s < 0:\n            \"A seed is a whole number of up to 9 digits.\" ^0\n        else:\n            s => seed\n            rng.Rng(seed) => r\n            (\"Seed set to \" + str(seed) + \": the same seed gives the same rolls.\") ^0\n    elif choice == \"5\":\n        tally.show(counts)\n    elif choice == \"6\":\n        False => running\n    else:\n        \"Pick a number from 1 to 6.\" ^0\n\"Bye.\" ^0\n",
      "python": "import pig\nimport rng\nimport tally\nlongest_name = 12\n\ndef trim(s):\n    i = 0\n    j = len(s)\n    while i < j and s[i] == \" \":\n        i = i + 1\n    while j > i and s[j - 1] == \" \":\n        j = j - 1\n    return s[i:j]\n\ndef lower(s):\n    big = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n    small = \"abcdefghijklmnopqrstuvwxyz\"\n    out = \"\"\n    for c in s:\n        k = 0\n        while k < 26 and big[k] != c:\n            k = k + 1\n        if k < 26:\n            out = out + small[k]\n        else:\n            out = out + c\n    return out\n\ndef number(s):\n    if s == \"\" or len(s) > 9:\n        return -1\n    n = 0\n    for c in s:\n        if not c in \"0123456789\":\n            return -1\n        n = n * 10 + int(c)\n    return n\n\ndef ask_name(prompt, taken):\n    while True:\n        name = trim(input(prompt))\n        if name == \"\":\n            return \"\"\n        letters = True\n        for c in name:\n            if not c in \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\":\n                letters = False\n        if not letters or len(name) > longest_name:\n            print(\"A name is 1 to \" + str(longest_name) + \" letters.\")\n        else:\n            clash = \"\"\n            for t in taken:\n                if lower(t) == lower(name):\n                    clash = t\n            if clash == \"\":\n                return name\n            print(clash + \" is already playing.\")\n\ndef human_turn(r, name, score, target):\n    turn = 0\n    rolls = []\n    while True:\n        answer = lower(trim(input(name + \" (turn \" + str(turn) + \")> \")))\n        if answer == \"r\":\n            d = r.die()\n            rolls = rolls + [d]\n            if d == 1:\n                print(name + \" rolls 1 - the turn is lost.\")\n                return [\"lost\", 0, rolls]\n            turn = turn + d\n            if score + turn >= target:\n                print(name + \" rolls \" + str(d) + \" - turn \" + str(turn) + \", score \" + str(score + turn) + \".\")\n                return [\"won\", turn, rolls]\n            print(name + \" rolls \" + str(d) + \" - turn \" + str(turn) + \".\")\n        elif answer == \"h\":\n            if turn == 0:\n                print(\"Roll at least once before holding.\")\n            else:\n                print(name + \" holds: \" + str(turn) + \", score \" + str(score + turn) + \".\")\n                return [\"held\", turn, rolls]\n        elif answer == \"q\":\n            return [\"stopped\", 0, rolls]\n        else:\n            print(\"Type r to roll, h to hold or q to stop the game.\")\n\ndef computer_turn(r, score, target):\n    rolls = pig.computer_turn(r, score, target)\n    if rolls[len(rolls) - 1] == 1:\n        print(\"Computer rolls \" + pig.listed(rolls) + \" - the turn is lost.\")\n        return [\"lost\", 0, rolls]\n    turn = 0\n    for d in rolls:\n        turn = turn + d\n    if score + turn >= target:\n        print(\"Computer rolls \" + pig.listed(rolls) + \" - turn \" + str(turn) + \", score \" + str(score + turn) + \".\")\n        return [\"won\", turn, rolls]\n    print(\"Computer rolls \" + pig.listed(rolls) + \" and holds: \" + str(turn) + \", score \" + str(score + turn) + \".\")\n    return [\"held\", turn, rolls]\n\ndef play(r, names, computer, target, counts):\n    scores = [0, 0]\n    p = 0\n    print(\"Type r to roll, h to hold, q to stop the game.\")\n    if computer:\n        print(\"The computer holds at 20, or as soon as its turn would win.\")\n    while True:\n        print(names[0] + \" \" + str(scores[0]) + \", \" + names[1] + \" \" + str(scores[1]) + \" - \" + names[p] + \" to play.\")\n        if computer and p == 1:\n            t = computer_turn(r, scores[1], target)\n        else:\n            t = human_turn(r, names[p], scores[p], target)\n        counts = tally.counted(counts, t[2])\n        if t[0] == \"stopped\":\n            print(\"Game stopped.\")\n            return counts\n        scores[p] = scores[p] + t[1]\n        if t[0] == \"won\":\n            print(names[p] + \" wins, \" + str(scores[p]) + \" to \" + str(scores[1 - p]) + \"!\")\n            return counts\n        p = 1 - p\n\ndef new_game(r, computer, target, counts):\n    if computer:\n        a = ask_name(\"your name> \", [\"Computer\"])\n        if a == \"\":\n            print(\"Cancelled.\")\n            return counts\n        return play(r, [a, \"Computer\"], True, target, counts)\n    a = ask_name(\"player 1> \", [])\n    if a == \"\":\n        print(\"Cancelled.\")\n        return counts\n    b = ask_name(\"player 2> \", [a])\n    if b == \"\":\n        print(\"Cancelled.\")\n        return counts\n    return play(r, [a, b], False, target, counts)\n\ntarget = 100\nseed = 2026\nr = rng.Rng(seed)\ncounts = [0, 0, 0, 0, 0, 0]\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"== Pig (first to \" + str(target) + \", seed \" + str(seed) + \") ==\")\n    print(\"1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\")\n    choice = trim(input(\"choice> \"))\n    if choice == \"1\":\n        counts = new_game(r, False, target, counts)\n    elif choice == \"2\":\n        counts = new_game(r, True, target, counts)\n    elif choice == \"3\":\n        answer = trim(input(\"target (10 to 500)> \"))\n        n = number(answer)\n        if answer == \"\":\n            print(\"Cancelled.\")\n        elif n >= 10 and n <= 500:\n            target = n\n            print(\"The first to \" + str(target) + \" wins.\")\n        else:\n            print(\"The target stays \" + str(target) + \": type a number from 10 to 500.\")\n    elif choice == \"4\":\n        answer = trim(input(\"seed> \"))\n        s = number(answer)\n        if answer == \"\":\n            print(\"Cancelled.\")\n        elif s < 0:\n            print(\"A seed is a whole number of up to 9 digits.\")\n        else:\n            seed = s\n            r = rng.Rng(seed)\n            print(\"Seed set to \" + str(seed) + \": the same seed gives the same rolls.\")\n    elif choice == \"5\":\n        tally.show(counts)\n    elif choice == \"6\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 6.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "pig.eml",
      "eml": "# P035 dice game Pig - the computer's play. On a turn a player rolls as\n# often as they like: every roll adds to the turn, a 1 loses the whole turn,\n# and holding banks the turn. The first to the target wins; a turn that\n# reaches the target is banked at once.\n\n20 => hold_at\n\ndef should_hold(turn, score, target):\n    # The computer's fixed strategy: hold at 20, or as soon as the turn wins.\n    # A roll at turn total t loses t one time in six and otherwise adds 4 on\n    # average ((2 + 3 + 4 + 5 + 6) / 5), so it is worth (20 - t) / 6 points\n    # on average: rolling pays while the turn is below 20.\n    return turn >= hold_at or score + turn >= target\n\ndef computer_turn(r, score, target):\n    # The rolls of one turn, in order; the last one is 1 if the turn was lost.\n    [] => rolls\n    0 => turn\n    while True:\n        r.die() => d\n        rolls + [d] => rolls\n        if d == 1:\n            return rolls\n        turn + d => turn\n        if should_hold(turn, score, target):\n            return rolls\n\ndef listed(rolls):\n    # [3, 5, 1] as \"3, 5, 1\".\n    \"\" => out\n    for d in rolls:\n        if out != \"\":\n            out + \", \" => out\n        out + str(d) => out\n    return out\n",
      "python": "hold_at = 20\n\ndef should_hold(turn, score, target):\n    return turn >= hold_at or score + turn >= target\n\ndef computer_turn(r, score, target):\n    rolls = []\n    turn = 0\n    while True:\n        d = r.die()\n        rolls = rolls + [d]\n        if d == 1:\n            return rolls\n        turn = turn + d\n        if should_hold(turn, score, target):\n            return rolls\n\ndef listed(rolls):\n    out = \"\"\n    for d in rolls:\n        if out != \"\":\n            out = out + \", \"\n        out = out + str(d)\n    return out\n"
    },
    {
      "name": "rng.eml",
      "eml": "# P035 dice game Pig - random numbers written in EML: the linear\n# congruential generator of P008 (number guessing), with the constants of\n# the C standard's example rand(). Python's random module is not used, so a\n# seed gives the same rolls on every machine, and the interpreter can check\n# a whole session byte for byte.\n\nclass Rng:\n    def __init__(self, seed):\n        seed % 2147483648 => self.state\n\n    def step(self):\n        (1103515245 * self.state + 12345) % 2147483648 => self.state\n        return self.state\n\n    def below(self, n):\n        # A number from 0 to n - 1, taken from the high bits of the state: the\n        # low bits of this generator repeat with short periods. Dividing by\n        # 65536 is exact in a float for a state below 2^31.\n        return int(self.step() / 65536) % n\n\n    def die(self):\n        return 1 + self.below(6)\n",
      "python": "class Rng:\n    def __init__(self, seed):\n        self.state = seed % 2147483648\n    def step(self):\n        self.state = (1103515245 * self.state + 12345) % 2147483648\n        return self.state\n    def below(self, n):\n        return int(self.step() / 65536) % n\n    def die(self):\n        return 1 + self.below(6)\n"
    },
    {
      "name": "tally.eml",
      "eml": "# P035 dice game Pig - the dice tally: how often each face has come up in\n# this run, as in the corpus case dice-roll-tally, with a bar for each face.\n\ndef quotient(a, b):\n    return int((a - a % b) / b)\n\ndef counted(counts, rolls):\n    # counts is [how many 1s, ..., how many 6s]; returns it with rolls added.\n    [] => out\n    for face in [1:6]:\n        counts[face - 1] => n\n        for d in rolls:\n            if d == face:\n                n + 1 => n\n        out + [n] => out\n    return out\n\ndef show(counts):\n    0 => total\n    for n in counts:\n        total + n => total\n    if total == 0:\n        \"No dice rolled yet.\" ^0\n        return 0\n    if total == 1:\n        \"1 roll so far:\" ^0\n    else:\n        (str(total) + \" rolls so far:\") ^0\n    for face in [1:6]:\n        str(counts[face - 1]) => n\n        while len(n) < 3:\n            \" \" + n => n\n        (\"  \" + str(face) + \":\" + n + \"  \" + \"#\" * counts[face - 1]) => line\n        if counts[face - 1] == 0:\n            (\"  \" + str(face) + \":\" + n) => line\n        line ^0\n    # the most frequent face, the lowest on a tie\n    1 => best\n    for face in [2:6]:\n        if counts[face - 1] > counts[best - 1]:\n            face => best\n    \"times\" => times\n    if counts[best - 1] == 1:\n        \"time\" => times\n    # a fair die gives each face a sixth of the rolls; in tenths, halves up\n    quotient(total * 20 + 6, 12) => tenths\n    (\"Most often: \" + str(best) + \" (\" + str(counts[best - 1]) + \" \" + times + \"). A fair die would give each face \" + str(quotient(tenths, 10)) + \".\" + str(tenths % 10) + \" of them.\") ^0\n    return 0\n",
      "python": "def quotient(a, b):\n    return int((a - a % b) / b)\n\ndef counted(counts, rolls):\n    out = []\n    for face in range(1, 7):\n        n = counts[face - 1]\n        for d in rolls:\n            if d == face:\n                n = n + 1\n        out = out + [n]\n    return out\n\ndef show(counts):\n    total = 0\n    for n in counts:\n        total = total + n\n    if total == 0:\n        print(\"No dice rolled yet.\")\n        return 0\n    if total == 1:\n        print(\"1 roll so far:\")\n    else:\n        print(str(total) + \" rolls so far:\")\n    for face in range(1, 7):\n        n = str(counts[face - 1])\n        while len(n) < 3:\n            n = \" \" + n\n        line = \"  \" + str(face) + \":\" + n + \"  \" + \"#\" * counts[face - 1]\n        if counts[face - 1] == 0:\n            line = \"  \" + str(face) + \":\" + n\n        print(line)\n    best = 1\n    for face in range(2, 7):\n        if counts[face - 1] > counts[best - 1]:\n            best = face\n    times = \"times\"\n    if counts[best - 1] == 1:\n        times = \"time\"\n    tenths = quotient(total * 20 + 6, 12)\n    print(\"Most often: \" + str(best) + \" (\" + str(counts[best - 1]) + \" \" + times + \"). A fair die would give each face \" + str(quotient(tenths, 10)) + \".\" + str(tenths % 10) + \" of them.\")\n    return 0\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n5\n3\n5\n3\n501\n3\nx\n3\n\n4\nx\n4\n1234567890\n4\n\n1\nAl1\nAbcdefghijklm\nAnn\nANN\nBen\nh\nx\nroll\nR\nr\nq\n2\ncomputer\n\n1\nAnn\n\n5\n4\n7\n1\nAnn\nBen\nr\nr\nr\nq\n4\n7\n1\nAnn\nBen\nr\nr\nr\nq\n5\n6\n",
      "screen": "\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 0\nPick a number from 1 to 6.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> x\nPick a number from 1 to 6.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 5\nNo dice rolled yet.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 3\ntarget (10 to 500)> 5\nThe target stays 100: type a number from 10 to 500.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 3\ntarget (10 to 500)> 501\nThe target stays 100: type a number from 10 to 500.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 3\ntarget (10 to 500)> x\nThe target stays 100: type a number from 10 to 500.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 3\ntarget (10 to 500)> \nCancelled.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 4\nseed> x\nA seed is a whole number of up to 9 digits.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 4\nseed> 1234567890\nA seed is a whole number of up to 9 digits.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 4\nseed> \nCancelled.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 1\nplayer 1> Al1\nA name is 1 to 12 letters.\nplayer 1> Abcdefghijklm\nA name is 1 to 12 letters.\nplayer 1> Ann\nplayer 2> ANN\nAnn is already playing.\nplayer 2> Ben\nType r to roll, h to hold, q to stop the game.\nAnn 0, Ben 0 - Ann to play.\nAnn (turn 0)> h\nRoll at least once before holding.\nAnn (turn 0)> x\nType r to roll, h to hold or q to stop the game.\nAnn (turn 0)> roll\nType r to roll, h to hold or q to stop the game.\nAnn (turn 0)> R\nAnn rolls 5 - turn 5.\nAnn (turn 5)> r\nAnn rolls 1 - the turn is lost.\nAnn 0, Ben 0 - Ben to play.\nBen (turn 0)> q\nGame stopped.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 2\nyour name> computer\nComputer is already playing.\nyour name> \nCancelled.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 1\nplayer 1> Ann\nplayer 2> \nCancelled.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 5\n2 rolls so far:\n  1:  1  #\n  2:  0\n  3:  0\n  4:  0\n  5:  1  #\n  6:  0\nMost often: 1 (1 time). A fair die would give each face 0.3 of them.\n\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 4\nseed> 7\nSeed set to 7: the same seed gives the same rolls.\n\n== Pig (first to 100, seed 7) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 1\nplayer 1> Ann\nplayer 2> Ben\nType r to roll, h to hold, q to stop the game.\nAnn 0, Ben 0 - Ann to play.\nAnn (turn 0)> r\nAnn rolls 5 - turn 5.\nAnn (turn 5)> r\nAnn rolls 3 - turn 8.\nAnn (turn 8)> r\nAnn rolls 3 - turn 11.\nAnn (turn 11)> q\nGame stopped.\n\n== Pig (first to 100, seed 7) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 4\nseed> 7\nSeed set to 7: the same seed gives the same rolls.\n\n== Pig (first to 100, seed 7) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 1\nplayer 1> Ann\nplayer 2> Ben\nType r to roll, h to hold, q to stop the game.\nAnn 0, Ben 0 - Ann to play.\nAnn (turn 0)> r\nAnn rolls 5 - turn 5.\nAnn (turn 5)> r\nAnn rolls 3 - turn 8.\nAnn (turn 8)> r\nAnn rolls 3 - turn 11.\nAnn (turn 11)> q\nGame stopped.\n\n== Pig (first to 100, seed 7) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 5\n8 rolls so far:\n  1:  1  #\n  2:  0\n  3:  4  ####\n  4:  0\n  5:  3  ###\n  6:  0\nMost often: 3 (4 times). A fair die would give each face 1.3 of them.\n\n== Pig (first to 100, seed 7) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "3\n40\n1\nAna\nBo\nr\nr\nr\nr\nr\nr\nh\nr\nr\nr\nr\nr\nr\nr\nr\nr\nr\nh\nr\nr\nr\nr\nr\nr\nr\nr\nr\nr\nr\nh\nr\nr\nr\nh\nr\nr\nr\nh\nr\n2\nCy\nr\nr\nr\nr\nr\nr\nr\nr\nh\nr\nr\nr\nh\nr\nr\n5\n6\n",
      "screen": "\n== Pig (first to 100, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 3\ntarget (10 to 500)> 40\nThe first to 40 wins.\n\n== Pig (first to 40, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 1\nplayer 1> Ana\nplayer 2> Bo\nType r to roll, h to hold, q to stop the game.\nAna 0, Bo 0 - Ana to play.\nAna (turn 0)> r\nAna rolls 5 - turn 5.\nAna (turn 5)> r\nAna rolls 1 - the turn is lost.\nAna 0, Bo 0 - Bo to play.\nBo (turn 0)> r\nBo rolls 2 - turn 2.\nBo (turn 2)> r\nBo rolls 3 - turn 5.\nBo (turn 5)> r\nBo rolls 3 - turn 8.\nBo (turn 8)> r\nBo rolls 6 - turn 14.\nBo (turn 14)> h\nBo holds: 14, score 14.\nAna 0, Bo 14 - Ana to play.\nAna (turn 0)> r\nAna rolls 3 - turn 3.\nAna (turn 3)> r\nAna rolls 2 - turn 5.\nAna (turn 5)> r\nAna rolls 4 - turn 9.\nAna (turn 9)> r\nAna rolls 1 - the turn is lost.\nAna 0, Bo 14 - Bo to play.\nBo (turn 0)> r\nBo rolls 1 - the turn is lost.\nAna 0, Bo 14 - Ana to play.\nAna (turn 0)> r\nAna rolls 3 - turn 3.\nAna (turn 3)> r\nAna rolls 1 - the turn is lost.\nAna 0, Bo 14 - Bo to play.\nBo (turn 0)> r\nBo rolls 5 - turn 5.\nBo (turn 5)> r\nBo rolls 4 - turn 9.\nBo (turn 9)> r\nBo rolls 3 - turn 12.\nBo (turn 12)> h\nBo holds: 12, score 26.\nAna 0, Bo 26 - Ana to play.\nAna (turn 0)> r\nAna rolls 3 - turn 3.\nAna (turn 3)> r\nAna rolls 1 - the turn is lost.\nAna 0, Bo 26 - Bo to play.\nBo (turn 0)> r\nBo rolls 3 - turn 3.\nBo (turn 3)> r\nBo rolls 3 - turn 6.\nBo (turn 6)> r\nBo rolls 4 - turn 10.\nBo (turn 10)> r\nBo rolls 1 - the turn is lost.\nAna 0, Bo 26 - Ana to play.\nAna (turn 0)> r\nAna rolls 4 - turn 4.\nAna (turn 4)> r\nAna rolls 4 - turn 8.\nAna (turn 8)> r\nAna rolls 2 - turn 10.\nAna (turn 10)> r\nAna rolls 2 - turn 12.\nAna (turn 12)> r\nAna rolls 4 - turn 16.\nAna (turn 16)> h\nAna holds: 16, score 16.\nAna 16, Bo 26 - Bo to play.\nBo (turn 0)> r\nBo rolls 2 - turn 2.\nBo (turn 2)> r\nBo rolls 6 - turn 8.\nBo (turn 8)> r\nBo rolls 5 - turn 13.\nBo (turn 13)> h\nBo holds: 13, score 39.\nAna 16, Bo 39 - Ana to play.\nAna (turn 0)> r\nAna rolls 5 - turn 5.\nAna (turn 5)> r\nAna rolls 6 - turn 11.\nAna (turn 11)> r\nAna rolls 5 - turn 16.\nAna (turn 16)> h\nAna holds: 16, score 32.\nAna 32, Bo 39 - Bo to play.\nBo (turn 0)> r\nBo rolls 4 - turn 4, score 43.\nBo wins, 43 to 32!\n\n== Pig (first to 40, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 2\nyour name> Cy\nType r to roll, h to hold, q to stop the game.\nThe computer holds at 20, or as soon as its turn would win.\nCy 0, Computer 0 - Cy to play.\nCy (turn 0)> r\nCy rolls 6 - turn 6.\nCy (turn 6)> r\nCy rolls 5 - turn 11.\nCy (turn 11)> r\nCy rolls 1 - the turn is lost.\nCy 0, Computer 0 - Computer to play.\nComputer rolls 3, 2, 4, 5, 2, 5 and holds: 21, score 21.\nCy 0, Computer 21 - Cy to play.\nCy (turn 0)> r\nCy rolls 6 - turn 6.\nCy (turn 6)> r\nCy rolls 1 - the turn is lost.\nCy 0, Computer 21 - Computer to play.\nComputer rolls 1 - the turn is lost.\nCy 0, Computer 21 - Cy to play.\nCy (turn 0)> r\nCy rolls 5 - turn 5.\nCy (turn 5)> r\nCy rolls 6 - turn 11.\nCy (turn 11)> r\nCy rolls 6 - turn 17.\nCy (turn 17)> h\nCy holds: 17, score 17.\nCy 17, Computer 21 - Computer to play.\nComputer rolls 2, 1 - the turn is lost.\nCy 17, Computer 21 - Cy to play.\nCy (turn 0)> r\nCy rolls 4 - turn 4.\nCy (turn 4)> r\nCy rolls 5 - turn 9.\nCy (turn 9)> r\nCy rolls 5 - turn 14.\nCy (turn 14)> h\nCy holds: 14, score 31.\nCy 31, Computer 21 - Computer to play.\nComputer rolls 1 - the turn is lost.\nCy 31, Computer 21 - Cy to play.\nCy (turn 0)> r\nCy rolls 6 - turn 6.\nCy (turn 6)> r\nCy rolls 4 - turn 10, score 41.\nCy wins, 41 to 21!\n\n== Pig (first to 40, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 5\n57 rolls so far:\n  1: 11  ###########\n  2:  8  ########\n  3:  9  #########\n  4: 10  ##########\n  5: 11  ###########\n  6:  8  ########\nMost often: 1 (11 times). A fair die would give each face 9.5 of them.\n\n== Pig (first to 40, seed 2026) ==\n1) two players  2) play the computer  3) target  4) seed  5) dice tally  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "dice-roll-tally",
      "caseId": "018-dice-roll-tally",
      "title": "Case corpus: a self-authored dice roll tally"
    }
  ],
  "updated": "2026-10-10"
}
