 # devcraftsman's solution

## to Queen Attack in the Scala Track

Published at Sep 13 2019 · 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.

The Scala exercises assume an SBT project scheme. The exercise solution source should be placed within the exercise directory/src/main/scala. The exercise unit tests can be found within the exercise directory/src/test/scala.

To run the tests simply run the command `sbt test` in the exercise directory.

For more detailed info about the Scala track see the help page.

## 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.

### QueenAttackTest.scala

``````import org.scalatest.{Matchers, FunSuite}

/** @version 2.1.0 */
class QueenAttackTest extends FunSuite with Matchers {

private def create(x: Int, y: Int): Queen = {
Queen.create(x, y) match {
case Some(q) => q
case None => fail("Error creating queen")
}
}

test("queen with a valid position") {
Queen.create(2, 2) should be (Some(Queen(2, 2)))
}

test("queen must have positive row") {
pending
Queen.create(-2, 2) should be (None)
}

test("queen must have row on board") {
pending
Queen.create(8, 4) should be (None)
}

test("queen must have positive column") {
pending
Queen.create(2, -2) should be (None)
}

test("queen must have column on board") {
pending
Queen.create(4, 8) should be (None)
}

test("can not attack") {
pending
QueenAttack.canAttack(create(2, 4), create(6, 6)) should be (false)
}

test("can attack on same row") {
pending
QueenAttack.canAttack(create(2, 4), create(2, 6)) should be (true)
}

test("can attack on same column") {
pending
QueenAttack.canAttack(create(4, 5), create(2, 5)) should be (true)
}

test("can attack on first diagonal") {
pending
QueenAttack.canAttack(create(2, 2), create(0, 4)) should be (true)
}

test("can attack on second diagonal") {
pending
QueenAttack.canAttack(create(2, 2), create(3, 1)) should be (true)
}

test("can attack on third diagonal") {
pending
QueenAttack.canAttack(create(2, 2), create(1, 1)) should be (true)
}

test("can attack on fourth diagonal") {
pending
QueenAttack.canAttack(create(2, 2), create(5, 5)) should be (true)
}
}``````
``````case class Queen(row: Int, col : Int)

object Queen{

def create(x: Int, y:Int) : Option[Queen] = {
if ( x >=0 && x < 8 && y>=0 && y < 8) Some(Queen(x,y))
else None
}
}

object QueenAttack {

def canAttack(q1: Queen, q2: Queen) :Boolean = {

def isDiagonal(q1: Queen, q2: Queen)  :Boolean =  {
val xDistance = q1.col-q2.col
val yDistance : Int = q1.row-q2.row
xDistance*xDistance.signum - yDistance*yDistance.signum == 0
}

(q1,q2) match {
case (_,_) if (q1.col.equals(q2.col)) => true
case (_,_) if (q1.row.equals(q2.row)) => true
case (q1,q2) if (isDiagonal(q1,q2))  => true
case _ => false
}
}

}``````