From 7119211c9bba7a280cba147ddbbf2f5cc313b0f2 Mon Sep 17 00:00:00 2001 From: 234mati Date: Thu, 20 Jan 2022 15:05:45 +0100 Subject: [PATCH 1/3] Task 8 --- src/Main.scala | 416 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 src/Main.scala diff --git a/src/Main.scala b/src/Main.scala new file mode 100644 index 00000000..901d41ab --- /dev/null +++ b/src/Main.scala @@ -0,0 +1,416 @@ + +import java.rmi.server.LogStream.log +import scala.concurrent.duration.Duration +import scala.concurrent.{Await, ExecutionContext, Future} +import scala.concurrent.ExecutionContext.Implicits.global +import java.util.concurrent.{Executor, ForkJoinPool} +import scala.annotation.tailrec +import scala.collection.mutable + +object Main { + def main(args: Array[String]): Unit = { + var human = new Human() + var human2 = new Human() + var engine = new Enginee() + var engine2 = new Enginee() + + var serwer = new Serwer(engine,engine2) + serwer.Play() + } + +} + +def PrintArray(currentMapState: Array[Array[Int]]): Unit = + println(" ") + println(" Player 1 ") + println("--------------------") + print("| |") + for(n <- currentMapState(0).slice(1, 7).toList)print(n +" ") + println("| |") + println("| "+currentMapState(0)(0)+"| | "+currentMapState(1)(0) + "|") + print("| |") + for(n <- currentMapState(1).slice(1, 7).toList)print(n + " ") + println("| |") + println("--------------------") + println(" Player 2 ") + + println(" ") + +trait gameLogic{ + def MakeMove(newCurrentMapState: Array[Array[Int]], player: Int, move: Int): (Array[Array[Int]],Int) = + var currentMapState = Array.fill(2)(Array.fill(7)(4)) + for(i <- 0 to 1){ + for(j <- 0 to 6){ + currentMapState(i)(j) = newCurrentMapState(i)(j) + } + } + + if currentMapState(player)(move) == 0 then { println("Błąd!!! Nie można się tak ruszyć!!!"); (currentMapState,player) } + else + var leftStones = currentMapState(player)(move) + currentMapState(player)(move) = 0 + var successor = move + var line = player + var enemyPlayer = 0 + if player == 0 then enemyPlayer = 1 else enemyPlayer = 0 + var nextPlayer = enemyPlayer + + while(leftStones > 0){ + if line == 0 then successor = successor - 1 + else if successor == 0 then {successor = 6; line = 0} + else successor = successor + 1 + successor match + case 0 => if player != line then successor = 1; line = player + case 7 => if player != line then {successor = 6; line = player; } else {successor = 0; line = 1} + case -1 => if line == 0 then {successor = 1; line = 1 }else {successor = 6; line = 0} + case n => + + if successor != 0 || line == player then + currentMapState(line)(successor) = currentMapState(line)(successor) + 1 + leftStones = leftStones -1 + + // println("Succesor: " + successor + " Left Stones: " + leftStones + " Line: " +line) + + if leftStones == 0 && line == player && currentMapState(line)(successor) == 1 && successor != 0 && currentMapState(enemyPlayer)(successor) != 0then + currentMapState(player)(0) = currentMapState(player)(0) + currentMapState(player)(successor) + currentMapState(enemyPlayer)(successor) + currentMapState(player)(successor) = 0 + currentMapState(enemyPlayer)(successor) = 0 + + if leftStones == 0 && line == player && successor == 0 then nextPlayer = player + //PrintArray(currentMapState) + } + + (currentMapState,nextPlayer) + + def CheckAvailableMoves(currentMapState: Array[Array[Int]], player: Int): List[Int] = + // @tailrec + def CheckAvailableMovesRec( pitsNumber: Int): List[Int] = + if pitsNumber < 7 then + if currentMapState(player)(pitsNumber) > 0 then pitsNumber::CheckAvailableMovesRec(pitsNumber+1) else CheckAvailableMovesRec(pitsNumber+1) + else + List() + CheckAvailableMovesRec(1) + + def IsOver(CurrentMapState: Array[Array[Int]]): Boolean = + def pitsCheck(list: List[Int]): Boolean = + list match + case List() => true + case h::t => if h != 0 then false else pitsCheck(t) + pitsCheck(CurrentMapState(0).toList.tail) || pitsCheck(CurrentMapState(1).toList.tail) + + def GetWinner(CurrentMapState: Array[Array[Int]]): Int ={ + def pitsCounting(list: List[Int]): Int = + list match + case List() => 0 + case h::t => h + pitsCounting(t) + if pitsCounting(CurrentMapState(0).toList) > pitsCounting(CurrentMapState(1).toList) + then return 1 + else if pitsCounting(CurrentMapState(0).toList) < pitsCounting(CurrentMapState(1).toList) + then return 2 + else return 0 + } + + def EndingMap(CurrentMapState: Array[Array[Int]]): Unit = + def pitsCounting(iterator: Int, player: Int): Unit = + if iterator < 7 + then{ CurrentMapState(player)(0) = CurrentMapState(player)(0) + CurrentMapState(player)(iterator);CurrentMapState(player)(iterator) = 0; pitsCounting(iterator+1,player)} + pitsCounting(1,0) + pitsCounting(1,1) +} + +class Enginee extends Player { + + private var results = Array.fill(6)(0) + private var move = Array.fill(6)(0) + private var parrarelControler = Array.fill(6)(1) + private var stop = 0 + private var borderOfBadResult = 60000 + private var listOfAvialableMoves: List[Int] = List() + private var howDeepShouldWeMine = 6*6*6*6*6*6*6 + + @Override + override def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit = + stop = 0 + val ectx = ExecutionContext.global + val executor: Executor = new ForkJoinPool(6) + for(i <- 1 to 6){ + results(i-1) = 0 + move(i-1) = -1 + } + parrarelControler = Array.fill(6)(1) + var synchronizedDataBase = new SynchronizedDataBase() + + listOfAvialableMoves = CheckAvailableMoves(startMapState,player) + ectx.execute(() => mainThreadTask()) + for( i <- listOfAvialableMoves){ + // println("nowy wątek: " + i) + move(i-1) = i + executor.execute(() => threadTask(i-1,startMapState,player)) + } + + def threadTask(number: Int, startMapState: Array[Array[Int]],player: Int): Unit = + //println("nowy wątek start: " + number) + if synchronizedDataBase.getQueue(number).isEmpty + then{ val helper = MakeMove(startMapState, player, number+1); + synchronizedDataBase.getQueue(number).append(new Result(number+1,helper._1,helper._2))} + + var size = 0 + + while(parrarelControler(number) == 1){ + if !synchronizedDataBase.getQueue(number).isEmpty + then + val currentResult = synchronizedDataBase.getQueue(number).dequeue() + synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) - 1) + if currentResult != null then + if player == 0 + then results(number) = results(number) + currentResult.GetMapState()(0)(0) - currentResult.GetMapState()(1)(0) + else results(number) = results(number) + currentResult.GetMapState()(1)(0) - currentResult.GetMapState()(0)(0) + + if synchronizedDataBase.getQueueElementsQuantity(number) < howDeepShouldWeMine + then + for( i <- CheckAvailableMoves(currentResult.GetMapState(),currentResult.GetNextPlayer())){ + var helper = MakeMove(currentResult.GetMapState(),currentResult.GetNextPlayer(),i) + synchronizedDataBase.getQueue(number).append(new Result(i,helper._1,helper._2)) + synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) + 1) + } + + size = size +1; + //println(" "+size+":"+number+" ") + //print(number) + + + // then parrarelControler(number) = 0 + //println("QueueQuantity: "+ synchronizedDataBase.getQueueElementsQuantity(number)) + } + //println("Thread: " + number + " end") +// 2015538 + def mainThreadTask(): Unit = + while(stop == 0){ + //println("Move:") + for(i <- 0 to 5) { + //print(move(i) +" " ) + } + Thread.sleep(100) + val minimus = GetMinimumAndMaximum(results) + //println(results(minimus._1) + " " +results(minimus._2)) + if results(minimus._2) - results(minimus._1) > borderOfBadResult && move(minimus._2) != move(minimus._1) && results(minimus._2) != 0 + then {parrarelControler(minimus._1) = 0; + synchronizedDataBase.splitQueueBetweenTwo(minimus._2,minimus._1) + move(minimus._1) = move(minimus._2) + results(minimus._1) = results(minimus._2) + synchronizedDataBase.setQueueElementsQuantity(minimus._1,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) + synchronizedDataBase.setQueueElementsQuantity(minimus._2,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) + parrarelControler(minimus._1) = 1 + executor.execute(()=>threadTask(minimus._1,startMapState,player)) + } + if !searchingNeed() + then {stop = 1 + for(i <- 0 to 5) { + parrarelControler(i) = 0 + } + } + } + //println("MAIN THREAD END") + for(i <- 0 to 5) { + parrarelControler(i) = 0 + synchronizedDataBase.getQueue(i).clear() + } + + + override def searchingNeed(): Boolean = + var retrunValue = false + val compareValue = move(0) + for( i <- 1 to 5) { + if compareValue != move(i) && move(i) != 0 then retrunValue = true + } + retrunValue + + def findBestMove(): Int = + var resultMove = 0 + var result = Int.MinValue + for( i <- listOfAvialableMoves){ + var quantityOfMoves = 0 + var valueOfMoves = 0 + for( j <- 0 to 5){ + if move(i-1) == move(j) && move(j) != -1 then{ quantityOfMoves= quantityOfMoves +1; valueOfMoves = valueOfMoves + results(j)} + } + //print(" ResultFIndBest: "+i + " "+ valueOfMoves/quantityOfMoves) + if valueOfMoves/quantityOfMoves > result && valueOfMoves != 0 then{ result = valueOfMoves/quantityOfMoves; resultMove = i-1} + } + for(i <- 0 to 5) { + + + parrarelControler(i) = 0 + } + //println("\nresult move: "+resultMove) + move(resultMove) + + @Override + override def ReturnMove(): Int = + for(i <- 0 to 5) { + //println("Return " + i + " Result: " + results(i) + " Move: " +move(i) + " ParrarelControler: " + parrarelControler(i) + " List: " + listOfAvialableMoves) + parrarelControler(i) = 0 + } + stop = 1; + findBestMove() + +} + +def GetMinimums(array: Array[Int]): (Int,Int) = + var result: (Int,Int) = (0,0) + for(i <- 1 to 5){ + if array(result._1) > array(i) then result = (i,result._1) + else if array(result._1) < array(i) && array(result._2) > array(i) then result = (result._1, i) + } + result + +def GetMinimumAndMaximum(array: Array[Int]): (Int,Int) = + var result: (Int,Int) = (0,0) + for(i <- 1 to 5){ + if array(result._1) > array(i) then result = (i,result._2) + if array(result._2) < array(i) then result = (result._1, i) + } + result +//private var advantage: Int,private var previousMoves: List[Int], +class Result(private var previousMove: Int, private var mapState: Array[Array[Int]], private var nextPlayer: Int) extends gameLogic { + + def GetNextPlayer(): Int = nextPlayer + def GetMapState(): Array[Array[Int]] = mapState + +} + +class SynchronizedDataBase() { + private var queues: Array[mutable.Queue[Result]] = Array.fill(6)(new mutable.Queue[Result]()) + private var access: Array[Boolean] = Array.fill(6)(true) + private var queueElementsQuantity = Array.fill(6)(0) + + def getQueue( number: Int) = this.synchronized { + while !access(number) do wait() + queues(number) + } + + def getQueueElementsQuantity( number: Int): Int = + queueElementsQuantity(number) + + def setQueueElementsQuantity( number: Int, quantity: Int): Unit = + queueElementsQuantity(number) = quantity + + def splitQueueBetweenTwo(toSplit: Int, taker: Int): Unit = + access(toSplit) = false +// while( !queues(toSplit).isEmpty) +// helpQueue.enqueue(queues(toSplit).dequeue()) + + var counter = 0 +// !helpQueue.isEmpty + while (counter < queueElementsQuantity(toSplit)/2 ){ + if !queues(toSplit).isEmpty then + queues(taker).enqueue(queues(toSplit).dequeue()) + counter += 1 + // if counter%2 == 0 + // then queues(toSplit).enqueue(helpQueue.dequeue()) + // else queues(taker).enqueue(helpQueue.dequeue()) + + } + access(toSplit) = true +} + +abstract class Player() extends gameLogic{ + def ReturnMove(): Int + def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit + def searchingNeed(): Boolean +} + +class Human() extends Player{ + private var result = -1 + private var currentMapState: Array[Array[Int]] = Array.fill(2)(Array.fill(7)(0)) + private var player: Int = 0 + + + override def ReturnMove(): Int = + if result == -1 + then + CheckAvailableMoves(currentMapState,player).head + else + result + + @Override + override def Possibilities(startMapState: Array[Array[Int]],playerNum: Int): Unit = { + player = playerNum + result = -1 + currentMapState = startMapState + print("Podaj Liczbę: ") + var line = Console.in.readLine(); + if line != "" + then + while(!CheckAvailableMoves(currentMapState,player).contains(line.charAt(0).asDigit)){ + print("Podaj Liczbę: ") + line = Console.in.readLine(); + println("") + } + result = line.charAt(0).asDigit + } + + override def searchingNeed(): Boolean = + if result == -1 then true else false + +} + +class Serwer(private var player0: Player, private var player1: Player) extends gameLogic { + + def Play(): Unit = + var map = Array.fill(2)(Array.fill(7)(4)) + map (0)(0) = 0 + map (1)(0) = 0 + var currentPlayer = 0; + + + + while(!IsOver(map)){ + val ectx = ExecutionContext.global + PrintArray(map) + if currentPlayer == 0 + then + println("\nPlayer 1 move!") + ectx.execute(() => player0.Possibilities(map,currentPlayer)) + else + println("\nPlayer 2 move!") + ectx.execute(() => player1.Possibilities(map,currentPlayer)) + + val start = System.nanoTime() + var end = System.nanoTime() + + while ((end - start)/1000000000 < 30) { + Thread.sleep(100) + end = System.nanoTime() + + if currentPlayer == 0 + then + if !player0.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 + else + if !player1.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 + } + + + // println("O BOGOWIE") + + if currentPlayer == 0 + then + val move = MakeMove(map,currentPlayer,player0.ReturnMove()) + map = move._1 + currentPlayer = move._2 + else + val move = MakeMove(map,currentPlayer,player1.ReturnMove()) + map = move._1 + currentPlayer = move._2 + Thread.sleep(100) + } + PrintArray(map) + println("-------------------GAMEOVER----------------------") + if GetWinner(map) == 0 + then println("REMIS") + else println("Player " + GetWinner(map) + " have won!!!") + EndingMap(map) + PrintArray(map) + println("-------------------------------------------------") + +} \ No newline at end of file From b1ec279fbf78fc630b11b4b903c5450a083ee64c Mon Sep 17 00:00:00 2001 From: 234mati Date: Thu, 20 Jan 2022 16:10:39 +0100 Subject: [PATCH 2/3] Task 8, server upgrade --- src/Main.scala | 101 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 23 deletions(-) diff --git a/src/Main.scala b/src/Main.scala index 901d41ab..dbae0410 100644 --- a/src/Main.scala +++ b/src/Main.scala @@ -14,27 +14,23 @@ object Main { var engine = new Enginee() var engine2 = new Enginee() - var serwer = new Serwer(engine,engine2) - serwer.Play() + println(human.getClass) + + var serwer = new Serwer(List(human,human2)) + + human.Start() + human2.Start() + + serwer.Main() + + + + } } -def PrintArray(currentMapState: Array[Array[Int]]): Unit = - println(" ") - println(" Player 1 ") - println("--------------------") - print("| |") - for(n <- currentMapState(0).slice(1, 7).toList)print(n +" ") - println("| |") - println("| "+currentMapState(0)(0)+"| | "+currentMapState(1)(0) + "|") - print("| |") - for(n <- currentMapState(1).slice(1, 7).toList)print(n + " ") - println("| |") - println("--------------------") - println(" Player 2 ") - - println(" ") + trait gameLogic{ def MakeMove(newCurrentMapState: Array[Array[Int]], player: Int, move: Int): (Array[Array[Int]],Int) = @@ -116,6 +112,21 @@ trait gameLogic{ then{ CurrentMapState(player)(0) = CurrentMapState(player)(0) + CurrentMapState(player)(iterator);CurrentMapState(player)(iterator) = 0; pitsCounting(iterator+1,player)} pitsCounting(1,0) pitsCounting(1,1) + + def PrintArray(currentMapState: Array[Array[Int]]): Unit = + println(" ") + println(" Player 1 ") + println("--------------------") + print("| |") + for(n <- currentMapState(0).slice(1, 7).toList)print(n +" ") + println("| |") + println("| "+currentMapState(0)(0)+"| | "+currentMapState(1)(0) + "|") + print("| |") + for(n <- currentMapState(1).slice(1, 7).toList)print(n + " ") + println("| |") + println("--------------------") + println(" Player 2 ") + println(" ") } class Enginee extends Player { @@ -324,7 +335,28 @@ class Human() extends Player{ private var result = -1 private var currentMapState: Array[Array[Int]] = Array.fill(2)(Array.fill(7)(0)) private var player: Int = 0 + private var wantPlay: Int = 0 + + def Start(): Unit ={ + println("Welcome!!!" + + "\n1. Player vs Player" + + "\n2. Player vs Computer" + + "\n3. Computer vs Computer" + + "\n4. End") + var line = ""; + while(line == ""){ + line = Console.in.readLine(); + line match + case "1" => wantPlay = 1 + case "2" => wantPlay = 2 + case "3" => wantPlay = 3 + case "4" => wantPlay = 0 + case _ => + } + + } + def GetWantPlay(): Int = wantPlay override def ReturnMove(): Int = if result == -1 @@ -332,7 +364,6 @@ class Human() extends Player{ CheckAvailableMoves(currentMapState,player).head else result - @Override override def Possibilities(startMapState: Array[Array[Int]],playerNum: Int): Unit = { player = playerNum @@ -355,16 +386,37 @@ class Human() extends Player{ } -class Serwer(private var player0: Player, private var player1: Player) extends gameLogic { +class Serwer(private var listOfPlayers: List[Human]) extends gameLogic { + private var engine = new Enginee() + private var engine2 = new Enginee() - def Play(): Unit = + def Main(): Unit ={ + var stop = false + var firstPlayer: Human = null + while(!stop){ + Thread.sleep(100) + var i = 0 + while (i Date: Thu, 20 Jan 2022 16:57:10 +0100 Subject: [PATCH 3/3] Task 8, split to diffrent classes --- src/Engine.scala | 199 +++++++++++ src/Human.scala | 54 +++ src/Main.scala | 887 +++++++++++++++++++++++------------------------ src/Player.scala | 102 ++++++ src/Server.scala | 85 +++++ 5 files changed, 881 insertions(+), 446 deletions(-) create mode 100644 src/Engine.scala create mode 100644 src/Human.scala create mode 100644 src/Player.scala create mode 100644 src/Server.scala diff --git a/src/Engine.scala b/src/Engine.scala new file mode 100644 index 00000000..a6a52fcd --- /dev/null +++ b/src/Engine.scala @@ -0,0 +1,199 @@ +import java.util.concurrent.{Executor, ForkJoinPool} +import scala.collection.mutable +import scala.concurrent.ExecutionContext + +class Enginee extends Player { + + private var results = Array.fill(6)(0) + private var move = Array.fill(6)(0) + private var parrarelControler = Array.fill(6)(1) + private var stop = 0 + private var borderOfBadResult = 60000 + private var listOfAvialableMoves: List[Int] = List() + private var howDeepShouldWeMine = 6*6*6*6*6*6*6 + + @Override + override def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit = + stop = 0 + val ectx = ExecutionContext.global + val executor: Executor = new ForkJoinPool(6) + for(i <- 1 to 6){ + results(i-1) = 0 + move(i-1) = -1 + } + parrarelControler = Array.fill(6)(1) + var synchronizedDataBase = new SynchronizedDataBase() + + listOfAvialableMoves = CheckAvailableMoves(startMapState,player) + ectx.execute(() => mainThreadTask()) + for( i <- listOfAvialableMoves){ + // println("nowy wątek: " + i) + move(i-1) = i + executor.execute(() => threadTask(i-1,startMapState,player)) + } + + def threadTask(number: Int, startMapState: Array[Array[Int]],player: Int): Unit = + //println("nowy wątek start: " + number) + if synchronizedDataBase.getQueue(number).isEmpty + then{ val helper = MakeMove(startMapState, player, number+1); + synchronizedDataBase.getQueue(number).append(new Result(number+1,helper._1,helper._2))} + + var size = 0 + + while(parrarelControler(number) == 1){ + if !synchronizedDataBase.getQueue(number).isEmpty + then + val currentResult = synchronizedDataBase.getQueue(number).dequeue() + synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) - 1) + if currentResult != null then + if player == 0 + then results(number) = results(number) + currentResult.GetMapState()(0)(0) - currentResult.GetMapState()(1)(0) + else results(number) = results(number) + currentResult.GetMapState()(1)(0) - currentResult.GetMapState()(0)(0) + + if synchronizedDataBase.getQueueElementsQuantity(number) < howDeepShouldWeMine + then + for( i <- CheckAvailableMoves(currentResult.GetMapState(),currentResult.GetNextPlayer())){ + var helper = MakeMove(currentResult.GetMapState(),currentResult.GetNextPlayer(),i) + synchronizedDataBase.getQueue(number).append(new Result(i,helper._1,helper._2)) + synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) + 1) + } + + size = size +1; + //println(" "+size+":"+number+" ") + //print(number) + + + // then parrarelControler(number) = 0 + //println("QueueQuantity: "+ synchronizedDataBase.getQueueElementsQuantity(number)) + } + //println("Thread: " + number + " end") + // 2015538 + def mainThreadTask(): Unit = + while(stop == 0){ + //println("Move:") + for(i <- 0 to 5) { + //print(move(i) +" " ) + } + Thread.sleep(100) + val minimus = GetMinimumAndMaximum(results) + //println(results(minimus._1) + " " +results(minimus._2)) + if results(minimus._2) - results(minimus._1) > borderOfBadResult && move(minimus._2) != move(minimus._1) && results(minimus._2) != 0 + then {parrarelControler(minimus._1) = 0; + synchronizedDataBase.splitQueueBetweenTwo(minimus._2,minimus._1) + move(minimus._1) = move(minimus._2) + results(minimus._1) = results(minimus._2) + synchronizedDataBase.setQueueElementsQuantity(minimus._1,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) + synchronizedDataBase.setQueueElementsQuantity(minimus._2,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) + parrarelControler(minimus._1) = 1 + executor.execute(()=>threadTask(minimus._1,startMapState,player)) + } + if !searchingNeed() + then {stop = 1 + for(i <- 0 to 5) { + parrarelControler(i) = 0 + } + } + } + //println("MAIN THREAD END") + for(i <- 0 to 5) { + parrarelControler(i) = 0 + synchronizedDataBase.getQueue(i).clear() + } + + + override def searchingNeed(): Boolean = + var retrunValue = false + val compareValue = move(0) + for( i <- 1 to 5) { + if compareValue != move(i) && move(i) != 0 then retrunValue = true + } + retrunValue + + def findBestMove(): Int = + var resultMove = 0 + var result = Int.MinValue + for( i <- listOfAvialableMoves){ + var quantityOfMoves = 0 + var valueOfMoves = 0 + for( j <- 0 to 5){ + if move(i-1) == move(j) && move(j) != -1 then{ quantityOfMoves= quantityOfMoves +1; valueOfMoves = valueOfMoves + results(j)} + } + //print(" ResultFIndBest: "+i + " "+ valueOfMoves/quantityOfMoves) + if valueOfMoves/quantityOfMoves > result && valueOfMoves != 0 then{ result = valueOfMoves/quantityOfMoves; resultMove = i-1} + } + for(i <- 0 to 5) { + + + parrarelControler(i) = 0 + } + //println("\nresult move: "+resultMove) + move(resultMove) + + @Override + override def ReturnMove(): Int = + for(i <- 0 to 5) { + //println("Return " + i + " Result: " + results(i) + " Move: " +move(i) + " ParrarelControler: " + parrarelControler(i) + " List: " + listOfAvialableMoves) + parrarelControler(i) = 0 + } + stop = 1; + findBestMove() + + def GetMinimums(array: Array[Int]): (Int,Int) = + var result: (Int,Int) = (0,0) + for(i <- 1 to 5){ + if array(result._1) > array(i) then result = (i,result._1) + else if array(result._1) < array(i) && array(result._2) > array(i) then result = (result._1, i) + } + result + + def GetMinimumAndMaximum(array: Array[Int]): (Int,Int) = + var result: (Int,Int) = (0,0) + for(i <- 1 to 5){ + if array(result._1) > array(i) then result = (i,result._2) + if array(result._2) < array(i) then result = (result._1, i) + } + result + //private var advantage: Int,private var previousMoves: List[Int], + class Result(private var previousMove: Int, private var mapState: Array[Array[Int]], private var nextPlayer: Int) extends gameLogic { + + def GetNextPlayer(): Int = nextPlayer + def GetMapState(): Array[Array[Int]] = mapState + + } + + class SynchronizedDataBase() { + private var queues: Array[mutable.Queue[Result]] = Array.fill(6)(new mutable.Queue[Result]()) + private var access: Array[Boolean] = Array.fill(6)(true) + private var queueElementsQuantity = Array.fill(6)(0) + + def getQueue( number: Int) = this.synchronized { + while !access(number) do wait() + queues(number) + } + + def getQueueElementsQuantity( number: Int): Int = + queueElementsQuantity(number) + + def setQueueElementsQuantity( number: Int, quantity: Int): Unit = + queueElementsQuantity(number) = quantity + + def splitQueueBetweenTwo(toSplit: Int, taker: Int): Unit = + access(toSplit) = false + // while( !queues(toSplit).isEmpty) + // helpQueue.enqueue(queues(toSplit).dequeue()) + + var counter = 0 + // !helpQueue.isEmpty + while (counter < queueElementsQuantity(toSplit)/2 ){ + if !queues(toSplit).isEmpty then + queues(taker).enqueue(queues(toSplit).dequeue()) + counter += 1 + // if counter%2 == 0 + // then queues(toSplit).enqueue(helpQueue.dequeue()) + // else queues(taker).enqueue(helpQueue.dequeue()) + + } + access(toSplit) = true + } + +} \ No newline at end of file diff --git a/src/Human.scala b/src/Human.scala new file mode 100644 index 00000000..af8eeb33 --- /dev/null +++ b/src/Human.scala @@ -0,0 +1,54 @@ +class Human() extends Player{ + private var result = -1 + private var currentMapState: Array[Array[Int]] = Array.fill(2)(Array.fill(7)(0)) + private var player: Int = 0 + private var wantPlay: Int = 0 + + def Start(): Unit ={ + println("Welcome!!!" + + "\n1. Player vs Player" + + "\n2. Player vs Computer" + + "\n3. Computer vs Computer" + + "\n4. End") + var line = ""; + while(line == ""){ + line = Console.in.readLine(); + line match + case "1" => wantPlay = 1 + case "2" => wantPlay = 2 + case "3" => wantPlay = 3 + case "4" => wantPlay = 0 + case _ => + } + + } + + def GetWantPlay(): Int = wantPlay + + override def ReturnMove(): Int = + if result == -1 + then + CheckAvailableMoves(currentMapState,player).head + else + result + @Override + override def Possibilities(startMapState: Array[Array[Int]],playerNum: Int): Unit = { + player = playerNum + result = -1 + currentMapState = startMapState + print("Podaj Liczbę: ") + var line = Console.in.readLine(); + if line != "" + then + while(!CheckAvailableMoves(currentMapState,player).contains(line.charAt(0).asDigit)){ + print("Podaj Liczbę: ") + line = Console.in.readLine(); + println("") + } + result = line.charAt(0).asDigit + } + + override def searchingNeed(): Boolean = + if result == -1 then true else false + +} diff --git a/src/Main.scala b/src/Main.scala index dbae0410..7c63f7e4 100644 --- a/src/Main.scala +++ b/src/Main.scala @@ -11,461 +11,456 @@ object Main { def main(args: Array[String]): Unit = { var human = new Human() var human2 = new Human() - var engine = new Enginee() - var engine2 = new Enginee() - println(human.getClass) - - var serwer = new Serwer(List(human,human2)) + var serwer = new Server(List(human,human2)) human.Start() human2.Start() serwer.Main() - - - - } - -} - - - -trait gameLogic{ - def MakeMove(newCurrentMapState: Array[Array[Int]], player: Int, move: Int): (Array[Array[Int]],Int) = - var currentMapState = Array.fill(2)(Array.fill(7)(4)) - for(i <- 0 to 1){ - for(j <- 0 to 6){ - currentMapState(i)(j) = newCurrentMapState(i)(j) - } - } - - if currentMapState(player)(move) == 0 then { println("Błąd!!! Nie można się tak ruszyć!!!"); (currentMapState,player) } - else - var leftStones = currentMapState(player)(move) - currentMapState(player)(move) = 0 - var successor = move - var line = player - var enemyPlayer = 0 - if player == 0 then enemyPlayer = 1 else enemyPlayer = 0 - var nextPlayer = enemyPlayer - - while(leftStones > 0){ - if line == 0 then successor = successor - 1 - else if successor == 0 then {successor = 6; line = 0} - else successor = successor + 1 - successor match - case 0 => if player != line then successor = 1; line = player - case 7 => if player != line then {successor = 6; line = player; } else {successor = 0; line = 1} - case -1 => if line == 0 then {successor = 1; line = 1 }else {successor = 6; line = 0} - case n => - - if successor != 0 || line == player then - currentMapState(line)(successor) = currentMapState(line)(successor) + 1 - leftStones = leftStones -1 - - // println("Succesor: " + successor + " Left Stones: " + leftStones + " Line: " +line) - - if leftStones == 0 && line == player && currentMapState(line)(successor) == 1 && successor != 0 && currentMapState(enemyPlayer)(successor) != 0then - currentMapState(player)(0) = currentMapState(player)(0) + currentMapState(player)(successor) + currentMapState(enemyPlayer)(successor) - currentMapState(player)(successor) = 0 - currentMapState(enemyPlayer)(successor) = 0 - - if leftStones == 0 && line == player && successor == 0 then nextPlayer = player - //PrintArray(currentMapState) - } - - (currentMapState,nextPlayer) - - def CheckAvailableMoves(currentMapState: Array[Array[Int]], player: Int): List[Int] = - // @tailrec - def CheckAvailableMovesRec( pitsNumber: Int): List[Int] = - if pitsNumber < 7 then - if currentMapState(player)(pitsNumber) > 0 then pitsNumber::CheckAvailableMovesRec(pitsNumber+1) else CheckAvailableMovesRec(pitsNumber+1) - else - List() - CheckAvailableMovesRec(1) - - def IsOver(CurrentMapState: Array[Array[Int]]): Boolean = - def pitsCheck(list: List[Int]): Boolean = - list match - case List() => true - case h::t => if h != 0 then false else pitsCheck(t) - pitsCheck(CurrentMapState(0).toList.tail) || pitsCheck(CurrentMapState(1).toList.tail) - - def GetWinner(CurrentMapState: Array[Array[Int]]): Int ={ - def pitsCounting(list: List[Int]): Int = - list match - case List() => 0 - case h::t => h + pitsCounting(t) - if pitsCounting(CurrentMapState(0).toList) > pitsCounting(CurrentMapState(1).toList) - then return 1 - else if pitsCounting(CurrentMapState(0).toList) < pitsCounting(CurrentMapState(1).toList) - then return 2 - else return 0 } - def EndingMap(CurrentMapState: Array[Array[Int]]): Unit = - def pitsCounting(iterator: Int, player: Int): Unit = - if iterator < 7 - then{ CurrentMapState(player)(0) = CurrentMapState(player)(0) + CurrentMapState(player)(iterator);CurrentMapState(player)(iterator) = 0; pitsCounting(iterator+1,player)} - pitsCounting(1,0) - pitsCounting(1,1) - - def PrintArray(currentMapState: Array[Array[Int]]): Unit = - println(" ") - println(" Player 1 ") - println("--------------------") - print("| |") - for(n <- currentMapState(0).slice(1, 7).toList)print(n +" ") - println("| |") - println("| "+currentMapState(0)(0)+"| | "+currentMapState(1)(0) + "|") - print("| |") - for(n <- currentMapState(1).slice(1, 7).toList)print(n + " ") - println("| |") - println("--------------------") - println(" Player 2 ") - println(" ") -} - -class Enginee extends Player { - - private var results = Array.fill(6)(0) - private var move = Array.fill(6)(0) - private var parrarelControler = Array.fill(6)(1) - private var stop = 0 - private var borderOfBadResult = 60000 - private var listOfAvialableMoves: List[Int] = List() - private var howDeepShouldWeMine = 6*6*6*6*6*6*6 - - @Override - override def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit = - stop = 0 - val ectx = ExecutionContext.global - val executor: Executor = new ForkJoinPool(6) - for(i <- 1 to 6){ - results(i-1) = 0 - move(i-1) = -1 - } - parrarelControler = Array.fill(6)(1) - var synchronizedDataBase = new SynchronizedDataBase() - - listOfAvialableMoves = CheckAvailableMoves(startMapState,player) - ectx.execute(() => mainThreadTask()) - for( i <- listOfAvialableMoves){ - // println("nowy wątek: " + i) - move(i-1) = i - executor.execute(() => threadTask(i-1,startMapState,player)) - } - - def threadTask(number: Int, startMapState: Array[Array[Int]],player: Int): Unit = - //println("nowy wątek start: " + number) - if synchronizedDataBase.getQueue(number).isEmpty - then{ val helper = MakeMove(startMapState, player, number+1); - synchronizedDataBase.getQueue(number).append(new Result(number+1,helper._1,helper._2))} - - var size = 0 - - while(parrarelControler(number) == 1){ - if !synchronizedDataBase.getQueue(number).isEmpty - then - val currentResult = synchronizedDataBase.getQueue(number).dequeue() - synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) - 1) - if currentResult != null then - if player == 0 - then results(number) = results(number) + currentResult.GetMapState()(0)(0) - currentResult.GetMapState()(1)(0) - else results(number) = results(number) + currentResult.GetMapState()(1)(0) - currentResult.GetMapState()(0)(0) - - if synchronizedDataBase.getQueueElementsQuantity(number) < howDeepShouldWeMine - then - for( i <- CheckAvailableMoves(currentResult.GetMapState(),currentResult.GetNextPlayer())){ - var helper = MakeMove(currentResult.GetMapState(),currentResult.GetNextPlayer(),i) - synchronizedDataBase.getQueue(number).append(new Result(i,helper._1,helper._2)) - synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) + 1) - } - - size = size +1; - //println(" "+size+":"+number+" ") - //print(number) - - - // then parrarelControler(number) = 0 - //println("QueueQuantity: "+ synchronizedDataBase.getQueueElementsQuantity(number)) - } - //println("Thread: " + number + " end") -// 2015538 - def mainThreadTask(): Unit = - while(stop == 0){ - //println("Move:") - for(i <- 0 to 5) { - //print(move(i) +" " ) - } - Thread.sleep(100) - val minimus = GetMinimumAndMaximum(results) - //println(results(minimus._1) + " " +results(minimus._2)) - if results(minimus._2) - results(minimus._1) > borderOfBadResult && move(minimus._2) != move(minimus._1) && results(minimus._2) != 0 - then {parrarelControler(minimus._1) = 0; - synchronizedDataBase.splitQueueBetweenTwo(minimus._2,minimus._1) - move(minimus._1) = move(minimus._2) - results(minimus._1) = results(minimus._2) - synchronizedDataBase.setQueueElementsQuantity(minimus._1,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) - synchronizedDataBase.setQueueElementsQuantity(minimus._2,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) - parrarelControler(minimus._1) = 1 - executor.execute(()=>threadTask(minimus._1,startMapState,player)) - } - if !searchingNeed() - then {stop = 1 - for(i <- 0 to 5) { - parrarelControler(i) = 0 - } - } - } - //println("MAIN THREAD END") - for(i <- 0 to 5) { - parrarelControler(i) = 0 - synchronizedDataBase.getQueue(i).clear() - } - - - override def searchingNeed(): Boolean = - var retrunValue = false - val compareValue = move(0) - for( i <- 1 to 5) { - if compareValue != move(i) && move(i) != 0 then retrunValue = true - } - retrunValue - - def findBestMove(): Int = - var resultMove = 0 - var result = Int.MinValue - for( i <- listOfAvialableMoves){ - var quantityOfMoves = 0 - var valueOfMoves = 0 - for( j <- 0 to 5){ - if move(i-1) == move(j) && move(j) != -1 then{ quantityOfMoves= quantityOfMoves +1; valueOfMoves = valueOfMoves + results(j)} - } - //print(" ResultFIndBest: "+i + " "+ valueOfMoves/quantityOfMoves) - if valueOfMoves/quantityOfMoves > result && valueOfMoves != 0 then{ result = valueOfMoves/quantityOfMoves; resultMove = i-1} - } - for(i <- 0 to 5) { - - - parrarelControler(i) = 0 - } - //println("\nresult move: "+resultMove) - move(resultMove) - - @Override - override def ReturnMove(): Int = - for(i <- 0 to 5) { - //println("Return " + i + " Result: " + results(i) + " Move: " +move(i) + " ParrarelControler: " + parrarelControler(i) + " List: " + listOfAvialableMoves) - parrarelControler(i) = 0 - } - stop = 1; - findBestMove() - } -def GetMinimums(array: Array[Int]): (Int,Int) = - var result: (Int,Int) = (0,0) - for(i <- 1 to 5){ - if array(result._1) > array(i) then result = (i,result._1) - else if array(result._1) < array(i) && array(result._2) > array(i) then result = (result._1, i) - } - result - -def GetMinimumAndMaximum(array: Array[Int]): (Int,Int) = - var result: (Int,Int) = (0,0) - for(i <- 1 to 5){ - if array(result._1) > array(i) then result = (i,result._2) - if array(result._2) < array(i) then result = (result._1, i) - } - result -//private var advantage: Int,private var previousMoves: List[Int], -class Result(private var previousMove: Int, private var mapState: Array[Array[Int]], private var nextPlayer: Int) extends gameLogic { - - def GetNextPlayer(): Int = nextPlayer - def GetMapState(): Array[Array[Int]] = mapState - -} - -class SynchronizedDataBase() { - private var queues: Array[mutable.Queue[Result]] = Array.fill(6)(new mutable.Queue[Result]()) - private var access: Array[Boolean] = Array.fill(6)(true) - private var queueElementsQuantity = Array.fill(6)(0) - - def getQueue( number: Int) = this.synchronized { - while !access(number) do wait() - queues(number) - } - - def getQueueElementsQuantity( number: Int): Int = - queueElementsQuantity(number) - - def setQueueElementsQuantity( number: Int, quantity: Int): Unit = - queueElementsQuantity(number) = quantity - - def splitQueueBetweenTwo(toSplit: Int, taker: Int): Unit = - access(toSplit) = false -// while( !queues(toSplit).isEmpty) -// helpQueue.enqueue(queues(toSplit).dequeue()) - - var counter = 0 -// !helpQueue.isEmpty - while (counter < queueElementsQuantity(toSplit)/2 ){ - if !queues(toSplit).isEmpty then - queues(taker).enqueue(queues(toSplit).dequeue()) - counter += 1 - // if counter%2 == 0 - // then queues(toSplit).enqueue(helpQueue.dequeue()) - // else queues(taker).enqueue(helpQueue.dequeue()) - - } - access(toSplit) = true -} - -abstract class Player() extends gameLogic{ - def ReturnMove(): Int - def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit - def searchingNeed(): Boolean -} - -class Human() extends Player{ - private var result = -1 - private var currentMapState: Array[Array[Int]] = Array.fill(2)(Array.fill(7)(0)) - private var player: Int = 0 - private var wantPlay: Int = 0 - - def Start(): Unit ={ - println("Welcome!!!" + - "\n1. Player vs Player" + - "\n2. Player vs Computer" + - "\n3. Computer vs Computer" + - "\n4. End") - var line = ""; - while(line == ""){ - line = Console.in.readLine(); - line match - case "1" => wantPlay = 1 - case "2" => wantPlay = 2 - case "3" => wantPlay = 3 - case "4" => wantPlay = 0 - case _ => - } - - } - - def GetWantPlay(): Int = wantPlay - - override def ReturnMove(): Int = - if result == -1 - then - CheckAvailableMoves(currentMapState,player).head - else - result - @Override - override def Possibilities(startMapState: Array[Array[Int]],playerNum: Int): Unit = { - player = playerNum - result = -1 - currentMapState = startMapState - print("Podaj Liczbę: ") - var line = Console.in.readLine(); - if line != "" - then - while(!CheckAvailableMoves(currentMapState,player).contains(line.charAt(0).asDigit)){ - print("Podaj Liczbę: ") - line = Console.in.readLine(); - println("") - } - result = line.charAt(0).asDigit - } - - override def searchingNeed(): Boolean = - if result == -1 then true else false - -} - -class Serwer(private var listOfPlayers: List[Human]) extends gameLogic { - private var engine = new Enginee() - private var engine2 = new Enginee() - - def Main(): Unit ={ - var stop = false - var firstPlayer: Human = null - while(!stop){ - Thread.sleep(100) - var i = 0 - while (i player0.Possibilities(map,currentPlayer)) - else - println("\nPlayer 2 move!") - ectx.execute(() => player1.Possibilities(map,currentPlayer)) - - val start = System.nanoTime() - var end = System.nanoTime() - - while ((end - start)/1000000000 < 30) { - Thread.sleep(100) - end = System.nanoTime() - - if currentPlayer == 0 - then - if !player0.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 - else - if !player1.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 - } - - - // println("O BOGOWIE") - - if currentPlayer == 0 - then - val move = MakeMove(map,currentPlayer,player0.ReturnMove()) - map = move._1 - currentPlayer = move._2 - else - val move = MakeMove(map,currentPlayer,player1.ReturnMove()) - map = move._1 - currentPlayer = move._2 - Thread.sleep(100) - } - PrintArray(map) - println("-------------------GAMEOVER----------------------") - if GetWinner(map) == 0 - then println("REMIS") - else println("Player " + GetWinner(map) + " have won!!!") - EndingMap(map) - PrintArray(map) - println("-------------------------------------------------") - - if player0.getClass.toString == "class Human" then player0.asInstanceOf[Human].Start() - if player1.getClass.toString == "class Human" then player0.asInstanceOf[Human].Start() -} \ No newline at end of file +// +//trait gameLogic{ +// def MakeMove(newCurrentMapState: Array[Array[Int]], player: Int, move: Int): (Array[Array[Int]],Int) = +// var currentMapState = Array.fill(2)(Array.fill(7)(4)) +// for(i <- 0 to 1){ +// for(j <- 0 to 6){ +// currentMapState(i)(j) = newCurrentMapState(i)(j) +// } +// } +// +// if currentMapState(player)(move) == 0 then { println("Błąd!!! Nie można się tak ruszyć!!!"); (currentMapState,player) } +// else +// var leftStones = currentMapState(player)(move) +// currentMapState(player)(move) = 0 +// var successor = move +// var line = player +// var enemyPlayer = 0 +// if player == 0 then enemyPlayer = 1 else enemyPlayer = 0 +// var nextPlayer = enemyPlayer +// +// while(leftStones > 0){ +// if line == 0 then successor = successor - 1 +// else if successor == 0 then {successor = 6; line = 0} +// else successor = successor + 1 +// successor match +// case 0 => if player != line then successor = 1; line = player +// case 7 => if player != line then {successor = 6; line = player; } else {successor = 0; line = 1} +// case -1 => if line == 0 then {successor = 1; line = 1 }else {successor = 6; line = 0} +// case n => +// +// if successor != 0 || line == player then +// currentMapState(line)(successor) = currentMapState(line)(successor) + 1 +// leftStones = leftStones -1 +// +// // println("Succesor: " + successor + " Left Stones: " + leftStones + " Line: " +line) +// +// if leftStones == 0 && line == player && currentMapState(line)(successor) == 1 && successor != 0 && currentMapState(enemyPlayer)(successor) != 0then +// currentMapState(player)(0) = currentMapState(player)(0) + currentMapState(player)(successor) + currentMapState(enemyPlayer)(successor) +// currentMapState(player)(successor) = 0 +// currentMapState(enemyPlayer)(successor) = 0 +// +// if leftStones == 0 && line == player && successor == 0 then nextPlayer = player +// //PrintArray(currentMapState) +// } +// +// (currentMapState,nextPlayer) +// +// def CheckAvailableMoves(currentMapState: Array[Array[Int]], player: Int): List[Int] = +// // @tailrec +// def CheckAvailableMovesRec( pitsNumber: Int): List[Int] = +// if pitsNumber < 7 then +// if currentMapState(player)(pitsNumber) > 0 then pitsNumber::CheckAvailableMovesRec(pitsNumber+1) else CheckAvailableMovesRec(pitsNumber+1) +// else +// List() +// CheckAvailableMovesRec(1) +// +// def IsOver(CurrentMapState: Array[Array[Int]]): Boolean = +// def pitsCheck(list: List[Int]): Boolean = +// list match +// case List() => true +// case h::t => if h != 0 then false else pitsCheck(t) +// pitsCheck(CurrentMapState(0).toList.tail) || pitsCheck(CurrentMapState(1).toList.tail) +// +// def GetWinner(CurrentMapState: Array[Array[Int]]): Int ={ +// def pitsCounting(list: List[Int]): Int = +// list match +// case List() => 0 +// case h::t => h + pitsCounting(t) +// if pitsCounting(CurrentMapState(0).toList) > pitsCounting(CurrentMapState(1).toList) +// then return 1 +// else if pitsCounting(CurrentMapState(0).toList) < pitsCounting(CurrentMapState(1).toList) +// then return 2 +// else return 0 +// } +// +// def EndingMap(CurrentMapState: Array[Array[Int]]): Unit = +// def pitsCounting(iterator: Int, player: Int): Unit = +// if iterator < 7 +// then{ CurrentMapState(player)(0) = CurrentMapState(player)(0) + CurrentMapState(player)(iterator);CurrentMapState(player)(iterator) = 0; pitsCounting(iterator+1,player)} +// pitsCounting(1,0) +// pitsCounting(1,1) +// +// def PrintArray(currentMapState: Array[Array[Int]]): Unit = +// println(" ") +// println(" Player 1 ") +// println("--------------------") +// print("| |") +// for(n <- currentMapState(0).slice(1, 7).toList)print(n +" ") +// println("| |") +// println("| "+currentMapState(0)(0)+"| | "+currentMapState(1)(0) + "|") +// print("| |") +// for(n <- currentMapState(1).slice(1, 7).toList)print(n + " ") +// println("| |") +// println("--------------------") +// println(" Player 2 ") +// println(" ") +//} +// +//class Enginee extends Player { +// +// private var results = Array.fill(6)(0) +// private var move = Array.fill(6)(0) +// private var parrarelControler = Array.fill(6)(1) +// private var stop = 0 +// private var borderOfBadResult = 60000 +// private var listOfAvialableMoves: List[Int] = List() +// private var howDeepShouldWeMine = 6*6*6*6*6*6*6 +// +// @Override +// override def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit = +// stop = 0 +// val ectx = ExecutionContext.global +// val executor: Executor = new ForkJoinPool(6) +// for(i <- 1 to 6){ +// results(i-1) = 0 +// move(i-1) = -1 +// } +// parrarelControler = Array.fill(6)(1) +// var synchronizedDataBase = new SynchronizedDataBase() +// +// listOfAvialableMoves = CheckAvailableMoves(startMapState,player) +// ectx.execute(() => mainThreadTask()) +// for( i <- listOfAvialableMoves){ +// // println("nowy wątek: " + i) +// move(i-1) = i +// executor.execute(() => threadTask(i-1,startMapState,player)) +// } +// +// def threadTask(number: Int, startMapState: Array[Array[Int]],player: Int): Unit = +// //println("nowy wątek start: " + number) +// if synchronizedDataBase.getQueue(number).isEmpty +// then{ val helper = MakeMove(startMapState, player, number+1); +// synchronizedDataBase.getQueue(number).append(new Result(number+1,helper._1,helper._2))} +// +// var size = 0 +// +// while(parrarelControler(number) == 1){ +// if !synchronizedDataBase.getQueue(number).isEmpty +// then +// val currentResult = synchronizedDataBase.getQueue(number).dequeue() +// synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) - 1) +// if currentResult != null then +// if player == 0 +// then results(number) = results(number) + currentResult.GetMapState()(0)(0) - currentResult.GetMapState()(1)(0) +// else results(number) = results(number) + currentResult.GetMapState()(1)(0) - currentResult.GetMapState()(0)(0) +// +// if synchronizedDataBase.getQueueElementsQuantity(number) < howDeepShouldWeMine +// then +// for( i <- CheckAvailableMoves(currentResult.GetMapState(),currentResult.GetNextPlayer())){ +// var helper = MakeMove(currentResult.GetMapState(),currentResult.GetNextPlayer(),i) +// synchronizedDataBase.getQueue(number).append(new Result(i,helper._1,helper._2)) +// synchronizedDataBase.setQueueElementsQuantity(number,synchronizedDataBase.getQueueElementsQuantity(number) + 1) +// } +// +// size = size +1; +// //println(" "+size+":"+number+" ") +// //print(number) +// +// +// // then parrarelControler(number) = 0 +// //println("QueueQuantity: "+ synchronizedDataBase.getQueueElementsQuantity(number)) +// } +// //println("Thread: " + number + " end") +// // 2015538 +// def mainThreadTask(): Unit = +// while(stop == 0){ +// //println("Move:") +// for(i <- 0 to 5) { +// //print(move(i) +" " ) +// } +// Thread.sleep(100) +// val minimus = GetMinimumAndMaximum(results) +// //println(results(minimus._1) + " " +results(minimus._2)) +// if results(minimus._2) - results(minimus._1) > borderOfBadResult && move(minimus._2) != move(minimus._1) && results(minimus._2) != 0 +// then {parrarelControler(minimus._1) = 0; +// synchronizedDataBase.splitQueueBetweenTwo(minimus._2,minimus._1) +// move(minimus._1) = move(minimus._2) +// results(minimus._1) = results(minimus._2) +// synchronizedDataBase.setQueueElementsQuantity(minimus._1,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) +// synchronizedDataBase.setQueueElementsQuantity(minimus._2,synchronizedDataBase.getQueueElementsQuantity(minimus._2)/2 ) +// parrarelControler(minimus._1) = 1 +// executor.execute(()=>threadTask(minimus._1,startMapState,player)) +// } +// if !searchingNeed() +// then {stop = 1 +// for(i <- 0 to 5) { +// parrarelControler(i) = 0 +// } +// } +// } +// //println("MAIN THREAD END") +// for(i <- 0 to 5) { +// parrarelControler(i) = 0 +// synchronizedDataBase.getQueue(i).clear() +// } +// +// +// override def searchingNeed(): Boolean = +// var retrunValue = false +// val compareValue = move(0) +// for( i <- 1 to 5) { +// if compareValue != move(i) && move(i) != 0 then retrunValue = true +// } +// retrunValue +// +// def findBestMove(): Int = +// var resultMove = 0 +// var result = Int.MinValue +// for( i <- listOfAvialableMoves){ +// var quantityOfMoves = 0 +// var valueOfMoves = 0 +// for( j <- 0 to 5){ +// if move(i-1) == move(j) && move(j) != -1 then{ quantityOfMoves= quantityOfMoves +1; valueOfMoves = valueOfMoves + results(j)} +// } +// //print(" ResultFIndBest: "+i + " "+ valueOfMoves/quantityOfMoves) +// if valueOfMoves/quantityOfMoves > result && valueOfMoves != 0 then{ result = valueOfMoves/quantityOfMoves; resultMove = i-1} +// } +// for(i <- 0 to 5) { +// +// +// parrarelControler(i) = 0 +// } +// //println("\nresult move: "+resultMove) +// move(resultMove) +// +// @Override +// override def ReturnMove(): Int = +// for(i <- 0 to 5) { +// //println("Return " + i + " Result: " + results(i) + " Move: " +move(i) + " ParrarelControler: " + parrarelControler(i) + " List: " + listOfAvialableMoves) +// parrarelControler(i) = 0 +// } +// stop = 1; +// findBestMove() +// +// def GetMinimums(array: Array[Int]): (Int,Int) = +// var result: (Int,Int) = (0,0) +// for(i <- 1 to 5){ +// if array(result._1) > array(i) then result = (i,result._1) +// else if array(result._1) < array(i) && array(result._2) > array(i) then result = (result._1, i) +// } +// result +// +// def GetMinimumAndMaximum(array: Array[Int]): (Int,Int) = +// var result: (Int,Int) = (0,0) +// for(i <- 1 to 5){ +// if array(result._1) > array(i) then result = (i,result._2) +// if array(result._2) < array(i) then result = (result._1, i) +// } +// result +// //private var advantage: Int,private var previousMoves: List[Int], +// class Result(private var previousMove: Int, private var mapState: Array[Array[Int]], private var nextPlayer: Int) extends gameLogic { +// +// def GetNextPlayer(): Int = nextPlayer +// def GetMapState(): Array[Array[Int]] = mapState +// +// } +// +// class SynchronizedDataBase() { +// private var queues: Array[mutable.Queue[Result]] = Array.fill(6)(new mutable.Queue[Result]()) +// private var access: Array[Boolean] = Array.fill(6)(true) +// private var queueElementsQuantity = Array.fill(6)(0) +// +// def getQueue( number: Int) = this.synchronized { +// while !access(number) do wait() +// queues(number) +// } +// +// def getQueueElementsQuantity( number: Int): Int = +// queueElementsQuantity(number) +// +// def setQueueElementsQuantity( number: Int, quantity: Int): Unit = +// queueElementsQuantity(number) = quantity +// +// def splitQueueBetweenTwo(toSplit: Int, taker: Int): Unit = +// access(toSplit) = false +// // while( !queues(toSplit).isEmpty) +// // helpQueue.enqueue(queues(toSplit).dequeue()) +// +// var counter = 0 +// // !helpQueue.isEmpty +// while (counter < queueElementsQuantity(toSplit)/2 ){ +// if !queues(toSplit).isEmpty then +// queues(taker).enqueue(queues(toSplit).dequeue()) +// counter += 1 +// // if counter%2 == 0 +// // then queues(toSplit).enqueue(helpQueue.dequeue()) +// // else queues(taker).enqueue(helpQueue.dequeue()) +// +// } +// access(toSplit) = true +// } +// +//} +// +//abstract class Player() extends gameLogic{ +// def ReturnMove(): Int +// def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit +// def searchingNeed(): Boolean +//} +// +//class Human() extends Player{ +// private var result = -1 +// private var currentMapState: Array[Array[Int]] = Array.fill(2)(Array.fill(7)(0)) +// private var player: Int = 0 +// private var wantPlay: Int = 0 +// +// def Start(): Unit ={ +// println("Welcome!!!" + +// "\n1. Player vs Player" + +// "\n2. Player vs Computer" + +// "\n3. Computer vs Computer" + +// "\n4. End") +// var line = ""; +// while(line == ""){ +// line = Console.in.readLine(); +// line match +// case "1" => wantPlay = 1 +// case "2" => wantPlay = 2 +// case "3" => wantPlay = 3 +// case "4" => wantPlay = 0 +// case _ => +// } +// +// } +// +// def GetWantPlay(): Int = wantPlay +// +// override def ReturnMove(): Int = +// if result == -1 +// then +// CheckAvailableMoves(currentMapState,player).head +// else +// result +// @Override +// override def Possibilities(startMapState: Array[Array[Int]],playerNum: Int): Unit = { +// player = playerNum +// result = -1 +// currentMapState = startMapState +// print("Podaj Liczbę: ") +// var line = Console.in.readLine(); +// if line != "" +// then +// while(!CheckAvailableMoves(currentMapState,player).contains(line.charAt(0).asDigit)){ +// print("Podaj Liczbę: ") +// line = Console.in.readLine(); +// println("") +// } +// result = line.charAt(0).asDigit +// } +// +// override def searchingNeed(): Boolean = +// if result == -1 then true else false +// +//} + + +// +//class Serwer(private var listOfPlayers: List[Human]) extends gameLogic { +// private var engine = new Enginee() +// private var engine2 = new Enginee() +// +// def Main(): Unit ={ +// var stop = false +// var firstPlayer: Human = null +// while(!stop){ +// Thread.sleep(100) +// var i = 0 +// while (i player0.Possibilities(map,currentPlayer)) +// else +// println("\nPlayer 2 move!") +// ectx.execute(() => player1.Possibilities(map,currentPlayer)) +// +// val start = System.nanoTime() +// var end = System.nanoTime() +// +// while ((end - start)/1000000000 < 30) { +// Thread.sleep(100) +// end = System.nanoTime() +// +// if currentPlayer == 0 +// then +// if !player0.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 +// else +// if !player1.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 +// } +// +// +// // println("O BOGOWIE") +// +// if currentPlayer == 0 +// then +// val move = MakeMove(map,currentPlayer,player0.ReturnMove()) +// map = move._1 +// currentPlayer = move._2 +// else +// val move = MakeMove(map,currentPlayer,player1.ReturnMove()) +// map = move._1 +// currentPlayer = move._2 +// Thread.sleep(100) +// } +// PrintArray(map) +// println("-------------------GAMEOVER----------------------") +// if GetWinner(map) == 0 +// then println("REMIS") +// else println("Player " + GetWinner(map) + " have won!!!") +// EndingMap(map) +// PrintArray(map) +// println("-------------------------------------------------") +// +// if player0.getClass.toString == "class Human" then player0.asInstanceOf[Human].Start() +// if player1.getClass.toString == "class Human" then player0.asInstanceOf[Human].Start() +// +//} \ No newline at end of file diff --git a/src/Player.scala b/src/Player.scala new file mode 100644 index 00000000..adaea070 --- /dev/null +++ b/src/Player.scala @@ -0,0 +1,102 @@ +abstract class Player() extends gameLogic{ + def ReturnMove(): Int + def Possibilities(startMapState: Array[Array[Int]],player: Int): Unit + def searchingNeed(): Boolean +} + +trait gameLogic{ + def MakeMove(newCurrentMapState: Array[Array[Int]], player: Int, move: Int): (Array[Array[Int]],Int) = + var currentMapState = Array.fill(2)(Array.fill(7)(4)) + for(i <- 0 to 1){ + for(j <- 0 to 6){ + currentMapState(i)(j) = newCurrentMapState(i)(j) + } + } + + if currentMapState(player)(move) == 0 then { println("Błąd!!! Nie można się tak ruszyć!!!"); (currentMapState,player) } + else + var leftStones = currentMapState(player)(move) + currentMapState(player)(move) = 0 + var successor = move + var line = player + var enemyPlayer = 0 + if player == 0 then enemyPlayer = 1 else enemyPlayer = 0 + var nextPlayer = enemyPlayer + + while(leftStones > 0){ + if line == 0 then successor = successor - 1 + else if successor == 0 then {successor = 6; line = 0} + else successor = successor + 1 + successor match + case 0 => if player != line then successor = 1; line = player + case 7 => if player != line then {successor = 6; line = player; } else {successor = 0; line = 1} + case -1 => if line == 0 then {successor = 1; line = 1 }else {successor = 6; line = 0} + case n => + + if successor != 0 || line == player then + currentMapState(line)(successor) = currentMapState(line)(successor) + 1 + leftStones = leftStones -1 + + // println("Succesor: " + successor + " Left Stones: " + leftStones + " Line: " +line) + + if leftStones == 0 && line == player && currentMapState(line)(successor) == 1 && successor != 0 && currentMapState(enemyPlayer)(successor) != 0then + currentMapState(player)(0) = currentMapState(player)(0) + currentMapState(player)(successor) + currentMapState(enemyPlayer)(successor) + currentMapState(player)(successor) = 0 + currentMapState(enemyPlayer)(successor) = 0 + + if leftStones == 0 && line == player && successor == 0 then nextPlayer = player + //PrintArray(currentMapState) + } + + (currentMapState,nextPlayer) + + def CheckAvailableMoves(currentMapState: Array[Array[Int]], player: Int): List[Int] = + // @tailrec + def CheckAvailableMovesRec( pitsNumber: Int): List[Int] = + if pitsNumber < 7 then + if currentMapState(player)(pitsNumber) > 0 then pitsNumber::CheckAvailableMovesRec(pitsNumber+1) else CheckAvailableMovesRec(pitsNumber+1) + else + List() + CheckAvailableMovesRec(1) + + def IsOver(CurrentMapState: Array[Array[Int]]): Boolean = + def pitsCheck(list: List[Int]): Boolean = + list match + case List() => true + case h::t => if h != 0 then false else pitsCheck(t) + pitsCheck(CurrentMapState(0).toList.tail) || pitsCheck(CurrentMapState(1).toList.tail) + + def GetWinner(CurrentMapState: Array[Array[Int]]): Int ={ + def pitsCounting(list: List[Int]): Int = + list match + case List() => 0 + case h::t => h + pitsCounting(t) + if pitsCounting(CurrentMapState(0).toList) > pitsCounting(CurrentMapState(1).toList) + then return 1 + else if pitsCounting(CurrentMapState(0).toList) < pitsCounting(CurrentMapState(1).toList) + then return 2 + else return 0 + } + + def EndingMap(CurrentMapState: Array[Array[Int]]): Unit = + def pitsCounting(iterator: Int, player: Int): Unit = + if iterator < 7 + then{ CurrentMapState(player)(0) = CurrentMapState(player)(0) + CurrentMapState(player)(iterator);CurrentMapState(player)(iterator) = 0; pitsCounting(iterator+1,player)} + pitsCounting(1,0) + pitsCounting(1,1) + + def PrintArray(currentMapState: Array[Array[Int]]): Unit = + println(" ") + println(" Player 1 ") + println("--------------------") + print("| |") + for(n <- currentMapState(0).slice(1, 7).toList)print(n +" ") + println("| |") + println("| "+currentMapState(0)(0)+"| | "+currentMapState(1)(0) + "|") + print("| |") + for(n <- currentMapState(1).slice(1, 7).toList)print(n + " ") + println("| |") + println("--------------------") + println(" Player 2 ") + println(" ") +} \ No newline at end of file diff --git a/src/Server.scala b/src/Server.scala new file mode 100644 index 00000000..84b2c21f --- /dev/null +++ b/src/Server.scala @@ -0,0 +1,85 @@ +import scala.concurrent.ExecutionContext + +class Server(private var listOfPlayers: List[Human]) extends gameLogic { + private var engine = new Enginee() + private var engine2 = new Enginee() + + def Main(): Unit ={ + var stop = false + var firstPlayer: Human = null + while(!stop){ + Thread.sleep(100) + var i = 0 + while (i player0.Possibilities(map,currentPlayer)) + else + println("\nPlayer 2 move!") + ectx.execute(() => player1.Possibilities(map,currentPlayer)) + + val start = System.nanoTime() + var end = System.nanoTime() + + while ((end - start)/1000000000 < 30) { + Thread.sleep(100) + end = System.nanoTime() + + if currentPlayer == 0 + then + if !player0.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 + else + if !player1.searchingNeed() then end = start + System.nanoTime() + 1000000000*30 + } + + + // println("O BOGOWIE") + + if currentPlayer == 0 + then + val move = MakeMove(map,currentPlayer,player0.ReturnMove()) + map = move._1 + currentPlayer = move._2 + else + val move = MakeMove(map,currentPlayer,player1.ReturnMove()) + map = move._1 + currentPlayer = move._2 + Thread.sleep(100) + } + PrintArray(map) + println("-------------------GAMEOVER----------------------") + if GetWinner(map) == 0 + then println("REMIS") + else println("Player " + GetWinner(map) + " have won!!!") + EndingMap(map) + PrintArray(map) + println("-------------------------------------------------") + + if player0.getClass.toString == "class Human" then player0.asInstanceOf[Human].Start() + if player1.getClass.toString == "class Human" then player0.asInstanceOf[Human].Start() + +} \ No newline at end of file