Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L8 #433

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

L8 #433

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions Board.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package KalahaGame
import KalahaGame._


import scala.language.postfixOps

class Board {
private val numberOfStones: Int = 6
val board: Array[Int] = createBoard()
private var if1PlayerMove = true
private var ifOneMoreMove = false
var ifGameIsOver = false

def getScores:(Int, Int) = (board(6), board(13))

def isPlayer1Move: Boolean = if1PlayerMove

def hasLastPlayerOneMoreMove: Boolean = ifOneMoreMove

def isGameOver: Boolean = ifGameIsOver

def makeMove(fieldNumber: Int): Boolean = {
if (fieldNumber < 1 || fieldNumber > 6 || board(fieldNumber +
(if(if1PlayerMove) -1 else 6)) == 0) {
println("\nInvalid input, try again:")
false
}
else {
var index = fieldNumber + (if(if1PlayerMove) -1 else 6)
var stones = board(index)

board(index) = 0

while (stones > 0) {
index = (index + 1) % 14
if(index != (if(if1PlayerMove) 13 else 6)) {
board(index) = board(index) + 1
stones = stones - 1
}
}

if (index == (if(if1PlayerMove) 6 else 13)) ifOneMoreMove = true
else if (board(index) == 1 && index >= (if(if1PlayerMove) 0 else 7) && index <= (if(if1PlayerMove) 5 else 12)) {
board(if(if1PlayerMove) 6 else 13) += board(12-index) + 1
board(12 - index) = 0
board(index) = 0
if1PlayerMove = !if1PlayerMove
ifOneMoreMove = false
}
else {
if1PlayerMove = !if1PlayerMove
ifOneMoreMove = false
}

ifEndOfGame()

true
}
}

private def createBoard(): Array[Int] = {
val board = Array.fill(14)(numberOfStones)
board(6) = 0
board(13) = 0
board
}

def ifEndOfGame(): Unit = {
ifGameIsOver = true

for (i <- if(if1PlayerMove) 0 to 5 else 7 to 12)
ifGameIsOver = ifGameIsOver && board(i) == 0

if(ifGameIsOver) {
for(i <- 0 to 5) {
board(6) += board(i)
board(13) += board(i + 7)
board(i) = 0
board(i + 7) = 0
}
printScore()
}
}

override def clone(): Board = {
val clone = new Board
for(i <- 0 to 13)
clone.board(i) = board(i)
clone.if1PlayerMove = if1PlayerMove
clone.ifOneMoreMove = ifOneMoreMove
clone.ifGameIsOver = ifGameIsOver

clone
}

def ifCorrectFieldNumber(fieldNumber: Int): Boolean =
fieldNumber >= 1 && fieldNumber <= 6 && board(fieldNumber + (if(if1PlayerMove) -1 else + 6)) != 0

def printBoard(): Unit = {
printf(f" ${board(12)}%2d - ${board(11)}%2d - ${board(10)}%2d - ${board(9)}%2d - ${board(8)}%2d - ${board(7)}%2d %n" +
f"(${board(13)}%2d ) (${board(6)}%2d ) %n" +
f" ${board(0)}%2d - ${board(1)}%2d - ${board(2)}%2d - ${board(3)}%2d - ${board(4)}%2d - ${board(5)}%2d")
}

def printScore(): Unit = {
val playerScore1 = board(6)
val playerScore2 = board(13)

println("\n-> 1. player score: " + playerScore1)
println("-> 2. player score: " + playerScore2)
if(playerScore1 == playerScore2)
println("DRAW")
else println("WINNER: " + (if(playerScore1 > playerScore2) "1. player: " + playerScore1 else "2. player: " + playerScore2))
}

def printScoreAfterTimeOut(): Unit = {
ifGameIsOver = true
for(i <- 0 to 5) {
board(6) += board(i)
board(13) += board(i + 7)
board(i) = 0
board(i + 7) = 0
}
printScore()
}

}
42 changes: 42 additions & 0 deletions Computer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package KalahaGame
import KalahaGame._


