summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Zambito <Zambito101@gmail.com>2019-11-24 19:13:56 -0500
committerRobby Zambito <Zambito101@gmail.com>2019-11-24 19:13:56 -0500
commitc7c84b658487f51d61cbeff0199c124fcf13a268 (patch)
tree458ecc971c6fef5e1e370175fb16927d79dfbcbe
parent3c17082bd73f3623fe0680393b1b96938d63be30 (diff)
Fixed end condition to handle when the current player can not move but the opponent can.
-rw-r--r--.idea/scala_compiler.xml4
-rw-r--r--src/main/scala/me/robbyzambito/othello/game/AIPlayer.scala19
-rw-r--r--src/main/scala/me/robbyzambito/othello/game/Game.scala20
-rw-r--r--src/main/scala/me/robbyzambito/othello/game/Player.scala15
-rw-r--r--src/main/scala/me/robbyzambito/othello/game/UserPlayer.scala7
5 files changed, 53 insertions, 12 deletions
diff --git a/.idea/scala_compiler.xml b/.idea/scala_compiler.xml
index a26a233..8fdaf03 100644
--- a/.idea/scala_compiler.xml
+++ b/.idea/scala_compiler.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ScalaCompilerConfiguration">
- <profile name="sbt 1" modules="OthelloAI" />
+ <profile name="sbt 1" modules="OthelloAI">
+ <option name="implicitConversions" value="true" />
+ </profile>
</component>
</project> \ No newline at end of file
diff --git a/src/main/scala/me/robbyzambito/othello/game/AIPlayer.scala b/src/main/scala/me/robbyzambito/othello/game/AIPlayer.scala
index 5c3efc6..307c8e1 100644
--- a/src/main/scala/me/robbyzambito/othello/game/AIPlayer.scala
+++ b/src/main/scala/me/robbyzambito/othello/game/AIPlayer.scala
@@ -1,12 +1,29 @@
package me.robbyzambito.othello.game
+/**
+ * Decides how the AI player should behave.
+ *
+ * Written by Robby Zambito
+ * Written on 11/20/2019
+ * Targeting Scala 2.13.1
+ *
+ * See [[Player]]
+ */
case class AIPlayer(override val color: Position) extends Player(color) {
override def nextMove(board: Board): Move = {
+
+ implicit val moveOrdering: Ordering[Move] = new Ordering[Move] {
+ override def compare(x: Move, y: Move): Int = {
+ x.takenPositions.length.compareTo(y.takenPositions.length)
+ }
+ }
+
println(s"$this moving...")
Thread.sleep(500L)
println()
- possibleMoves(board).head
+
+ possibleMoves(board).max
}
}
diff --git a/src/main/scala/me/robbyzambito/othello/game/Game.scala b/src/main/scala/me/robbyzambito/othello/game/Game.scala
index 4c0e7a2..6fc278f 100644
--- a/src/main/scala/me/robbyzambito/othello/game/Game.scala
+++ b/src/main/scala/me/robbyzambito/othello/game/Game.scala
@@ -17,6 +17,10 @@ case class Game(board: Board,
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) {
@@ -38,10 +42,10 @@ case class Game(board: Board,
*
* [[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)))
+ val winner: Option[Player] = {
+ if (currentPlayer.canMove(board) || currentOpponent.canMove(board))
None
- else { // No one can move
+ else { // No one can move => Game is finished
val whiteCount = board.positions.flatten.count(_ == Position.WHITE)
val blackCount = board.positions.flatten.count(_ == Position.BLACK)
@@ -64,9 +68,15 @@ case class Game(board: Board,
def takeTurn: Game = {
println(s"${this}\n")
- val move = currentPlayer.nextMove(board)
+ if (currentPlayer.canMove(board)) {
+ val move = currentPlayer.nextMove(board)
- this.copy(board = move(board, currentPlayer), turnCount = turnCount + 1)
+ 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 =
diff --git a/src/main/scala/me/robbyzambito/othello/game/Player.scala b/src/main/scala/me/robbyzambito/othello/game/Player.scala
index 7abf3d2..925f7d2 100644
--- a/src/main/scala/me/robbyzambito/othello/game/Player.scala
+++ b/src/main/scala/me/robbyzambito/othello/game/Player.scala
@@ -2,6 +2,16 @@ package me.robbyzambito.othello.game
import scala.util.Try
+/**
+ * Represents a party which is partaking in the game.
+ * Both the AI and the end user are instances of Player.
+ *
+ * Written by Robby Zambito
+ * Written on 11/20/2019
+ * Targeting Scala 2.13.1
+ *
+ * @param color The color of the player.
+ */
abstract class Player(val color: Position) {
def nextMove(board: Board): Move
@@ -59,7 +69,7 @@ abstract class Player(val color: Position) {
} else List.empty
}
- // Check can move left or right
+ // Check can move down or up
val changes = checkInDirection(rowCount, 1) ::: checkInDirection(rowCount, -1)
if (changes.nonEmpty)
Some(Move(rowCount, colCount, changes))
@@ -75,8 +85,7 @@ abstract class Player(val color: Position) {
Some(
Move(rowCount,
colCount,
- acc.map(_.takenPositions).getOrElse(List.empty) ::: vert.map(_.takenPositions).getOrElse(List.empty)
- )
+ acc.map(_.takenPositions).getOrElse(List.empty) ::: vert.map(_.takenPositions).getOrElse(List.empty))
)
else None
}).flatten
diff --git a/src/main/scala/me/robbyzambito/othello/game/UserPlayer.scala b/src/main/scala/me/robbyzambito/othello/game/UserPlayer.scala
index dc1c84c..4ecf1e1 100644
--- a/src/main/scala/me/robbyzambito/othello/game/UserPlayer.scala
+++ b/src/main/scala/me/robbyzambito/othello/game/UserPlayer.scala
@@ -4,12 +4,13 @@ import scala.io.StdIn
import scala.util.Try
/**
- * Represents a party which is partaking in the game.
- * Both the AI and the end user are instances of Player.
+ * Allows for the User to input their moves.
*
* Written by Robby Zambito
* Written on 11/20/2019
* Targeting Scala 2.13.1
+ *
+ * See [[Player]]
*/
case class UserPlayer(override val color: Position) extends Player(color) {
@@ -22,6 +23,8 @@ case class UserPlayer(override val color: Position) extends Player(color) {
Try(StdIn.readLine(s"Enter the col to move for ${this}: ").toInt)
).dropWhile(_.isFailure).next().get
+ println()
+
(rowCount, colCount)
}