Kalaha: Scala + Java = ?


Was macht denn board.getHouses aus? Gibt das was java-kompatibles zurück?


[quote=Shadow992]
Dem kann ich soweit zustimmen, wobei natürlich gute Algorithmen viel Zeit “sparen können”, genau so geht es aber auch andersrum, dass manche Sprachen, schlechte Algorithmen gut machen (einfach weil sie mehr Simulationen pro Sekunde schaffen). Jetzt nachdem sowieso schon einige mit Codes in Java angefangen haben, denke ich, lohnt es sich auch nicht mehr ernsthaft über [/quote]

Bei ICPC ist da immer das Argument “kenne deine Sprache, lebe mit den Einschränkungen”. Wer Dinge in C++ schreibt, der hat halt den Vorteil, dass es dreimal so schnell ist wie in Java - dafür muss er dann auch damit leben, keine Speichersicherheit und weniger Standardbibliothek zu haben.

Ich fand Aufgaben, bei denen man sich eigenständig was bauen konnte und nicht an Vorlagen wurschteln musste, eigentlich immer am angenehmsten. (Disclaimer: Ich höre momentan kein KI :slight_smile: )


[quote=iridium]

Da hast du natürlich Recht, wir werden mal die Köpfe zusammenstecken :smiley:


Heyhey, bei mir funktioniert das ganze nicht und ich versteh nicht ganz wieso - ich habe afaik denselben Code wie mein Teamkollege, und bei dem geht’s.

Am Ende der Framework.scala-Zeile

val (sc1,sc2) = if (finished contains Player1) (Store1.sum, Store2.get) else (Store1.get, Store2.sum)

bekomme ich die Meldung

value contains is not a member of Option[Game.this.Player]

Weiss jemand woran das liegen koennte?


Ich hab grad mal gegooglet - Option.contains existiert seit scala 2.11 - was für eine version benutzt du denn?

1 „Gefällt mir“

Ich hab grad nochmal ne version ohne Option.contains hochgeladen (jetzt beschwert sich der IntelliJ-styleguide, dass ich da doch gefälligst .contains benutzen soll xD ) - wenn ich das richtig verstanden habe müsste das jetzt mit mindestens scala 2.10 kompatibel sein


Ich hab mal eine ganz triviale Frage: Wir würden gerne die Java Seite benutzen und einfach einmal eine sehr simple main-Methode, die ein Spiel mit einem Human-Player und einem Random-Player startet, schreiben. Diese sieht etwa so aus:

import info.kwarc.teaching.AI.Kalah.Agent;
import info.kwarc.teaching.AI.Kalah.Game;
import info.kwarc.teaching.AI.Kalah.HumanPlayer;
import info.kwarc.teaching.AI.Kalah.RandomPlayer;

public class Test {
	public static void main(String[] args)
	{
		Agent agent_orange = new RandomPlayer("Agent Orange");
		Agent me = new HumanPlayer("Me");
		Game game = new Game(agent_orange, me, 6, 4);
		game.play(true);
	}
}

Mit eingebundenem Scala und Java8 compiliert das ganze auch, nur ergibt sich beim Ausführen eine Exception in thread "main" java.lang.NoSuchMethodError: scala.Product.$init$(Lscala/Product;)V at info.kwarc.teaching.AI.Kalah.Game$Player1$.<init>(Framework.scala:140) at info.kwarc.teaching.AI.Kalah.Game.Player1$lzycompute$1(Framework.scala:140) at info.kwarc.teaching.AI.Kalah.Game.info$kwarc$teaching$AI$Kalah$Game$$Player1(Framework.scala:140) at info.kwarc.teaching.AI.Kalah.Game$$anon$1.<init>(Framework.scala:182) at info.kwarc.teaching.AI.Kalah.Game.<init>(Framework.scala:182)
Woran könnte das liegen / was machen wir falsch / wie müssten wir das Spiel richtig starten?


