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