 # mab's solution

## to Queen Attack in the TypeScript Track

Published at May 16 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.

## Setup

Go through the setup instructions for TypeScript to install the necessary dependencies:

https://exercism.io/tracks/typescript/installation

## Requirements

Install assignment dependencies:

``````\$ yarn install
``````

## Making the test suite pass

Execute the tests with:

``````\$ yarn test
``````

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by changing `xit` to `it`.

## 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 can see how others have completed the exercise.

### queen-attack.test.ts

``````import QueenAttack from "./queen-attack"

describe("Queens", () => {
it("initialized with specific placement", () => {
const queens = new QueenAttack({ white: [3, 7], black: [6, 1] })
expect(queens.white).toEqual([3, 7])
expect(queens.black).toEqual([6, 1])
})

xit("cannot occupy the same space", () => {
const positioning: { black: [number, number]; white: [number, number] } = {
black: [2, 4],
white: [2, 4]
}
const expectedError = "Queens cannot share the same space"
expect(() => new QueenAttack(positioning)).toThrow(expectedError)
})

xit("toString representation", () => {
const positioning: { black: [number, number]; white: [number, number] } = {
white: [2, 4],
black: [6, 6]
}
const queens = new QueenAttack(positioning)
const board = [
"_ _ _ _ _ _ _ _",
"_ _ _ _ _ _ _ _",
"_ _ _ _ W _ _ _",
"_ _ _ _ _ _ _ _",
"_ _ _ _ _ _ _ _",
"_ _ _ _ _ _ _ _",
"_ _ _ _ _ _ B _",
"_ _ _ _ _ _ _ _\n"
].join("\n")
expect(queens.toString()).toEqual(board)
})

xit("queens cannot attack", () => {
const queens = new QueenAttack({ white: [2, 3], black: [4, 7] })
expect(queens.canAttack()).toEqual(false)
})

xit("queens can attack when they are on the same row", () => {
const queens = new QueenAttack({ white: [2, 4], black: [2, 7] })
expect(queens.canAttack()).toEqual(true)
})

xit("queens can attack when they are on the same column", () => {
const queens = new QueenAttack({ white: [5, 4], black: [2, 4] })
expect(queens.canAttack()).toEqual(true)
})

xit("queens can attack diagonally", () => {
const queens = new QueenAttack({ white: [1, 1], black: [6, 6] })
expect(queens.canAttack()).toEqual(true)
})

xit("queens can attack another diagonally", () => {
const queens = new QueenAttack({ white: [0, 6], black: [1, 7] })
expect(queens.canAttack()).toEqual(true)
})

xit("queens can attack yet another diagonally", () => {
const queens = new QueenAttack({ white: [4, 1], black: [6, 3] })
expect(queens.canAttack()).toEqual(true)
})

xit("queens can attack on a north-east/south-west diagonal", () => {
const queens = new QueenAttack({ white: [7, 0], black: [0, 7] })
expect(queens.canAttack()).toEqual(true)
})

xit("queens can attack on another ne/sw diagonal", () => {
const queens = new QueenAttack({ white: [2, 6], black: [5, 3] })
expect(queens.canAttack()).toEqual(true)
})
})``````
``````const WHITE: Player = 'W';
const BLACK: Player = 'B';
const BOARD_WIDTH = 8;
const EMPTY_SQUARE = '_';

type Position = [number, number];
type Player = 'W' | 'B';

class Board {
static build(pieceOn: (square: Square) => string) {
let board = '';
for (let rank = 0; rank < BOARD_WIDTH; rank++) {
for (let file = 0; file < BOARD_WIDTH; file++) {
board += `\${pieceOn(new Square([rank, file]))} `;
}
board = board.trim() + '\n';
}
return board;
}
}

class Square {
public rank: number;
public file: number;

constructor([rank, file]: Position) {
this.rank = rank;
this.file = file;
}

sameSquare(square: Square) {
return this.file === square.file && this.rank === square.rank;
}

sameRow(square: Square) {
return this.rank === square.rank;
}

sameColumn(square: Square) {
return this.file === square.file;
}

inDiagonal(square: Square) {
return Math.abs(this.file - square.file) === Math.abs(this.rank - square.rank);
}
}

class Piece extends Square {
public icon: string;

constructor(square: Position, icon: string) {
super(square);
this.icon = icon;
}
}

class QueenAttack {
public white: Position;
public black: Position;
public whiteQueen: Piece;
public blackQueen: Piece;

constructor({ white = [0, 3], black = [7, 3] }: { black: Position; white: Position }) {
this.white = white;
this.black = black;
this.whiteQueen = new Piece(white, WHITE);
this.blackQueen = new Piece(black, BLACK);

if (this.whiteQueen.sameSquare(this.blackQueen)) {
throw new Error(`Queens cannot share the same space`);
}
}

toString() {
return Board.build((square: Square): string => this.pieceOn(square));
}

pieceOn(square: Square) {
for (const queen of [this.blackQueen, this.whiteQueen]) {
if (square.sameSquare(queen)) return queen.icon;
}
return EMPTY_SQUARE;
}

canAttack() {
return (
this.whiteQueen.sameRow(this.blackQueen) ||
this.whiteQueen.sameColumn(this.blackQueen) ||
this.whiteQueen.inDiagonal(this.blackQueen)
);
}
}

export default QueenAttack;``````