Hey everyone. I’m very new to both zig and programming in general. I do have experience with Python and R but just for simple data analysis purposes. Ive been going through ziglings…I decided to try and push myself by crafting a simple rock,paper,scissors game. Ive spent hours on it not getting anywhere, I’m starting to feel dumb. Ive been trying tonpiece together from the small amount of tutorials out there but Im at a loss. Would someone be willing to guide me in the right direction?
Welcome to the forum, @z1fire
You’re in the right place! I think there’s many people who would be more than happy to help you.
Can you give us some more info on the game you are trying to design?
Does the player pick one of the three options, and then the computer randomly selects another?
What kind of interface would you like? Does the console suffice?
Do you have any code that we can look at so far?
Here was a humorous post recently made by @jw3126 to randomly select an enum value and print it to the console (it was funny because that’s how the forum “solution” was resolved).
From: Const slice can be mutated? - #4 by jw3126
const std = @import("std");
const rand = std.rand;
pub fn main() void {
var rng = rand.DefaultPrng.init(42);
const Answer = enum {
squeek502,
IntegratedQuantum,
};
const answer = (rng.random().enumValue(Answer));
std.debug.print("Accept: {any}\n", .{answer});
}
That may give you an idea of how to start. You’ll probably want to use some kind of a switch statement to detect if the player choice defeats the computer’s choice. That said, we can talk more about that when you give us some more info to work from
Just a simple console game where a user picks one of the options a the computer selects random one. I dont have any code right now. Ive done nothing but type then delete all day lol.
Okay, I’ll build a simple version of this later and post a solution here when I have a moment.
You are awesome. I was doing everything i could before asking for help, but started getting frustrated after about the 5th hour of working on it. Ive just been having a hard time combining what ive been learning into something that works.
Thank you for that link. I will study that and try to understand it line by line.
I’d like to share what my goal is. First ill say I like zig even though i cant put my finger on why. Id like to start documenting my learning of zig in a way that will help and resonate with others that dont have a lot programming experience. Just from my observations it seems that most that are using zig come from a programming background so there is a void when it comes to tutorials for the simpler things. Id like to start doing that for that niche.
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;
}
}
I can not express how grateful i am of this!!! Ill get a chance tonight to really dig into it. Using this as inspiration would you be okay with me using this to create a youtube tutorial on it(of course after i feel confident i fully understand how it comes together and can explain as such.)
You may use it however you wish - full permission granted
If you have any questions, feel free to ask. I’m glad I could help you today!
Thank you!!! Im really finding the zig community to be some great people!
Glad to see that you made progress, if I can share one small piece of wisdom as somebody who also did a bit of data engineering in the past:
Data wrangling and analyisis is a very different skillset than software engineering. In both cases you use a programming language to implement your solution, but the constraints under which you do that work are significantly different. Zig puts explicit emphasis on many things that you normally just don’t even want to think about when dealing with data in, say, a jupyter notebook, and more in general the patterns and approaches to things are different when creating a generic software solution vs a data transformation script.
So this is a bit like in The Matrix when Neo asks Morpheus why does his eyes hurt: it’s because you’ve never used them.
Enjoy the experience of learning something new and, while it’s painful at times, keep in mind that it will make you a more well rounded professional in the end.
Thank you, i agree 100%. Knowing some python for data analysis is very different than knowing software engineering. I like data analysis but as i was learning python for it i started wanting to do more. I had heard of zig a while back and did a quick browse of it and it never left the back of my mind. Its been eating away at me to learn it.