25.5. Plansza

Gra w szachy przebiega na planszy złożonej z 64 pól. Kod obsługujący planszę jest zdefiniowany w pliku Board.scala.

Plik Board.scala:
package chess

import compat.Platform.EOL

object Board {

  type Board = Map[Field,Figure] 

  def startingBoard: Board = Map(
    Field(1,1) -> Figure(Rook,White),
    Field(2,1) -> Figure(Knight,White),
    Field(3,1) -> Figure(Bishop,White),
    Field(4,1) -> Figure(Queen,White),
    Field(5,1) -> Figure(King,White),
    Field(6,1) -> Figure(Bishop,White),
    Field(7,1) -> Figure(Knight,White),
    Field(8,1) -> Figure(Rook,White),
    Field(1,2) -> Figure(Pawn,White),
    Field(2,2) -> Figure(Pawn,White),
    Field(3,2) -> Figure(Pawn,White),
    Field(4,2) -> Figure(Pawn,White),
    Field(5,2) -> Figure(Pawn,White),
    Field(6,2) -> Figure(Pawn,White),
    Field(7,2) -> Figure(Pawn,White),
    Field(8,2) -> Figure(Pawn,White),
    Field(1,7) -> Figure(Pawn,Black),
    Field(2,7) -> Figure(Pawn,Black),
    Field(3,7) -> Figure(Pawn,Black),
    Field(4,7) -> Figure(Pawn,Black),
    Field(5,7) -> Figure(Pawn,Black),
    Field(6,7) -> Figure(Pawn,Black),
    Field(7,7) -> Figure(Pawn,Black),
    Field(8,7) -> Figure(Pawn,Black),
    Field(1,8) -> Figure(Rook,Black),
    Field(2,8) -> Figure(Knight,Black),
    Field(3,8) -> Figure(Bishop,Black),
    Field(4,8) -> Figure(Queen,Black),
    Field(5,8) -> Figure(King,Black),
    Field(6,8) -> Figure(Bishop,Black),
    Field(7,8) -> Figure(Knight,Black),
    Field(8,8) -> Figure(Rook,Black))

  def showBoard(board: Board): String = {
    def rowToString(row: Int) = 1.to(8).map(col=>
      board.get(Field(col,row)).map(_.toString).getOrElse(".")).mkString
    " abcdefgh" + EOL + 8.to(1,-1).map(row =>
    row.toString + rowToString(row) + row.toString + EOL).mkString + " abcdefgh"
  }

  def updateBoard(board: Board, move: Move): Board = move match {
    case RegularMove(from,to) =>
      board.get(from).fold(board)( figure =>
        board - from + (to->figure))
    case PromotionMove(from,to,figure) =>
      board.get(from).fold(board)( _ =>
        board - from + (to->figure))
    case EnPassantMove(from,to,captured) =>
      board.get(from).fold(board)( figure =>
        board - from - captured + (to->figure))
    case CastlingMove(from,to,rookFrom,rookTo) =>
      (board.get(from), board.get(rookFrom)) match {
        case (Some(figure),Some(rookFigure)) =>
          board - from + (to->figure) - rookFrom + (rookTo->rookFigure)
        case _ => board
      }
  }

}

Informacja o tym jakie figury znajdują się na planszy na jakich polach jest reprezentowana przez mapę odwzorowującą pola (wartości typu Field) na figury (wartości typu Figure). Zdefiniowany w wierszu typ Board reprezentuje taką mapę. Metoda startingBoard zwraca mapę reprezentującą początkowy stan gry — przed wykonaniem pierwszego ruchu — w którym na planszy znajduje się po 16 figur każdego koloru.

scala> import chess._, Board._
import chess._
import Board._
scala> startingBoard
res0: chess.Board.Board = Map(g1 -> n, a8 -> R, f7 -> P, e2 -> p, e1 -> k, g7 -> P, d7 -> P, g8 -> N, c1 -> b, f1 -> b, d1 -> q, f2 -> p, h1 -> r, b8 -> N, f8 -> B, a1 -> r, h2 -> p, h8 -> R, e7 -> P, c2 -> p, b2 -> p, d8 -> Q, b7 -> P, d2 -> p, c7 -> P, e8 -> K, a7 -> P, a2 -> p, b1 -> n, h7 -> P, g2 -> p, c8 -> B)

Metoda showBoard zwraca stan planszy w postaci napisu pokazującego zawartość poszczególnych pól planszy. Puste pola reprezentuje znak kropki, a pola na których znajduje się jakaś figura reprezentuje jednoznakowy symbol tej figury.

scala> showBoard(startingBoard)
res1: String =
" abcdefgh
8RNBQKBNR8
7PPPPPPPP7
6........6
5........5
4........4
3........3
2pppppppp2
1rnbqkbnr1
 abcdefgh"

Metoda updateBoard zwraca nową planszę, powstałą po wykonaniu na planszy wejściowej określonego ruchu. Na przykład poniższe polecenie pokazuje stan planszy odpowiadający przesunięciu w pierwszym ruchu białych piona z pola d2 na d4.

scala> println(showBoard(updateBoard(startingBoard,RegularMove(Field(4,2),Field(4,4)))))
 abcdefgh
8RNBQKBNR8
7PPPPPPPP7
6........6
5........5
4...p....4
3........3
2ppp.pppp2
1rnbqkbnr1
 abcdefgh

Metoda updateBoard dokonuje zmiany sytuacji na planszy bez sprawdzania, czy ta zmiana odpowiada prawidłowemu ruchowi szachowemu, zgodnemu z regułami gry. Na przykład poniższe polecenie pokazuje planszę po dokonaniu roszady w pierwszym ruchu białych, mimo że reguły gry w szachy nie pozwalają na taki ruch.

scala> println(showBoard(updateBoard(startingBoard,CastlingMove(Field(5,1),Field(3,1),Field(1,1),Field(4,1)))))
 abcdefgh
8RNBQKBNR8
7PPPPPPPP7
6........6
5........5
4........4
3........3
2pppppppp2
1.nkr.bnr1
 abcdefgh

Język programowania Scala Wydanie 2. Copyright © Grzegorz Balcerek 2016

Licencja Creative Commons

Ten utwór jest dostępny na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowe.

Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.