diff --git a/config.json b/config.json index 18a74d5c..0795d495 100644 --- a/config.json +++ b/config.json @@ -378,15 +378,15 @@ "slug": "queen-attack", "name": "Queen Attack", "practices": [ + "asserting", "control-flow", - "error-sets", "importing", "methods", "structs" ], "prerequisites": [ + "asserting", "control-flow", - "error-sets", "importing", "methods", "structs" diff --git a/exercises/practice/queen-attack/.meta/example.zig b/exercises/practice/queen-attack/.meta/example.zig index 58b8845d..16491439 100644 --- a/exercises/practice/queen-attack/.meta/example.zig +++ b/exercises/practice/queen-attack/.meta/example.zig @@ -1,31 +1,22 @@ const std = @import("std"); -const math = std.math; - -pub const QueenError = error{ - InitializationFailure, - InvalidAttack, -}; pub const Queen = struct { - row: i8, - col: i8, + row: u3, + col: u3, - pub fn init(row: i8, col: i8) QueenError!Queen { - if (row < 0 or row > 7 or col < 0 or col > 7) { - return QueenError.InitializationFailure; - } - return Queen{ - .row = row, - .col = col, - }; + pub fn init(row: u3, col: u3) Queen { + return .{ .row = row, .col = col }; } - pub fn canAttack(self: Queen, other: Queen) QueenError!bool { - if (self.row == other.row and self.col == other.col) { - return QueenError.InvalidAttack; - } - return (self.row == other.row) or (self.col == other.col) or - (math.absInt(self.row - other.row) catch unreachable == - math.absInt(self.col - other.col) catch unreachable); + /// Asserts that `a` and `b` are on different squares. + pub fn canAttack(a: Queen, b: Queen) bool { + std.debug.assert(a.row != b.row or a.col != b.col); + return a.row == b.row or a.col == b.col or + absDiff(u3, a.row, b.row) == absDiff(u3, a.col, b.col); } }; + +// Returns the absolute difference of `a` and `b`. +fn absDiff(comptime T: type, a: T, b: T) T { + return if (a > b) a - b else b - a; +} diff --git a/exercises/practice/queen-attack/.meta/tests.toml b/exercises/practice/queen-attack/.meta/tests.toml index e0624123..bb2e506d 100644 --- a/exercises/practice/queen-attack/.meta/tests.toml +++ b/exercises/practice/queen-attack/.meta/tests.toml @@ -14,15 +14,19 @@ description = "Test creation of Queens with valid and invalid positions -> queen [4e812d5d-b974-4e38-9a6b-8e0492bfa7be] description = "Test creation of Queens with valid and invalid positions -> queen must have positive row" +include = false [f07b7536-b66b-4f08-beb9-4d70d891d5c8] description = "Test creation of Queens with valid and invalid positions -> queen must have row on board" +include = false [15a10794-36d9-4907-ae6b-e5a0d4c54ebe] description = "Test creation of Queens with valid and invalid positions -> queen must have positive column" +include = false [6907762d-0e8a-4c38-87fb-12f2f65f0ce4] description = "Test creation of Queens with valid and invalid positions -> queen must have column on board" +include = false [33ae4113-d237-42ee-bac1-e1e699c0c007] description = "Test the ability of one queen to attack another -> cannot attack" diff --git a/exercises/practice/queen-attack/queen_attack.zig b/exercises/practice/queen-attack/queen_attack.zig index 2e8990ff..ebd6a3ff 100644 --- a/exercises/practice/queen-attack/queen_attack.zig +++ b/exercises/practice/queen-attack/queen_attack.zig @@ -1,15 +1,14 @@ -pub const QueenError = error{ - InitializationFailure, -}; - pub const Queen = struct { - pub fn init(row: i8, col: i8) QueenError!Queen { + // Please implement the fields of this struct. + + pub fn init(row: u3, col: u3) Queen { _ = row; _ = col; @compileError("please implement the init method"); } - pub fn canAttack(self: Queen, other: Queen) QueenError!bool { + /// Asserts that `self` and `other` are on different squares. + pub fn canAttack(self: Queen, other: Queen) bool { _ = self; _ = other; @compileError("please implement the canAttack method"); diff --git a/exercises/practice/queen-attack/test_queen_attack.zig b/exercises/practice/queen-attack/test_queen_attack.zig index 5511811a..f6b34cf7 100644 --- a/exercises/practice/queen-attack/test_queen_attack.zig +++ b/exercises/practice/queen-attack/test_queen_attack.zig @@ -2,14 +2,13 @@ const std = @import("std"); const testing = std.testing; const queen_attack = @import("queen_attack.zig"); -const QueenError = queen_attack.QueenError; test "queen has exactly two fields" { try testing.expectEqual(2, std.meta.fields(queen_attack.Queen).len); } test "queen with a valid position" { - const queen = try queen_attack.Queen.init(2, 2); + const queen = queen_attack.Queen.init(2, 2); // Allow the fields to have any name. const fields = std.meta.fields(@TypeOf(queen)); inline for (fields) |f| { @@ -19,70 +18,50 @@ test "queen with a valid position" { } } -test "queen must have positive row" { - const queen = queen_attack.Queen.init(-2, 2); - try testing.expectError(QueenError.InitializationFailure, queen); -} - -test "queen must have row on board" { - const queen = queen_attack.Queen.init(8, 4); - try testing.expectError(QueenError.InitializationFailure, queen); -} - -test "queen must have positive column" { - const queen = queen_attack.Queen.init(2, -2); - try testing.expectError(QueenError.InitializationFailure, queen); -} - -test "queen must have column on board" { - const queen = queen_attack.Queen.init(4, 8); - try testing.expectError(QueenError.InitializationFailure, queen); -} - test "cannot attack" { - const white = try queen_attack.Queen.init(2, 4); - const black = try queen_attack.Queen.init(6, 6); - try testing.expect(!try white.canAttack(black)); + const white = queen_attack.Queen.init(2, 4); + const black = queen_attack.Queen.init(6, 6); + try testing.expect(!white.canAttack(black)); } test "can attack on same row" { - const white = try queen_attack.Queen.init(2, 4); - const black = try queen_attack.Queen.init(2, 6); - try testing.expect(try white.canAttack(black)); + const white = queen_attack.Queen.init(2, 4); + const black = queen_attack.Queen.init(2, 6); + try testing.expect(white.canAttack(black)); } test "can attack on same column" { - const white = try queen_attack.Queen.init(4, 5); - const black = try queen_attack.Queen.init(2, 5); - try testing.expect(try white.canAttack(black)); + const white = queen_attack.Queen.init(4, 5); + const black = queen_attack.Queen.init(2, 5); + try testing.expect(white.canAttack(black)); } test "can attack on first diagonal" { - const white = try queen_attack.Queen.init(2, 2); - const black = try queen_attack.Queen.init(0, 4); - try testing.expect(try white.canAttack(black)); + const white = queen_attack.Queen.init(2, 2); + const black = queen_attack.Queen.init(0, 4); + try testing.expect(white.canAttack(black)); } test "can attack on second diagonal" { - const white = try queen_attack.Queen.init(2, 2); - const black = try queen_attack.Queen.init(3, 1); - try testing.expect(try white.canAttack(black)); + const white = queen_attack.Queen.init(2, 2); + const black = queen_attack.Queen.init(3, 1); + try testing.expect(white.canAttack(black)); } test "can attack on third diagonal" { - const white = try queen_attack.Queen.init(2, 2); - const black = try queen_attack.Queen.init(1, 1); - try testing.expect(try white.canAttack(black)); + const white = queen_attack.Queen.init(2, 2); + const black = queen_attack.Queen.init(1, 1); + try testing.expect(white.canAttack(black)); } test "can attack on fourth diagonal" { - const white = try queen_attack.Queen.init(1, 7); - const black = try queen_attack.Queen.init(0, 6); - try testing.expect(try white.canAttack(black)); + const white = queen_attack.Queen.init(1, 7); + const black = queen_attack.Queen.init(0, 6); + try testing.expect(white.canAttack(black)); } test "cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal" { - const white = try queen_attack.Queen.init(4, 1); - const black = try queen_attack.Queen.init(2, 5); - try testing.expect(!try white.canAttack(black)); + const white = queen_attack.Queen.init(4, 1); + const black = queen_attack.Queen.init(2, 5); + try testing.expect(!white.canAttack(black)); }