mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2025-12-11 20:02:09 +00:00
Add Zig implementation
This commit is contained in:
parent
8e9e31f9b8
commit
152c38549b
@ -14,6 +14,9 @@ diff_program:meld
|
|||||||
# Settings for the c (cmocka) version
|
# Settings for the c (cmocka) version
|
||||||
#executable:${TEXTTEST_HOME}/c_cmocka/cmake-build-debug/main
|
#executable:${TEXTTEST_HOME}/c_cmocka/cmake-build-debug/main
|
||||||
|
|
||||||
|
# Settings for the zig version
|
||||||
|
#executable:${TEXTTEST_HOME}/zig/zig-out/bin/zig
|
||||||
|
|
||||||
# Settings for the Java version using Gradle wrapped in a python script
|
# Settings for the Java version using Gradle wrapped in a python script
|
||||||
#executable:${TEXTTEST_HOME}/Java/texttest_rig.py
|
#executable:${TEXTTEST_HOME}/Java/texttest_rig.py
|
||||||
#interpreter:python
|
#interpreter:python
|
||||||
|
|||||||
13
zig/.gitignore
vendored
Normal file
13
zig/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/zig
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=zig
|
||||||
|
|
||||||
|
### zig ###
|
||||||
|
# Zig programming language
|
||||||
|
|
||||||
|
zig-cache/
|
||||||
|
zig-out/
|
||||||
|
build/
|
||||||
|
build-*/
|
||||||
|
docgen_tmp/
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/zig
|
||||||
34
zig/README.md
Normal file
34
zig/README.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Gilded Rose starting position in Zig
|
||||||
|
|
||||||
|
I assume you have [installed](https://ziglang.org/learn/getting-started/#installing-zig) `zig` on your system.
|
||||||
|
|
||||||
|
## Run unit tests from the command line
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ zig build test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run the TextTest fixture on the command line
|
||||||
|
|
||||||
|
Build and install the executable
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ zig build
|
||||||
|
```
|
||||||
|
|
||||||
|
Execute it on the command line with an argument for the number of days:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ./zig/zig-out/bin/zig 10
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run the TextTest approval test that comes with this project
|
||||||
|
|
||||||
|
There are instructions in the [TextTest Readme](../texttests/README.md) for setting up TextTest.
|
||||||
|
You will need to specify the executable in [config.gr](../texttests/config.gr).
|
||||||
|
Uncomment this line to use it:
|
||||||
|
|
||||||
|
```
|
||||||
|
#executable:${TEXTTEST_HOME}/zig/zig-out/bin/zig
|
||||||
|
```
|
||||||
|
|
||||||
68
zig/build.zig
Normal file
68
zig/build.zig
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// Although this function looks imperative, note that its job is to
|
||||||
|
// declaratively construct a build graph that will be executed by an external
|
||||||
|
// runner.
|
||||||
|
pub fn build(b: *std.Build) 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 optimization options allow the person running `zig build` to select
|
||||||
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||||
|
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "zig",
|
||||||
|
.root_source_file = b.path("src/main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
// This declares intent for the executable to be installed into the
|
||||||
|
// standard location when the user invokes the "install" step (the default
|
||||||
|
// step when running `zig build`).
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
// This *creates* a Run step in the build graph, to be executed when another
|
||||||
|
// step is evaluated that depends on it. The next line below will establish
|
||||||
|
// such a dependency.
|
||||||
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
|
|
||||||
|
// By making the run step depend on the install step, it will be run from the
|
||||||
|
// installation directory rather than directly from within the cache directory.
|
||||||
|
// This is not necessary, however, if the application depends on other installed
|
||||||
|
// files, this ensures they will be present and in the expected location.
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
|
// This allows the user to pass arguments to the application in the build
|
||||||
|
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_cmd.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This creates a build step. It will be visible in the `zig build --help` menu,
|
||||||
|
// and can be selected like this: `zig build run`
|
||||||
|
// This will evaluate the `run` step rather than the default, which is "install".
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
|
||||||
|
// Creates a step for unit testing. This only builds the test executable
|
||||||
|
// but does not run it.
|
||||||
|
const lib_unit_tests = b.addTest(.{
|
||||||
|
.root_source_file = b.path("src/gilded_rose.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||||
|
|
||||||
|
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||||
|
// the `zig build --help` menu, providing a way for the user to request
|
||||||
|
// running the unit tests.
|
||||||
|
const test_step = b.step("test", "Run unit tests");
|
||||||
|
test_step.dependOn(&run_lib_unit_tests.step);
|
||||||
|
}
|
||||||
79
zig/src/gilded_rose.zig
Normal file
79
zig/src/gilded_rose.zig
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const Item = struct {
|
||||||
|
name: []const u8,
|
||||||
|
sell_in: i32,
|
||||||
|
quality: i32,
|
||||||
|
|
||||||
|
pub fn init(name: []const u8, sell_in: i32, quality: i32) Item {
|
||||||
|
return Item{
|
||||||
|
.name = name,
|
||||||
|
.sell_in = sell_in,
|
||||||
|
.quality = quality,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const GildedRose = struct {
|
||||||
|
items: []Item,
|
||||||
|
|
||||||
|
pub fn init(items: []Item) GildedRose {
|
||||||
|
return GildedRose{ .items = items };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn updateQuality(self: *GildedRose) []Item {
|
||||||
|
for (0..self.items.len) |i| {
|
||||||
|
if (!std.mem.eql(u8, self.items[i].name, "Aged Brie") and !std.mem.eql(u8, self.items[i].name, "Backstage passes to a TAFKAL80ETC concert")) {
|
||||||
|
if (self.items[i].quality > 0) {
|
||||||
|
if (!std.mem.eql(u8, self.items[i].name, "Sulfuras, Hand of Ragnaros")) {
|
||||||
|
self.items[i].quality = self.items[i].quality - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (self.items[i].quality < 50) {
|
||||||
|
self.items[i].quality = self.items[i].quality + 1;
|
||||||
|
if (std.mem.eql(u8, self.items[i].name, "Backstage passes to a TAFKAL80ETC concert")) {
|
||||||
|
if (self.items[i].sell_in < 11) {
|
||||||
|
if (self.items[i].quality < 50) {
|
||||||
|
self.items[i].quality = self.items[i].quality + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self.items[i].sell_in < 6) {
|
||||||
|
if (self.items[i].quality < 50) {
|
||||||
|
self.items[i].quality = self.items[i].quality + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!std.mem.eql(u8, self.items[i].name, "Sulfuras, Hand of Ragnaros")) {
|
||||||
|
self.items[i].sell_in = self.items[i].sell_in - 1;
|
||||||
|
}
|
||||||
|
if (self.items[i].sell_in < 0) {
|
||||||
|
if (!std.mem.eql(u8, self.items[i].name, "Aged Brie")) {
|
||||||
|
if (!std.mem.eql(u8, self.items[i].name, "Backstage passes to a TAFKAL80ETC concert")) {
|
||||||
|
if (self.items[i].quality > 0) {
|
||||||
|
if (!std.mem.eql(u8, self.items[i].name, "Sulfuras, Hand of Ragnaros")) {
|
||||||
|
self.items[i].quality = self.items[i].quality - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.items[i].quality = self.items[i].quality - self.items[i].quality;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (self.items[i].quality < 50) {
|
||||||
|
self.items[i].quality = self.items[i].quality + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self.items;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "updateQuality" {
|
||||||
|
var items = [_]Item{Item.init("foo", 0, 0)};
|
||||||
|
var app = GildedRose.init(&items);
|
||||||
|
_ = app.updateQuality();
|
||||||
|
try std.testing.expectEqualStrings("fixme", items[0].name);
|
||||||
|
}
|
||||||
43
zig/src/main.zig
Normal file
43
zig/src/main.zig
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const gilded_rose = @import("gilded_rose.zig");
|
||||||
|
const Item = gilded_rose.Item;
|
||||||
|
const GildedRose = gilded_rose.GildedRose;
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
|
const args = try std.process.argsAlloc(allocator);
|
||||||
|
var days: u8 = 2;
|
||||||
|
if (args.len >= 2) {
|
||||||
|
days = try std.fmt.parseInt(u8, args[1], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = [_]Item{
|
||||||
|
Item.init("+5 Dexterity Vest", 10, 20),
|
||||||
|
Item.init("Aged Brie", 2, 0),
|
||||||
|
Item.init("Elixir of the Mongoose", 5, 7),
|
||||||
|
Item.init("Sulfuras, Hand of Ragnaros", 0, 80),
|
||||||
|
Item.init("Sulfuras, Hand of Ragnaros", -1, 80),
|
||||||
|
Item.init("Backstage passes to a TAFKAL80ETC concert", 15, 20),
|
||||||
|
Item.init("Backstage passes to a TAFKAL80ETC concert", 10, 49),
|
||||||
|
Item.init("Backstage passes to a TAFKAL80ETC concert", 5, 49),
|
||||||
|
// this Conjured item doesn't yet work properly
|
||||||
|
Item.init("Conjured Mana Cake", 3, 6),
|
||||||
|
};
|
||||||
|
var app = GildedRose.init(&items);
|
||||||
|
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
try stdout.print("OMGHAI!\n", .{});
|
||||||
|
|
||||||
|
for (0..days + 1) |day| {
|
||||||
|
try stdout.print("-------- day {d} --------\n", .{day});
|
||||||
|
try stdout.print("name, sellIn, quality\n", .{});
|
||||||
|
for (items) |item| {
|
||||||
|
try stdout.print("{s}, {d}, {d}\n", .{ item.name, item.sell_in, item.quality });
|
||||||
|
}
|
||||||
|
try stdout.print("\n", .{});
|
||||||
|
_ = app.updateQuality();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user