Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exercises(queen-attack): remove input validation tests #335

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
37 changes: 14 additions & 23 deletions exercises/practice/queen-attack/.meta/example.zig
Original file line number Diff line number Diff line change
@@ -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;
}
4 changes: 4 additions & 0 deletions exercises/practice/queen-attack/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
11 changes: 5 additions & 6 deletions exercises/practice/queen-attack/queen_attack.zig
Original file line number Diff line number Diff line change
@@ -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");
Expand Down
71 changes: 25 additions & 46 deletions exercises/practice/queen-attack/test_queen_attack.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand All @@ -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));
}