Shadow hat euren code ausprobiert und bei ihm funktioniert er einwandfrei. Könnt ihr euer framework updaten (siehe neuer thread zum thema) und es damit nochmal probieren?


Versucht. Es ändert sich leider nichts am Fehler. Zum Updaten langt es ja, wenn ich die neuen .jar Datein im Git statt der alten einbinde?


Ich habe zum Testen keinerlei class oder jar files verwendet, sondern direkt den Scala-Source-Code. Ich benutze IntelliJ auf Windows mit dem Scala-Plugin. Dort kompiliert es so wie du es probiert hattest einwandfrei. Ich vermute, dass die *.jar Datei irgendwelche Informationen entfernt, die man aber braucht, wenn man die Main ändert. Ich bin leider selbst kein Profi, aber warum versucht ihr überhaupt die Main nach Java zu migrieren? Ich kann auch ungefähr 0 Scala, aber die Scala-Main ist relativ intuitiv zu lesen und erlaubt das Benutzen von Java-Objekten ohne Murren und Verrenkungen.


Ich update die jar immer mit, ja…

Ich steh grad ein bisschen auf dem Schlauch warum das passiert… die scala-lib ist sicherlich eingebunden?


Wir sind jetzt soweit, dass Alpha-Beta pruning läuft und wir uns nur noch um das 5 Sekunden Limit kümmern müssen.
Unsere bisherige Idee wäre es einen eigenen Time zu starten der dann nach 4.5 Sekunden oder so uns abschießt damit wir dann ein Zwischenergebnis ausgeben.
Das kommt mir aber etwas verschwenderisch vor (man muss die Zeit dann so wählen dass möglichst groß aber klein genug um nicht ein timeout zu bekommen).
Stattdessen fände ich es ein schöneres Interface, wenn man einfach nach 5 Sekunden abgeschossen wird und dann das Game ein vorgegebenes public Attribut aus dem Agent ausliest, in dem man immer die Zwischenergebnisse speichert. Damit spart man sich den zweiten Timer und läuft nicht Gefahr zu wenig oder zu viel Zeit zu verbrauchen.
Das sollte sogar möglich sein ohne das Interface zu ändern, wenn man es nur als fallback implementiert für den Fall dass die move länger als 5 Sekunden braucht und sonst immer noch der Rückgabewert verwendet wird.

1 „Gefällt mir“

klingt vernünftig; kann man machen :wink:


Ich glaube ich habe Await.result falsch verstanden. Der aktuelle Code wartet jetzt ja 5 Sekunden und frägt dann timeoutMove ab, falls die Funktion nicht terminiert. Aber die Funktion läuft dann im Hintergrund trotzdem weiter. Dass heißt, dass man nun doch auch noch einen Timer einbauen muss oder es werden im Hintergrund immer mehr Threads gestartet.
Könntest du das so ändern, dass die Funktion auch wirklich abgebrochen wird nach 5 Sekunden?


Krieg ich bestimmt irgendwie hin :wink: Wär ja unsinnig wenn sonst überall zombiethreads rumeiern…


Done


Ich hab jetzt IntelliJ installiert, das Project mit der .sbt aufgebaut, -source 8 verwendet.
Die Test.scala läuft sauber durch.

Wie kann ich gegen die KI spielen, als menschlicher Spieler?


es gibt eine Agentenklasse HumanPlayer(name : String), die von der Konsole einliest. Bedenke aber, dass du auch als menschlicher Spieler nur 5sekunden zeit hast :smiley:

wenn dein Agent also MyAgent heißt kannst du ein Spiel starten mit
(new Game(MyAgent, new HumanPlayer(„Bla“))(#houses,#seeds)).play(false)


.play(true) :wink:


Kann man den Timeout auch ausstellen? Es passieren bei mir sehr seltsame “Illegal Moves”, die ich nur auf den Timeout zurückführen kann, wenn ich spiele…