Mugwump

Descripción del contenido de la página

Conversión de Mugwump a varios lenguajes de programación.

Etiquetas:

Este programa ha sido convertido a 17 lenguajes de programación.

Original

Origin of mugwump.bas:

Mugwump (by Bud Valenti's students, Bob Albrecht), 1978.

Creative Computing's BASIC Games.

- https://www.atariarchives.org/basicgames/showpage.php?page=114
- http://vintage-basic.net/games.html
- http://vintage-basic.net/bcg/mugwump.bas

1 PRINT TAB(33);"MUGWUMP"
2 PRINT TAB(15);"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
3 PRINT:PRINT:PRINT
4 REM     COURTESY PEOPLE'S COMPUTER COMPANY
10 DIM P(4,2)
20 PRINT "THE OBJECT OF THIS GAME IS TO FIND FOUR MUGWUMPS"
30 PRINT "HIDDEN ON A 10 BY 10 GRID.  HOMEBASE IS POSITION 0,0."
40 PRINT "ANY GUESS YOU MAKE MUST BE TWO NUMBERS WITH EACH"
50 PRINT "NUMBER BETWEEN 0 AND 9, INCLUSIVE.  FIRST NUMBER"
60 PRINT "IS DISTANCE TO RIGHT OF HOMEBASE AND SECOND NUMBER"
70 PRINT "IS DISTANCE ABOVE HOMEBASE."
80 PRINT
90 PRINT "YOU GET 10 TRIES.  AFTER EACH TRY, I WILL TELL"
100 PRINT "YOU HOW FAR YOU ARE FROM EACH MUGWUMP."
110 PRINT
240 GOSUB 1000
250 T=0
260 T=T+1
270 PRINT
275 PRINT
290 PRINT "TURN NO.";T;"-- WHAT IS YOUR GUESS";
300 INPUT M,N
310 FOR I=1 TO 4
320 IF P(I,1)=-1 THEN 400
330 IF P(I,1)<>M THEN 380
340 IF P(I,2)<>N THEN 380
350 P(I,1)=-1
360 PRINT "YOU HAVE FOUND MUGWUMP";I
370 GOTO 400
380 D=SQR((P(I,1)-M)^2+(P(I,2)-N)^2)
390 PRINT "YOU ARE";(INT(D*10))/10;"UNITS FROM MUGWUMP";I
400 NEXT I
410 FOR J=1 TO 4
420 IF P(J,1)<>-1 THEN 470
430 NEXT J
440 PRINT
450 PRINT "YOU GOT THEM ALL IN";T;"TURNS!"
460 GOTO 580
470 IF T<10 THEN 260
480 PRINT
490 PRINT "SORRY, THAT'S 10 TRIES.  HERE IS WHERE THEY'RE HIDING:"
540 FOR I=1 TO 4
550 IF P(I,1)=-1 THEN 570
560 PRINT "MUGWUMP";I;"IS AT (";P(I,1);",";P(I,2);")"
570 NEXT I
580 PRINT
600 PRINT "THAT WAS FUN! LET'S PLAY AGAIN......."
610 PRINT "FOUR MORE MUGWUMPS ARE NOW IN HIDING."
630 GOTO 240
1000 FOR J=1 TO 2
1010 FOR I=1 TO 4
1020 P(I,J)=INT(10*RND(1))
1030 NEXT I
1040 NEXT J
1050 RETURN
1099 END

En Arturo

; Mugwump

; Original version in BASIC:
;   Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA), 1978.
;   Slightly modified by Bob Albrecht of People's Computer Company.
;   Creative Computing's BASIC Games.
;   - https://www.atariarchives.org/basicgames/showpage.php?page=114
;   - http://vintage-basic.net/games.html

; This version in Arturo:
;   Copyright (c) 2023, Marcos Cruz (programandala.net)
;   SPDX-License-Identifier: Fair
;
; Written in 2023-10-19/21
;
; Last modified: 20251205T0047+0100.

; Constants
let 'gridSize 10
let 'firstCoord 0
let 'lastCoord sub gridSize 1
let 'maxTurns 10
let 'mugwumps 4
let 'firstMugwump 0
let 'lastMugwump sub mugwumps 1

; Arrays
let 'mugwumpX array .of: mugwumps 0
let 'mugwumpY array .of: mugwumps 0
let 'mugwumpHidden array .of: mugwumps false

; Variables
let 'found 0 ; counter

; Print the given prompt, wait until the user enters a valid integer
; and return it.
getNumber: function [prompt] [
    until [
        try? [ let 'number to :integer input prompt ]
    ] []
    number
]

; Return `true` if the given string is "yes" or a synonym.
isYes: function [answer] [
    contains? ["ok", "yeah", "yes", "y"] answer
]

; Return `true` if the given string is "no" or a synonym.
isNo: function [answer] [
    contains? ["no", "nope", "n"] answer
]

; Print the given prompt, wait until the user enters a valid yes/no
; string, and return `true` for "yes" or `false` for "no".
yes: function [prompt] [
    until
        [ let 'answer input prompt ]
        [ or?
            isYes answer
            isNo answer
        ]
    isYes answer
]

; Clear the screen, print the credits and ask the user to press enter.
printCredits: function [] [
    clear
    print "Mugwump\n"
    print "Original version in BASIC:"
    print "    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA)."
    print "    Slightly modified by Bob Albrecht of People's Computer Company."
    print "    Published by Creative Computing (Morristown, New Jersey, USA), 1978."
    print "    - https://www.atariarchives.org/basicgames/showpage.php?page=114"
    print "    - http://vintage-basic.net/games.html\n"
    print "This version in Arturo:"
    print "    Copyright (c) 2023, Marcos Cruz (programandala.net)"
    print "    SPDX-License-Identifier: Fair\n"
    input "Press Enter to read the instructions. "
]

; Clear the screen, print the instructions and ask the user to press enter.
printInstructions: function [] [
    clear
    print "Mugwump\n"
    print render "The object of this game is to find |mugwumps| mugwumps"
    print render "hidden on a |gridSize| by |gridSize| grid.  Homebase is position |firstCoord|,|firstCoord|."
    print "Any guess you make must be two numbers with each"
    print render "number between |firstCoord| and |lastCoord|, inclusive.  First number"
    print "is distance to right of homebase and second number"
    print "is distance above homebase.\n"
    print render "You get |maxTurns| tries.  After each try, you will see"
    print "how far you are from each mugwump.\n"
    input "Press Enter to start. "
]

; Init the mugwumps' positions, `hidden` flags and count.
hideMugwumps: function [] [
    loop range firstMugwump lastMugwump 'm [
        mugwumpX\[m]: random firstCoord lastCoord
        mugwumpY\[m]: random firstCoord lastCoord
        mugwumpHidden\[m]: true
    ]
    let 'found 0 ; counter
]

; Print the given prompt, wait until the user enters a valid coord
; and return it.
getCoord: function [prompt] [
    while [ true ] [
        let 'coord getNumber prompt
        if contains? range firstCoord lastCoord coord [ return coord ]
        print render "Invalid value |coord|: not in range [|firstCoord|, |lastCoord|]."
    ]
]

; Return `true` if the given mugwump is hidden in the given coords.
isThere?: function [m x y] [
    and?
        mugwumpHidden\[m]
        and?
            equal? mugwumpX\[m] x
            equal? mugwumpY\[m] y
]

; Return the distance between the given mugwump and the given coords.
distance: function [m x y] [
    to
        :integer
        round
            sqrt
                add
                    pow  sub mugwumpX\[m] x  2
                    pow  sub mugwumpY\[m] y  2
]

; Return the given plural or singular ending depending of the given number.
plural: function [n pluralSuffix singularSuffix] [
    if? greater? n 1 [ pluralSuffix ] else [ singularSuffix ]
]

; Run the game.
play: function [] [
    until [ ; game loop
        clear
        hideMugwumps
        loop range 1 maxTurns 'turn [ ; turns loop
            print render "Turn number |turn|\n"
            print render "What is your guess (in range [|firstCoord|, |lastCoord|])?"
            let 'x getCoord "Distance right of homebase (x-axis): "
            let 'y getCoord "Distance above homebase (y-axis): "
            print render "\nYour guess is (|x|, |y|)."
            loop range firstMugwump lastMugwump 'm [
                if isThere? m x y [
                    mugwumpHidden\[m]: false
                    inc 'found
                    print render "You have found mugwump |add m 1|!"
                    if equal? found mugwumps [ break ]
                ]
            ]
            if equal? found mugwumps [ break ] ; exit the turns loop
            loop range firstMugwump lastMugwump 'm [
                if mugwumpHidden\[m] [
                    print render "You are |distance m y y| units from mugwump |add m 1|."
                ]
            ]
            print ""
        ] ; turns loop
        if? equal? found mugwumps [
            print render "\nYou got them all in |turn| turn|plural turn {s} {}|!\n"
            print "That was fun! let's play again…"
            print render "|mugwumps| more mugwumps are now in hiding."
        ] else [
            print render "\nSorry, that's |maxTurns| tr|plural maxTurns {ies} {y}|.\n"
            print "Here is where they're hiding:"
            loop range firstMugwump lastMugwump 'm [
                if mugwumpHidden\[m] [
                    print render "Mugwump |add m 1| is at (|mugwumpX\[m]|, |mugwumpY\[m]|)."
                ]
            ]
        ]
        print ""
    ] [ not? yes "Do you want to play again? " ] ; game loop
]

printCredits
printInstructions
play

En C#

// Mugwump

// Original version in BASIC:
//  Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
//  Slightly modified by Bob Albrecht of People's Computer Company.
//  Published by Creative Computing (Morristown, New Jersey, USA), 1978.
//  - https://www.atariarchives.org/basicgames/showpage.php?page=114
//  - http://vintage-basic.net/games.html
//  - http://vintage-basic.net/bcg/mugwump.bas

// This version in C#:
//  Copyright (c) 2024, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written on 2024-12-25.
//
// Last modified: 20251205T1542+0100.

using System;
using System.Linq;

class MugwumpGame
{
    const int GRID_SIZE = 10;
    const int TURNS = 10;
    const int MUGWUMPS = 4;

    class Mugwump
    {
        internal int x = 0;
        internal int y = 0;
        internal bool hidden = false;
    }

    static Mugwump[] mugwump = new Mugwump[MUGWUMPS];
    static int found; // counter

    static string GetString(string prompt)
    {
        Console.Write(prompt);
        return Console.ReadLine();
    }

    // Print the given prompt, wait until the user enters a valid integer and
    // return it.
    //
    static int GetNumber(string prompt)
    {
        int n = 0;

        while (true)
        {
            try
            {
                n = Int32.Parse(GetString(prompt));
                break;
            }
            catch
            {
            }
        }

        return n;
    }

    // Return `true` if the given string is "yes" or a synonym.
    //
    static bool IsYes(string s)
    {
        string[] validOptions = {"ok", "y", "yeah", "yes"};
        return validOptions.Contains(s.ToLower());
    }

    // Return `true` if the given string is "no" or a synonym.
    //
    static bool IsNo(string s)
    {
        string[] validOptions = {"n", "no", "nope"};
        return validOptions.Contains(s.ToLower());
    }

    // Print the given prompt, wait until the user enters a valid yes/no string,
    // and return `true` for "yes" or `false` for "no".
    //
    static bool Yes(string prompt)
    {
        while (true)
        {
            string answer = GetString(prompt);
            if (IsYes(answer))
            {
                return true;
            }
            if (IsNo(answer))
            {
                return false;
            }
        }
    }

    // Clear the screen, print the credits and ask the user to press enter.
    //
    static void PrintCredits()
    {
        Console.Clear();
        Console.WriteLine("Mugwump\n");
        Console.WriteLine("Original version in BASIC:");
        Console.WriteLine("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).");
        Console.WriteLine("    Slightly modified by Bob Albrecht of People's Computer Company.");
        Console.WriteLine("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.");
        Console.WriteLine("    - https://www.atariarchives.org/basicgames/showpage.php?page=114");
        Console.WriteLine("    - http://vintage-basic.net/games.html\n");
        Console.WriteLine("This version in C#:");
        Console.WriteLine("    Copyright (c) 2024, Marcos Cruz (programandala.net)");
        Console.WriteLine("    SPDX-License-Identifier: Fair\n");
        GetString("Press Enter to read the instructions. ");
    }

    // Clear the screen, print the instructions and ask the user to press enter.
    //
    static void PrintInstructions()
    {
        Console.Clear();
        Console.WriteLine("Mugwump\n");
        Console.WriteLine("The object of this game is to find four mugwumps");
        Console.WriteLine("hidden on a 10 by 10 grid.  Homebase is position 0,0.");
        Console.WriteLine("Any guess you make must be two numbers with each");
        Console.WriteLine("number between 0 and 9, inclusive.  First number");
        Console.WriteLine("is distance to right of homebase and second number");
        Console.WriteLine("is distance above homebase.\n");
        Console.WriteLine($"You get {TURNS} tries.  After each try, you will see");
        Console.WriteLine("how far you are from each mugwump.\n");
        GetString("Press Enter to start. ");
    }

    static void InitMugwumps()
    {
        for (int m = 0; m < MUGWUMPS; m++)
        {
            mugwump[m] = new Mugwump();
        }
    }

    // Init the mugwumps' positions, `hidden` flags and count.
    //
    static void HideMugwumps()
    {
        Random rand = new Random();

        for (int m = 0; m < MUGWUMPS; m++)
        {
            mugwump[m].x = rand.Next(GRID_SIZE);
            mugwump[m].y = rand.Next(GRID_SIZE);
            mugwump[m].hidden = true;
        }
        found = 0; // counter
    }

    // Print the given prompt, wait until the user enters a valid coord and return
    // it.
    //
    static int GetCoord(string prompt)
    {
        int coord = 0;
        while (true)
        {
            coord = GetNumber(prompt);
            if (coord < 0 || coord >= GRID_SIZE)
            {
                Console.WriteLine($"Invalid value {coord}: not in range [0, {GRID_SIZE - 1}].");
            }
            else
            {
                break;
            }
        }
        return coord;
    }

    // Return `true` if the given mugwump is hidden in the given coords.
    //
    static bool IsHere(int m, int x, int y)
    {
        return mugwump[m].hidden && mugwump[m].x == x && mugwump[m].y == y;
    }

    // Return the distance between the given mugwump and the given coords.
    //
    static int Distance(int m, int x, int y)
    {
        return (int) Math.Sqrt
            (
                Math.Pow((double) (mugwump[m].x - x), 2) +
                Math.Pow((double) (mugwump[m].y - y), 2)
            );
    }

    static string Plural(int n, string plural = "s", string singular = "")
    {
        return n > 1 ? plural : singular;
    }

    // Run the game.
    //
    static void Play()
    {
        int turn = 1; // counter
        InitMugwumps();
        while (true) {; // game
            Console.Clear();
            HideMugwumps();
            while (turn <= TURNS)
            {
                Console.WriteLine($"Turn number {turn}\n");
                Console.WriteLine($"What is your guess (in range [0, {GRID_SIZE - 1}])?");
                int x = GetCoord("Distance right of homebase (x-axis): ");
                int y = GetCoord("Distance above homebase (y-axis): ");
                Console.WriteLine($"\nYour guess is ({x}, {y}).");
                for (int m = 0; m < MUGWUMPS; m++)
                {
                    if (IsHere(m, x, y))
                    {
                        mugwump[m].hidden = false;
                        found++;
                        Console.WriteLine($"You have found mugwump {m}!");
                        if (found == MUGWUMPS)
                        {
                            goto endTurns;
                        }
                    }
                }
                for (int m = 0; m < MUGWUMPS; m++)
                {
                    if (mugwump[m].hidden)
                    {
                        Console.WriteLine($"You are {Distance(m, x, y)} units from mugwump {m}.");
                    }
                }
                Console.WriteLine();
                turn++;
            }; // turns
            endTurns:
            if (found == MUGWUMPS)
            {
                Console.WriteLine($"\nYou got them all in {turn} turn{Plural(turn)}!\n");
                Console.WriteLine("That was fun! let's play again…");
                Console.WriteLine("Four more mugwumps are now in hiding.");
            }
            else
            {
                Console.WriteLine($"\nSorry, that's {TURNS} tr{Plural(TURNS, "ies", "y")}.\n");
                Console.WriteLine("Here is where they're hiding:");
                for (int m = 0; m < MUGWUMPS; m++)
                {
                    if (mugwump[m].hidden)
                    {
                        Console.WriteLine($"Mugwump {m} is at ({mugwump[m].x}, {mugwump[m].y}).");
                    }
                }
            }
            Console.WriteLine();
            if (!Yes("Do you want to play again? "))
            {
                break;
            }
        }; // game
    }

    static void Main()
    {
        PrintCredits();
        PrintInstructions();
        Play();
    }
}

En Chapel

// Mugwump

// Original version in BASIC:
//     Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
//     Slightly modified by Bob Albrecht of People's Computer Company.
//     Published by Creative Computing (Morristown, New Jersey, USA), 1978.
//     - https://www.atariarchives.org/basicgames/showpage.php?page=114
//     - http://vintage-basic.net/games.html

// This version in Chapel:
//     Copyright (c) 2025, Marcos Cruz (programandala.net)
//     SPDX-License-Identifier: Fair
//
// Written on 2025-04-07.
//
// Last modified: 20250731T1954+0200.

// Modules {{{1
// =============================================================

import IO;
import Math;
import Random;

// Terminal {{{1
// =============================================================================

const NORMAL_STYLE = 0;

proc moveCursorHome() {
    write("\x1B[H");
}

proc setStyle(style: int) {
    writef("\x1B[%im", style);
}

proc resetAttributes() {
    setStyle(NORMAL_STYLE);
}

proc eraseScreen() {
    write("\x1B[2J");
}

proc clearScreen() {
    eraseScreen();
    resetAttributes();
    moveCursorHome();
}

// Data {{{1
// =============================================================================

const GRID_SIZE = 10;
const TURNS = 10;
const MUGWUMPS = 4;

record Mugwump {
    var x: int;
    var y: int;
    var hidden: bool;
}

var mugwump: [0 ..< MUGWUMPS] Mugwump;
var found: int = 0; // counter

// User input {{{1
// =============================================================================

proc acceptString(prompt: string): string {
    write(prompt);
    IO.stdout.flush();
    return IO.readLine().strip();
}

proc acceptValidInteger(prompt: string): int {
    var result: int;
    while true {
        var s: string = acceptString(prompt);
        try {
            result = (s): int;
            break;
        }
        catch exc {
            writeln("Integer expected.");
        }
    }
    return result;
}

proc isYes(s: string): bool {
    select s.toLower() {
        when "ok", "y", "yeah", "yes" do return true;
        otherwise do return false;
    }
}

proc isNo(s: string): bool {
    select s.toLower() {
        when "n", "no", "nope" do return true;
        otherwise do return false;
    }
}

// Print the given prompt, wait until the user enters a valid yes/no string;
// and return `true` for "yes" or `false` for "no".
//
proc yes(prompt: string): bool {
    var result: bool;
    while true {
        var answer: string = acceptString(prompt);
        if isYes(answer) {
            result = true;
            break;
        }
        if isNo(answer) {
            result = false;
            break;
        }
    }
    return result;
}

// Credits and instructions {{{1
// =============================================================================

// Clear the screen, print the credits and ask the user to press enter.
//
proc printCredits() {
    clearScreen();
    writeln("Mugwump\n");
    writeln("Original version in BASIC:");
    writeln("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).");
    writeln("    Slightly modified by Bob Albrecht of People's Computer Company.");
    writeln("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.");
    writeln("    - https://www.atariarchives.org/basicgames/showpage.php?page=114");
    writeln("    - http://vintage-basic.net/games.html\n");
    writeln("This version in Chapel:");
    writeln("    Copyright (c) 2025, Marcos Cruz (programandala.net)");
    writeln("    SPDX-License-Identifier: Fair\n");
    acceptString("Press Enter to read the instructions. ");
}

// Clear the screen, print the instructions and ask the user to press enter.
//
proc printInstructions() {
    clearScreen();
    writeln("Mugwump\n");
    writeln("The object of this game is to find four mugwumps");
    writeln("hidden on a 10 by 10 grid.  Homebase is position 0,0.");
    writeln("Any guess you make must be two numbers with each");
    writeln("number between 0 and 9, inclusive.  First number");
    writeln("is distance to right of homebase and second number");
    writeln("is distance above homebase.\n");
    writef("You get %i tries.  After each try, you will see\n", TURNS);
    writeln("how far you are from each mugwump.\n");
    acceptString("Press Enter to start. ");
}

// Game {{{1
// =============================================================================

proc hideMugwumps() {
    var rsInt = new Random.randomStream(int);
    for m in 0 ..< MUGWUMPS {
        mugwump[m].x = rsInt.next(0, GRID_SIZE - 1);
        mugwump[m].y = rsInt.next(0, GRID_SIZE - 1);
        mugwump[m].hidden = true;
    }
    found = 0; // counter
}

// Print the given prompt, wait until the user enters a valid coord and return
// it.
//
proc getCoord(prompt: string): int {
    var coord: int = 0;
    while true {
        coord = acceptValidInteger(prompt);
        if coord < 0 || coord >= GRID_SIZE {
            writef("Invalid value %i: not in range [0, %i].\n", coord, GRID_SIZE - 1);
        } else {
            break;
        }
    }
    return coord;
}

// Return `true` if the given mugwump is hidden in the given coords.
//
proc isHere(m: int, x: int, y: int): bool {
    return mugwump[m].hidden && mugwump[m].x == x && mugwump[m].y == y;
}

// Return the distance between the given mugwump and the given coords.
//
proc distance(m: int, x: int, y: int): int {
    return sqrt(
        (mugwump[m].x - x) ** 2.0 +
        (mugwump[m].y - y) ** 2.0): int;
}

// Return a plural suffix (default: "s") if the given number is greater than 1
// otherwise return a singular suffix (default: an empty string).
//
proc plural(n: int, pluralSuffix: string = "s", singularSuffix: string = ""): string {
    return if n > 1 then pluralSuffix else singularSuffix;
}

// Run the game.
//
proc play() {

    var x: int = 0;
    var y: int = 0;

    while true { // game

        clearScreen();
        hideMugwumps();

        var turn: int = 1;

        label turnsLoop while turn <= TURNS {
            writef("Turn number %i\n\n", turn);
            writef("What is your guess (in range [0, %i])?\n", GRID_SIZE - 1);
            x = getCoord("Distance right of homebase (x-axis): ");
            y = getCoord("Distance above homebase (y-axis): ");
            writef("\nYour guess is (%i, %i).\n", x, y);

            for m in 0 ..< MUGWUMPS {
                if isHere(m, x, y) {
                    mugwump[m].hidden = false;
                    found += 1;
                    writef("You have found mugwump %i!\n", m);
                    if found == MUGWUMPS {
                        break turnsLoop;
                    }
                }
            }

            for m in 0 ..< MUGWUMPS {
                if mugwump[m].hidden {
                    writef("You are %i units from mugwump %i.\n", distance(m, x, y) , m);
                }
            }
            writeln("");
            turn += 1;
        } // turns

        if found == MUGWUMPS {
            writef("\nYou got them all in %i turn%s!\n\n", turn, plural(turn));
            writeln("That was fun! let's play again…");
            writeln("Four more mugwumps are now in hiding.");
        } else {
            writef("\nSorry, that's %i tr%s.\n\n", TURNS, plural(TURNS, "ies", "y"));
            writeln("Here is where they're hiding:");
            for m in 0 ..< MUGWUMPS {
                if mugwump[m].hidden {
                    writef("Mugwump %i is at (%i, %i).\n", m, mugwump[m].x, mugwump[m].y);
                }
            }
        }

        if !yes("\nDo you want to play again? ") {
            break;
        }
    } // game
}

// Main {{{1
// =============================================================================

proc initData() {
    // Build the `mugwump` array.
    for i in 0 ..< MUGWUMPS {
        mugwump[i] = new Mugwump();
    }
}

proc main() {
    printCredits();
    printInstructions();
    initData();
    play();
}

En Crystal

# Mugwump

# Original version in BASIC:
#   Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
#   Slightly modified by Bob Albrecht of People's Computer Company.
#   Published by Creative Computing (Morristown, New Jersey, USA), 1978.
#   - https://www.atariarchives.org/basicgames/showpage.php?page=114
#   - http://vintage-basic.net/games.html

# This version in Crystal:
#   Copyright (c) 2023, Marcos Cruz (programandala.net)
#   SPDX-License-Identifier: Fair
#
# Written in 2023-09, 2023-10, 2023-11.
#
# Last modified: 20231104T0057+0100.

GRID_SIZE = 10
TURNS     = 10
MUGWUMPS  =  4

class Mugwump
  property hidden : Bool
  property x : Int32
  property y : Int32

  def initialize
    @hidden = true
    @x = rand(GRID_SIZE)
    @y = rand(GRID_SIZE)
  end

  def init
    initialize
  end

  def reveal
    @hidden = false
  end
end

# Moves the cursor to the top left position of the terminal.
def home
  print "\e[H"
end

# Clears the terminal and moves the cursor to the top left position.
def clear
  print "\e[2J"
  home
end

# Prints the given prompt, waits until the user enters a valid integer and
# returns it.
def get_number(prompt : String) : Int
  while true
    print prompt
    begin
      n = gets.not_nil!.to_i
      break
    rescue
      puts "Invalid number."
    end
  end
  n
end

# Prompts the user to enter a command and returns it.
def command(prompt = "> ") : String
  s = nil
  while s.is_a?(Nil)
    print prompt
    s = gets
  end
  s
end

# Prints the given prompt and waits until the user enters an empty string.
def press_enter(prompt : String)
  until command(prompt) == ""
  end
end

# Returns `true` if the given string is "yes" or a synonym.
def is_yes?(answer : String) : Bool
  ["ok", "yeah", "yes", "y"].any? { |yes| answer.downcase == yes }
end

# Returns `true` if the given string is "no" or a synonym.
def is_no?(answer : String) : Bool
  ["no", "nope", "n"].any? { |no| answer.downcase == no }
end

# Prints the given prompt, waits until the user enters a valid yes/no
# string, and returns `true` for "yes" or `false` for "no".
def yes?(prompt : String) : Bool
  answer = ""
  while !(is_yes?(answer) || is_no?(answer))
    answer = command(prompt)
  end
  is_yes?(answer)
end

# Clears the screen, prints the credits and asks the user to press enter.
def print_credits
  clear
  puts "Mugwump\n"
  puts "Original version in BASIC:"
  puts "    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA)."
  puts "    Slightly modified by Bob Albrecht of People's Computer Company."
  puts "    Published by Creative Computing (Morristown, New Jersey, USA), 1978."
  puts "    - https://www.atariarchives.org/basicgames/showpage.php?page=114"
  puts "    - http://vintage-basic.net/games.html\n"
  puts "This version in Crystal:"
  puts "    Copyright (c) 2023, Marcos Cruz (programandala.net)"
  puts "    SPDX-License-Identifier: Fair\n"
  press_enter("Press Enter to read the instructions. ")
end

# Clears the screen, prints the instructions and asks the user to press enter.
def print_instructions
  clear
  puts "Mugwump\n"
  puts "The object of this game is to find four mugwumps"
  puts "hidden on a 10 by 10 grid.  Homebase is position 0,0."
  puts "Any guess you make must be two numbers with each"
  puts "number between 0 and 9, inclusive.  First number"
  puts "is distance to right of homebase and second number"
  puts "is distance above homebase.\n"
  puts "You get #{TURNS} tries.  After each try, you will see"
  puts "how far you are from each mugwump.\n"
  press_enter("Press Enter to start. ")
end

# Prints the given prompt, then waits until the user enters a valid coord and
# returns it.
def get_coord(prompt : String) : Int
  while true
    coord = get_number(prompt)
    if coord < 0 || coord >= GRID_SIZE
      puts "Invalid value #{coord}: not in range [0, #{GRID_SIZE - 1}]."
    else
      break
    end
  end
  coord
end

# Returns `true` if the given mugwump is hidden in the given coords.
def is_here?(m : Mugwump, x : Int, y : Int) : Bool
  m.hidden && m.x == x && m.y == y
end

# Returns the distance between the given mugwump and the given coords.
def distance(m : Mugwump, x : Int, y : Int) : Int
  Math.sqrt((m.x - x) ** 2 + (m.y - y) ** 2).to_i
end

# If the given number is greater than 1, this method returns a plural ending
# (default: "s"); otherwise it returns a singular ending (default: an empty
# string).
def plural(n : Int, plural = "s", singular = "") : String
  n > 1 ? plural : singular
end

# Prints the mugwumps found in the given coordinates and returns the count.
def found(mugwump : Array(Mugwump), x, y) : Int
  found = 0
  (0...MUGWUMPS).each do |m|
    if is_here?(mugwump[m], x, y)
      mugwump[m].reveal
      found += 1
      puts "You have found mugwump #{m}!"
    end
  end
  found
end

# Runs the game.
def play
  found : Int32 # counter
  turn : Int32  # counter
  mugwump = [] of Mugwump
  (0...MUGWUMPS).each do |m|
    mugwump << Mugwump.new
  end
  while true # game
    clear
    (0...MUGWUMPS).each do |m|
      mugwump[m].init
    end
    found = 0
    turn = 1
    while turn < TURNS
      puts "Turn number #{turn}\n"
      puts "What is your guess (in range [0, #{GRID_SIZE - 1}])?"
      x = get_coord("Distance right of homebase (x-axis): ")
      y = get_coord("Distance above homebase (y-axis): ")
      puts "\nYour guess is (#{x}, #{y})."
      found += found(mugwump, x, y)
      if found == MUGWUMPS
        break # turns
      else
        (0...MUGWUMPS).each do |m|
          if mugwump[m].hidden
            puts "You are #{distance(mugwump[m], x, y)} units from mugwump #{m}."
          end
        end
        puts
      end
      turn += 1
    end # turns
    if found == MUGWUMPS
      puts "\nYou got them all in #{turn} turn#{plural(turn)}!\n"
      puts "That was fun! let's play again…"
      puts "Four more mugwumps are now in hiding."
    else
      puts "\nSorry, that's #{TURNS} tr#{plural(TURNS, "ies", "y")}.\n"
      puts "Here is where they're hiding:"
      (0...MUGWUMPS).each do |m|
        if mugwump[m].hidden
          puts "Mugwump #{m} is at (#{mugwump[m].x}, #{mugwump[m].y})."
        end
      end
    end
    puts
    if !yes?("Do you want to play again? ")
      break # game
    end
  end # game
end

