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

# Toochane's solution

## to Queen Attack in the Haskell Track

Published at Feb 02 2021 · 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.

## Hints

To complete this exercise, you need to implement the following functions:

• `boardString`
• `canAttack`

You will find the type signatures already in place, but it is up to you to define the functions.

Positions are specified as two-tuples:

• The first element is the row (rank in Chess terms).
• The second element is is the column (file in Chess terms).
• (0, 0) is the top left of the board, (0, 7) is the upper right,
• (7, 0) is the bottom left, and (7, 7) is the bottom right.

## Getting Started

Please refer to the installation and learning help pages.

## Running the tests

To run the test suite, execute the following command:

``````stack test
``````

#### If you get an error message like this...

``````No .cabal file found in directory
``````

You are probably running an old stack version and need to upgrade it.

#### Otherwise, if you get an error message like this...

``````No compiler found, expected minor version match with...
Try running "stack setup" to install the correct GHC...
``````

Just do as it says and it will download and install the correct compiler version:

``````stack setup
``````

## Running GHCi

If you want to play with your solution in GHCi, just run the command:

``````stack ghci
``````

## Feedback, Issues, Pull Requests

The exercism/haskell repository on GitHub is the home for all of the Haskell exercises.

If you have feedback about an exercise, or want to help implementing a new one, head over there and create an issue. We'll do our best to help you!

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

### Tests.hs

``````{-# OPTIONS_GHC -fno-warn-type-defaults #-}

import Data.Foldable     (for_)
import Test.Hspec        (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

import Queens (boardString, canAttack)

main :: IO ()
main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = do

-- Track-specific test cases.

describe "boardString" \$ do

it "empty board" \$ boardString Nothing Nothing
`shouldBe` unlines [ "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _" ]

it "board with just white queen" \$ boardString (Just (2, 4)) Nothing
`shouldBe` unlines [ "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ W _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _" ]

it "board with just black queen" \$ boardString Nothing (Just (0, 0))
`shouldBe` unlines [ "B _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _" ]

it "board" \$ boardString (Just (2, 4)) (Just (6, 6))
`shouldBe` unlines [ "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ W _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ _ _"
, "_ _ _ _ _ _ B _"
, "_ _ _ _ _ _ _ _" ]

-- The function described by the reference file as `create` doesn't
-- exist in this track, so only the `canAttack` test cases were
-- implemented here

describe "canAttack" \$ do

let test (description, white, black, expected) =
it description \$ canAttack white black `shouldBe` expected

cases = [ ("can not attack"               , (2, 4), (6, 6), False)
, ("can attack on same rank"      , (2, 4), (2, 6), True )
, ("can attack on same file"      , (4, 5), (2, 5), True )
, ("can attack on first diagonal" , (2, 2), (0, 4), True )
, ("can attack on second diagonal", (2, 2), (3, 1), True )
, ("can attack on third diagonal" , (2, 2), (1, 1), True )
, ("can attack on fourth diagonal", (2, 2), (5, 5), True ) ]

for_ cases test

-- cc646595d39e13c4d310da2629599bcc45e92bd9``````
``````module Queens (boardString, canAttack) where

boardString :: Maybe (Int, Int) -> Maybe (Int, Int) -> String
boardString Nothing Nothing = take 128 (cycle (take 15 (cycle "_ ") ++ "\n"))
boardString white Nothing = take (getIndex white) (boardString Nothing Nothing) ++ "W" ++ drop (1 + (getIndex white)) (boardString Nothing Nothing)
boardString white black = take (getIndex black) (boardString white Nothing) ++ "B" ++ drop (1 + (getIndex black)) (boardString white Nothing)

canAttack :: (Int, Int) -> (Int, Int) -> Bool
canAttack queenA queenB
| fst queenA == fst queenB = True
| snd queenA == snd queenB = True
| abs ((snd queenA) - (snd queenB)) == abs ((fst queenA) - (fst queenB)) = True
| otherwise = False

getIndex :: Maybe (Int, Int) -> Int
getIndex Nothing = -1
getIndex (Just (a, b)) = 16 * a + 2 * b``````

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