Best Practice Würfelturm Permutationen

Lupus

Neues Mitglied
Guten Abend zusammen,
meine Aufgabe ist es, mir alle Kombinationsmöglichkeiten eines Würfelturms(4 Würfel) ausgeben zu lassen.
Die Bedingung sind:
1. Rekursiv
2. Jeder Würfel hat 6 farbige Felder, die 4 Würfel unterscheiden sich in der Regel.
3. Ein Ergebnis zeichnet sich dadurch aus, dass auf jeweils jeder Senkrechten Flanke keine Farbe doppelt vorkommen darf.
Also schaue ich mir im Prinzip ein String[4][4] an.

Wie ich dass grob angehe habe ich auch schon als UML. Mein irgendwie komme ich mit der Rekursionsmethode nicht gut zurecht.
Dabei habe ich aber auch schon einen Groben ansatz. Und zwar drehe ich den Würfel auf n. rekusionstiefe 3 mal nach rechts und schaue ob ein Ergebnis dabei ist, speicher es ggf..

So, wie mache ich dass jetzt mit der Ober- und Unterseite der Würfel. Ich kann sie ja in 6 verschieden Positionen auslegen? Es ist ja leider für alle möglichen Ergebnisse relevant.

Ich hoffe mir kann so schonmal einer was helfen.
 

Holunderbeere

Mitglied
Pack Code bitte immer direkt in die Antworten. Externe Dienste verschwinden gerne, und dann ist die Loesung auch verloren.
Java:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;

/**
 * Die Main Klasse fragt die Eingabe ab und ruft die Rekursion zur Loesung auf.
 */
public class Main {

    /**
     * main-Methode
     * @param args nicht genutzt
     */
    public static void main(String args[]) {
        Wuerfelturm turm = new Wuerfelturm();
         for (int i = 0; i < 4; i++)
             while (true) {
                 try {
                     System.out.println("Bitte geben Sie vier Würfel mit der jeweils gewünschten Farbkombination ein. \n" +
                             "Zur Auswahl stehen die folgenden vier Farben: \n" + "*rot\n" + "*blau\n" + "*grün\n" + "*gelb\n" +
                             "\n" + "Bitte trennen Sie die Farben mit jeweils einem Leerzeichen. \n" + "Ihre Eingabe:\n");
                     // Eingaben hier mit Scanner einfügen (Exceptions auffangen)
                     // String eingabeTop = ;
                     // String eingabeSeiten = ;
                     // String[] eingabeSeitenSplit = eingabeSeiten.split(" ");
                     // String eingabeBottom = ;

                     String[] eingabeFarben = new String[6];
                     eingabeFarben[0] = eingabeTop;
                     eingabeFarben[1] = eingabeSeitenSplit[0];
                     eingabeFarben[2] = eingabeSeitenSplit[1];
                     eingabeFarben[3] = eingabeSeitenSplit[2];
                     eingabeFarben[4] = eingabeSeitenSplit[3];
                     eingabeFarben[5] = eingabeBottom;

                     if (!(Wuerfel.getFarbe().contains(eingabeFarben[0]))) {
                         System.out.println("Sie haben einen Fehler bei 'Top' gemacht. Bitte überprüfen Sie Ihre Eingabe bezüglich Rechtschreibung und Leerzeichen.\n");
                         continue;
                     }

                     if (!(Wuerfel.getFarbe().contains(eingabeFarben[1]) && Wuerfel.getFarbe().contains(eingabeFarben[2]) &&
                             Wuerfel.getFarbe().contains(eingabeFarben[3]) && Wuerfel.getFarbe().contains(eingabeFarben[4]))) {
                         System.out.println("Sie haben einen Fehler bei 'Seiten' gemacht. Bitte überprüfen Sie Ihre Eingabe bezüglich Rechtschreibung und Leerzeichen.\n");
                         continue;
                     }

                     if (!(Wuerfel.getFarbe().contains(eingabeFarben[5]))) {
                         System.out.println("Sie haben einen Fehler bei 'Bottom' gemacht. Bitte überprüfen Sie Ihre Eingabe bezüglich Rechtschreibung und Leerzeichen.\n");
                         continue;
                     }
                     turm.neuerWuerfel(new Wuerfel(eingabeTop, new ArrayList<String>(Arrays.asList(eingabeSeitenSplit[0],
                             eingabeSeitenSplit[1], eingabeSeitenSplit[2], eingabeSeitenSplit[3])), eingabeBottom), i);
                     break;

                 } catch (ArrayIndexOutOfBoundsException e) {
                     System.out.println("Sie haben einen Fehler gemacht. Bitte überprüfen Sie Ihre Eingabe bezüglich Rechtschreibung und Leerzeichen.\n +" +
                             "Bitte beachten Sie, dass Sie bei Top und Bottom jeweils eine Farbe und bei Seiten genau vier Farben angeben müssen.\n");
                 }
             }
        HashSet<String> visitedTowers = new HashSet<>();
        HashSet<String> visitedTowersFull = new HashSet<>();

        turm.sortRecursive(0,0, visitedTowers, visitedTowersFull);
    }
}
Java:
import java.util.ArrayList;
import java.util.HashSet;

