aboutsummaryrefslogtreecommitdiff
path: root/src/scalevalapokalypsi/UI/main.scala
blob: e172f248fdae8165f77c9ebf2737410b90b812f9 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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 <joel.kronqvist@iki.fi> 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.")