blob: 8072bf117d0ab291368d43aea52004871ab72467 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
package me.robbyzambito.othello.game
import scala.io.StdIn
import scala.util.Try
/**
* Represents the state of the game.
* Reports the winner of the game when that state is reached.
*
* Written by Robby Zambito
* Written on 11/20/2019
* Targeting Scala 2.13.1
*/
case class Game(board: Board,
players: List[Player],
turnCount: Int = 0) {
val currentPlayer: Player = players(turnCount % players.length)
val currentOpponent: Player = players(turnCount % players.length)
/**
* Save the game state to a file to be loaded at a later date.
*
* @return true if the game was successfully saved, otherwise false.
*/
def save(): Boolean = ???
/**
* The winner of the game. Ties are not yet handled
*
* [[None]] if there has not been a winner yet. Otherwise return the [[Player]] which has won.
*/
lazy val winner: Option[Player] = {
if (currentPlayer.canMove(board) || (!currentPlayer.canMove(board) && currentOpponent.canMove(board)))
None
else { // No one can move
val whiteCount = board.positions.flatten.count(_ == Position.WHITE)
val blackCount = board.positions.flatten.count(_ == Position.BLACK)
if (whiteCount > blackCount)
players.find(p => p.color == Position.WHITE)
else if (whiteCount < blackCount)
players.find(p => p.color == Position.BLACK)
else None
// throw new Error("Game tied")
}
}
lazy val winnerMessage: String = s"${winner.map(_.toString).getOrElse("Nobody")} has won!"
/**
* Take a turn
*
* @return the game with the next turn state
*/
def takeTurn: Game = {
println(s"${this}\n")
def getPos: (Int, Int) = {
val rowCount = Iterator.continually(
Try(StdIn.readLine(s"Enter the row to move for ${currentPlayer}: ").toInt)
).dropWhile(_.isFailure).next().get
val colCount = Iterator.continually(
Try(StdIn.readLine(s"Enter the col to move for ${currentPlayer}: ").toInt)
).dropWhile(_.isFailure).next().get
(rowCount, colCount)
}
val possibleMoves = currentPlayer.possibleMoves(board)
val pos = Iterator.continually(getPos)
.dropWhile(!possibleMoves.map(m => (m.rowCount, m.colCount)).contains(_))
.next()
val move = possibleMoves.find(m => m.rowCount == pos._1 && m.colCount == pos._2).get
this.copy(board = move(board, currentPlayer), turnCount = turnCount + 1)
}
override def toString: String =
s""" ${0 to 7 mkString " "}
|${board.toString.split("\n").zipWithIndex.map { case (s, i) => s"$i $s" }.mkString("\n")}""".stripMargin
}
object Game {
def apply(): Game = new Game(Board.init(), List(Player(Position.WHITE), Player(Position.BLACK)))
}
|