Skip to content

Instantly share code, notes, and snippets.

@peterhellberg
Created March 11, 2025 10:46
Show Gist options
  • Save peterhellberg/b4c26b1f3d71f8c6650e3969173d2b7c to your computer and use it in GitHub Desktop.
Save peterhellberg/b4c26b1f3d71f8c6650e3969173d2b7c to your computer and use it in GitHub Desktop.
const std = @import("std");
const Reset = "\x1b[0;0m";
const Red = "\x1b[0;31m";
const Green = "\x1b[0;32m";
const Black = "\x1b[0;30m";
const Who = enum {
N,
O,
X,
fn next(self: Who) Who {
return switch (self) {
.N => .O,
.O => .X,
.X => .O,
};
}
fn string(self: Who, comptime n: u4) []const u8 {
return switch (self) {
.N => Black ++ comptime number(n) ++ Reset,
.O => Red ++ "O" ++ Reset,
.X => Green ++ "X" ++ Reset,
};
}
fn number(n: u4) []const u8 {
return switch (n) {
0 => "1",
1 => "2",
2 => "3",
3 => "4",
4 => "5",
5 => "6",
6 => "7",
7 => "8",
8 => "9",
else => "N",
};
}
};
const Board = struct {
state: [9]Who = .{.N} ** 9,
turn: Who = .X,
fn at(self: *Board, comptime i: u4) []const u8 {
return self.state[@intCast(i)].string(i);
}
fn draw(self: *Board) !void {
const stdout = std.io.getStdOut().writer();
try stdout.print(
\\
\\ {s} | {s} | {s}
\\ ---+---+---
\\ {s} | {s} | {s}
\\ ---+---+---
\\ {s} | {s} | {s}
\\
\\ Turn: {s}
\\ Move:
, .{
self.at(0), self.at(1), self.at(2),
self.at(3), self.at(4), self.at(5),
self.at(6), self.at(7), self.at(8),
self
.turn.string(10),
});
}
};
var board = Board{};
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const invalidMove = Red ++ "\n TRY AGAIN!" ++ Reset ++ "\n";
while (true) {
try board.draw();
const n = getNumber(usize) catch {
try stdout.print(invalidMove, .{});
continue;
};
if (n == 0) {
board.state = .{.N} ** 9;
} else if (board.state[n - 1] == .N) {
board.state[n - 1] = board.turn;
board.turn = board.turn.next();
} else {
try stdout.print(invalidMove, .{});
}
}
}
fn getNumber(comptime number_type: type) !number_type {
const stdin = std.io.getStdIn().reader();
var buffer: [8]u8 = undefined;
if (try stdin.readUntilDelimiterOrEof(buffer[0..], '\n')) |value| {
const n = try std.fmt.parseInt(number_type, value, 10);
return if (n > 9) error.InvalidMove else n;
} else {
return error.InvalidMove;
}
}
@peterhellberg
Copy link
Author

xo

@peterhellberg
Copy link
Author

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "zig_xo",
        .root_source_file = b.path("xo.zig"),
        .target = target,
        .optimize = optimize,
    });

    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);

    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment