8-puzzle

Status
Nicht offen für weitere Antworten.

Agent

Mitglied
Hi,

ich versuche mich gerade daran, das Spiel 8-puzzle in Java zu implementieren. Ausgangspunkt ist ein 3x3 Spielfeld mit 8 durchnummerierten Feldern und einem Blank-Feld. Das blank darf pro Spielzug um ein Feld verschoben werden. Am Ende müssen die Felder aufsteigend durchnummeriert sein (von links nach rechts, von oben nach unten) und das blank muss sich am Ende befinden.

Das ganze wird in der Kommandozeile ablaufen und ich werde es später wahlweise mit verschiedenen Algorithmen (Breitensuche, Tiefensuche, A*,...) implementieren. Das ist jetzt erst einmal nicht mein Problem.

Ich stehe gerade ganz am Anfang meiner Aufgabe vor der Frage, wie ich das Ausgangsfeld in der Konsole einlesen und evtl. in einem 3x3-Array abspeichern kann. In der Aufgabenstellung steht, dass man folgende Befehle nutzen soll:
java EightPuzzle.class -n 5
java EightPuzzle -s searchtype -h heuristictype -m maxnodes < startposition.txt
Switch -m, -s, -h

Es wäre super, wenn mir jemand erklären könnte, was diese Befehle bedeuten. Mein Problem ist nicht die Implementierung der Algorithmen, sondern die Initialisierung mittels stdin und stdout.

Anbei die Aufgabenstellung:
The file holding the main class will be called EightPuzzle.class
The execution will be tailored by command line options.
java EightPuzzle.class –n 5
will take a starting position which is the final position of a completed game and “run the
game backwards” by generating random moves (in this case by 5 such random moves)
and applying them.
This is a way of generating a valid starting configuration (one you know you can start
from and end with the desired end position).
The output will be (sent to stdout) the board position reached after those 5 random
moves.
java EightPuzzle –s searchtype –h heuristictype –m maxnodes < startposition.txt
will take the input (in any text file – such as startposition.txt – that has the above 3 line
formatted description of a starting board state) and try to find the shortest moves to go
from that position to the desired end position – i.e., play the game.
Switch –m is followed by an integer, maxnodes, that specifies the maximum number
nodes in the search tree that is expanded.
Switches –s and –h are followed by strings that cause the play to adopt a particular search
strategy and a particular heuristic, respectively.
You have to provide support for the following searches methods (the strings should have
the obvious meanings/associations):
DepthFirst
BreadthFirst
ASTAR
BestFirst
And the heuristics should include:
CountMissplacedTiles
SumManhattanDistance
 

faetzminator

Gesperrter Benutzer
1. System.in ist ein InputStream, mit welchem du von der Konsole lesen kannst
1a. System.out und System.err sind PrintStream's
1b. wenn du java 5 / 6 verwendest, kannst du für das einlesen die Klasse Scanner verwenden
2. "java EightPuzzle -s searchtype -h heuristictype -m maxnodes < startposition.txt" --> EightPuzzle ist deine Klasse, welche von java gestartet wird (bzw. deren main()). "-s searchtype -h heuristictype -m maxnodes" werden dir im main mit Hilfe des vorhandenen String[] übergeben. "<" ist eine Funktionalität der Eingabeaufforderung, shell etc.

Gruss, faetzminator
 

Agent

Mitglied
1. System.in ist ein InputStream, mit welchem du von der Konsole lesen kannst
1a. System.out und System.err sind PrintStream's
Das ist mir klar. Aber ist damit dieses stdin und stdout gemeint? Bzw. ist dies das gleiche wie stdin und stdout? Falls nein, was ist überhaupt stdin/stdout?

"-s searchtype -h heuristictype -m maxnodes" werden dir im main mit Hilfe des vorhandenen String[] übergeben. "<" ist eine Funktionalität der Eingabeaufforderung.
Ah, OK. Aber wie sieht das dann konkret an einem Beispiel aus?
Wenn ich mit java EightPuzzle -s 2 -h 5 -m 3 mein Programm aufrufe, steht dann in diesem Anfangs-String "253" drin?
Ich habe es mal mittels System.out.println(args); ausprobiert und es wurde [Ljava.lang.String;@c3c749 ausgegeben. Macht für mich gerade keinen Sinn ???:L

Das mit dem "<" als Funktionalität der Eingabeaufforderung habe ich noch nicht richtig verstanden.

Vielen Dank für die Unterstützung!!
 
Zuletzt bearbeitet:

ARadauer

Top Contributor
System.out.println(Arrays.toString(args));

was genau erwartest du wenn du eine array ausgibst?
 

Agent

Mitglied
Danke! Nach Hinzufügen von import java.util.*; klappt das jetzt auch :)

Die Eingabe
java EightPuzzle -s 2 -h 5 -m-z
führt zur Ausgabe:
[-s, 2, -h, 5, -m-z]
Es ist quasi so, dass Java diesen args-String grundsätzlich mit zwei eckigen Klammern umrandet und die Kombination aus Leerzeichen+Minuszeichen+Buchstabe automatisch mit einem Komma abtrennt.