print_credits
print_instructions
play

En D

// Mugwump

// Original version in BASIC:
//     Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
//     Slightly modified by Bob Albrecht of People's Computer Company.
//     Published by Creative Computing (Morristown, New Jersey, USA), 1978.
//     - https://www.atariarchives.org/basicgames/showpage.php?page=114
//     - http://vintage-basic.net/games.html

// This version in D:
//     Copyright (c) 2025, Marcos Cruz (programandala.net)
//     SPDX-License-Identifier: Fair
//
// Written on 2025-03-24.
//
// Last modified: 20251220T0620+0100.

module mugwump;

// Terminal {{{1
// =============================================================================

enum NORMAL_STYLE = 0;

void moveCursorHome()
{
    import std.stdio : write;

    write("\x1B[H");
}

void setStyle(int style)
{
    import std.stdio : writef;

    writef("\x1B[%dm", style);
}

void resetAttributes()
{
    setStyle(NORMAL_STYLE);
}

void eraseScreen()
{
    import std.stdio : write;

    write("\x1B[2J");
}

void clearScreen()
{
    eraseScreen();
    resetAttributes();
    moveCursorHome();
}

// Data {{{1
// =============================================================================

enum GRID_SIZE = 10;
enum TURNS = 10;
enum MUGWUMPS = 4;

class Mugwump
{
    int x;
    int y;
    bool hidden;
}

Mugwump[MUGWUMPS] mugwump;

int found = 0; // counter

// User input {{{1
// =============================================================================

string acceptString(string prompt)
{
    import std.stdio : readln;
    import std.stdio : write;
    import std.string : strip;

    write(prompt);
    return strip(readln());
}

int acceptValidInteger(string prompt)
{
    import std.conv : to;
    import std.stdio : writeln;

    int result;
    while (true)
    {
        string s = acceptString(prompt);
        try
        {
            result = to!int(s);
            break;
        }
        catch (Exception exc)
        {
            writeln("Integer expected.");
        }
    }
    return result;
}

bool isYes(string s)
{
    import std.uni : toLower;

    switch (toLower(s))
    {
        case "ok":
        case "y":
        case "yeah":
        case "yes":
            return true;
        default:
            return false;
    }
}

bool isNo(string s)
{
    import std.uni : toLower;

    switch (toLower(s))
    {
        case "n":
        case "no":
        case "nope":
            return true;
        default:
            return false;
    }
}

/// Print the given prompt, wait until the user enters a valid yes/no string;
/// and return `true` for "yes" or `false` for "no".

bool yes(string prompt)
{
    while (true)
    {
        string answer = acceptString(prompt);
        if (isYes(answer))
        {
            return true;
        }
        if (isNo(answer))
        {
            return false;
        }
    }
}

// Credits and instructions {{{1
// =============================================================================

/// Clear the screen, print the credits and ask the user to press enter.

void printCredits()
{
    import std.stdio : writeln;

    clearScreen();
    writeln("Mugwump\n");
    writeln("Original version in BASIC:");
    writeln("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).");
    writeln("    Slightly modified by Bob Albrecht of People's Computer Company.");
    writeln("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.");
    writeln("    - https://www.atariarchives.org/basicgames/showpage.php?page=114");
    writeln("    - http://vintage-basic.net/games.html\n");
    writeln("This version in D:");
    writeln("    Copyright (c) 2025, Marcos Cruz (programandala.net)");
    writeln("    SPDX-License-Identifier: Fair\n");
    acceptString("Press Enter to read the instructions. ");
}

/// Clear the screen, print the instructions and ask the user to press enter.

void printInstructions()
{
    import std.stdio : writefln;
    import std.stdio : writeln;

    clearScreen();
    writeln("Mugwump\n");
    writeln("The object of this game is to find four mugwumps");
    writeln("hidden on a 10 by 10 grid.  Homebase is position 0,0.");
    writeln("Any guess you make must be two numbers with each");
    writeln("number between 0 and 9, inclusive.  First number");
    writeln("is distance to right of homebase and second number");
    writeln("is distance above homebase.\n");
    writefln("You get %d tries.  After each try, you will see", TURNS);
    writeln("how far you are from each mugwump.\n");
    acceptString("Press Enter to start. ");
}

// Game {{{1
// =============================================================================

void hideMugwumps()
{
    import std.random : uniform;

    foreach (int m; 0 .. MUGWUMPS)
    {
        mugwump[m].x = uniform(0, GRID_SIZE);
        mugwump[m].y = uniform(0, GRID_SIZE);
        mugwump[m].hidden = true;
    }
    found = 0; // counter
}

/// Print the given prompt, wait until the user enters a valid coord and return
/// it.

int getCoord(string prompt)
{
    import std.stdio : writefln;

    int coord = 0;
    while (true)
    {
        coord = acceptValidInteger(prompt);
        if (coord < 0 || coord >= GRID_SIZE)
        {
            writefln("Invalid value %d: not in range [0, %d].", coord, GRID_SIZE - 1);
        }
        else
        {
            break;
        }
    }
    return coord;
}

// Return `true` if the given mugwump is hidden in the given coords.

bool isHere(int m, int x, int y)
{
    return mugwump[m].hidden && mugwump[m].x == x && mugwump[m].y == y;
}

/// Return the distance between the given mugwump and the given coords.

int distance(int m, int x, int y)
{
    import std.math : pow;
    import std.math : sqrt;

    return cast(int)sqrt(
        pow((mugwump[m].x - x), 2.0) +
        pow((mugwump[m].y - y), 2.0));
}

/// Return a plural suffix (default: "s") if the given number is greater than 1
/// otherwise return a singular suffix (default: an empty string).

string plural(int n, string pluralSuffix = "s", string singularSuffix = "")
{
    return n > 1 ? pluralSuffix : singularSuffix;
}

/// Run the game.

void play()
{
    import std.stdio : writefln;
    import std.stdio : writeln;

    int x = 0;
    int y = 0;
    int turn = 0; // counter

    while (true) { // game

        clearScreen();
        hideMugwumps();

        turnsLoop: for (turn = 1; turn <= TURNS; turn += 1)
        {
            writefln("Turn number %d\n", turn);
            writefln("What is your guess (in range [0, %d])?", GRID_SIZE - 1);
            x = getCoord("Distance right of homebase (x-axis): ");
            y = getCoord("Distance above homebase (y-axis): ");
            writefln("\nYour guess is (%d, %d).", x, y);

            foreach (int m; 0 .. MUGWUMPS)
            {
                if (isHere(m, x, y))
                {
                    mugwump[m].hidden = false;
                    found += 1;
                    writefln("You have found mugwump %d!", m);
                    if (found == MUGWUMPS)
                    {
                        break turnsLoop;
                    }
                }
            }

            foreach (int m; 0 .. MUGWUMPS)
            {
                if (mugwump[m].hidden)
                {
                    writefln("You are %d units from mugwump %d.", distance(m, x, y) , m);
                }
            }
            writeln();
        } // turns

        if (found == MUGWUMPS)
        {
            writefln("\nYou got them all in %d turn%s!\n", turn, plural(turn));
            writeln("That was fun! let's play again…");
            writeln("Four more mugwumps are now in hiding.");
        }
        else
        {
            writefln("\nSorry, that's %d tr%s.\n", TURNS, plural(TURNS, "ies", "y"));
            writeln("Here is where they're hiding:");
            foreach (int m; 0 .. MUGWUMPS)
            {
                if (mugwump[m].hidden)
                {
                    writefln("Mugwump %d is at (%d, %d).", m, mugwump[m].x, mugwump[m].y);
                }
            }
        }

        if (!yes("\nDo you want to play again? "))
        {
            break;
        }
    } // game
}

// Main {{{1
// =============================================================================

void init()
{
    // Build the `mugwump` array.
    foreach (int i; 0 .. MUGWUMPS)
    {
        mugwump[i] = new Mugwump();
    }
}

void main()
{
    printCredits();
    printInstructions();
    init();
    play();
}

En Go

/*
Mugwump

Original version in BASIC:
    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
    Slightly modified by Bob Albrecht of People's Computer Company.
    Published by Creative Computing (Morristown, New Jersey, USA), 1978.
    - https://www.atariarchives.org/basicgames/showpage.php?page=114
    - http://vintage-basic.net/games.html

This version in Go:
    Copyright (c) 2025, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2025-01-08.

Last modified: 20250108T1558+0100.
*/

package main

import "fmt"
import "math"
import "math/rand"
import "strconv"
import "strings"

// Console {{{1
// =============================================================

const blackColor = 0
const redColor = 1
const greenColor = 2
const yellowColor = 3
const blueColor = 4
const magentaColor = 5
const cyanColor = 6
const whiteColor = 7
const defaultColor = 9

const normalAttributes = 0

const foreground = +30
const background = +40
const bright = +60

func clearScreen() {
    fmt.Print("\x1B[0;0H\x1B[2J")
}

func moveCursorHome() {
    fmt.Print("\x1B[H")
}

func hideCursor() {
    fmt.Print("\x1B[?25l")
}

func showCursor() {
    fmt.Print("\x1B[?25h")
}

func setColor(color int) {
    fmt.Printf("\x1B[%vm", color)
}

// Global variables and constants {{{1
// =============================================================

const defaultInk = foreground + whiteColor
const inputInk = foreground + bright + greenColor
const instructionsInk = foreground + yellowColor
const titleInk = foreground + bright + redColor

const gridSize int = 10
const turns int = 10
const mugwumps int = 4

type Mugwump struct {
    x      int
    y      int
    hidden bool
}

var mugwump [mugwumps]Mugwump

var found int // counter

// User input {{{1
// =============================================================

// Print the given prompt and wait until the user enters a string.
func getString(prompt string) string {

    setColor(inputInk)
    defer setColor(defaultInk)
    fmt.Print(prompt)
    var s = ""
    fmt.Scanf("%s", &s)
    return s

}

// Print the given prompt and wait until the user enters an integer.
func getNumber(prompt string) int {

    var number int64
    var err error
    setColor(inputInk)
    defer setColor(defaultInk)
    for {
        number, err = strconv.ParseInt(getString(prompt), 10, 0)
        if err == nil {
            break
        } else {
            fmt.Println("Integer expected.")
        }
    }
    return int(number)

}

// Print the given prompt and wait until the user presses Enter.
func pressEnter(prompt string) {

    getString(prompt)

}

// Return `true` if the given string is "yes" or a synonym.
func isYes(s string) bool {

    switch strings.ToLower(strings.TrimSpace(s)) {
    case "ok", "yeah", "yes", "y":
        return true
    default:
        return false
    }

}

// Return `true` if the given string is "no" or a synonym.
func isNo(s string) bool {

    switch strings.ToLower(strings.TrimSpace(s)) {
    case "n", "no", "nope":
        return true
    default:
        return false
    }

}

// Print the given prompt, wait until the user enters a valid yes/no string,
// and return `true` for "yes" or `false` for "no".
func yes(prompt string) bool {

    for {
        var answer = getString(prompt)
        if isYes(answer) {
            return true
        }
        if isNo(answer) {
            return false
        }
    }

}

// Title, instructions and credits {{{1
// =============================================================

func printTitle() {

    setColor(titleInk)
    defer setColor(defaultInk)
    fmt.Println("Mugwump\n")

}

