ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# Greycoat21's solution

## to Queen Attack in the Delphi Pascal Track

Published at Jan 26 2020 · 0 comments
Instructions
Test suite
Solution

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.

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:

``````_ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ 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.

## Testing

In order to run the tests for this track, you will need to install DUnitX. Please see the installation instructions for more information.

If Delphi is properly installed, and `*.dpr` file types have been associated with Delphi, then double clicking the supplied `*.dpr` file will start Delphi and load the exercise/project. `control + F9` is the keyboard shortcut to compile the project or pressing `F9` will compile and run the project.

Alternatively you may opt to start Delphi and load your project via. the `File` drop down menu.

### When Questions Come Up

We monitor the Pascal-Delphi support room on gitter.im to help you with any questions that might arise.

### Submitting Exercises

Note that, when trying to submit an exercise, make sure the exercise file you're submitting is in the `exercism/delphi/<exerciseName>` directory.

For example, if you're submitting `ubob.pas` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/delphi/bob/ubob.pas`.

## Source

J Dalbey's Programming Practice problems http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you may request help from a mentor.

### uQueenAttackTests.pas

``````unit uQueenAttackTests;

interface
uses
DUnitX.TestFramework, uQueenAttack;

const
CanonicalVersion = '2.3.0.1';

type
[TestFixture('Creation of queens with valid and invalid positions')]
TQueenCreationTests = class(TObject)
public
[Test]
//    [Ignore('Comment the "[Ignore]" statement to run the test')]
procedure queen_with_a_valid_position;

[Test]
[Ignore]
procedure queen_must_have_positive_row;

[Test]
[Ignore]
procedure queen_must_have_row_on_board;

[Test]
[Ignore]
procedure queen_must_have_positive_column;

[Test]
[Ignore]
procedure queen_must_have_column_on_board;
end;

[TestFixture('Ability of one queen to attack another')]
TQueenAttackTests = class(TObject)
private
WhiteQueen: TQueen;
BlackQueen: TQueen;
public
[Test]
[Ignore]
procedure can_not_attack;

[Test]
[Ignore]
procedure can_attack_on_same_row;

[Test]
[Ignore]
procedure can_attack_on_same_column;

[Test]
[Ignore]
procedure can_attack_on_first_diagonal;

[Test]
[Ignore]
procedure can_attack_on_second_diagonal;

[Test]
[Ignore]
procedure can_attack_on_third_diagonal;

[Test]
[Ignore]
procedure can_attack_on_fourth_diagonal;
end;

implementation
uses
System.SysUtils;

{\$REGION 'TQueenCreationTests'}

procedure TQueenCreationTests.queen_must_have_column_on_board;
begin
Assert.WillRaise(procedure
begin
TQueen.Create(4, 8)
end, EArgumentException, 'column not on board');

end;

procedure TQueenCreationTests.queen_must_have_positive_column;
begin
Assert.WillRaise(procedure
begin
TQueen.Create(2, -2)
end, EArgumentException, 'column not positive');
end;

procedure TQueenCreationTests.queen_must_have_positive_row;
begin
Assert.WillRaise(procedure
begin
TQueen.Create(-2, 2)
end, EArgumentException, 'row not positive');
end;

procedure TQueenCreationTests.queen_must_have_row_on_board;
begin
Assert.WillRaise(procedure
begin
TQueen.Create(8, 4)
end, EArgumentException, 'row not on board');
end;

procedure TQueenCreationTests.queen_with_a_valid_position;
begin
Assert.WillNotRaise(
procedure
begin
TQueen.Create(2, 2)
end, EArgumentException);
end;

{\$ENDREGION}

{\$REGION 'TQueenAttackTests'}

procedure TQueenAttackTests.can_attack_on_first_diagonal;
begin
WhiteQueen := TQueen.Create(2, 2);
BlackQueen := TQueen.Create(0, 4);
Assert.IsTrue(WhiteQueen.CanAttack(BlackQueen));
end;

procedure TQueenAttackTests.can_attack_on_fourth_diagonal;
begin
WhiteQueen := TQueen.Create(1, 7);
BlackQueen := TQueen.Create(0, 6);
Assert.IsTrue(WhiteQueen.CanAttack(BlackQueen));
end;

procedure TQueenAttackTests.can_attack_on_same_column;
begin
WhiteQueen := TQueen.Create(4, 5);
BlackQueen := TQueen.Create(2, 5);
Assert.IsTrue(WhiteQueen.CanAttack(BlackQueen));
end;

procedure TQueenAttackTests.can_attack_on_same_row;
begin
WhiteQueen := TQueen.Create(2, 4);
BlackQueen := TQueen.Create(2, 6);
Assert.IsTrue(WhiteQueen.CanAttack(BlackQueen));
end;

procedure TQueenAttackTests.can_attack_on_second_diagonal;
begin
WhiteQueen := TQueen.Create(2, 2);
BlackQueen := TQueen.Create(3, 1);
Assert.IsTrue(WhiteQueen.CanAttack(BlackQueen));
end;

procedure TQueenAttackTests.can_attack_on_third_diagonal;
begin
WhiteQueen := TQueen.Create(2, 2);
BlackQueen := TQueen.Create(1, 1);
Assert.IsTrue(WhiteQueen.CanAttack(BlackQueen));
end;

procedure TQueenAttackTests.can_not_attack;
begin
WhiteQueen := TQueen.Create(2, 4);
BlackQueen := TQueen.Create(6, 6);
Assert.IsFalse(WhiteQueen.CanAttack(BlackQueen));
end;

{\$ENDREGION}

initialization
TDUnitX.RegisterTestFixture(TQueenCreationTests);
TDUnitX.RegisterTestFixture(TQueenAttackTests);
end.``````
``````unit uQueenAttack;

interface

type
TQueen = class
x, y: Integer;
constructor Create(x, y: Integer);
function CanAttack(Enemy: TQueen): Boolean;
end;

implementation

uses
SysUtils;

{ TQueen }

function TQueen.CanAttack(Enemy: TQueen): Boolean;

function SameRow(Queen1, Queen2: TQueen): Boolean;
begin
Result := Queen1.x = Queen2.x;
end;
function SameColumn(Queen1, Queen2: TQueen): Boolean;
begin
Result := Queen1.y = Queen2.y;
end;
function SameDiagonal(Queen1, Queen2: TQueen): Boolean;
var
DiffX, DiffY: Integer;
begin
DiffX := Abs(Queen1.x - Queen2.x);
DiffY := Abs(Queen1.y - Queen2.y);

Result := DiffX = DiffY;
end;

begin
Result := SameRow(Self, Enemy)
or SameColumn(Self, Enemy)
or SameDiagonal(Self, Enemy);
end;

constructor TQueen.Create(x, y: Integer);

procedure ValidateBoardIndex(x: Integer; TypeCode: string);
const
MinBoardIndex = 0;
MaxBoardIndex = 7;
begin
if (MinBoardIndex > x) then
raise EArgumentException.Create(TypeCode + ' not positive');
if (x > MaxBoardIndex) then
raise EArgumentException.Create(TypeCode + ' not on board');
end;

const
sCol = 'column';
sRow = 'row';
begin
ValidateBoardIndex(x, sCol);
ValidateBoardIndex(y, sRow);
Self.x := x;
Self.y := y;
end;

end.``````