From 85fbb331048eae03a2d739f3e3d45b6c14f71a94 Mon Sep 17 00:00:00 2001 From: Tarik Hijstek Date: Tue, 26 Jul 2022 23:31:46 +0200 Subject: [PATCH] initial --- .gitignore | 7 ++++++ build.zig | 34 +++++++++++++++++++++++++++++ readme.md | 5 +++++ src/main.zig | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ src/snooker.zig | 53 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+) create mode 100644 .gitignore create mode 100644 build.zig create mode 100644 readme.md create mode 100644 src/main.zig create mode 100644 src/snooker.zig diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab961ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +zig-cache/ +zig-out/ +/release/ +/debug/ +/build/ +/build-*/ +/docgen_tmp/ diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..62304af --- /dev/null +++ b/build.zig @@ -0,0 +1,34 @@ +const std = @import("std"); + +pub fn build(b: *std.build.Builder) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard release options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + const mode = b.standardReleaseOptions(); + + const exe = b.addExecutable("snookerScore", "src/main.zig"); + exe.setTarget(target); + exe.setBuildMode(mode); + exe.install(); + + const run_cmd = exe.run(); + 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); + + const exe_tests = b.addTest("src/main.zig"); + exe_tests.setTarget(target); + exe_tests.setBuildMode(mode); + + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&exe_tests.step); +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..fa4089a --- /dev/null +++ b/readme.md @@ -0,0 +1,5 @@ +# Snooker Scorer + +A rewrite from https://github.com/seltf/Snooker-Score-Tracker in zig. + +Targets zig 0.9.1 diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..6b92621 --- /dev/null +++ b/src/main.zig @@ -0,0 +1,57 @@ +const std = @import("std"); +const io = std.io; +const mem = std.mem; +const os = std.os; + +pub fn main() anyerror!void { + std.log.info("All your codebase are belong to us.", .{}); + + //Get input + const stdIn = io.getStdIn(); + const stdOut = io.getStdOut(); + var quit: bool = false; + + var buffer: [1000]u8 = undefined; + // var fba = std.heap.FixedBufferAllocator.init(&buffer); + // const allocator = fba.allocator(); + + try stdOut.writer().print(">", .{}); + while (!quit) { + const input = (try nextLine(stdIn.reader(), &buffer)).?; + + try parser(input); + try stdOut.writer().print(">", .{}); + } +} + +fn nextLine(reader: anytype, buffer: []u8) !?[]const u8 { + var line = (try reader.readUntilDelimiterOrEof( + buffer, + '\n', + )) orelse return null; + // trim annoying windows-only carriage return character + if (@import("builtin").os.tag == .windows) { + return std.mem.trimRight(u8, line, "\r"); + } else { + return line; + } +} + +//TODO: Create command parser +fn parser(query: []const u8) !void { + if (mem.eql(u8, query, "quit")) { + try quitApp(); + } +} + +fn quitApp() !void { + const stdOut = io.getStdOut(); + try stdOut.writer().print("Bye!\n", .{}); + os.exit(0); +} + +//TODO: Create inital settings + +test "basic test" { + try std.testing.expectEqual(10, 3 + 7); +} diff --git a/src/snooker.zig b/src/snooker.zig new file mode 100644 index 0000000..061af10 --- /dev/null +++ b/src/snooker.zig @@ -0,0 +1,53 @@ +const testing = @import("std").testing; +// Snooker game rules +// 15 red balls to start. + +const ballValue = enum(u8) { + red = 1, + yellow = 2, + green = 3, + brown = 4, + blue = 5, + pink = 6, + black = 7, +}; + +const Table = struct { + ///Holds all balls in play. + var balls: [21]ballValue = .{ ballValue.red ** 15, ballValue.yellow, ballValue.green, ballValue.brown, ballValue.blue, ballValue.pink, ballValue.black }; + var lastPottedBall: ballValue = undefined; + var currentStriker: u8 = 0; + + /// Removes a ball from play, and adds the score to the current player. + pub fn potBall(self: Table, pottedBall: ballValue) void { + //TODO: Remove Red ball from play. + //TODO: increment current player's score + + if (pottedBall == lastPottedBall) { + //This is an illegal snooker play. + //End the turn & Red ball is NOT respotted. + } + + if (pottedBall == ballValue.red) { + //remove ball from play + var ballIndex = findBall(pottedBall); + self.balls.indexOfScalar(ballValue.red); + self.balls[ballIndex] = 0; + } + } + + fn findBall(self: Table, ballScore: ballValue) error{notFound}!u8 { + for (self.balls) |ball, index| { + if (ball == ballScore) { + return index; + } + } + return error.notFound; + } +}; + +test "potRed" { + Table.potBall(ballValue.red); + + //expect red ball to be removed. +}