// Clear the screen, print the credits and ask the user to press enter.
func printCredits() {

    clearScreen()
    printTitle()
    setColor(instructionsInk)
    defer setColor(defaultInk)
    fmt.Println("Original version in BASIC:")
    fmt.Println("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
    fmt.Println("    Slightly modified by Bob Albrecht of People's Computer Company.")
    fmt.Println("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")
    fmt.Println("    - https://www.atariarchives.org/basicgames/showpage.php?page=114")
    fmt.Println("    - http://vintage-basic.net/games.html\n")
    fmt.Println("This version in Go:")
    fmt.Println("    Copyright (c) 2025, Marcos Cruz (programandala.net)")
    fmt.Println("    SPDX-License-Identifier: Fair\n")
    pressEnter("Press Enter to read the instructions. ")

}

// Clear the screen, print the instructions and ask the user to press enter.
func printInstructions() {

    clearScreen()
    printTitle()
    setColor(instructionsInk)
    defer setColor(defaultInk)
    fmt.Println("The object of this game is to find four mugwumps")
    fmt.Println("hidden on a 10 by 10 grid.  Homebase is position 0,0.")
    fmt.Println("Any guess you make must be two numbers with each")
    fmt.Println("number between 0 and 9, inclusive.  First number")
    fmt.Println("is distance to right of homebase and second number")
    fmt.Println("is distance above homebase.\n")
    fmt.Printf("You get %v tries.  After each try, you will see\n", turns)
    fmt.Println("how far you are from each mugwump.\n")
    pressEnter("Press Enter to start. ")

}

// Stock functions {{{1
// =============================================================

// Return the given plural ending if the given number is greater than 1;
// otherwise return the given singular ending.
func plural_(n int, plural string, singular string) string {

    if n > 1 {
        return plural
    } else {
        return singular
    }

}

// Return the plural "s" ending if the given number is greater than 1;
// otherwise return an empty string.
func plural(n int) string {

    return plural_(n, "s", "")

}

// Game {{{1
// =============================================================

// Init the mugwumps' positions, `hidden` flags and count.
func hideMugwumps() {

    for m := 0; m < mugwumps; m++ {
        mugwump[m].x = rand.Intn(gridSize)
        mugwump[m].y = rand.Intn(gridSize)
        mugwump[m].hidden = true
    }
    found = 0 // counter

}

// Print the given prompt, wait until the user enters a valid coord and return
// it.
func getCoord(prompt string) (coord int) {

    for {
        coord = getNumber(prompt)
        if coord < 0 || coord >= gridSize {
            fmt.Printf("Invalid value %v: not in range [0, %v].\n", coord, gridSize-1)
        } else {
            break
        }
    }
    return

}

// Return `true` if the given mugwump is hidden in the given coords.
func isHere(m int, x int, y int) bool {

    return mugwump[m].hidden && mugwump[m].x == x && mugwump[m].y == y

}

// Return the distance between the given mugwump and the given coords.
func distance(m int, x int, y int) int {

    return int(math.Sqrt(
        math.Pow(float64(mugwump[m].x-x), 2) +
            math.Pow(float64(mugwump[m].y-y), 2)))

}

// Run the game.
func play() {

    var x int
    var y int
    var turn = 0 // counter
    for {
        clearScreen()
        hideMugwumps()
    turnsLoop:
        for turn = 1; turn <= turns; turn += 1 {
            fmt.Printf("Turn number %v\n\n", turn)
            fmt.Printf("What is your guess (in range [0, %v])?\n", gridSize-1)
            x = getCoord("Distance right of homebase (x-axis): ")
            y = getCoord("Distance above homebase (y-axis): ")
            fmt.Printf("\nYour guess is (%v, %v).\n", x, y)
            for m := 0; m < mugwumps; m++ {
                if isHere(m, x, y) {
                    mugwump[m].hidden = false
                    found += 1
                    fmt.Printf("You have found mugwump %v!\n", m)
                    if found == mugwumps {
                        break turnsLoop
                    }
                }
            }
            for m := 0; m < mugwumps; m++ {
                if mugwump[m].hidden {
                    fmt.Printf("You are %v units from mugwump %v.\n", distance(m, x, y), m)
                }
            }
            fmt.Println()
        } // turns
        if found == mugwumps {
            fmt.Printf("\nYou got them all in %v turn%s!\n\n", turn, plural(turn))
            fmt.Println("That was fun! let's play again…")
            fmt.Println("Four more mugwumps are now in hiding.")
        } else {
            fmt.Printf("\nSorry, that's %v tr%s.\n\n", turns, plural_(turns, "ies", "y"))
            fmt.Println("Here is where they're hiding:")
            for m := 0; m < mugwumps; m++ {
                if mugwump[m].hidden {
                    fmt.Printf("Mugwump %v is at (%v, %v).\n", m, mugwump[m].x, mugwump[m].y)
                }
            }
        }
        fmt.Println()
        if !yes("Do you want to play again? ") {
            break
        }
    }

}

// Main {{{1
// =============================================================

func main() {

    printCredits()
    printInstructions()
    play()

}

En Hare

// Mugwump
//
// Original version in BASIC:
//      Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
//      Slightly modified by Bob Albrecht of People's Computer Company.
//      Published by Creative Computing (Morristown, New Jersey, USA), 1978.
//      - https://www.atariarchives.org/basicgames/showpage.php?page=114
//      - http://vintage-basic.net/games.html
//
// This version in Hare:
//      Copyright (c) 2025, Marcos Cruz (programandala.net)
//      SPDX-License-Identifier: Fair
//
// Written in 2025-02-14/15.
//
// Last modified: 20260213T1645+0100.

// Modules {{{1
// =============================================================================

use ascii;
use bufio;
use fmt;
use math;
use math::random;
use os;
use strconv;
use strings;
use time;

// Terminal {{{1
// =============================================================================

def NORMAL_STYLE = 0;

fn move_cursor_home() void = {
        fmt::print("\x1B[H")!;
};

fn set_style(style: int) void = {
        fmt::printf("\x1B[{}m", style)!;
};

fn reset_attributes() void = {
        set_style(NORMAL_STYLE);
};

fn erase_screen() void = {
        fmt::print("\x1B[2J")!;
};

fn clear_screen() void = {
        erase_screen();
        reset_attributes();
        move_cursor_home();
};

// Data {{{1
// =============================================================================

def GRID_SIZE = 10;
def TURNS = 10;
def MUGWUMPS = 4;

type Mugwump = struct {
        x: int,
        y: int,
        hidden: bool,

};

let mugwump: [MUGWUMPS]Mugwump = [Mugwump{x = 0, y = 0, hidden = false}...];
let found: int = 0; // counter

// User input {{{1
// =============================================================================

fn print_prompt(prompt: str = "") void = {
        fmt::print(prompt)!;
        bufio::flush(os::stdout)!;
};

fn accept_string(prompt: str = "") str = {
        print_prompt(prompt);
        const buffer = match (bufio::read_line(os::stdin)!) {
                case let buffer: []u8 =>
                        yield buffer;
                case =>
                        return "";
                };
        defer free(buffer);
        return strings::dup(strings::fromutf8(buffer)!)!;
};

fn accept_integer() (int | ...strconv::error) = {
        const s = accept_string();
        defer free(s);
        return strconv::stoi(s);
};

fn prompted_integer(prompt: str) (int | ...strconv::error) = {
        fmt::print(prompt)!;
        bufio::flush(os::stdout)!;
        return accept_integer();
};

fn prompted_valid_integer(prompt: str, error: str = "Integer expected.") int = {
        let result: int = 0;
        for (true) {
                match (prompted_integer(prompt)) {
                case let i: int =>
                        result = i;
                        break;
                case =>
                        fmt::println(error)!;
                };
        };
        return result;
};

// Return `true` if the given string is "yes" or a synonym.
//
fn is_yes(s: str) bool = {
        const lowercase_s = ascii::strlower(s)!;
        defer free(lowercase_s);
        return switch(lowercase_s) {
                case "ok", "y", "yeah", "yes" =>
                        yield true;
                case =>
                        yield false;
        };
};

// Return `true` if the given string is "no" or a synonym.
//
fn is_no(s: str) bool = {
        const lowercase_s = ascii::strlower(s)!;
        defer free(lowercase_s);
        return switch(lowercase_s) {
                case "n", "no", "nope" =>
                        yield true;
                case =>
                        yield false;
        };
};

// Print the given prompt, wait until the user enters a valid yes/no string,
// and return `true` for "yes" or `false` for "no".
//
fn yes(prompt: str) bool = {
        for (true) {
                let answer = accept_string(prompt);
                defer free(answer);
                if (is_yes(answer)) {
                        return true;
                };
                if (is_no(answer)) {
                        return false;
                };
        };
};

// Credits and instructions {{{1
// =============================================================================

// Clear the screen, print the credits and ask the user to press enter.
//
fn print_credits() void = {
        clear_screen();
        fmt::println("Mugwump\n")!;
        fmt::println("Original version in BASIC:")!;
        fmt::println("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")!;
        fmt::println("    Slightly modified by Bob Albrecht of People's Computer Company.")!;
        fmt::println("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")!;
        fmt::println("    - https://www.atariarchives.org/basicgames/showpage.php?page=114")!;
        fmt::println("    - http://vintage-basic.net/games.html\n")!;
        fmt::println("This version in Hare:")!;
        fmt::println("    Copyright (c) 2025, Marcos Cruz (programandala.net)")!;
        fmt::println("    SPDX-License-Identifier: Fair\n")!;
        accept_string("Press Enter to read the instructions. ");
};

// Clear the screen, print the instructions and ask the user to press enter.
//
fn print_instructions() void = {
        clear_screen();
        fmt::println("Mugwump\n")!;
        fmt::println("The object of this game is to find four mugwumps")!;
        fmt::println("hidden on a 10 by 10 grid.  Homebase is position 0,0.")!;
        fmt::println("Any guess you make must be two numbers with each")!;
        fmt::println("number between 0 and 9, inclusive.  First number")!;
        fmt::println("is distance to right of homebase and second number")!;
        fmt::println("is distance above homebase.\n")!;
        fmt::printfln("You get {} tries.  After each try, you will see", TURNS)!;
        fmt::println("how far you are from each mugwump.\n")!;
        accept_string("Press Enter to start. ");
};

// Game {{{1
// =============================================================================

// Init the mugwumps' positions, `hidden` flags and count.
//
fn hide_mugwumps() void = {
        for (let m = 0; m < MUGWUMPS; m += 1) {
                mugwump[m].x = random::u64n(&rand, GRID_SIZE): int;
                mugwump[m].y = random::u64n(&rand, GRID_SIZE): int;
                mugwump[m].hidden = true;
        };
        found = 0; // counter
};

// Print the given prompt, wait until the user enters a valid coord and return
// it.
//
fn get_coord(prompt: str) int = {
        let coord: int = 0;
        for (true) {
                coord = prompted_valid_integer(prompt);
                if (coord < 0 || coord >= GRID_SIZE) {
                        fmt::printfln("Invalid value {}: not in range [0, {}].", coord, GRID_SIZE - 1)!;
                } else {
                        break;
                };
        };
        return coord;
};

// Return `true` if the given mugwump is hidden in the given coords.
//
fn is_here(m: int, x: int, y: int) bool = {
        return mugwump[m].hidden && mugwump[m].x == x && mugwump[m].y == y;
};

// Return the distance between the given mugwump and the given coords.
//
fn distance(m: int, x: int, y: int) int = {
        return math::sqrtf64(
                math::powf64((mugwump[m].x - x): f64, 2.0) +
                math::powf64((mugwump[m].y - y): f64, 2.0)): int;
};

// Return a plural suffix (default: "s") if the given number is greater than 1
// otherwise return a singular suffix (default: an empty string).
//
fn plural(n: int, plural_suffix: str = "s", singular_suffix: str = "") str = {
        return if (n > 1) plural_suffix else singular_suffix;
};

// Run the game.
//
fn play() void = {
        let x: int = 0;
        let y: int = 0;
        let turn: int = 0; // counter

        for (true) { // game

                clear_screen();
                hide_mugwumps();

                for :turns_loop (let turn = 1; turn <= TURNS; turn += 1) {

                        fmt::printfln("Turn number {}\n", turn)!;
                        fmt::printfln("What is your guess (in range [0, {}])?", GRID_SIZE - 1)!;
                        x = get_coord("Distance right of homebase (x-axis): ");
                        y = get_coord("Distance above homebase (y-axis): ");
                        fmt::printfln("\nYour guess is ({}, {}).", x, y)!;

                        for (let m = 0; m < MUGWUMPS; m += 1) {
                                if (is_here(m, x, y)) {
                                        mugwump[m].hidden = false;
                                        found += 1;
                                        fmt::printfln("You have found mugwump {}!", m)!;
                                        if (found == MUGWUMPS) {
                                                break :turns_loop;
                                        };
                                };
                        };

                        for (let m = 0; m < MUGWUMPS; m += 1) {
                                if (mugwump[m].hidden) {
                                        fmt::printfln("You are {} units from mugwump {}.", distance(m, x, y) , m)!;
                                };
                        };
                        fmt::println()!;

                }; // turns

                if (found == MUGWUMPS) {
                        fmt::printfln("\nYou got them all in {} turn{}!\n", turn, plural(turn))!;
                        fmt::println("That was fun! let's play again…")!;
                        fmt::println("Four more mugwumps are now in hiding.")!;
                } else {
                        fmt::printfln("\nSorry, that's {} tr{}.\n", TURNS, plural(TURNS, "ies", "y"))!;
                        fmt::println("Here is where they're hiding:")!;
                        for (let m = 0; m < MUGWUMPS; m += 1) {
                                if (mugwump[m].hidden) {
                                        fmt::printfln("Mugwump {} is at ({}, {}).", m, mugwump[m].x, mugwump[m].y)!;
                                };
                        };
                };

                if (!yes("\nDo you want to play again? ")) {
                        break;
                };

        }; // game
};

// Main {{{1
// =============================================================================

let rand: random::random = 0;

fn randomize() void = {
        rand = random::init(time::now(time::clock::MONOTONIC).sec: u64);
};

fn init() void = {
        randomize();
};

export fn main() void = {
        init();
        print_credits();
        print_instructions();
        play();
};

En Julia

# Mugwump

# Original version in BASIC:
#   Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
#   Slightly modified by Bob Albrecht of People's Computer Company.
#   Published by Creative Computing (Morristown, New Jersey, USA), 1978.
#   - https://www.atariarchives.org/basicgames/showpage.php?page=114
#   - http://vintage-basic.net/games.html

# This version in Julia:
#   Copyright (c) 2024, Marcos Cruz (programandala.net)
#   SPDX-License-Identifier: Fair
#
# Written on 2024-07-02/03.
#
# Last modified: 20241030T0038+0100.

const GRID_SIZE = 10
const TURNS     = 10
const MUGWUMPS  =  4

mutable struct Mugwump
    hidden::Bool
    x::Int
    y::Int
end

# Move the cursor to the top left position of the terminal.

function home()
    print("\e[H")
end

# Clear the terminal and move the cursor to the top left position.

function clear()
    print("\e[2J")
    home()
end

# Print the given prompt, wait until the user enters a valid integer and return
# it.

function get_number(prompt::String)::Int
    n = 0
    while true
        print(prompt)
        n = tryparse(Int, readline())
        if isnothing(n)
            println("Invalid number.")
        else
            break
        end
    end
    return n
end

# Prompt the user to enter a command and return it.

function command(prompt = "> ")::String
    print(prompt)
    return readline()
end

# Print the given prompt and wait until the user enters an empty string.

function press_enter(prompt::String)
    while command(prompt) != ""
    end
end

# Return `true` if the given string is "yes" or a synonym; otherwise return
# `false`.

function is_yes(answer::String)::Bool
    return lowercase(answer) in ["ok", "yeah", "yes", "y"]
end

# Return `true` if the given string is "no" or a synonym; otherwise return
# `false`.

function is_no(answer::String)::Bool
    return lowercase(answer) in ["no", "nope", "n"]
end

# Print the given prompt, wait until the user enters a valid yes/no string, and
# return `true` for "yes" or `false` for "no".

function yes(prompt::String)::Bool
    answer = ""
    while ! (is_yes(answer) || is_no(answer))
        answer = command(prompt)
    end
    return is_yes(answer)
end

# Clear the screen, print the credits and ask the user to press enter.

function print_credits()
    clear()
    println("Mugwump\n")
    println("Original version in BASIC:")
    println("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
    println("    Slightly modified by Bob Albrecht of People's Computer Company.")
    println("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")
    println("    - https://www.atariarchives.org/basicgames/showpage.php?page=114")
    println("    - http://vintage-basic.net/games.html\n")
    println("This version in Julia:")
    println("    Copyright (c) 2024, Marcos Cruz (programandala.net)")
    println("    SPDX-License-Identifier: Fair\n")
    press_enter("Press Enter to read the instructions. ")
end

# Clear the screen, print the instructions and ask the user to press enter.

function print_instructions()
    clear()
    println("Mugwump\n")
    println("The object of this game is to find four mugwumps")
    println("hidden on a 10 by 10 grid.  Homebase is position 0,0.")
    println("Any guess you make must be two numbers with each")
    println("number between 0 and 9, inclusive.  First number")
    println("is distance to right of homebase and second number")
    println("is distance above homebase.\n")
    println("You get $TURNS tries.  After each try, you will see")
    println("how far you are from each mugwump.\n")
    press_enter("Press Enter to start. ")
end

# Print the given prompt, then waits until the user enters a valid coord and
# returns it.

function get_coord(prompt::String)::Int
    coord = 0
    while true
        coord = get_number(prompt)
        if coord < 0 || coord >= GRID_SIZE
            println("Invalid value $coord: not in range [0, $(GRID_SIZE - 1)].")
        else
            break
        end
    end
    return coord
end

# Return `true` if the given mugwump is hidden in the given coords.

function is_here(m::Mugwump, x::Int, y::Int)::Bool
    return m.hidden && m.x == x && m.y == y
end

# Return the distance between the given mugwump and the given coords.

function distance(m::Mugwump, x::Int, y::Int)::Int
    return round(sqrt((m.x - x) ^ 2 + (m.y - y) ^ 2))
end

# If the given number is greater than 1, return the given plural ending
# (default: "s"); otherwise return the given singular ending (default: an empty
# string).

function plural(n::Int, plural = "s", singular = "")::String
    return n > 1 ? plural : singular
end

# Print the mugwumps found in the given coordinates and return the count.

function mugwumps_found(mugwump::Array{Mugwump}, x, y)::Int
    found = 0
    for m in 1 : MUGWUMPS
        if is_here(mugwump[m], x, y)
            mugwump[m].hidden = false
            found += 1
            println("You have found mugwump $(m)!")
        end
    end
    return found
end

# Run the game.

function play()
    found = 0 # counter
    turn  = 0 # counter
    mugwump = Array{Mugwump, 1}(undef, MUGWUMPS)
    while true # game
        clear()
        for m in 1 : MUGWUMPS
             mugwump[m] = Mugwump(
                                  true,
                                  rand(0 : GRID_SIZE - 1),
                                  rand(0 : GRID_SIZE - 1)
                                  )
        end
        found = 0
        turn = 1
        while turn < TURNS
            println("Turn number $turn\n")
            println("What is your guess (in range [0, $(GRID_SIZE - 1)])?")
            x = get_coord("Distance right of homebase (x-axis): ")
            y = get_coord("Distance above homebase (y-axis): ")
            println("\nYour guess is ($x, $y).")
            found += mugwumps_found(mugwump, x, y)
            if found == MUGWUMPS
                break # turns
            else
                for m in 1 : MUGWUMPS
                    if mugwump[m].hidden
                        println("You are $(distance(mugwump[m], x, y)) units from mugwump $m.")
                    end
                end
                println()
            end
            turn += 1
        end # turns
        if found == MUGWUMPS
            println("\nYou got them all in $turn turn$(plural(turn))!\n")
            println("That was fun! let's play again…")
            println("Four more mugwumps are now in hiding.")
        else
            println("\nSorry, that's $TURNS tr$(plural(TURNS, "ies", "y")).\n")
            println("Here is where they're hiding:")
            for m in 1 : MUGWUMPS
                if mugwump[m].hidden
                    println("Mugwump $m is at ($(mugwump[m].x), $(mugwump[m].y)).")
                end
            end
        end
        println()
        if ! yes("Do you want to play again? ")
            break # game
        end
    end # game
end

print_credits()
print_instructions()
play()

En Kotlin

/*
Mugwump

Original version in BASIC:
    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
    Slightly modified by Bob Albrecht of People's Computer Company.
    Published by Creative Computing (Morristown, New Jersey, USA), 1978.
    - https://www.atariarchives.org/basicgames/showpage.php?page=114
    - http://vintage-basic.net/games.html

This version in Kotlin:
    Copyright (c) 2023, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written in 2023-10.

Last modified: 20250518T2359+0200.
*/

import kotlin.math.pow
import kotlin.math.sqrt

const val GRID_SIZE = 10
const val TURNS = 10
const val MUGWUMPS = 4

class Mugwump {
    var x: Int = 0
    var y: Int = 0
    var hidden: Boolean = false
}

var mugwump: MutableList<Mugwump> = mutableListOf()

var found: Int = 0 // counter

// Move the cursor to the top left position of the terminal.
fun home() {
    print("\u001B[H")
}

// Clear the terminal and move the cursor to the top left position.
fun clear() {
    print("\u001B[2J")
    home()
}

// Print the given prompt, wait until the user enters a valid integer
// and return it.
fun getNumber(prompt: String): Int {
    var number: Int
    while (true) {
        try {
            print(prompt)
            number = readln().toInt()
            break
        }
        catch (e: Exception) { }
    }
    return number
}

// Return `true` if the given string is "yes" or a synonym.
fun isYes(answer: String): Boolean {
    when (answer.lowercase()) {
        "ok", "yeah", "yes", "y" -> return true
        else -> return false
    }
}

// Return `true` if the given string is "no" or a synonym.
fun isNo(answer: String): Boolean {
    when (answer.lowercase()) {
        "no", "nope", "n" -> return true
        else -> return false
    }
}

// Print the given prompt, wait until the user enters a valid yes/no
// String, and return `true` for "yes" or `false` for "no".
fun yes(prompt: String): Boolean {
    var answer = ""
    while (!(isYes(answer) || isNo(answer))) {
        println(prompt)
        answer = readln()
    }
    return isYes(answer)
}


// Clear the screen, print the credits and ask the user to press enter.
fun printCredits() {
    clear()
    println("Mugwump\n")
    println("Original version in BASIC:")
    println("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
    println("    Slightly modified by Bob Albrecht of People's Computer Company.")
    println("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")
    println("    - https://www.atariarchives.org/basicgames/showpage.php?page=114")
    println("    - http://vintage-basic.net/games.html\n")
    println("This version in Kotlin:")
    println("    Copyright (c) 2023, Marcos Cruz (programandala.net)")
    println("    SPDX-License-Identifier: Fair\n")
    print("Press Enter to read the instructions. ")
    readln()
}

// Clear the screen, print the instructions and ask the user to press enter.
fun printInstructions() {
    clear()
    println("Mugwump\n")
    println("The object of this game is to find four mugwumps")
    println("hidden on a 10 by 10 grid.  Homebase is position 0,0.")
    println("Any guess you make must be two numbers with each")
    println("number between 0 and 9, inclusive.  First number")
    println("is distance to right of homebase and second number")
    println("is distance above homebase.\n")
    println("You get $TURNS tries.  After each try, you will see")
    println("how far you are from each mugwump.\n")
    print("Press Enter to start. ")
    readln()
}

// Init the mugwumps' positions, `hidden` flags and count.
fun hideMugwumps() {
    for (m in mugwump.indices) {
        mugwump[m].x = (0..<GRID_SIZE).random()
        mugwump[m].y = (0..<GRID_SIZE).random()
        mugwump[m].hidden = true
    }
    found = 0 // counter
}

// Create the mugwumps.
fun createMugwumps() {
    for (m in 0..<MUGWUMPS) {
        mugwump.add(Mugwump())
    }
}

// Print the given prompt, wait until the user enters a valid coord
// and return it.
fun getCoord(prompt: String): Int {
    var coord: Int
    while (true) {
        coord = getNumber(prompt)
        if (coord < 0 || coord >= GRID_SIZE) {
            println("Invalid value $coord: not in range [0, ${GRID_SIZE - 1}].")
        } else {
            break
        }
    }
    return coord
}

// Return `true` if the given mugwump is hidden in the given coords.
fun isHere(m: Int, x: Int, y: Int): Boolean {
    return mugwump[m].hidden && mugwump[m].x == x && mugwump[m].y == y
}

// Return the distance between the given mugwump and the given coords.
fun distance(m: Int, xCoord: Int, yCoord: Int): Int {
    return sqrt((mugwump[m].x.toDouble() - xCoord.toDouble()).pow(2.0) + (mugwump[m].y.toDouble() - yCoord.toDouble()).pow(2.0)).toInt()
}

// Return a plural ending (default: "s") if the given number is greater than 1;
// otherwise return a singular ending (default: an empty string).
fun plural(n: Int, pluralEnding: String = "s", singularEnding: String = ""): String {
    return if (n > 1) pluralEnding else singularEnding
}

// Run the game.
fun play() {
    var x: Int
    var y: Int
    createMugwumps()
    while (true) { // game
        clear()
        hideMugwumps()
        var turn: Int = 1
        turnsLoop@ while (turn <= TURNS) {
            println("Turn number $turn\n")
            println("What is your guess (in range 0..${GRID_SIZE - 1})?")
            x = getCoord("Distance right of homebase (x-axis): ")
            y = getCoord("Distance above homebase (y-axis): ")
            println("\nYour guess is ($x, $y).")
            for (m in mugwump.indices) {
                if (isHere(m, x, y)) {
                    mugwump[m].hidden = false
                    found += 1
                    println("You have found mugwump $m!")
                    if (found == mugwump.size) { break@turnsLoop }
                }
            }
            for (m in mugwump.indices) {
                if (mugwump[m].hidden) {
                    println("You are ${distance(m, x, y)} units from mugwump $m.")
                }
            }
            println()
            turn += 1
        } // turns
        if (found == mugwump.size) {
            println("\nYou got them all in $turn ${plural(turn)}!")
            println("That was fun! let's play again…")
            println("Four more mugwumps are now in hiding.")
        } else {
            println("Sorry, that's $TURNS tr${plural(TURNS, "ies", "y")}.\n")
            println("Here is where they're hiding:")
            for (m in mugwump.indices) {
                if (mugwump[m].hidden) {
                    println("Mugwump $m is at (${mugwump[m].x}, ${mugwump[m].y}).")
                }
            }
        }
        println()
        if (!yes("Do you want to play again? ")) { break }
    } // game
}

fun main() {
    printCredits()
    printInstructions()
    play()
}

En Nim

#[
Mugwump

Original version in BASIC:
  Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
  Slightly modified by Bob Albrecht of People's Computer Company.
  Published by Creative Computing (Morristown, New Jersey, USA), 1978.
  - https://www.atariarchives.org/basicgames/showpage.php?page=114
  - http://vintage-basic.net/games.html

This version in Nim:
  Copyright (c) 2025, Marcos Cruz (programandala.net)
  SPDX-License-Identifier: Fair

Written on 2025-01-20.

Last modified: 20250404T0159+0200.
]#

import std/math
import std/random
import std/strutils
import std/terminal
import std/unicode

proc cursorHome() =
  setCursorPos(0, 0)

proc clearScreen() =
  eraseScreen()
  cursorHome()

const gridSize = 10
const turns = 10
const mugwumps = 4

type Mugwump = tuple[
  x: int,
  y: int,
  hidden: bool,
  ]

var mugwump: array[mugwumps, Mugwump]
var found: int # counter

# Wait until the user enters a string and return it.
#
proc getString(prompt: string): string =
  write(stdout, prompt)
  result = readLine(stdin)

# Print the given prompt, wait until the user enters a valid integer and
# return it.
#
proc getNumber(prompt: string): int =
  var n: int
  while true:
    try:
      write(stdout, prompt)
      n = parseInt(readLine(stdin))
      break
    except ValueError:
      discard
  result = n

# Return `true` if the given string is "yes" or a synonym.
#
proc isYes(s: string): bool  =
  result = toLower(s) in ["ok", "y", "yeah", "yes"]

# Return `true` if the given string is "no" or a synonym.
#
proc isNo(s: string): bool  =
  result = toLower(s) in ["n", "no", "nope"]

# Print the given prompt, wait until the user enters a valid yes/no string,
# and return `true` for "yes" or `false` for "no".
#
proc yes(prompt: string): bool =
  while true:
    var answer = getString(prompt)
    if isYes(answer):
        return true
    if isNo(answer):
        return false

# Return a plural ending (default: "s") if the given number is greater than 1;
# otherwise return a singular ending (default: an empty string).
#
proc plural(n: int, plural = "s", singular = ""): string =
  result = if n > 1: plural else: singular

# Clear the screen, print the credits and ask the user to press enter.
#
proc printCredits() =
  clearScreen()
  writeLine(stdout, "Mugwump\n")
  writeLine(stdout, "Original version in BASIC:")
  writeLine(stdout, "    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
  writeLine(stdout, "    Slightly modified by Bob Albrecht of People's Computer Company.")
  writeLine(stdout, "    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")
  writeLine(stdout, "    - https://www.atariarchives.org/basicgames/showpage.php?page=114")
  writeLine(stdout, "    - http://vintage-basic.net/games.html\n")
  writeLine(stdout, "This version in Nim:")
  writeLine(stdout, "    Copyright (c) 2025, Marcos Cruz (programandala.net)")
  writeLine(stdout, "    SPDX-License-Identifier: Fair")
  write(stdout, "\nPress Enter to read the instructions. ")
  discard readLine(stdin)

# Clear the screen, print the instructions and ask the user to press enter.
#
proc printInstructions() =
  clearScreen()
  writeLine(stdout, "Mugwump\n")
  writeLine(stdout, "The object of this game is to find four mugwumps")
  writeLine(stdout, "hidden on a 10 by 10 grid.  Homebase is position 0,0.")
  writeLine(stdout, "Any guess you make must be two numbers with each")
  writeLine(stdout, "number between 0 and 9, inclusive.  First number")
  writeLine(stdout, "is distance to right of homebase and second number")
  writeLine(stdout, "is distance above homebase.\n")
  var tries: string = plural(turns, "tries", "try")
  writeLine(stdout, "You get ", turns, " ", tries, ".  After each try, you will see")
  writeLine(stdout, "how far you are from each mugwump.")
  write(stdout, "\nPress Enter to start. ")
  discard readLine(stdin)

# Init the mugwumps' positions, `hidden` flags and count.
#
proc hideMugwumps() =
  for m in 0 ..< mugwumps:
    mugwump[m].x = rand(gridSize - 1)
    mugwump[m].y = rand(gridSize - 1)
    mugwump[m].hidden = true
  found = 0 # counter

# Print the given prompt, wait until the user enters a valid coord and return
# it.
#
proc getCoord(prompt: string): int =
  while true:
    result = getNumber(prompt)
    if result < 0 or result >= gridSize:
      writeLine(stdout, "Invalid value ", result, ": not in range [0, ", gridSize - 1, "].")
    else:
      break

# Return `true` if the given mugwump is hidden in the given coords.
#
proc isHere(m: int, x: int, y: int): bool =
  result = mugwump[m].hidden and mugwump[m].x == x and mugwump[m].y == y

# Return the distance between the given mugwump and the given coords.
#
proc distance(m: int, x: int, y: int): int =
  result = int(sqrt(
    pow(float(mugwump[m].x - x), 2) +
    pow(float(mugwump[m].y - y), 2)))

# Run the game.
#
proc play() =
  var x: int
  var y: int
  var turn: int # counter
  while true: # game
    clearScreen()
    hideMugwumps()
    block playing:
      for turn in 1 ..< turns:
        writeLine(stdout, "Turn number ", turn, "\n")
        writeLine(stdout, "What is your guess (in range [0, ", gridSize - 1, "])?")
        x = getCoord("Distance right of homebase (x-axis): ")
        y = getCoord("Distance above homebase (y-axis): ")
        writeLine(stdout, "\nYour guess is (", x, ", ", y, ").")
        for m in 0 ..< mugwumps:
          if isHere(m, x, y):
            mugwump[m].hidden = false
            found += 1
            writeLine(stdout, "You have found mugwump ", m, "!")
            if found == mugwumps:
              break playing
        for m in 0 ..< mugwumps:
          if mugwump[m].hidden:
            writeLine(stdout, "You are ", distance(m, x, y), " units from mugwump ", m, ".")
        writeLine(stdout, "")
    if found == mugwumps:
      writeLine(stdout, "\nYou got them all in ", turn, " turn", plural(turn), "!")
      writeLine(stdout, "\nThat was fun! let's play again…")
      writeLine(stdout, "Four more mugwumps are now in hiding.")
    else:
      var tries: string = plural(turns, "tries", "try")
      writeLine(stdout, "\nSorry, that's ", turns, " ", tries, ".")
      writeLine(stdout, "\nHere is where they're hiding:")
      for m in 0 ..< mugwumps:
        if mugwump[m].hidden:
          writeLine(stdout, "Mugwump ", m, " is at (", mugwump[m].x, ", ", mugwump[m].y, ").")
    writeLine(stdout, "")
    if not yes("Do you want to play again? "):
      break

printCredits()
printInstructions()
play()

En Odin

/*
Mugwump

Original version in BASIC:
    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
    Slightly modified by Bob Albrecht of People's Computer Company.
    Published by Creative Computing (Morristown, New Jersey, USA), 1978.
    - https://www.atariarchives.org/basicgames/showpage.php?page=114
    - http://vintage-basic.net/games.html

This version in Odin:
    Copyright (c) 2023, 2025, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written in 2023-03, 2023-09, 2023-12, 2025-02.

Last modified: 20250731T1954+0200.
*/

package mugwump

import "../lib/anodino/src/read"
import "../lib/anodino/src/term"
import "core:fmt"
import "core:math"
import "core:math/rand"
import "core:slice"
import "core:strings"

GRID_SIZE :: 10
TURNS     :: 10
MUGWUMPS  :: 4

Mugwump :: struct {
    x : int,
    y : int,
    hidden : bool,

}

mugwump : [MUGWUMPS]Mugwump
found   : int // counter

// Wait until the user enters a string and return it.
//
get_string :: proc(prompt : string) -> string {

    fmt.print(prompt)
    return read.a_string() or_else ""

}

// Print the given prompt, wait until the user enters a valid integer and
// return it.
//
get_number :: proc(prompt : string) -> (number : int) {

    ok := false
    for ; !ok; number, ok = read.a_prompted_int(prompt) {}
    return number

}

// Print the given prompt and wait until the user enters an empty string.
//
press_enter :: proc(prompt : string) {

    for {
        s := get_string(prompt)
        if len(s) == 0 do break
        defer delete(s)
    }

}

// Return `true` if the given string is "yes" or a synonym.
//
is_yes :: proc(s : string) -> bool {

    lowercase_s := strings.to_lower(s)
    defer delete(lowercase_s)
    return slice.any_of([]string{"ok", "y", "yeah", "yes"}, lowercase_s)

}

// Return `true` if the given string is "no" or a synonym.
//
is_no :: proc(s : string) -> bool {

    lowercase_s := strings.to_lower(s)
    defer delete(lowercase_s)
    return slice.any_of([]string{"n", "no", "nope"}, lowercase_s)

}

// Print the given prompt, wait until the user enters a valid yes/no string,
// and return `true` for "yes" or `false` for "no".
//
yes :: proc(prompt : string) -> bool {

    for {
        answer := get_string(prompt)
        defer delete(answer)
        if is_yes(answer) do return true
        if is_no(answer) do return false
    }

}

// Clear the screen, print the credits and ask the user to press enter.
//
print_credits :: proc() {

    term.clear_screen()
    fmt.println("Mugwump\n")
    fmt.println("Original version in BASIC:")
    fmt.println("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
    fmt.println("    Slightly modified by Bob Albrecht of People's Computer Company.")
    fmt.println("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")
    fmt.println("    - https://www.atariarchives.org/basicgames/showpage.php?page=114")
    fmt.println("    - http://vintage-basic.net/games.html\n")
    fmt.println("This version in Odin:")
    fmt.println("    Copyright (c) 2023, 2025, Marcos Cruz (programandala.net)")
    fmt.println("    SPDX-License-Identifier: Fair\n")
    press_enter("Press Enter to read the instructions. ")

}

// Clear the screen, print the instructions and ask the user to press enter.
//
print_instructions :: proc() {

    term.clear_screen()
    fmt.println("Mugwump\n")
    fmt.println("The object of this game is to find four mugwumps")
    fmt.println("hidden on a 10 by 10 grid.  Homebase is position 0,0.")
    fmt.println("Any guess you make must be two numbers with each")
    fmt.println("number between 0 and 9, inclusive.  First number")
    fmt.println("is distance to right of homebase and second number")
    fmt.println("is distance above homebase.\n")
    fmt.printfln("You get %v tries.  After each try, you will see", TURNS)
    fmt.println("how far you are from each mugwump.\n")
    press_enter("Press Enter to start. ")

}

// Init the mugwumps' positions, `hidden` flags and count.
//
hide_mugwumps :: proc() {

    for m in 0 ..< MUGWUMPS {
        mugwump[m].x = rand.int_max(GRID_SIZE)
        mugwump[m].y = rand.int_max(GRID_SIZE)
        mugwump[m].hidden = true
    }
    found = 0 // counter

}

// Print the given prompt, wait until the user enters a valid coord and return
// it.
//
get_coord :: proc(prompt : string) -> (coord : int) {

    for {
        coord = get_number(prompt)
        if coord < 0 || coord >= GRID_SIZE {
            fmt.printfln("Invalid value %v: not in range [0, %v].", coord, GRID_SIZE - 1)
        } else {
            break
        }
    }
    return

}

// Return `true` if the given mugwump is hidden in the given coords.
//
is_here :: proc(m : int, x : int, y : int) -> bool {

    return mugwump[m].hidden && mugwump[m].x == x && mugwump[m].y == y

}

// Return the distance between the given mugwump and the given coords.
//
distance :: proc(m : int, x : int, y : int) -> int {

    return int(math.sqrt( \
          math.pow_f64(f64(mugwump[m].x - x), 2) \
        + math.pow_f64(f64(mugwump[m].y - y), 2)))

}

// Return a plural ending (default: "s") if the given number is greater than 1;
// otherwise return a singular ending (default: an empty string).
//
plural :: proc(n : int, plural := "s", singular := "") -> string {

    return n > 1 ? plural : singular

}

// Run the game.
//
play :: proc() {

    x, y : int
    turn : int // counter
    for { // game
        term.clear_screen()
        hide_mugwumps()
        turns_loop: for turn = 1; turn <= TURNS; turn += 1 {
            fmt.printfln("Turn number %v\n", turn)
            fmt.printfln("What is your guess (in range [0, %v])?", GRID_SIZE - 1)
            x = get_coord("Distance right of homebase (x-axis): ")
            y = get_coord("Distance above homebase (y-axis): ")
            fmt.printfln("\nYour guess is (%v, %v).", x, y)
            for m in 0 ..< MUGWUMPS {
                if is_here(m, x, y) {
                    mugwump[m].hidden = false
                    found += 1
                    fmt.printfln("You have found mugwump %v!", m)
                    if found == MUGWUMPS do break turns_loop
                }
            }
            for m in 0 ..< MUGWUMPS {
                if mugwump[m].hidden {
                    fmt.printfln("You are %v units from mugwump %v.", distance(m, x, y) , m)
                }
            }
            fmt.println()
        } // turns
        if found == MUGWUMPS {
            fmt.printfln("\nYou got them all in %v turn%s!\n", turn, plural(turn))
            fmt.println("That was fun! let's play again…")
            fmt.println("Four more mugwumps are now in hiding.")
        } else {
            fmt.printfln("\nSorry, that's %v tr%s.\n", TURNS, plural(TURNS, "ies", "y"))
            fmt.println("Here is where they're hiding:")
            for m in 0 ..< MUGWUMPS {
                if mugwump[m].hidden {
                    fmt.printfln("Mugwump %v is at (%v, %v).", m, mugwump[m].x, mugwump[m].y)
                }
            }
        }
        fmt.println()
        if !yes("Do you want to play again? ") do break
    } // game

}

main :: proc() {

    print_credits()
    print_instructions()
    play()

}

En Pike

#!/usr/bin/env pike

// Mugwump

// Original version in BASIC:
//  Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
//  Slightly modified by Bob Albrecht of People's Computer Company.
//  Published by Creative Computing (Morristown, New Jersey, USA), 1978.
//  - https://www.atariarchives.org/basicgames/showpage.php?page=114
//  - http://vintage-basic.net/games.html

// This version in Pike:
//  Copyright (c) 2025, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written in 2025-03-11/12.
//
// Last modified: 20250731T1954+0200.

// Terminal {{{1
// =============================================================================

constant NORMAL_STYLE = 0;

void move_cursor_home() {
    write("\x1B[H");
}

void set_style(int style) {
    write("\x1B[%dm", style);
}

void reset_attributes() {
    set_style(NORMAL_STYLE);
}

void erase_screen() {
    write("\x1B[2J");
}

void clear_screen() {
    erase_screen();
    reset_attributes();
    move_cursor_home();
}

// Data {{{1
// =============================================================================

constant GRID_SIZE = 10;
constant TURNS = 10;
constant MUGWUMPS = 4;

class Mugwump {
    int x;
    int y;
    bool hidden;
}

array(Mugwump) mugwump = allocate(MUGWUMPS);
int found = 0; // counter

// User input {{{1
// =============================================================================

string accept_string(string prompt) {
    write(prompt);
    return Stdio.stdin->gets();
}

// Print the given prompt, accept a string from the user. If the whole typed
// string is a valid integer (excluding trailing and leading white spaces,
// i.e.: space, tab, newline, carriage return, form feed, vertical tab and all
// the white spaces defined in Unicode), then return the number; otherwise
// return the typed string.
//
int|string accept_integer(string prompt) {
    string s = String.trim(accept_string(prompt));
    int n = (int) s;
    if ((string) n == s) {
        return n;
    } else {
        return s;
    }
}

int prompted_valid_integer(string prompt) {
    while (true) {
        int|string answer = accept_integer(prompt);
        if (stringp(answer)) {
            write("Integer expected.\n");
        } else {
            return answer;
        }
    }
}

bool is_yes(string s) {
    switch(lower_case(s)) {
        case "ok":
        case "y":
        case "yeah":
        case "yes":
            return true;
        default:
            return false;
    }
}

bool is_no(string s) {
    switch(lower_case(s)) {
        case "n":
        case "no":
        case "nope":
            return true;
        default:
            return false;
    }
}

// Print the given prompt, wait until the user enters a valid yes/no string;
// and return `true` for "yes" or `false` for "no".
//
bool yes(string prompt) {
    while (true) {
        string answer = accept_string(prompt);
        if (is_yes(answer)) {
            return true;
        }
        if (is_no(answer)) {
            return false;
        }
    }
}

// Credits and instructions {{{1
// =============================================================================

// Clear the screen, print the credits and ask the user to press enter.
//
void print_credits() {
    clear_screen();
    write("Mugwump\n\n");
    write("Original version in BASIC:\n");
    write("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).\n");
    write("    Slightly modified by Bob Albrecht of People's Computer Company.\n");
    write("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.\n");
    write("    - https://www.atariarchives.org/basicgames/showpage.php?page=114\n");
    write("    - http://vintage-basic.net/games.html\n\n");
    write("This version in Pike:\n");
    write("    Copyright (c) 2025, Marcos Cruz (programandala.net)\n");
    write("    SPDX-License-Identifier: Fair\n\n");
    accept_string("Press Enter to read the instructions. ");
}

// Clear the screen, print the instructions and ask the user to press enter.
//
void print_instructions() {
    clear_screen();
    write("Mugwump\n\n");
    write("The object of this game is to find four mugwumps\n");
    write("hidden on a 10 by 10 grid.  Homebase is position 0,0.\n");
    write("Any guess you make must be two numbers with each\n");
    write("number between 0 and 9, inclusive.  First number\n");
    write("is distance to right of homebase and second number\n");
    write("is distance above homebase.\n\n");
    write("You get %d tries.  After each try, you will see\n", TURNS);
    write("how far you are from each mugwump.\n\n");
    accept_string("Press Enter to start. ");
}

// Game {{{1
// =============================================================================

void hide_mugwumps() {
    for (int m = 0; m < MUGWUMPS; m += 1) {
        mugwump[m]->x = random(GRID_SIZE);
        mugwump[m]->y = random(GRID_SIZE);
        mugwump[m]->hidden = true;
    }
    found = 0; // counter
}

// Print the given prompt, wait until the user enters a valid coord and return
// it.
//
int get_coord(string prompt) {
    int coord = 0;
    while (true) {
        coord = prompted_valid_integer(prompt);
        if (coord < 0 || coord >= GRID_SIZE) {
            write("Invalid value %d: not in range [0, %d].\n", coord, GRID_SIZE - 1);
        } else {
            break;
        }
    }
    return coord;
}

// Return `true` if the given mugwump is hidden in the given coords.
//
bool is_here(int m, int x, int y) {
    return mugwump[m]->hidden && mugwump[m]->x == x && mugwump[m]->y == y;
}

// Return the distance between the given mugwump and the given coords.
//
int distance(int m, int x, int y) {
    return (int) sqrt(
        pow((mugwump[m]->x - x), 2.0) +
        pow((mugwump[m]->y - y), 2.0));
}

// Return a plural suffix (default: "s") if the given number is greater than 1
// otherwise return a singular suffix (default: an empty string).
//
string plural(int n, string|void plural_suffix, string|void singular_suffix) {
    plural_suffix = plural_suffix || "s";
    singular_suffix = singular_suffix || "";
    return n > 1 ? plural_suffix : singular_suffix;
}

// Run the game.
//
void play() {
    int x = 0;
    int y = 0;
    int turn = 0; // counter

    while (true) { // game

        clear_screen();
        hide_mugwumps();

        turns_loop: for (int turn = 1; turn <= TURNS; turn += 1) {
            write("Turn number %d\n\n", turn);
            write("What is your guess (in range [0, %d])?\n", GRID_SIZE - 1);
            x = get_coord("Distance right of homebase (x-axis): ");
            y = get_coord("Distance above homebase (y-axis): ");
            write("\nYour guess is (%d, %d).\n", x, y);

            for (int m = 0; m < MUGWUMPS; m += 1) {
                if (is_here(m, x, y)) {
                    mugwump[m]->hidden = false;
                    found += 1;
                    write("You have found mugwump %d!\n", m);
                    if (found == MUGWUMPS) {
                        break turns_loop;
                    }
                }
            }

            for (int m = 0; m < MUGWUMPS; m += 1) {
                if (mugwump[m]->hidden) {
                    write("You are %d units from mugwump %d.\n", distance(m, x, y) , m);
                }
            }
            write("\n");
        } // turns

        if (found == MUGWUMPS) {
            write("\nYou got them all in %d turn%s!\n\n", turn, plural(turn));
            write("That was fun! let's play again…\n");
            write("Four more mugwumps are now in hiding.\n");
        } else {
            write("\nSorry, that's %d tr%s.\n\n", TURNS, plural(TURNS, "ies", "y"));
            write("Here is where they're hiding:\n");
            for (int m = 0; m < MUGWUMPS; m += 1) {
                if (mugwump[m]->hidden) {
                    write("Mugwump %d is at (%d, %d).\n", m, mugwump[m]->x, mugwump[m]->y);
                }
            }
        }

        if (!yes("\nDo you want to play again? ")) {
            break;
        }
    } // game
}

// Main {{{1
// =============================================================================

void init() {
    // Build the `mugwump` array.
    for (int i = 0; i < MUGWUMPS; i += 1) {
        mugwump[i] = Mugwump();
    }
}

void main() {
    print_credits();
    print_instructions();
    init();
    play();
}

En Python

# Mugwump

# Original version in BASIC:
#   Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
#   Slightly modified by Bob Albrecht of People's Computer Company.
#   Published by Creative Computing (Morristown, New Jersey, USA), 1978.
#   - https://www.atariarchives.org/basicgames/showpage.php?page=114
#   - http://vintage-basic.net/games.html

# This version in Python:
#   Copyright (c) 2024, Marcos Cruz (programandala.net)
#   SPDX-License-Identifier: Fair
#
# Written on 2024-10-29.
#
# Last modified: 20241203T2231+0100.

import ast
from dataclasses import dataclass
import math
import os
import random

GRID_SIZE = 10
TURNS     = 10
MUGWUMPS  =  4

@dataclass
class Mugwump:
    hidden: bool
    x: int
    y: int

# Clear the terminal and move the cursor to the top left position.

def clear():
    if os.name == 'nt':
        _ = os.system('cls')
    else:
        # on mac and linux, `os.name` is 'posix'
        _ = os.system('clear')

# Print the given prompt, wait until the user enters a valid integer and return
# it.

def get_number(prompt):
    while True:
        try:
            n = ast.literal_eval(input(prompt))
            break
        except:
            print("Not a valid number.")
    return n

# Prompt the user to enter a command and return it.

def command(prompt = "> "):
    print(prompt, end = "")
    return input()

# Print the given prompt and wait until the user enters an empty string.

def press_enter(prompt):
    user_input = "X"
    while user_input != "":
        user_input = command(prompt)

# Return `True` if the given string is "yes" or a synonym; otherwise return
# `False`.

def is_yes(answer):
    return answer.lower() in ["ok", "yeah", "yes", "y"]

# Return `True` if the given string is "no" or a synonym; otherwise return
# `False`.

def is_no(answer):
    return answer.lower() in ["no", "nope", "n"]

# Print the given prompt, wait until the user enters a valid yes/no string, and
# return `True` for "yes" or `False` for "no".

def yes(prompt):
    answer = ""
    while not (is_yes(answer) or is_no(answer)):
        answer = command(prompt)
    return is_yes(answer)

# Clear the screen, print the credits and ask the user to press enter.

def print_credits():
    clear()
    print("Mugwump\n")
    print("Original version in BASIC:")
    print("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
    print("    Slightly modified by Bob Albrecht of People's Computer Company.")
    print("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")
    print("    - https://www.atariarchives.org/basicgames/showpage.php?page=114")
    print("    - http://vintage-basic.net/games.html\n")
    print("This version in Python:")
    print("    Copyright (c) 2024, Marcos Cruz (programandala.net)")
    print("    SPDX-License-Identifier: Fair\n")
    press_enter("Press Enter to read the instructions. ")

# Clear the screen, print the instructions and ask the user to press enter.

def print_instructions():
    clear()
    print("Mugwump\n")
    print("The object of this game is to find four mugwumps")
    print("hidden on a 10 by 10 grid.  Homebase is position 0,0.")
    print("Any guess you make must be two numbers with each")
    print("number between 0 and 9, inclusive.  First number")
    print("is distance to right of homebase and second number")
    print("is distance above homebase.\n")
    print(f"You get {TURNS} tries.  After each try, you will see")
    print("how far you are from each mugwump.\n")
    press_enter("Press Enter to start. ")

# Print the given prompt, then waits until the user enters a valid coord and
# returns it.

def get_coord(prompt):
    coord = 0
    while True:
        coord = get_number(prompt)
        if coord < 0 or coord >= GRID_SIZE:
            print(f"Invalid value {coord}: not in range [0, {GRID_SIZE - 1}].")
        else:
            break
    return coord

# Return `True` if the given mugwump is hidden in the given coords.

def is_here(m, x, y):
    return m.hidden and m.x == x and m.y == y

# Return the distance between the given mugwump and the given coords.

def distance(m, x, y):
    return round(math.sqrt((m.x - x) ** 2 + (m.y - y) ** 2))

# If the given number is greater than 1, return the given plural ending
# (default: "s"); otherwise return the given singular ending (default: an empty
# string).

def plural(n, plural = "s", singular = ""):
    return plural if n > 1 else singular

# Print the mugwumps found in the given coordinates and return the count.

def mugwumps_found(mugwump, x, y):
    found = 0
    for m in range(0, MUGWUMPS):
        if is_here(mugwump[m], x, y):
            mugwump[m].hidden = False
            found += 1
            print(f"You have found mugwump {m}!")
    return found

# Run the game.

def play():
    while True : # game
        clear()
        mugwump = []
        for m in range(0, MUGWUMPS):
            mugwump.append(
                Mugwump(
                    True,
                    random.randrange(0, GRID_SIZE),
                    random.randrange(0, GRID_SIZE)))
        found = 0
        turn = 1
        while turn < TURNS:
            print(f"Turn number {turn}\n")
            print(f"What is your guess (in range [0, {GRID_SIZE - 1}])?")
            x = get_coord("Distance right of homebase (x-axis): ")
            y = get_coord("Distance above homebase (y-axis): ")
            print(f"\nYour guess is ({x}, {y}).")
            found += mugwumps_found(mugwump, x, y)
            if found == MUGWUMPS:
                break # turns
            else:
                for m in range(0, MUGWUMPS):
                    if mugwump[m].hidden:
                        print("You are", distance(mugwump[m], x, y), f"units from mugwump {m}.")
                print()
            turn += 1
        # end of turns
        if found == MUGWUMPS:
            print(f"\nYou got them all in {turn} turn", plural(turn), "!\n", sep = "")
            print("That was fun! let's play again…")
            print("Four more mugwumps are now in hiding.")
        else:
            print(f"Sorry, that's {TURNS} tr", plural(TURNS, "ies", "y"), ".\n", sep = "")
            print("Here is where they're hiding:")
            for m in range(0, MUGWUMPS):
                if mugwump[m].hidden:
                    print(f"Mugwump {m} is at (", mugwump[m].x, ", ", mugwump[m].y, ").", sep = "")
        print()
        if not yes("Do you want to play again? "):
            break # game
    # end of game

print_credits()
print_instructions()
play()

En Raku

# Mugwump
#
# Original version in BASIC:
#   Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
#   Slightly modified by Bob Albrecht of People's Computer Company.
#   Published by Creative Computing (Morristown, New Jersey, USA), 1978.
#   - https://www.atariarchives.org/basicgames/showpage.php?page=114
#   - http://vintage-basic.net/games.html
#
# This version in Raku:
#   Copyright (c) 2024, Marcos Cruz (programandala.net)
#   SPDX-License-Identifier: Fair
#
# Written on 2024-12-07/11.
#
# Last modified: 20241211T1237+0100.

sub clear_screen {

    print "\e[0;0H\e[2J";

}

constant $GRID_SIZE = 10;
constant $TURNS = 10;
constant $MUGWUMPS = 4;

class Mugwump {
    has Int $.x is rw = 0;
    has Int $.y is rw = 0;
    has Bool $.hidden is rw = False;
}

my @mugwump of Mugwump;

for 0 ..^ $MUGWUMPS {
    push @mugwump, Mugwump.new;
}

my Int $found; # counter

# Print the given prompt, wait until the user enters a valid integer and
# return it.
#
sub prompt_number(Str $prompt --> Int) {

    my Int $n;
    my Str $s = '';
    constant $ERROR = 'Valid integer expected.';

    loop {
        loop {
            $s = prompt($prompt);
            if not $s eq '' {
                last;
            }
            put $ERROR;
        }
        try {
            $n = (+$s).Int;
            CATCH {
                default {
                    put $ERROR;
                    next;
                }
            }
        }
        last;
    }

    return $n;

}

# Return `True` if the given string is "yes" or a synonym.
#
sub is_yes(Str $answer --> Bool) {

    return $answer.lc (elem) ["ok", "y", "yeah", "yes"]

}

# Return `True` if the given string is "no" or a synonym.
#
sub is_no(Str $answer --> Bool) {

    return $answer.lc (elem) ["n", "no", "nope"];

}

# Print the given prompt, wait until the user enters a valid yes/no string,
# and return `True` for "yes" or `False` for "no".
#
sub yes(Str $prompt --> Bool) {

    loop {
        my $answer = prompt($prompt);
        if is_yes($answer) { return True };
        if is_no($answer) { return False };
    }

}

# Clear the screen, print the credits and ask the user to press enter.
#
sub print_credits {

    clear_screen;
    put "Mugwump\n";
    put 'Original version in BASIC:';
    put "    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).";
    put "    Slightly modified by Bob Albrecht of People's Computer Company.";
    put '    Published by Creative Computing (Morristown, New Jersey, USA), 1978.';
    put '    - https://www.atariarchives.org/basicgames/showpage.php?page=114';
    put "    - http://vintage-basic.net/games.html\n";
    put 'This version in Raku:';
    put '    Copyright (c) 2024, Marcos Cruz (programandala.net)';
    put "    SPDX-License-Identifier: Fair\n";
    prompt 'Press Enter to read the instructions. ';

}

# Clear the screen, print the instructions and ask the user to press enter.
#
sub print_instructions {

    clear_screen;
    put "Mugwump\n";
    put 'The object of this game is to find four mugwumps';
    put 'hidden on a 10 by 10 grid.  Homebase is position 0,0.';
    put 'Any guess you make must be two numbers with each';
    put 'number between 0 and 9, inclusive.  First number';
    put 'is distance to right of homebase and second number';
    put "is distance above homebase.\n";
    put "You get $TURNS tries.  After each try, you will see";
    put "how far you are from each mugwump.\n";
    prompt 'Press Enter to start. ';

}

# Init the mugwumps' positions, `hidden` flags and count.
#
sub hide_mugwumps {

    #say @mugwump[0]; # XXX TMP --> Mugwump.new
    for 0 ..^ $MUGWUMPS  -> $m {
        @mugwump[$m].x = (0 ..^ $GRID_SIZE).pick;
        @mugwump[$m].y = (0 ..^ $GRID_SIZE).pick;
        @mugwump[$m].hidden = True;
    }
    $found = 0 ; # counter

}

# Print the given prompt, wait until the user enters a valid coord and return
# it.
#
sub get_coord(Str $prompt --> Int) {

    my Int $coord;
    loop {
        $coord = prompt_number($prompt);
        if $coord < 0 or $coord >= $GRID_SIZE {
            put "Invalid value $coord: not in range [0, {$GRID_SIZE - 1}].";
        } else {
            last;
        }
    }
    return $coord;

}

# Return `True` if the given mugwump is hidden in the given coords.
#
sub is_here(Int $m, Int $x, Int $y --> Bool) {

    return (@mugwump[$m].hidden and @mugwump[$m].x == $x and @mugwump[$m].y == $y);

}

# Return the distance between the given mugwump and the given coords.
#
sub distance(Int $m, Int $x, Int $y --> Int) {

    return Int(sqrt(((@mugwump[$m].x - $x) ** 2) + ((@mugwump[$m].y - $y) ** 2)));

}

# Return a plural ending (default: "s") if the given number is greater than 1;
# otherwise return a singular ending (default: an empty string).
#
sub plural(Int $n, $plural = 's', $singular = '' --> Str) {

    return $n > 1 ?? $plural !! $singular;

}

# Run the game.
#
sub play {

    my Int $x;
    my Int $y;
    my Int $turn; # counter
    loop { # game
        clear_screen;
        hide_mugwumps;
        TURNS_LOOP: for 1 ..^ $TURNS -> $t {
            $turn = $t;
            put "Turn number $turn\n";
            put "What is your guess (in range [0, {$GRID_SIZE - 1}])?";
            $x = get_coord('Distance right of homebase (x-axis): ');
            $y = get_coord('Distance above homebase (y-axis): ');
            put "\nYour guess is ($x, $y).";
            for 0 ..^ $MUGWUMPS  -> $m {
                if is_here($m, $x, $y) {
                    @mugwump[$m].hidden = False;
                    $found += 1;
                    put "You have found mugwump $m!";
                    if $found == $MUGWUMPS {
                        last TURNS_LOOP;
                    }
                }
            }
            for 0 ..^ $MUGWUMPS  -> $m {
                if @mugwump[$m].hidden {
                    put "You are {distance($m, $x, $y)} units from mugwump $m.";
                }
            }
            put '';
        } # turns
        if $found == $MUGWUMPS {
            put "You got them all in $turn turn{plural($turn)}!\n";
            put "That was fun! let's play again…";
            put 'Four more mugwumps are now in hiding.';
        } else {
            put "Sorry, that's $TURNS tr{plural($TURNS, "ies", "y")}.\n";
            put "Here is where they're hiding:";
            for 0 ..^ $MUGWUMPS  -> $m {
                if @mugwump[$m].hidden {
                    put "Mugwump $m is at ({@mugwump[$m].x}, {@mugwump[$m].y}).";
                }
            }
        }
        put '';
        if not yes('Do you want to play again? ') {
            last;
        }
    } # game

}

print_credits;
print_instructions;
play;

En Ring

/*
Mugwump

Original version in BASIC:
    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
    Slightly modified by Bob Albrecht of People's Computer Company.
    Published by Creative Computing (Morristown, New Jersey, USA), 1978.
    - https://www.atariarchives.org/basicgames/showpage.php?page=114
    - http://vintage-basic.net/games.html

This version in Ring:
    Copyright (c) 2024, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written in 2024-03/04.

Last modified: 20240405T1416+0200.
*/

GRID_SIZE = 10
TURNS = 10
MUGWUMPS = 4

mugwump = list(MUGWUMPS)

found = 0 // counter

# Clear the terminal and move the cursor to the top left position.
func clearScreen()
    system("clear")
end

// Return `true` if the given string is "yes" or a synonym.
func isYes(answer) {
    switch lower(answer) {
        case "y" return true
        case "yeah" return true
        case "yes" return true
        case "ok" return true
        else return false
    }
}

// Return `true` if the given string is "no" or a synonym.
func isNo(answer) {
    switch lower(answer) {
        case "n" return true
        case "no" return true
        case "nope" return true
        else return false
    }
}

// Print the given prompt, wait until the user enters a valid yes/no
// String, and return `true` for "yes" or `false` for "no".
func yes(prompt) {
    answer = ""
    while (!(isYes(answer) || isNo(answer))) {
        print(prompt + nl)
        answer = getString()
    }
    return isYes(answer)
}

// Clear the screen, print the credits and ask the user to press enter.
func printCredits() {
    clearScreen()
    print("Mugwump\n\n")
    print("Original version in BASIC:\n")
    print(" Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).\n")
    print(" Slightly modified by Bob Albrecht of People's Computer Company.\n")
    print(" Published by Creative Computing (Morristown, New Jersey, USA), 1978.\n")
    print(" - https://www.atariarchives.org/basicgames/showpage.php?page=114\n")
    print(" - http://vintage-basic.net/games.html\n\n")
    print("This version in Ring:\n")
    print(" Copyright (c) 2024, Marcos Cruz (programandala.net)\n")
    print(" SPDX-License-Identifier: Fair\n\n")
    print("Press Enter to read the instructions. ")
    getString()
}

// Clear the screen, print the instructions and ask the user to press enter.
func printInstructions() {
    clearScreen()
    print("Mugwump\n\n")
    print("The object of this game is to find four mugwumps\n")
    print("hidden on a 10 by 10 grid.  Homebase is position 0,0.\n")
    print("Any guess you make must be two numbers with each\n")
    print("number between 0 and 9, inclusive.  First number\n")
    print("is distance to right of homebase and second number\n")
    print("is distance above homebase.\n\n")
    print("You get #{TURNS} tries.  After each try, you will see\n")
    print("how far you are from each mugwump.\n\n")
    print("Press Enter to start. ")
    getString()
}

// Init the mugwumps' positions, `hidden` flags and count.
func hideMugwumps() {
    for m = 1 to MUGWUMPS {
        mugwump[m].x = random(GRID_SIZE - 1) + 1
        mugwump[m].y = random(GRID_SIZE - 1) + 1
        mugwump[m].hidden = true
    }
    found = 0 // counter
}

// Create the mugwumps.
func createMugwumps() {
    for m = 1 to MUGWUMPS {
        mugwump[m] = new Mugwump { x = 0 y = 0 hidden = false }
    }
}

// Print the given prompt, wait until the user enters a valid coord
// and return it.
func getCoord(prompt) {
    while (true) {
        print(prompt)
        coord = getNumber()
        if (coord < 0 || coord >= GRID_SIZE) {
            print("Invalid value #{coord}: not in range [0, #{GRID_SIZE - 1}].\n")
        else
            break
        }
    }
    return coord
}

// Return `true` if the given mugwump is hidden in the given coords.
func isHere(m, x, y) {
    return mugwump[m].hidden && mugwump[m].x = x && mugwump[m].y = y
}

// Return the distance between the given mugwump and the given coords.
func distance(m, xCoord, yCoord) {
    return floor(sqrt(((mugwump[m].x - xCoord) ** 2) + ((mugwump[m].y - yCoord) ** 2)))
}

// Return a plural ending (default: "s") if the given number is greater than 1;
// otherwise return a singular ending (default: an empty string).
func plural(n, pluralEnding, singularEnding) {
    if (n > 1) {
        if pluralEnding = null {
            return "s" // default
        else
            return pluralEnding
        }
    else
        if singularEnding = null {
            return "" // default
        else
            return singularEnding
        }
    }
}

// Run the game.
func play() {
    createMugwumps()
    while (true) { // game
        clearScreen()
        hideMugwumps()
        turn = 1
        while (turn <= TURNS) {
            print("Turn number #{turn}\n\n")
            print("What is your guess (in range 0..#{GRID_SIZE - 1})?\n")
            x = getCoord("Distance right of homebase (x-axis): ")
            y = getCoord("Distance above homebase (y-axis): ")
            print("Your guess is (#{x}, #{y}).\n")
            for m = 1 to len(mugwump) {
                if (isHere(m, x, y)) {
                    mugwump[m].hidden = false
                    found += 1
                    print("You have found mugwump #{m}!\n")
                    if (found = len(mugwump)) { break 2 }
                }
            }
            for m = 1 to len(mugwump) {
                if (mugwump[m].hidden) {
                    print("You are #{distance(m, x, y)} units from mugwump #{m}.\n")
                }
            }
            print("\n")
            turn += 1
        } // turns
        if (found = len(mugwump)) {
            print("\nYou got them all in #{turn} #{plural(turn, null, null)}!\n")
            print("That was fun! let's play again…\n")
            print("Four more mugwumps are now in hiding.\n")
        else
            print("Sorry, that's #{TURNS} tr" + plural(TURNS, "ies", "y") + "\n")
            print("Here is where they're hiding:\n")
            for m = 1 to len(mugwump) {
                if (mugwump[m].hidden) {
                    print("Mugwump #{m} is at (#{mugwump[m].x}, #{mugwump[m].y}).\n")
                }
            }
        }
        print("\n")
        if (!yes("Do you want to play again? ")) { break }
    } // game
}

func main() {
    printCredits()
    printInstructions()
    play()
}

class Mugwump {
    x = 0
    y = 0
    hidden = false
}

En Scala

// Mugwump
//
// Original version in BASIC:
//   Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
//   Slightly modified by Bob Albrecht of People's Computer Company.
//   Published by Creative Computing (Morristown, New Jersey, USA), 1978.
//   - https://www.atariarchives.org/basicgames/showpage.php?page=114
//   - http://vintage-basic.net/games.html
//
// This version in Scala:
//   Copyright (c) 2023, Marcos Cruz (programandala.net)
//   SPDX-License-Identifier: Fair
//
// Written in 2023-09, 2023-11.
//
// Last modified: 20231104T0113+0100.

val GridSize = 10
val Turns = 10
val Mugwumps = 4

class Mugwump :
  var hidden : Boolean = true
  var x : Int = 0
  var y : Int = 0
  def reveal() =
    hidden = false
  def init() =
    hidden = true
    x = util.Random.nextInt(GridSize)
    y = util.Random.nextInt(GridSize)

// Moves the cursor to the top left position of the terminal.
def home() =
  print("\u001B[H")

// Clears the terminal and moves the cursor to the top left position.
def clear() =
  print("\u001B[2J")
  home()

// Prompts the user to enter a command and returns it trimmed.
def command(prompt : String = "> ") : String =
  io.StdIn.readLine(prompt).trim

// Prints the given prompt, waits until the user enters a valid integer and
// returns it.
def getNumber(prompt : String) : Int =
  var number = 0
  var ok = false
  while !ok do
    try
      number = command(prompt).toInt
      ok = true
    catch
    case _ => println("Invalid number.")
  number

// Prints the given prompt and waits until the user enters an empty string.
def pressEnter(prompt : String) =
  var ok = false
  while !ok do
    ok = io.StdIn.readLine(prompt) == ""

// Returns `true` if the given string is "yes" or a synonym.
def isYes(answer : String) : Boolean =
  answer.toLowerCase match
    case "ok" => true
    case "yeah" => true
    case "yes" => true
    case "y" => true
    case _ => false

// Returns `true` if the given string is "no" or a synonym.
def isNo(answer : String) : Boolean =
  answer.toLowerCase match
    case "no" => true
    case "nope" => true
    case "n" => true
    case _ => false

// Prints the given prompt, waits until the user enters a valid yes/no
// string, and returns `true` for "yes" or `false` for "no".
def yes(prompt : String) : Boolean =
  var answer : String = ""
  while !(isYes(answer) || isNo(answer)) do
    answer = command(prompt)
  isYes(answer)

// Clears the screen, prints the credits and asks the user to press enter.
def printCredits() =
  clear()
  println("Mugwump\n")
  println("Original version in BASIC:")
  println("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
  println("    Slightly modified by Bob Albrecht of People's Computer Company.")
  println("    Published by Creative Computing (Morristown, New Jersey, USA), 1978.")
  println("    - https://www.atariarchives.org/basicgames/showpage.php?page=114")
  println("    - http://vintage-basic.net/games.html\n")
  println("This version in Scala:")
  println("    Copyright (c) 2023, Marcos Cruz (programandala.net)")
  println("    SPDX-License-Identifier: Fair\n")
  pressEnter("Press Enter to read the instructions. ")

// Clears the screen, prints the instructions and asks the user to press enter.
def printInstructions() =
  clear()
  println("Mugwump\n")
  println("The object of this game is to find four mugwumps")
  println("hidden on a 10 by 10 grid.  Homebase is position 0,0.")
  println("Any guess you make must be two numbers with each")
  println("number between 0 and 9, inclusive.  First number")
  println("is distance to right of homebase and second number")
  println("is distance above homebase.\n")
  print(s"You get ${Turns} tries.  After each try, you will see\n")
  println("how far you are from each mugwump.\n")
  pressEnter("Press Enter to start. ")

// Prints the given prompt, then waits until the user enters a valid coord and
// returns it.
def getCoord(prompt : String) : Int =
  var coord : Int = 0
  var right = false
  while !right do
    coord = getNumber(prompt)
    if coord < 0 || coord >= GridSize then
      print(s"Invalid value ${coord}: not in range [0, ${GridSize - 1}].\n")
    else
      right = true
  coord

// Returns `true` if the given mugwump is hidden in the given coords.
def isHere(m : Mugwump, x : Int, y : Int) : Boolean =
  m.hidden && m.x == x && m.y == y

// Returns the distance between the given mugwump and the given coords.
def distance(m : Mugwump, x : Int, y : Int) : Int =
  math.sqrt(math.pow((m.x - x), 2) + math.pow((m.y - y), 2)).toInt

// If the given number is greater than 1, this method returns a plural ending
// (default: "s"); otherwise it returns a singular ending (default: an empty
// string).
def plural(n : Int, plural : String = "s", singular : String = "") : String =
  if n > 1 then plural else singular

// Prints the mugwumps found in the given coordinates and returns the count.
def foundAt(mugwump : Array[Mugwump], x : Int, y : Int) : Int =
  var found : Int = 0
  for m <- 0 until Mugwumps do
    if isHere(mugwump(m), x, y) then
      mugwump(m).reveal()
      found += 1
      print(s"You have found mugwump ${m}!\n")
    end if
  end for
  found

// Runs the game.
def play() =

  var found : Int = 0 // counter
  var turn : Int = 0 // counter
  var m : Int = 0
  var x : Int = 0
  var y : Int = 0
  var gameOver = false

  val mugwump = new Array[Mugwump](Mugwumps)
  for m <- 0 until Mugwumps do
    mugwump(m) = new Mugwump

  while !gameOver do // game

    clear()

    for m <- 0 until Mugwumps do
      mugwump(m).init()

    found = 0
    turn = 0
    while turn < Turns && found < Mugwumps do
      turn += 1
      print(s"Turn number ${turn}\n\n")
      print(s"What is your guess (in range [0, ${GridSize - 1}])?\n")
      x = getCoord("Distance right of homebase (x-axis): ")
      y = getCoord("Distance above homebase (y-axis): ")
      print(s"\nYour guess is ($x, $y).\n")
      found += foundAt(mugwump, x, y)
      if found < Mugwumps then
        for m <- 0 until Mugwumps do
          if mugwump(m).hidden then
            print(s"You are ${distance(mugwump(m), x, y)} units from mugwump ${m}.\n")
          end if
        end for
        println("")
      end if
    end while // turns

    if found == Mugwumps then
      print(s"\nYou got them all in ${turn} turn${plural(turn)}!\n\n")
      println("That was fun! let's play again…")
      println("Four more mugwumps are now in hiding.")
    else
      print(s"\nSorry, that's ${Turns} tr${plural(Turns, "ies", "y")}.\n\n")
      println("Here is where they're hiding:")
      for m <- 0 until Mugwumps do
        if mugwump(m).hidden then
          print(s"Mugwump $m is at (${mugwump(m).x}, ${mugwump(m).y}).\n")
        end if
      end for
    end if

    println("")
    gameOver = !yes("Do you want to play again? ")

  end while // game

@main def main() =
  printCredits()
  printInstructions()
  play()

En V

/*
Mugwump

Original version in BASIC:
    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).
    Slightly modified by Bob Albrecht of People's Computer Company.
    Published by Creative Computing (Morristown, New Jersey, USA), 1978.
    - https://www.atariarchives.org/basicgames/showpage.php?page=114
    - http://vintage-basic.net/games.html

This version in V:
    Copyright (c) 2025, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2025-01-07

Last modified: 20250406T0126+0200.
*/
import math
import os
import rand
import strconv
import term

const grid_size = 10
const turns = 10
const mugwumps = 4

struct Mugwump {
mut:
    x      int
    y      int
    hidden bool
}

// Print the given prompt and wait until the user enters a string.
//
fn input_string(prompt string) string {
    return os.input(prompt)
}

// Print the given prompt and wait until the user enters an integer.
//
fn input_int(prompt string) int {
    mut n := 0
    for {
        n = strconv.atoi(input_string(prompt)) or { continue }
        break
    }
    return n
}

// Print the given prompt and wait until the user enters an empty string.
//
fn press_enter(prompt string) {
    for input_string(prompt).len != 0 {}
}

// Return `true` if the given string is "yes" or a synonym.
//
fn is_yes(s string) bool {
    return ['ok', 'y', 'yeah', 'yes'].any(it == s.to_lower())
}

// Return `true` if the given string is "no" or a synonym.
//
fn is_no(s string) bool {
    return ['n', 'no', 'nope'].any(it == s.to_lower())
}

// Print the given prompt, wait until the user enters a valid yes/no string,
// and return `true` for "yes" or `false` for "no".
//
fn yes(prompt string) bool {
    mut result := false
    for {
        answer := input_string(prompt)
        if is_yes(answer) {
            result = true
            break
        }
        if is_no(answer) {
            result = false
            break
        }
    }
    return result
}

// Clear the screen, print the credits and ask the user to press enter.
//
fn print_credits() {
    term.clear()
    println('Mugwump\n')
    println('Original version in BASIC:')
    println("    Written by Bud Valenti's students of Project SOLO (Pittsburg, Pennsylvania, USA).")
    println("    Slightly modified by Bob Albrecht of People's Computer Company.")
    println('    Published by Creative Computing (Morristown, New Jersey, USA), 1978.')
    println('    - https://www.atariarchives.org/basicgames/showpage.php?page=114')
    println('    - http://vintage-basic.net/games.html\n')
    println('This version in V:')
    println('    Copyright (c) 2025, Marcos Cruz (programandala.net)')
    println('    SPDX-License-Identifier: Fair\n')
    press_enter('Press Enter to read the instructions. ')
}

// Clear the screen, print the instructions and ask the user to press enter.
//
fn print_instructions() {
    term.clear()
    println('Mugwump\n')
    println('The object of this game is to find four mugwumps')
    println('hidden on a 10 by 10 grid.  Homebase is position 0,0.')
    println('Any guess you make must be two numbers with each')
    println('number between 0 and 9, inclusive.  First number')
    println('is distance to right of homebase and second number')
    println('is distance above homebase.\n')
    println('You get ${turns} tries.  After each try, you will see')
    println('how far you are from each mugwump.\n')
    press_enter('Press Enter to start. ')
}

// Init the mugwumps' positions, `hidden` flags and count.
//
fn hide_mugwumps(mut mugwump [mugwumps]Mugwump) {
    for m in 0 .. mugwumps {
        mugwump[m].x = rand.intn(grid_size) or { 0 }
        mugwump[m].y = rand.intn(grid_size) or { 0 }
        mugwump[m].hidden = true
    }
}

// Print the given prompt, wait until the user enters a valid coord and return
// it.
//
fn get_coord(prompt string) int {
    mut coord := 0
    for {
        coord = input_int(prompt)
        if coord < 0 || coord >= grid_size {
            println('Invalid value ${coord}: not in range [0, ${grid_size - 1}].')
        } else {
            break
        }
    }
    return coord
}

// Return `true` if the given mugwump is hidden in the given coords.
//
fn is_here(m Mugwump, x int, y int) bool {
    return m.hidden && m.x == x && m.y == y
}

// Return the distance between the given mugwump and the given coords.
//
fn distance(m Mugwump, x int, y int) int {
    return int(math.sqrt(math.pow(f64(m.x - x), 2) + math.pow(f64(m.y - y), 2)))
}

// Return a plural ending (default: "s") if the given number is greater than 1;
// otherwise return a singular ending (default: an empty string).
//
fn plural_(n int, plural string, singular string) string {
    return if n > 1 { plural } else { singular }
}

// Return a plural "s" ending if the given number is greater than 1;
// otherwise return an empty string.
//
fn plural(n int) string {
    return plural_(n, 's', '')
}

// Run the game.
//
fn play() {
    mut mugwump := [mugwumps]Mugwump{}
    mut found := 0 // counter

    mut x := 0
    mut y := 0
    mut turn := 0 // counter
    for { // game
        term.clear()
        hide_mugwumps(mut mugwump) // XXX FIXME
        found = 0
        turns_loop: for turn = 1; turn <= turns; turn += 1 {
            println('Turn number ${turn}\n')
            println('What is your guess (in range [0, ${grid_size - 1}])?')
            x = get_coord('Distance right of homebase (x-axis): ')
            y = get_coord('Distance above homebase (y-axis): ')
            println('\nYour guess is (${x}, ${y}).')
            for m in 0 .. mugwumps {
                if is_here(mugwump[m], x, y) {
                    mugwump[m].hidden = false
                    found += 1
                    println('You have found mugwump ${m}!')
                    if found == mugwumps {
                        break turns_loop
                    }
                }
            }
            for m in 0 .. mugwumps {
                if mugwump[m].hidden {
                    println('You are ${distance(mugwump[m], x, y)} units from mugwump ${m}.')
                }
            }
            println('')
        } // turns
        if found == mugwumps {
            println('\nYou got them all in ${turn} turn${plural(turn)}!\n')
            println("That was fun! let's play again…")
            println('Four more mugwumps are now in hiding.')
        } else {
            println("\nSorry, that's ${turns} tr${plural_(turns, 'ies', 'y')}.\n")
            println("Here is where they're hiding:")
            for m in 0 .. mugwumps {
                if mugwump[m].hidden {
                    println('Mugwump ${m} is at (${mugwump[m].x}, ${mugwump[m].y}).')
                }
            }
        }
        println('')
        if !yes('Do you want to play again? ') {
            break
        }
    } // game
}

fn main() {
    print_credits()
    print_instructions()
    play()
}

Páginas relacionadas

Basics off
Metaproyecto sobre los proyectos «Basics of…».

Enlaces externos relacionados