3
\$\begingroup\$

Problem - Given a chess board and the position of only one queen piece in it, mark all the position where the queen can move with X.

Kindly review this Scala code and suggest improvements.

import scala.collection.mutable._

object ChessQueenAttack {
  val board = Array.fill(8)(Array.fill(8)('0'))
  def printBoard = {
    println
    println
    board foreach { row => println(row.mkString(" "))}
  }

  def main(args: Array[String]): Unit = {
    printBoard
    val qR = args(0).toInt
    val qC = args(1).toInt
    board(qR)(qC) = 'Q'
    printBoard

    var (r,c) = (qR, qC)

    // horizontal
    for ( i <- 0 until 8 ) {
      if (i != qC) board(qR)(i) = 'X'
      if (i != qR) board(i)(qC) = 'X'
    }

    // top left
    r = qR -1
    c = qC -1
    while (r >= 0 && c >= 0) {
      board(r)(c) ='X'
      r -= 1
      c -= 1
    }
    // top right
    r = qR - 1
    c = qC + 1
    while (r >= 0 && c  < 8) {
      board(r)(c) = 'X'
      r -= 1
      c += 1
    }
    // bottom right
    r = qR + 1
    c = qC + 1
    while (r < 8 && c < 8 ) {
      board(r)(c) = 'X'
      r += 1
      c += 1
    }
    // bottom left
    r = qR + 1
    c = qC - 1
    while (r<8 && c>=0) {
      board(r)(c) = 'X'
      r += 1
      c -= 1
    }
    printBoard
  }
}

Output -

scalac ChessQueenAttack.scala
scala ChessQueenAttack 3 3

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0


0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 Q 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0


X 0 0 X 0 0 X 0
0 X 0 X 0 X 0 0
0 0 X X X 0 0 0
X X X Q X X X X
0 0 X X X 0 0 0
0 X 0 X 0 X 0 0
X 0 0 X 0 0 X 0
0 0 0 X 0 0 0 X
\$\endgroup\$
2
\$\begingroup\$

Your solution is very procedural, and more like how a C program would be written. I don't consider it to be idiomatic Scala. You should decompose the problem into functions, such as isQueen and isAttacked in my solution below.

There should be very little code left over in main. As a shortcut, then, you can just plop the main code directly into the ChessQueenAttack by making it extend App.

object ChessQueenAttack extends App {
  def isQueen(r: Int, c: Int): Boolean = { (r, c) == queenPos }

  def isAttacked(r: Int, c: Int): Boolean = {
    (r == queenPos._1) ||                       // Same row as queen
    (c == queenPos._2) ||                       // Same column as queen
    (r + c == queenPos._1 + queenPos._2) ||     // On / diagonal
    (r - c == queenPos._1 - queenPos._2)        // On \ diagonal
  }

  def board: String = {
    (0 until 8).map { r =>
      (0 until 8).map { c =>
        if (isQueen(r, c))    "Q" else
        if (isAttacked(r, c)) "X" else
                              "0"
      }.mkString(" ")
    }.mkString("\n")
  }

  val queenPos = (args(0).toInt, args(1).toInt)
  println(board)
}
\$\endgroup\$
  • \$\begingroup\$ thanks, I agree my version is more procedural. \$\endgroup\$ – vikrant Oct 26 '18 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.