[Monkey] Freies Feld finden bei 2048 Klon

Übersicht Andere Programmiersprachen Allgemein

Neue Antwort erstellen

nX^

Betreff: Freies Feld finden bei 2048 Klon

BeitragSo, Okt 18, 2015 18:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich stehe vor einem kleinem Problem bei meinem 2048 Klon und zwar ein freies Feld zu finden...
Da Monkey ja keinen "echten" Zufall bietet, lasse ich X und Y solange per Rnd generieren bis es mit keinem belegtem Feld übereinstimmt in einer Repeat Schleife. Dies ist nicht die beste Lösung wie ich feststellen muss, da es manchmal sehr lange dauert bis ein freies Feld gefunden wurde... (Ich teste in HTML5). Ich könnte sonst alle freien Felder in einer Liste speichern... Dies erscheint mir aber auch nicht als die beste Lösung...

Seed = Millisecs() wird in Function Main aufgerufen.

Vielleicht kann man das Problem noch völlig anders lösen, denn manchmal sieht man bekanntlich Weise den Wald vor lauter Bäumen nicht... Very Happy

Code: [AUSKLAPPEN]
   Repeat
         X = Rnd(0,3)
         Y = Rnd(0,3)
         
         For Local t:Tile = Eachin Items
            If t.PosX = X And t.PosY = Y Then Test = True
         Next
      Until Not Test

Holzchopf

Meisterpacker

Betreff: Re: Freies Feld finden bei 2048 Klon

BeitragSo, Okt 18, 2015 19:39
Antworten mit Zitat
Benutzer-Profile anzeigen
nX^ hat Folgendes geschrieben:
Ich könnte sonst alle freien Felder in einer Liste speichern... Dies erscheint mir aber auch nicht als die beste Lösung...


Wieso nicht?

Ich würde es genau so machen. Die einzige Alternative, die ich mir vorstellen könnte, wäre, in einem ersten Schritt die freien Felder zu zählen (idealerweise hat man die Anzahl freier Felder eh jederzeit zur Verfügung) und zwischen 0 und Anzahlfreierfelder zu Rnden und dann von oben links nach unten rechts die ermittelte Zufahlszahl mitzuzählen und dann dementsprechend das Feld neu zu belegen. Das macht aber nur Sinn, wenn die Möglichkeit besteht, alles on-the-fly zu machen, z.B. in der Update-Routine.

MfG
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

nX^

BeitragSo, Okt 18, 2015 20:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde es jetzt so lösen:

Die Anzahl der freien Felder lassen sich ja leicht errechnen indem ich meine belegten Felder (per CountList) von den gesamt Feldern abziehe. Ich habe eine zweite Liste wo alle freien Felder drin gespeichert sind (Hat den Vorteil ich habe alle Positionen direkt zur Verfügung und muss diese nicht wieder abfragen). Dann verschiebe ich das Feld von der Liste Frei in die Liste belegt.

Beispiel:

16 Felder
2 Felder belegt
14 frei

Zufall 7

Freie Feld Liste durchgehen und bei der Nummer 7 anhalten...



Edit:

Da ich denke, dass die Frage aufkommen wird warum 2 Listen? Es ist einfacher die belegten und leeren Felder in separaten Listen zu speichern im Bezug auf verschieben/verschmelzen. Bei meinem ersten Versuch hatte 16 Felder in einer Liste gespeichert (leere Felder hatten den Wert 0). Das verschieben von mehr als 2 Werten in einer Spalte war zu aufwendig (zu viele For Next Schleifen) und dadurch "laggte" das Spiel ein wenig je nach Fülle des Feldes.

Thunder

BeitragSo, Okt 18, 2015 20:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Das wäre eine Möglichkeit.

Ich schreib noch dazu, wie ich das bei meinem 2048-Klon gemacht hab.
Ich hatte das schon vergessen und gerade wieder angeschaut, und finde es sehr einfallsreich Laughing

ich habe 2 Arrays (sagen wir A und B) mit Länge 4, wo ich die zahlen 0-3 speichere. Die werden gemischt.
Dann laufe ich mit 2 For-Schleifen (Variablen i, j) von 0-3 und setze x = A[i], y = B[j]. D.h. ich laufe alle Felder in zufälliger Reihenfolge durch (je einmal). Falls das Feld leer ist, setze ich eine zahl hinein und beende die Funktion.

Wen's interessiert, Code: https://github.com/chtisgit/te...text2048.c (Funktion spawn_number)
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

nX^

BeitragSo, Okt 18, 2015 22:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Was aber auch eine Möglichkeit ist, ist anhand der letzen Bewegung oder den letzten 2 Bewegungen die gegen überliegende Seite zu nehmen, da diese ja frei sein muss...
Bespiel: bei einer Bewegung von rechts nach links ist die rechte Seite frei und wenn man die Bewegung davor noch miteinbezieht welche von oben nach unten war, ist die beste freiste stelle im Feld logischer Weise die obere rechte Ecke. Jetzt kann man noch einen Offset (welcher per rnd bestimmt wird) von mehreren Feldern in jede Richtung mit einbeziehen...

Thunder

BeitragMi, Okt 21, 2015 17:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Naja, das ist dann wirklich nicht mehr ganz zufällig. Du veränderst das Spiel ja damit...
Man müsste halt testen, ob sich das nicht negativ auf das Gameplay auswirkt.

Gibt ja auch eine 2048 Variante, die die neue Zahl immer an der schlechtesten Position für den Spieler platziert (falls du die kennst). Sowas sollte halt nicht passieren, wenn das Spiel Spaß machen soll Very Happy

Link "2048 - Hard" : https://sztupy.github.io/2048-Hard/
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

DAK

BeitragFr, Okt 23, 2015 11:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab auch mal einen geschrieben, da hab ich die freien Felder in eine Liste gespeichert. Der Speicherverbrauch bei 16 Feldern liegt dann bei maximal 16 Feldern * 2 Koordinaten * (wenn man keinen kleineren Detentyp hat) 4 Bytes für das int = 128 Byte. Wenn du ein Array mit einem Längencounter verwendest, statt einer Liste, dann sparst du dir auch das neuallozieren. Wenn dir rund 128 Byte zu viel sind, dann optimierst du am falschen Eck.

Das ist so eine triviale Aufgabe/Lösung, die sowas von nichts an Rechenpower und Speicherplatz verbraucht, die braucht nicht über dieses Maß weg optimiert werden.
Gewinner der 6. und der 68. BlitzCodeCompo

nX^

BeitragFr, Okt 23, 2015 18:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Edit:

Ich habe meinen Fehler gefunden und den Rest des Posts entfernt, damit ich keine 20x Edit drinstehen habe...

Kann mir jemand erklären warum bei Zahl = 2 * Rnd(1,2) eine 2 oder 3 rauskommt und keine 2 oder 4?
Es gibt doch nur die Möglichkeit 2 * 1 oder 2 * 2 oder sehe ich dass falsch?

Tennisball

BeitragSa, Okt 24, 2015 15:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Rnd gibt einen Float zurück. In deinem Fall also zwischen 1 und 2. Beispielsweise gibt 2 * 1.8 = 3.6. Das wird dann zu 3 abgeschnitten. Für Ganzzahlen verwende Rand

nX^

BeitragSa, Okt 24, 2015 18:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Rand gibt es in Monkey nicht, wenn dann Int(Rnd()). Aber danke für die Info, die Zahl wird ja auf- bzw abgerundet, daran hatte ich nicht gedacht.

Neue Antwort erstellen


Übersicht Andere Programmiersprachen Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group