/**
 * Die Wurfel Klasse beschreibt einen Wuerfel
 */
public class Wuerfel {

    private static HashSet<String> farbe = new HashSet(){{
        add("rot");
        add("blau");
        add("grün");
        add("gelb");
    }};
    private ArrayList<String> seite = new ArrayList<>();
    private String top;
    private String bottom;
    private int state;

    /**
     * Konstruktor der Wuerfel Klasse
     * @param top Oberseite des Wuerfels
     * @param seite Seitenflaechen des Wuerfels (eins, zwei, drei, vier)
     * @param bottom Unterseite des Wuerfels
     */
    public Wuerfel(String top, ArrayList<String> seite, String bottom) {
        this.top = top;
        this.seite = seite;
        this.bottom = bottom;
        this.state = 1;
    }

    /**
     * Getter fuer Seitenflaechen
     * @return Seitenflaechen des Wuerfels
     */
    public ArrayList<String> getSeite() {
        return seite;
    }

    /**
     * Gibt moegliche Farbwerte fuer einen Wuerfel zurueck
     * @return
     */
    public static HashSet<String> getFarbe() {
        return farbe;
    }

    /**
     * Gibt alle Wuerfelseiten als ein String zurueck
     * @return alle Wuerfelseiten (oben, eins, zwei, drei, vier, unten)
     */
    @Override public String toString() {
        StringBuilder wuerfelString = new StringBuilder();
        wuerfelString.append(top).append("\n").append(seite).append("\n").append(bottom);
        return wuerfelString.toString();
    }

    /**
     * Gibt nur die vier Seitenflaechen des Wuerfels als ein String zurueck
     * @return vier Wuerfelseitenflaechen
     */
    public String toStringSeiten() {
        return String.valueOf(seite);
    }


    /**
     * dreht den Wuerfel
     */
    private void drehen() {
        seite.add(seite.get(0));
        seite.remove(seite.get(0));
    }

    /**
     * kippt den Wuerfel
     */
    private void kippen() {
        String temp = this.top;
        this.top = this.seite.get(2);
        this.seite.set(2, this.bottom);
        this.bottom = this.seite.get(0);
        this.seite.set(0, temp);
    }

