• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

Programmierwettbewerb 2: Aaah a snake!

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
Oh dann haben wir ja schon 3 Java-Lösungen.
Ich vermute allerdings das eure Lösungen schöner werden, da ihr eine Bibliothek dahinter sitzen habt.
Ich habe ja nahezu alles selber implementiert. - Da bin ich mal gespannt.
 

BurnerR

Bot #0384479

Registriert
20 Juli 2013
Beiträge
5.507
Wobei so mega viel dann auch nicht passiert mit Slick, Gott sei dank, ist ja Sinn der Sache ;-).
Ich bin jetzt "fast" fertig. Ich habe das Spiel "Tron" programmiert :D.
Das upgrade zu Snake dürfte die Tage passieren.

Wobei ich aktuell sehr schlechte frameraten habe... irgendwas mache ich vermutlich falsch, muss nochmal in die Slick2d docs schauen.



Kleine Preview

update aktualisiert die game logik
[src=java]
@Override
public void update(GameContainer gc, int i) throws SlickException {
millisecondsPassed += i;
if(millisecondsPassed >= MILLISECONDS_PER_STEP && gameField.getState() == GameState.RUNNING) {
gameField.doGameStep();
// doing a remapping as slick uses other coord system than game model
if(gc.getInput().isKeyPressed(Input.KEY_LEFT)) {
gameField.getSnake().setDirection(Direction.DOWN);
} else if(gc.getInput().isKeyPressed(Input.KEY_RIGHT)) {
gameField.getSnake().setDirection(Direction.UP);
} else if(gc.getInput().isKeyPressed(Input.KEY_UP)) {
gameField.getSnake().setDirection(Direction.LEFT);
} else if(gc.getInput().isKeyPressed(Input.KEY_DOWN)) {
gameField.getSnake().setDirection(Direction.RIGHT);
}
millisecondsPassed = 0;
}
}
[/src]

render ist natürlich fürs zeichnen zuständig
[src=java]
@Override
public void render(GameContainer gc, Graphics g) throws SlickException
{
SnakeRenderer renderer = new SnakeRenderer(20, gameField, g);
renderer.renderGameField();
if(gameField.getState() == GameState.FINISHED) {
g.drawString("GAME OVER", 400, 400);
}
}
[/src]

Die renderGameField benötigt noch ein Refactoring :D
[src=java]
// will draw every object gameField knows one by one
// by iterating through all locations of every single object
public void renderGameField() {
Iterator<SnakeObject> objIt = gameField.getObjectList().iterator();

while(objIt.hasNext()) {
SnakeObject nextObj = objIt.next();
Iterator<Position> posIt = nextObj.getPositions().iterator();

while(posIt.hasNext()) {
Position pos = posIt.next();
ImageBuffer pixel = createPixel(nextObj);
g.drawImage(pixel.getImage(),
toRenderPosition(pos.getX()),
toRenderPosition(pos.getY()));
}
}
}
[/src]
 
Zuletzt bearbeitet:

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Jemand (MOD) sollte mal den Termin für den Contest anpassen das auch das "Board" darüber Bescheid weiß ;)

Edit:
Danke ihr die ihr im Hintergrund die Fäden zieht , das Datum stimmt nun! :T
 
Zuletzt bearbeitet:

exomo

NGBler

Registriert
1 Aug. 2015
Beiträge
129
So, ich habe es heute morgen nun endlich geschafft die erste spielbare Version fertigzustellen.

Source ist im Repository. Zum bauen und ausführen wird die Bibliothek SFML benötigt. Ein Binärbündel gibt es im Anhang: Anhang anzeigen ExomoSnake.7z. Wer das mal ausprobieren will und Fehler/Probleme entdeckt darf mir gerne bescheid sagen :D

Mal sehen wie viele der geplanten Features ich bis Ende des Jahres noch umsetzen kann.
 
Zuletzt bearbeitet:

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.757
Ort
in der Zukunft
Servus Exomo,
unter win10 (und vermutlich auch jedem anderen windows) fehlt:

libstdc++6.dll
libgcc_s_dw2-1.dll