class Computer extends Player {
def makeMove(board: Board): Int = {
Thread.sleep(800)
getBestResultFieldNumber(createResults(board))
}


def getBestResultFieldNumber(results: Array[Int]): Int = {
var bestResultFieldNumber = 0
var bestResult = results(0)

for(i <- 1 to 5) {
if(results(i) > bestResult) {
bestResult = results(i)
bestResultFieldNumber = i
}
}
bestResultFieldNumber + 1
}

def createResults(board: Board): Array[Int] = {
val results: Array[Int] = new Array(6)
for(i <- 1 to 6)
results(i - 1) = countResult(i, board.clone())
results
}

def countResult(fieldNumber: Int, board: Board): Int = {
//if(!board.ifCorrectFieldNumber(fieldNumber)) return Int.MinValue
val ifPlayer1Move = board.isPlayer1Move
board.makeMove(fieldNumber)
val scoresAfterMove = board.getScores
var resultAfterMove = scoresAfterMove._2 - scoresAfterMove._1
if(ifPlayer1Move) resultAfterMove = -resultAfterMove
if(board.hasLastPlayerOneMoreMove) resultAfterMove + getBestResultFieldNumber(createResults(board))
else resultAfterMove
}
}
15 changes: 15 additions & 0 deletions HumanPlayer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package KalahaGame
import KalahaGame.*

import scala.concurrent.{Await, Future, TimeoutException}
import concurrent.duration.DurationInt
import scala.concurrent.ExecutionContext.Implicits.global

class HumanPlayer extends Player {

def makeMove(board: Board): Int = {
print("\nChoose a pit from 1 to 6: ")
val choice = scala.io.StdIn.readInt()
choice
}
}
6 changes: 6 additions & 0 deletions Player.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package KalahaGame
import KalahaGame._

abstract class Player {
def makeMove(board: Board): Int
}
92 changes: 92 additions & 0 deletions Server.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package KalahaGame
import KalahaGame.*

import concurrent.duration.DurationInt
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future, TimeoutException, blocking}
import scala.util.Random

import java.awt.Robot
import java.awt.event.KeyEvent

class Server {

var board = new Board
var player1: Player = _
var player2: Player = _
private val robot = new Robot
private var timeoutCounter = 0

def start(): Unit = {
play()
makeMove(player1)
}

def printMenu(): Unit = {
println("Menu")
println("Options:")
println("1. player vs player")
println("2. player vs computer")
println("3. computer vs computer")
print("Selected option: ")
}

private def play(): Unit = {
printMenu()
var choice = 0
try {
choice = scala.io.StdIn.readInt()
} catch {
case _: Exception => choice = 0
}
choice match {
case 1 =>
player1 = new HumanPlayer()
player2 = new HumanPlayer()
case 2 =>
player1 = new HumanPlayer()
player2 = new Computer()
case 3 =>
player1 = new Computer()
player2 = new Computer()
case _ =>
println("\nWrong input. Try again!\n")
play()
}
makeMove(player1)
}

def makeMove(player: Player): Unit = {
try{
while(!board.isGameOver) {
board.printBoard()
val move = Future {
player.makeMove(board)
}
val choice = Await.result(move, 30.seconds)
timeoutCounter = 0
if board.isPlayer1Move then println("\n1. player's choice: " + choice) else println("\n2. player's choice: " + choice)
board.makeMove(choice)
if board.hasLastPlayerOneMoreMove then {
println("\nYou have one more move!\n")
makeMove(player)
}

else if board.isPlayer1Move then makeMove(player1)
else makeMove(player2)
}
} catch {
case e: TimeoutException => {
robot.keyPress(KeyEvent.VK_ENTER)
println("\nTime out, try again")
if (timeoutCounter == 3) {
// board.printScoreAfterTimeOut()
board.ifGameIsOver = true
board.printScore()
}
timeoutCounter += 1
makeMove(player)
}
}
}
}
9 changes: 9 additions & 0 deletions Test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package KalahaGame
import KalahaGame._

object Test {
def main(args: Array[String]): Unit = {
def server = new Server
server.start()
}
}