Skip to content
1 change: 1 addition & 0 deletions bin/auto-sync.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ phone-number
pig-latin
protein-translation
proverb
queen-attack
raindrops
reverse-string
rna-transcription
Expand Down
36 changes: 15 additions & 21 deletions exercises/practice/queen-attack/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
# Instructions

Given the position of two queens on a chess board, indicate whether or not they
are positioned so that they can attack each other.
Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.

In the game of chess, a queen can attack pieces which are on the same
row, column, or diagonal.
In the game of chess, a queen can attack pieces which are on the same row, column, or diagonal.

A chessboard can be represented by an 8 by 8 array.

So if you're told the white queen is at (2, 3) and the black queen at
(5, 6), then you'd know you've got a set-up like so:

```text
_ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ W _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ _ _ _ B _
_ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _
```

You'd also be able to answer whether the queens can attack each other.
In this case, that answer would be yes, they can, because both pieces
share a diagonal.
So if you are told the white queen is at `c5` (zero-indexed at column 2, row 3) and the black queen at `f2` (zero-indexed at column 5, row 6), then you know that the set-up is like so:

![A chess board with two queens. Arrows emanating from the queen at c5 indicate possible directions of capture along file, rank and diagonal.](https://assets.exercism.org/images/exercises/queen-attack/queen-capture.svg)

You are also able to answer whether the queens can attack each other.
In this case, that answer would be yes, they can, because both pieces share a diagonal.

## Credit

The chessboard image was made by [habere-et-dispertire][habere-et-dispertire] using LaTeX and the [chessboard package][chessboard-package] by Ulrike Fischer.

[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire
[chessboard-package]: https://github.com/u-fischer/chessboard
3 changes: 2 additions & 1 deletion exercises/practice/queen-attack/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"G-Rath",
"kunicmarko20",
"kytrinyx",
"petemcfarlane"
"petemcfarlane",
"A-O-Emmanuel"
],
"files": {
"solution": [
Expand Down
22 changes: 0 additions & 22 deletions exercises/practice/queen-attack/.meta/example.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

/**
Expand Down
40 changes: 25 additions & 15 deletions exercises/practice/queen-attack/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -1,39 +1,49 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[3ac4f735-d36c-44c4-a3e2-316f79704203]
description = "queen with a valid position"
description = "Test creation of Queens with valid and invalid positions -> queen with a valid position"

[4e812d5d-b974-4e38-9a6b-8e0492bfa7be]
description = "queen must have positive row"
description = "Test creation of Queens with valid and invalid positions -> queen must have positive row"

[f07b7536-b66b-4f08-beb9-4d70d891d5c8]
description = "queen must have row on board"
description = "Test creation of Queens with valid and invalid positions -> queen must have row on board"

[15a10794-36d9-4907-ae6b-e5a0d4c54ebe]
description = "queen must have positive column"
description = "Test creation of Queens with valid and invalid positions -> queen must have positive column"

[6907762d-0e8a-4c38-87fb-12f2f65f0ce4]
description = "queen must have column on board"
description = "Test creation of Queens with valid and invalid positions -> queen must have column on board"

[33ae4113-d237-42ee-bac1-e1e699c0c007]
description = "can not attack"
description = "Test the ability of one queen to attack another -> cannot attack"

[eaa65540-ea7c-4152-8c21-003c7a68c914]
description = "can attack on same row"
description = "Test the ability of one queen to attack another -> can attack on same row"

[bae6f609-2c0e-4154-af71-af82b7c31cea]
description = "can attack on same column"
description = "Test the ability of one queen to attack another -> can attack on same column"

[0e1b4139-b90d-4562-bd58-dfa04f1746c7]
description = "can attack on first diagonal"
description = "Test the ability of one queen to attack another -> can attack on first diagonal"

[ff9b7ed4-e4b6-401b-8d16-bc894d6d3dcd]
description = "can attack on second diagonal"
description = "Test the ability of one queen to attack another -> can attack on second diagonal"

[0a71e605-6e28-4cc2-aa47-d20a2e71037a]
description = "can attack on third diagonal"
description = "Test the ability of one queen to attack another -> can attack on third diagonal"

[0790b588-ae73-4f1f-a968-dd0b34f45f86]
description = "can attack on fourth diagonal"
description = "Test the ability of one queen to attack another -> can attack on fourth diagonal"

[543f8fd4-2597-4aad-8d77-cbdab63619f8]
description = "Test the ability of one queen to attack another -> cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal"
102 changes: 47 additions & 55 deletions exercises/practice/queen-attack/QueenAttackTest.php
Original file line number Diff line number Diff line change
@@ -1,30 +1,9 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\TestDox;

class QueenAttackTest extends TestCase
{
Expand All @@ -34,110 +13,123 @@ public static function setUpBeforeClass(): void
}

/**
* Test a queen is placed in a valid position.
* uuid: 3ac4f735-d36c-44c4-a3e2-316f79704203
*/
public function testCreateQueenWithValidPosition(): void
#[TestDox('Test creation of Queens with valid and invalid positions -> queen with a valid position')]
public function testCreationOfQueensWithValidAndInvalidPositionsCreateQueenWithValidPosition(): void
{
$this->assertTrue(placeQueen(2, 2));
}

/**
* Test the queen is placed on a positive rank.
* uuid: 4e812d5d-b974-4e38-9a6b-8e0492bfa7be
*/
public function testQueenHasPositiveRank(): void
#[TestDox('Test creation of Queens with valid and invalid positions -> queen must have positive row')]
public function testCreationOfQueensWithValidAndInvalidPositionsQueenMustHavePositiveRow(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The rank and file numbers must be positive.');

placeQueen(-2, 2);
}

/**
* Test the queen has a rank on the board.
* uuid: f07b7536-b66b-4f08-beb9-4d70d891d5c8
*/
public function testQueenHasRankOnBoard(): void
#[TestDox('Test creation of Queens with valid and invalid positions -> queen must have row on board')]
public function testCreationOfQueensWithValidAndInvalidPositionsQueenMustHaveRowOnBoard(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The position must be on a standard size chess board.');

placeQueen(8, 4);
}

/**
* Test the queen is placed on a positive file.
* uuid: 15a10794-36d9-4907-ae6b-e5a0d4c54ebe
*/
public function testQueenHasPositiveFile(): void
#[TestDox('Test creation of Queens with valid and invalid positions -> queen must have positive column')]
public function testCreationOfQueensWithValidAndInvalidPositionsQueenMustHavePositiveColumn(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The rank and file numbers must be positive.');

placeQueen(2, -2);
}

/**
* Test the queen has a file on the board.
* uuid: 6907762d-0e8a-4c38-87fb-12f2f65f0ce4
*/
public function testQueenHasFileOnBoard(): void
#[TestDox('Test creation of Queens with valid and invalid positions -> queen must have column on board')]
public function testCreationOfQueensWithValidAndInvalidPositionsQueenMustHaveColumnOnBoard(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The position must be on a standard size chess board.');

placeQueen(4, 8);
}

/**
* Test if queens can attack each other.
* uuid: 33ae4113-d237-42ee-bac1-e1e699c0c007
*/
public function testQueensCanAttack(): void
#[TestDox('Test the ability of one queen to attack another -> cannot attack')]
public function testTheAbilityOfOneQueenToAttackAnotherCannotAttack(): void
{
$this->assertFalse(canAttack([2, 4], [6, 6]));
}

/**
* Test if queens can attack each other on the same rank.
* uuid: eaa65540-ea7c-4152-8c21-003c7a68c914
*/
public function testQueensCanAttackOnSameRank(): void
#[TestDox('Test the ability of one queen to attack another -> can attack on same row')]
public function testTheAbilityOfOneQueenToAttackAnotherCanAttackOnSameRow(): void
{
$this->assertTrue(canAttack([2, 4], [2, 6]));
}

/**
* Test if queens can attack each other on the same file.
* uuid: bae6f609-2c0e-4154-af71-af82b7c31cea
*/
public function testQueensCanAttackOnSameFile(): void
#[TestDox('Test the ability of one queen to attack another -> can attack on same column')]
public function testTheAbilityOfOneQueenToAttackAnotherCanAttackOnSameColumn(): void
{
$this->assertTrue(canAttack([4, 5], [2, 5]));
}

/**
* Test if queens can attack each other on the first diagonal.
* uuid: 0e1b4139-b90d-4562-bd58-dfa04f1746c7
*/
public function testQueensCanAttackOnFirstDiagonal(): void
#[TestDox('Test the ability of one queen to attack another -> can attack on first diagonal')]
public function testTheAbilityOfOneQueenToAttackAnotherCanAttackOnFirstDiagonal(): void
{
$this->assertTrue(canAttack([2, 2], [0, 4]));
}

/**
* Test if queens can attack each other on the second diagonal.
* uuid: ff9b7ed4-e4b6-401b-8d16-bc894d6d3dcd
*/
public function testQueensCanAttackOnSecondDiagonal(): void
#[TestDox('Test the ability of one queen to attack another -> can attack on second diagonal')]
public function testTheAbilityOfOneQueenToAttackAnotherCanAttackOnSecondDiagonal(): void
{
$this->assertTrue(canAttack([2, 2], [3, 1]));
}

/**
* Test if queens can attack each other on the third diagonal.
* uuid: 0a71e605-6e28-4cc2-aa47-d20a2e71037a
*/
public function testQueensCanAttackOnThirdDiagonal(): void
#[TestDox('Test the ability of one queen to attack another -> can attack on third diagonal')]
public function testTheAbilityOfOneQueenToAttackAnotherCanAttackOnThirdDiagonal(): void
{
$this->assertTrue(canAttack([2, 2], [1, 1]));
}

/**
* Test if queens can attack each other on the fourth diagonal.
* uuid: 0790b588-ae73-4f1f-a968-dd0b34f45f86
*/
#[TestDox('Test the ability of one queen to attack another -> can attack on fourth diagonal')]
public function testTheAbilityOfOneQueenToAttackAnotherCanAttackOnFourthDiagonal(): void
{
$this->assertTrue(canAttack([1, 7], [0, 6]));
}

/**
* uuid: 543f8fd4-2597-4aad-8d77-cbdab63619f8
*/
public function testQueensCanAttackOnFourthDiagonal(): void
#[TestDox('Test the ability of one queen to attack another -> cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal')]
public function testTheAbilityOfOneQueenToAttackAnotherCannotAttackReflectedDiagonal(): void
{
$this->assertTrue(canAttack([2, 2], [5, 5]));
$this->assertFalse(canAttack([4, 1], [2, 5]));
}
}
Loading