wobei mich etwas verwirrt wofür die gcc-lib gebraucht wird?
 

exomo

NGBler

Registriert
1 Aug. 2015
Beiträge
129
Danke für den Hinweis. Ich habe den Link oben aktualisiert. Im Paket sind jetzt die Runtimes mit drin. Ich wollte die eigentlich statisch dazu linken, das bringt aber auch nichts weil die SFML DLLs auch davon abhängig sind. Die komplett statisch gelinkte Version wird leider zu groß für den Anhang, aber zum testen hier ein Download der eigenltich ohne DLLs auskommen sollte, sofern die üblichen System-DLLs vorhanden sind: exomo.de/files/ExomoSnake.7z

Warum man die gcc-lib braucht weiß ich auch nicht, scheint aber normal zu sein beim gcc/g++.
 

Novgorod

ngb-Nutte

Registriert
14 Juli 2013
Beiträge
3.055
mangels input-buffer verhält es sich ähnlich wie bei thesplit (mag ja gewollt sein) und es tritt sogar wieder der bug auf, dass die schlange bei einem schnellen 180°-turn mit sich selbst kollidiert (d.h. auf der stelle umkehren will und kollidiert)..
 

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
Anhang anzeigen Snake 0.98.1.rar

Der ein oder andere Schönheitfehler wurde korrigiert.
Zudem werden nun Formen als Barrieren hinzugefügt, anstatt der bisherigen einzelnen Pixel (wie es hier ja von einigen gewünscht wurde).

Ein Bug ist mir allerdings noch aufgefallen, den ich bisher nicht ellegant beseitigen kann:
Wenn mehrere Barrieren-Figuren hinzugefügt werden, können beispielsweise zwei "L"s einen Hohlraum an der Wand bilden (oder mehrere Stäbe aneinander oder so).
In diesem Hohlraum kann dann entweder die Schlange gefangen sein oder ein Punkt spawnen, wodurch dieser nicht mehr erreichbar ist.
Ich weiß allerdings keine Lösung für das Problem, da dieses auch mitten auf dem Feld auftreten kann, dass ein Hohlraum gebildet wird, der mindestens 2x2 groß ist.
----
PowerUps gibt es derzeit nur die, die es in der letzten Version auch gab: Schlange halbieren und Geschwindigkeit halbieren.
----
Meine Java-Dateien beinhalten derzeit noch einige Methoden, die ungenutzt sind, allerdings vielleicht später mal genutzt werden könnten, um zum Beispiel zu gucken, ob ein Punkt neben einer Wand liegt oder so ähnliche kleine Dinge.

EDIT: Den Bug könnte man vermeiden, indem man einen "Pathfinder" implementiert, der für jeden Punkt, der generiert wird, ermittelt, ob die Schlange den Punkt erreichen kann - verbraucht aber verhältnismäßig viel Rechenleistung (der Pathfinder müsste immerhin bei jedem neu generierten Punkt, sowie bei jedem Hinzufügen von Barrieren ausgeführt werden), da immerhin jede Möglichkeit durchgetestet werden muss - und einen intelligenten Pathfinder zu implementieren würde dieses Projekt deutlich um Längen sprengen.
Hat jemand eine andere Lösung? - denn eigentlich wollte ich das hier nicht machen und würde dann einfach sagen: Pech gehabt.
 

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.757
Ort
in der Zukunft
Wie wäre es zumindest beim erstellen von Punkten nur zu schauen ob mind. 1 Feld rings rum um den Punkt frei ist?
.... Klar dann kann man nur "rein" fahren um den Punkt zu bekommen und nicht mehr raus ... aber wer das macht ist dann schlicht und ergreifend selber schuld ;D
Zusätzlich könnte man ja Punkte die "lange" nicht eingesammelt wurden verschwinden lassen.
 

Novgorod

ngb-Nutte

