blob: 6fc278f071158c5e02de031d0459f9fa937d411d (
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
88
89
90
91
92
|
package me.robbyzambito.othello.game
import scala.annotation.tailrec
/**
* 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)
/**
* Plays the game.
* @param game Current state of the game.
*/
@tailrec
final def loop(game: Game = this): Unit = {
if (game.winner.isEmpty) {
loop(game.takeTurn)
} else {
println(game.winnerMessage)
}
}
/**
* 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.
*/
val winner: Option[Player] = {
if (currentPlayer.canMove(board) || currentOpponent.canMove(board))
None
else { // No one can move => Game is finished
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")
if (currentPlayer.canMove(board)) {
val move = currentPlayer.nextMove(board)
this.copy(board = move(board, currentPlayer), turnCount = turnCount + 1)
} else {
println(s"$currentPlayer has no moves! Skipping turn...")
this.copy(board = board, 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(players: List[Player]): Game = new Game(Board.init(), players)
def apply(): Game = Game( List(UserPlayer(Position.WHITE), AIPlayer(Position.BLACK)) )
}
|