# 8-puzzle



## Agent (17. Apr 2009)

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
> ...


----------



## faetzminator (17. Apr 2009)

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 (17. Apr 2009)

> 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!!


----------



## ARadauer (17. Apr 2009)

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

was genau erwartest du wenn du eine array ausgibst?


----------



## Agent (17. Apr 2009)

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?


----------



## faetzminator (18. Apr 2009)

Agent hat gesagt.:


> 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 (30. Apr 2009)

faetzminator hat gesagt.:


> 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? 
	
	
	
	





```
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 (30. Apr 2009)

> 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!


```
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 (30. Apr 2009)

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) 
	
	
	
	





```
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 (30. Apr 2009)

Kannst Scanner verwenden.

```
public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            System.out.println(scanner.nextLine());
        }
    }
```


----------



## Agent (30. Apr 2009)

Habs hinbekommen, zumindest funktioniert es  
Für die Nachwelt:

```
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);
```


----------



## Agent (30. Apr 2009)

MarcB hat gesagt.:


> Kannst Scanner verwenden.
> 
> ```
> public static void main(String[] args) {
> ...


Danke!!! Das sieht ja mal gleich viel platzsparender aus :toll:


----------