Registriert
14 Juli 2013
Beiträge
3.055
@Roin: statt einem richtigen "pathfinder" sollte es auch reichen, wenn vor dem platzieren eines hindernisses sichergestellt wird, dass es rundherum mindestens 1 feld abtand zu jedem anderen hindernis und zu den wänden hat.. die koordinaten der wände und der anderen hindernisse sind ja bekannt, also kann man dynamisch eine liste von "verbotenen" koordinaten berechnen lassen und aus der liste aller koordinaten entfernen, aus der dann die koordinaten für das nächste hindernis ausgelost werden.. das dürfte bei der spielfeldgröße extrem schnell gehen und wäre auch nicht viel programmieraufwand.. der nachteil gegenüber einem "pathfinder" wäre höchstens, dass die hindernisse zu "safe" platziert werden (z.b. immer ein feld weg von der wand und voneinander, wobwohl das nicht immer zwingend nötig ist zum manövrieren)..
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
@exomo:

Unter Windows 7 bei deiner neuen Version komme ich zwar ins Spiel - also vom Menü ins Spiel und aus dem Spiel zurück ins Menü und kann beenden. Aber die Schlange bewegt sich nicht wenn ich im Spiel bin, es gibt aber auch keinen ersichtlichen Fehler, es passiert nur nichts weiter wenn die Schlange und Futter angezeigt werden.
 

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
Wie wäre es zumindest beim erstellen von Punkten nur zu schauen ob mind. 1 Feld rings rum um den Punkt frei ist?
Und was passiert bei einem Einschluss eines Feldes von 3x3 ?
Derzeit lasse ich überprüfen, ob bei jedem nicht blockierten Feld (also keine Barrieren und keine Schlange) mindestens 2 freie Felder angrenzen. Bei einem 2x2 Einschluss trifft das leider ebenfalls zu, alle anderen Möglichkeiten sind durch das Verfahren allerdings lösbar.

Zusätzlich könnte man ja Punkte die "lange" nicht eingesammelt wurden verschwinden lassen.
Ich lasse ja immer nur einen "normalen" Punkt und beliebig viele Extrapunkte generieren. Das es nur einen normalen Punkt gibt, soll die Schwierigkeit bis zu einem gewissen Grad konstant halten. Stehen 2 Punkte zur Verfügung oder "wandert" er, wäre es meiner Meinung nach dann zu "einfach". Ist ein Punkt an einer schwierig (aber lösbar) zu erreichenden Stelle, würde der Spieler einfach einige Zeit im Kreis fahren und z.B. nur Bonuspunkte einsammeln. Dann würde der Punkt versetzt und der Spieler könnte somit schwierige Situationen vermeiden.

BTW: Hat jemand Lust mal eine Snake Version zu schreiben, bei der das Futter wegläuft, sobald die Schlange zu nah kommt? Also wie eine Maus zum Beispiel, die dann bei z.B. 3 Felder Entfernung anfängt wegzulaufen?
Ich denke das baue ich noch bei mir als weiteres Zusatz ein - nicht als PowerUp, sondern als gelegentlichen extra-Bonus.


Das war bereits vorher eine der Lösungen für meine einzeln generierten Barrierenpunkte (keine Formen). Das finde ich aber zu "einfach" - Ich möchte auch mal ein Hindernis an der Wand haben, sodass man um dieses herum muss, um den Punkt darunter zu erreichen.

EDIT:
[src=java]public class Pathfinder {

/**
*
*/
private Point start;

/**
*
*/
private Point destination;

/**
*
*/
private int xMax = 1;

/**
*
*/
private int yMax = 1;

/**
*
*/
private int hasPath = -1;

/**
*
*/
private ArrayList<Point> barrier;

public Pathfinder(Point start, Point destination, int xMax, int yMax, ArrayList<Point> barrier) {
this.start = start;
this.destination = destination;
this.xMax = xMax;
this.yMax = yMax;
this.barrier = barrier;
}

/**
*
*/
private void findPath() {
if(this.findPath(this.start, null)) {
this.hasPath = 1;
} else {
this.hasPath = 0;
}
}

//Debug
private int i;
/**
*
* @param startPosition
* @param previousPoint
* @return
*/
private boolean findPath(Point startPosition, ArrayList<Point> previousPoints) {
ArrayList<Point> nextPoints = this.getPointsAround(startPosition, previousPoints);
if(previousPoints == null) {
previousPoints = new ArrayList<>();
}


i++;
System.out.println(i);


if(nextPoints.contains(this.destination)) {
return true;
} else {
if(!previousPoints.contains(startPosition)) {
previousPoints.add(startPosition);
}

for(Point p: nextPoints) {
if(this.findPath(p, (ArrayList<Point>) previousPoints)) {
return true;
}
}
return false;
}
}

public boolean hasPath() {
if(this.hasPath == -1) {
this.findPath();
}
if(this.hasPath == 0) {
return false;
} else {
return true;
}
}

/**
*
* @param p
* @param previousPoint can be null
* @return
*/
private ArrayList<Point> getPointsAround(Point p, ArrayList<Point> previousPoints) {
ArrayList<Point> pointsAround = new ArrayList<>();
if(previousPoints == null) {
previousPoints = new ArrayList<>();
}

if (p.x - 1 >= 0 && !this.barrier.contains(new Point(p.x - 1, p.y))
&& !previousPoints.contains(new Point(p.x-1, p.y))) {
pointsAround.add(new Point(p.x-1, p.y));
}
if (p.x + 1 <= this.xMax && !this.barrier.contains(new Point(p.x + 1, p.y))
&& !previousPoints.contains(new Point(p.x+1, p.y))) {
pointsAround.add(new Point(p.x+1, p.y));
}
if (p.y - 1 >= 0 && !this.barrier.contains(new Point(p.x, p.y - 1))
&& !previousPoints.contains(new Point(p.x, p.y-1))) {
pointsAround.add(new Point(p.x, p.y-1));
}
if (p.y + 1 <= this.yMax && !this.barrier.contains(new Point(p.x, p.y + 1))
&& !previousPoints.contains(new Point(p.x, p.y+1))) {
pointsAround.add(new Point(p.x, p.y+1));
}

return pointsAround;
}[/src]

Kann mir jemand sagen, wieso bei einem "leeren" Feld (auf dem nur ein Fresspunkt und die Schlange, mit Länge 1) der erste Punkt bereits "keine Verbindung" hat?
Es werden etwa 4200 Male die findPath-Methode aufgerufen. (Bei ca. 50x40), aber es kommt immer "keine Verbindung (hasPath = 0) raus. Das verstehe ich einfach nicht. Ich weiß jetzt auch nicht mehr, wie ich das testen soll...

Ich habe das deswegen erstmal ausgelagert, damit ich getrennt davon arbeiten kann.
 
Zuletzt bearbeitet:

exomo

NGBler

Registriert
1 Aug. 2015
Beiträge
129
So, kleines Update von mir:

Das Binärrelease gibt es bis auf weiteres nur für Windows und nur über den folgenden Link, der von Zeit zu Zeit aktualisiert wird:
ExomoSnake.7z

Änderungen am Spiel gegenüber letzter Version:
- Die 180° Bewegung ist nicht mehr möglich, man kann also nicht mehr direkt sterben wenn man in die falsche Richtung lenkt.
- Geschwindigkeit etwas erhöht, mir war es zu langsam.
- Position des Dreiecks etwas korrigiert damit es mehr in der Mitte des Feldes erscheint.

Sonstige Änderungen:
- Unterstützung für Linux. CMake Dateien eingefügt und String-Konstanten auf wstring geändert damit Umlaute korrekt angezeigt werden.
- Alle Dateien auf UTF-8 Kodierung geändert (auch wichtig für die Texte die ausgegeben werden)
- Readme.md hinzugefügt damit die Projekt Startseite auf gitlab nicht so leer ist. Darin enthalten ist auch eine Kurze Anleitung wie man das Projekt bauen kann.

Einen Eingabebuffer weiß ich noch nicht ob ich den wirklich einbauen will. Das war nicht unbedingt geplant, aber ich werde mal darüber nachdenken. Wenn dann maximal für zwei Bewegungen, so dass sichere U-Turns möglich sind. Alles darüber hinaus scheint mir für den Spieler mehr Verwirrung als Hilfe zu sein.

@theSplit: Ich habe noch keine Ahnung warum das bei dir nicht läuft. Ich habe es auch auf einem Windows 7 getestet, daran alleine kann es nicht liegen. So spontan habe ich keine Erklärung für das Verhalten. Eventuell passt etwas mit der Zeitberechnung für die Bewegungen nicht, das muss ich mir mal noch näher anschauen. Hast du irgendwelche Besonderheiten an deinem System?

@Roin:Wenn du wirklich sicher sein willst das die Punkte erreichbar sind, kannst du eine Art Breitensuche über das ganze Spielfeld machen. Ausgehend von einem bekannten freien Feld (Startfeld, Position der Schlange oder so) "besuchst" du alle Nachbarfelder wenn die ebenfalls frei sind, dann wieder deren Nachbarfelder usw. Die besuchten Felder werden als "erreichbar" markiert (und dürfen dann auch nicht nochmal besucht werden). Wenn du noch Sackgassen eliminieren willst musst du dir die Felder merken, die drei Wände als Nachbarn haben (also als "unerreichbar" markieren) und von denen ausgehend wieder solange das Nachbarfeld als unerreichbar markieren, wie es 3 Wände (bzw. 2 Wände und ein anderes unerreichbares Feld) gibt. Alle Felder die dann noch als "erreichbar" übrig bleiben sind gültige Positionen für Punkte (außer wenn die Schlange gerade darauf ist). Die Berechnung müsstest du dann immer machen wenn sich die Hindernisse ändern.
So viel zur Theorie. Das zu implementieren ist natürlich etwas Aufwand :D
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Besonderheiten an dem System gibt es eigentlich nicht :(

Kann es daran liegen das du das Spiel pausierst wenn das Fenster keinen Focus hat und es dann eventuell nicht wieder startest nachdem das Fenster wieder Fokus bekommt? Ansonsten könnte vielleicht die "msSecondsElapsed()" Schuld sein?

Irgend eine Fehlermeldung kommt auch nicht, hattest du das Spiel in einer VM getestet oder unter einer Windows 7 64bit Installation?
 

exomo

NGBler

Registriert
1 Aug. 2015
Beiträge
129
Also sowas wie Pause beim Verlassen gibt es nicht. Wäre zwar noch eine gute Idee, aber im Moment läuft das Spiel immer weiter, auch wenn man das Fenster verlässt.
Getestet habe ich das auf Win7 64-bit sowohl in einer virtuellen Maschine als auch auf einem echten Rechner.

Das einzige was ich mir vorstellen könnte ist, dass dein Rechner so schnell ist, dass ein Frame weniger als eine Millisekunde dauert. So wie es Aussieht funktioniert dann die Logik wann das nächste update gemacht wird nicht mehr weil immer "0 Millisekunden" addiert wird. Ich schreibe die Zeitsteuerung mal so um dass sich der Fehler nicht akkumuliert, das ist prinzipiell sowieso besser.
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Hi,

ich kann dir da leider keine Infos an die Hand geben, unter Linux hat deine vorvorletzte Version funktioniert, auch wenn das kompiblieren dann doch nur mit CodeBlocks funktioniert hat. Vielleicht ist das wirklich meinem Windows zu schulden, aber es wäre komisch.
 

exomo

NGBler

Registriert
1 Aug. 2015
Beiträge
129
Probier mal die neue Version: ExomoSnake.7z
Bei mir verhält es sich ganz genau so wie die vorherige Version, aber die Zeitmessung ist jetzt kontinuierlich so dass sich keine Fehler akkumulieren können.

EDIT:
Nochmal ein kleines Update: Es gibt jetzt die Möglichkeit das Spiel zu pausieren. Einfach im Spiel "P" drücken für Pause oder fortsetzen.
 
Zuletzt bearbeitet:

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
Anhang anzeigen Snake 0.98.2.rar
Neue Version inklusive Pathfinder - Das Punkteplatzierungsproblem ist nun behoben. Es sollten (eigentlichen) keine Bugs mehr auftreten.

Den "weglaufenden Punkt" habe ich allerdings noch nicht implementiert - ich weiß auch nicht, ob ich das noch machen werde.
 
Oben