Noob help with simple game

Here’s a working example with some descriptions to help along the way. You can do this in a variety of ways - I chose to use buffers and ints for simplicity.

This is a one round rock-paper-scissors game. For fun, see if you can make it multi-round. You’ll have to specify a break character and detect that before you attempt to convert the input to an integer.

It’s similar to @andrewrk’s link that was provided. You can see that most of our difficulty deals with reading and verifying input. The game logic is actually quite small.

You can also deal with a smaller buffer size if you discard the remaining input from stdin. For very large input sizes (greater than the buffer), the game will loop and replay whatever value remains in the buffer. I’ll leave that up to you as a research opportunity if you choose to do so.

const std = @import("std");
const io = std.io;   // handle for input and output utilities
const fmt = std.fmt; // handle for string formatting utilities


// We can do this in a variety of ways, but for this example, I'll
// choose directly using u8's instead of using enums. This can be
// done with enums as well.

// The reason I am using u8's is because I will be using them as
// indices into an array to get winning move combinations. Instead
// of converting enums to integers, we can just directly use the
// integers because we have a very small set of things to consider.


const rock: u8 = 0;
const paper: u8 = 1;
const scissors: u8 = 2;

// use this string array to print the computer choice later
const description: [3][] const u8 = .{
    "Rock", 
    "Paper", 
    "Scissors"
};

// Now we set up an array with the winning move for each value...
const winning_choice: [3]u8 = .{
    scissors, // rock (index 0) beats scissors
    rock, // paper (index 1) beats rock
    paper, // scissors (index 2) beats paper
};

// now, we can use this syntax:

// if (winning_choice[player_choice] == computer_choice) -> you win


pub fn main() !void {
    // setup our standard-out io
    const stdout = io.getStdOut().writer();    

    // setup our standard-in io
    const stdin = io.getStdIn();

    try stdout.print("\n\n--Rock Paper Scissors --\n\n", .{});

    while (true) {

        ////////////////////////////////
        // HANDLE USER INPUT FROM STDIN

        try stdout.print("\nEnter choice:\n  0 : Rock\n  1 : Paper\n  2 : Scissors\n\n", .{});

        var line_buf: [128]u8 = undefined; // larger than we need

        // read an amount from standard in
        const amt = try stdin.read(&line_buf);

        // the selection should only be two characters long ([0,2]+delimiter)
        if (amt == line_buf.len) {
            try stdout.print("\nInput too long.\n", .{});
            continue;
        }

        // clean the white-space/delimiters from the input
        const cleaned = std.mem.trimRight(u8, line_buf[0..amt], "\r\n");

        //////////////////////////////
        // GET COMPUTER/PLAYER CHOICES

        // it doesn't matter who chooses first 
        const computer_choice = std.crypto.random.intRangeLessThan(u8, 0, 3);

        // try to read a base ten integer from the cleaned input
        const player_choice = fmt.parseUnsigned(u8, cleaned, 10) catch {
            try stdout.print("\nInvalid Number.\n", .{});
            continue;
        };

        // make sure the player chose something reasonable
        if (player_choice > 2) {
            try stdout.print("\nNumber must be in range [0,2].\n", .{});
            continue;
        }

        ////////////////////////////////
        // COMPARE AND DETERMINE OUTCOME

        try stdout.print("\nComputer Choice: {s}\n", .{ description[computer_choice]});

        if (player_choice == computer_choice) {
            try stdout.print("\nIt's a draw!\n", .{});
        }
        else if (winning_choice[player_choice] == computer_choice) {
            try stdout.print("\nHumanity survives another day!\n", .{});
        }
        else {            
            try stdout.print("\nAll hail our AI overlords!\n", .{});
        }
        
        return; 
    }
}

3 Likes