    /**
     * Rotiert den Wuerfel in alle 24 moeglichen Orientierungen
     */
    public void rotate() {
        if (this.state < 4) {
            this.drehen();
            state++;
        } else if (this.state == 4) {
            this.kippen();
            state++;
        } else if (this.state < 8) {
            this.drehen();
            state++;
        } else if (this.state == 8) {
            this.kippen();
            state++;
        } else if (this.state < 12) {
            this.drehen();
            state++;
        } else if (this.state == 12) {
            this.drehen();
            this.kippen();
            state++;
        } else if (this.state < 16) {
            this.drehen();
            state++;
        } else if (this.state == 16) {
            this.drehen();
            this.kippen();
            state++;
        } else if (this.state < 20) {
            this.drehen();
            state++;
        } else if (this.state == 20) {
            this.drehen();
            this.drehen();
            this.kippen();
            state++;
        } else if (this.state < 24) {
            this.drehen();
            state++;
        } else if (this.state == 24) {
            this.drehen();
            this.kippen();
            this.kippen();
            this.state = 1;
        }
    }
}
Java:
import java.util.HashSet;

/**
 * Die Wurfelturm Klasse enthaelt die Logik zur Loesung des Wuerfelturms.
 */
public class Wuerfelturm {
    private Wuerfel[] turm = new Wuerfel[4];
    public void neuerWuerfel(Wuerfel wuerfel, int index){
        this.turm[index] = wuerfel;
    }

    /**
     * Rekursive Methode zur Loesung des Wuerfelturms
     * @param wuerfel index des Wuerfels
     * @param rotationen Anzahl der Rotationen eines Wuerfels
     * @param visitedTowers bereits gespeicherte Loesungen ohne TOP und BOTTOM Seite
     * @param visitedTowersFull bereits gespeicherte Loesungen mit TOP und BOTTOM Seite
     */
    public void sortRecursive(int wuerfel, int rotationen, HashSet<String> visitedTowers, HashSet<String> visitedTowersFull) {
        if (this.isValid()) {
            String towerString = this.toString();
            String towerStringWithoutTopAndBot = this.getTowerStringIgnoringTopAndBottom();
            if (!visitedTowers.contains(towerStringWithoutTopAndBot) && !visitedTowersFull.contains(towerString) ) {
                visitedTowers.add(towerStringWithoutTopAndBot);
                visitedTowersFull.add(towerString);
                System.out.println(towerString);
            }
        }

        if (rotationen < 24) {
            if (wuerfel < 3) {
                for (int i = 0; i < 24; i++) {
                    this.turm[wuerfel].rotate();
                    sortRecursive(wuerfel + 1, 0, visitedTowers, visitedTowersFull);
                }
            } else {
                this.turm[wuerfel].rotate();
                sortRecursive(wuerfel, rotationen + 1, visitedTowers, visitedTowersFull);
            }
        }
    }

    /**
     * Methode zur Ueberpruefung einer Loesung
     * @return ist der Wuerfelturm eine echte Loesung
     */
    private boolean isValid() {
        HashSet<String> farben = new HashSet<>();
        for (int i = 0; i < 4; i++) {
            for (int k = 0; k < 4; k++) {
                if (!farben.contains(turm[k].getSeite().get(i))) {
                    farben.add(turm[k].getSeite().get(i));
                } else {
                    return false;
                }
            }
            farben.clear();
        }
        return true;
    }

    /**
     * Methode zur Ausgabe des aktuellen Zustands des Wuerfelturms
     * @return Zeichenkette des Wuerfelturms
     */
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("###########").append("\n");
        for (int i = 0; i < 4; i++) {
            result.append("\n").append(this.turm[i].toString()).append("\n");
        }
        result.append("\n");
        return result.toString();
    }
    /**
     * Methode zur Ausgabe des aktuellen Zustands des Wuerfelturms ohne TOP und BOTTOM Seiten der Wuerfel
     * @return Zeichenkette des Wuerfelturms
     */
    private String getTowerStringIgnoringTopAndBottom() {
        StringBuilder result = new StringBuilder();
        for (int i = 1; i < 4; i++) {
            result.append(this.turm[i].toStringSeiten());
        };
        return result.toString();
    }
}
 

Neue Themen


Oben