package scalevalapokalypsi.UI import scalevalapokalypsi.Client.{newClient, Client, GameEvent} import scalevalapokalypsi.Server.Server import scalevalapokalypsi.constants.* import scalevalapokalypsi.utils.* import java.lang.Thread.sleep import scala.util.{Try,Success,Failure} import scala.collection.immutable.LazyList import java.lang.Thread import scala.io.StdIn.readLine @main def main(): Unit = val option = getValidInput[Int]( "Miten tahdot pelata?\n" + s"1) Liity viralliselle palvelimelle ($DEFAULT_SERVER)\n" + "2) Käynnistä palvelin laitteellasi ja liity sille\n" + "3) Liity mielivaltaiselle palvelimelle", s => s.toIntOption match case None => Left("Syötä kokonaisluku.") case Some(i) => if i < 1 || i > 3 then Left("Syötä kokonaisluku väliltä [1,3].") else Right(i) ) val serverName = if option == 3 then readLine("Syötä palvelimen verkkotunnus.\n> ") else if option == 2 then "127.0.0.1" else DEFAULT_SERVER val serverPort = if option == 1 then DEFAULT_PORT else getValidInput[Int]( s"Valitse portti palvelimelle. (Jätä tyhjäksi oletusta $DEFAULT_PORT varten)", s => if s == "" then Right(DEFAULT_PORT) else s.toIntOption match case None => Left("Syötä kokonaisluku.") case Some(i) => if i > 0 && i <= 65535 then Right(i) else Left("Syötä portti lailliselta väliltä.") ) val maxClients = if option == 2 then getValidInput[Int]( "Kuinka monta pelaajaa pelissä saa olla samanaikaisesti?", s => s.toIntOption match case None => Left("Syötä kokonaisluku.") case Some(i) => if i > 1000 then println( "Aika ison määrän valitsit, mutta olkoon menneeksi." ) if i > 0 then Right(i) else Left("Syötä positiivinen kokonaisluku.") ) else 0 val timeLimit = if option == 2 then getValidInput[Int]( s"Syötä vuorojen aikaraja yksiköttömänä sekunneissa odottelun vähentämiseksi. Syötä 0 aikarajan poistamiseksi. (Jätä tyhjäksi oletusta $DEFAULT_TURN_TIME_LIMIT varten)", s => if s == "" then Right(DEFAULT_TURN_TIME_LIMIT) else s.toIntOption .toRight("Syötä kokonaisluku") .filterOrElse( _ >= 0, "Syötä epänegatiivinen kokonaisluku." ) ) else 0 if option == 2 then Thread(() => new Server(serverPort, maxClients, timeLimit, true).startServer()).start() println("Palvelin käynnistetty taustalla.") val name = readLine("Valitse itsellesi pelin sisäinen alter ego.\n> ") Try(newClient(name, serverName, serverPort)) .toOption .flatten match case Some(client) => startClient(client) case None => println( "Palvelimelle liittyminen epäonnistui. Tarkista internet-yhteytesi. Jos yhteytesi on kunnossa ja liittyminen ei pian onnistu, ota yhteyttä Joel Kronqvistiin olettaen, ettei vuodesta 2024 ole kulunut kohtuuttomasti aikaa." ) /** Client game loop. Handles output to and from the client in the eyes of the * terminal. */ def startClient(client: Client): Unit = var hasQuit = false val stdinReader = StdinLineReader() stdinReader.startReading() while !hasQuit do sleep(POLL_INTERVAL) val line = stdinReader.newLine() if line.toOption.map(_.length).getOrElse(0) > 1024 then Printer.printLn("Virhe: Syötteesi oli liian pitkä.") else if line == Right("quit") || line == Left(true) then hasQuit = true println("Poistut pelistä.") else val gameEvent = client.clientStep(line.toOption) Printer.printGameEvent(gameEvent) if !gameEvent.gameIsOn then hasQuit = true println("Peli on pelattu.")