Avatar of artemkorsakov

artemkorsakov's solution

to Queen Attack in the Java Track

Published at Feb 08 2019 · 0 comments
Instructions
Test suite
Solution

Note:

This exercise has changed since this solution was written.

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.

Running the tests

You can run all the tests for an exercise by entering

$ gradle test

in your terminal.

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.

QueenAttackCalculatorTest.java

import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class QueenAttackCalculatorTest {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void testCreateQueenWithAValidPosition() {
        new Queen(2, 2);
    }

    @Ignore("Remove to run test")
    @Test
    public void testCreateQueenMustHavePositiveRow() {
        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("Queen position must have positive row.");

        new Queen(-2, 2);
    }

    @Ignore("Remove to run test")
    @Test
    public void testCreateQueenMustHaveRowOnBoard() {
        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("Queen position must have row <= 7.");

        new Queen(8, 4);
    }

    @Ignore("Remove to run test")
    @Test
    public void testCreateQueenMustHavePositiveColumn() {
        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("Queen position must have positive column.");

        new Queen(2, -2);
    }

    @Ignore("Remove to run test")
    @Test
    public void testCreateQueenMustHaveColumnOnBoard() {
        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("Queen position must have column <= 7.");

        new Queen(4, 8);
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensCannotAttack() {
        QueenAttackCalculator calculator
                = new QueenAttackCalculator(new Queen(2, 4), new Queen(6, 6));

        assertFalse(calculator.canQueensAttackOneAnother());
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensCanAttackOnTheSameRow() {
        QueenAttackCalculator calculator
                = new QueenAttackCalculator(new Queen(2, 4), new Queen(2, 6));

        assertTrue(calculator.canQueensAttackOneAnother());
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensCanAttackOnTheSameColumn() {
        QueenAttackCalculator calculator
                = new QueenAttackCalculator(new Queen(4, 5), new Queen(2, 5));

        assertTrue(calculator.canQueensAttackOneAnother());
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensCanAttackOnFirstDiagonal() {
        QueenAttackCalculator calculator
                = new QueenAttackCalculator(new Queen(2, 2), new Queen(0, 4));

        assertTrue(calculator.canQueensAttackOneAnother());
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensCanAttackOnSecondDiagonal() {
        QueenAttackCalculator calculator
                = new QueenAttackCalculator(new Queen(2, 2), new Queen(3, 1));

        assertTrue(calculator.canQueensAttackOneAnother());
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensCanAttackOnThirdDiagonal() {
        QueenAttackCalculator calculator
                = new QueenAttackCalculator(new Queen(2, 2), new Queen(1, 1));

        assertTrue(calculator.canQueensAttackOneAnother());
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensCanAttackOnFourthDiagonal() {
        QueenAttackCalculator calculator
                = new QueenAttackCalculator(new Queen(2, 2), new Queen(5, 5));

        assertTrue(calculator.canQueensAttackOneAnother());
    }

    @Ignore("Remove to run test")
    @Test
    public void testNullPositionsNotAllowed() {
        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("You must supply valid positions for both Queens.");

        new QueenAttackCalculator(null, new Queen(0, 7));
    }

    @Ignore("Remove to run test")
    @Test
    public void testQueensMustNotOccupyTheSameSquare() {
        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("Queens cannot occupy the same position.");

        new QueenAttackCalculator(new Queen(2, 2), new Queen(2, 2));
    }

}

src/main/java/Queen.java

class Queen {
    private int x;
    private int y;

    Queen(int x, int y) {
        if (x < 0) {
            throw new IllegalArgumentException("Queen position must have positive row.");
        }
        if (x > 7) {
            throw new IllegalArgumentException("Queen position must have row <= 7.");
        }
        if (y < 0) {
            throw new IllegalArgumentException("Queen position must have positive column.");
        }
        if (y > 7) {
            throw new IllegalArgumentException("Queen position must have column <= 7.");
        }
        this.x = x;
        this.y = y;
    }

    int getX() {
        return x;
    }

    int getY() {
        return y;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof Queen)) {
            return false;
        }

        Queen q = (Queen) o;
        return q.getX() == getX() && q.getY() == getY();
    }
}

src/main/java/QueenAttackCalculator.java

class QueenAttackCalculator {
    private Queen queen1;
    private Queen queen2;

    QueenAttackCalculator(Queen queen1, Queen queen2) {
        if (queen1 == null || queen2 == null) {
            throw new IllegalArgumentException("You must supply valid positions for both Queens.");
        }
        if (queen1.equals(queen2)) {
            throw new IllegalArgumentException("Queens cannot occupy the same position.");
        }
        this.queen1 = queen1;
        this.queen2 = queen2;
    }

    boolean canQueensAttackOneAnother() {
        return queen1.getX() == queen2.getX() ||
                queen1.getY() == queen2.getY() ||
                (queen1.getX() - queen1.getY()) == (queen2.getX() - queen2.getY()) ||
                (queen1.getX() + queen1.getY()) == (queen2.getX() + queen2.getY());
    }
}

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?