Created
March 11, 2025 10:46
-
-
Save peterhellberg/b4c26b1f3d71f8c6650e3969173d2b7c to your computer and use it in GitHub Desktop.
Xs and Os in Zig ⚡ https://www.zigfiddle.dev/?UA402D7T7J8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Author
peterhellberg
commented
Mar 11, 2025
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