Kann mir noch jemand bei meinem Problem mit stdin/stdout und "<" als Funktionalität der Eingabeaufforderung einen Rat geben?
 
Zuletzt bearbeitet:

faetzminator

Gesperrter Benutzer
Das ist mir klar. Aber ist damit dieses stdin und stdout gemeint? Bzw. ist dies das gleiche wie stdin und stdout? Falls nein, was ist überhaupt stdin/stdout?!
Ja, es ist vergleichbar mit stdin/stdout
Ah, OK. Aber wie sieht das dann konkret an einem Beispiel aus?
Wenn ich mit java EightPuzzle -s 2 -h 5 -m 3 mein Programm aufrufe, steht dann in diesem Anfangs-String "253" drin?
Du bekommst ein String[], also ein Array. in args[0] wär dann "-s", in args[1] "2" (welches du noch zu einem int oder Integer machen musst)
Ich habe es mal mittels System.out.println(args); ausprobiert und es wurde [Ljava.lang.String;@c3c749 ausgegeben. Macht für mich gerade keinen Sinn ???:L
System.out.println(Object o); gibt o.toString() aus. Da ein String[] keine "sinnvolle" toString() Methode hat, kommt nur der Typ und Hashcode (oä)
Das mit dem "<" als Funktionalität der Eingabeaufforderung habe ich noch nicht richtig verstanden.
du bekommst oben die 6 Parameter "-s 2 -h 5 -m 3". die < sagt der Konsole, dass der Inhalt von startposition.txt auf das stdin deines Programmes ausgegeben wird. Genau so wie man stdout mit > und (zumindest in der bash) stderr mit &> umleiten kann.
 

Agent

Mitglied
du bekommst oben die 6 Parameter "-s 2 -h 5 -m 3". die < sagt der Konsole, dass der Inhalt von startposition.txt auf das stdin deines Programmes ausgegeben wird. Genau so wie man stdout mit > und (zumindest in der bash) stderr mit &> umleiten kann.
Vielen Dank faetzminator! Hierzu hätte ich noch 2 Fragen:

1) Wo genau liegt der Unterschied zwischen String[] und String, bzw. warum geht folgende Anweisung schief?
Java:
String myString = args;

2) Wie kann ich im Programm auf den Text, der beim Programmaufruf hinter dem Zeichen < steht zugreifen. Beispiel: Wie bekomme ich testtext aus folgendem Programmaufruf in einen String?
java Testprogramm -p 500 < testtext
(Aufruf des Programms "Testprogramm" aus der Konsole)
 

ARadauer

Top Contributor
Es ist quasi so, dass Java diesen args-String grundsätzlich mit zwei eckigen Klammern umrandet und die Kombination aus Leerzeichen+Minuszeichen+Buchstabe automatisch mit einem Komma abtrennt.
args ist kein String! sondern ein Array mit Strings

Arrays.toString

toString ist eine static methode der Klasse Arrays und das erstellt eine String repräsentation des arrays

Wo genau liegt der Unterschied zwischen String[] und String, bzw. warum geht folgende Anweisung schief?

string array und string
ein string array ist kein string!

Java:
public class Test{

   public static void main(String[] args) throws Exception{
      System.out.println("Argumente ausgeben:");
      System.out.println(args.length+" Argrumente");
      for(int i = 0; i < args.length; i++){
         System.out.println(i+". "+args[i]);
      }
   }
}


tja, wenn du das nicht weißt, brauchen wir gar nicht erst weiterreden....
Galileo Computing :: Java ist auch eine Insel (8. Auflage) les mal die ersten 7 Kapitel, dann wird dir einiges klarer...

Es ist leider so, man braucht ein paar Grundlagen...
 

Agent

Mitglied
Habe mir soeben einen Überblick über die Sache ergoogelt. Die Sache mit dem Insel-Buch als OpenBook ist echt ein guter Tipp :)
Ich kann jetzt mit Hilfe des folgenden Codes die erste Zeile einer Textdatei lesen. (z.B. mit dem Programmaufruf "java Test < textdatei.txt)
Java:
import java.io.*;
public class Test {
  public static void main(String[] args) throws IOException  {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s = br.readLine();
    System.out.println(s);
  }
}
Allerdings hat meine Textdatei mehrere Zeilen. Wäre super, wenn man mir hier nochmal helfen könnte.
 

MarcB

Bekanntes Mitglied
Kannst Scanner verwenden.
Java:
public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            System.out.println(scanner.nextLine());
        }
    }
 

Agent

Mitglied
Habs hinbekommen, zumindest funktioniert es :D
Für die Nachwelt:
Java:
        StringBuffer contents = new StringBuffer();
        BufferedReader reader = null; 
        try
        {
            reader = new BufferedReader(new InputStreamReader(System.in));
            String text = null;
 
            // repeat until all lines is read
            while ((text = reader.readLine()) != null)
            {
                contents.append(text)
                    .append(System.getProperty(
                        "line.separator"));
            }
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        } finally
        {
            try
            {
                if (reader != null)
                {
                    reader.close();
                }
            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }
	String content=contents.toString();
	System.out.println(content);
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben