HashMaps

Naster

Mitglied
Hallo, ich habe ein Problem bei der Bearbeitung einer Aufgabe.
Ziel des Programms soll es sein, eine Quilt-Decke aus s verschiedenen Stoffmustern zu nähen, wobei von jedem Stoffmuster s insgesamt q gleiche Flicken vorhanden sind.
Das Quilt soll am Ende h*b (h*b < s*q) groß sein (es können also Flicken überig bleiben).
Bedingungen, die also eingehalten werden müssen sind, dass pro Muster s nicht mehr als die vorhandene Flicken q verwendet werden. Außerdem sollen nebeneinander und diagonal keine gleichen Muster eingenäht werden.
Jedes Muster per Zufall ausgewählt werden.

Meine Überlegung ist folgende:
Die Muster entsprechen jeweils einer Zahl.
Java:
import java.util.HashMap;

import gdi.quilt.QuiltPainter;

public class Quilt extends QuiltPainter {

    public Quilt(int h, int b, int s, int q, String[] args) {
        super(h, b, s, q, args);
    }

    int rows = getHeight();
    int columns = getWidth();

    int[] patterns = new int[getNumberOfPatterns()];

    private void savePatterns() {
        for (int i = 0; i < patterns.length; i++) {
            patterns[i] = i;
        }
    }

    public void tailorQuilt(int[][] quilt) {
        savePatterns();
        HashMap<Integer, Integer> patternCount = new HashMap<>();
        int counter = 0;       
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                int randomPattern = patterns[(int) (Math.random() * getNumberOfPatterns())];
                        patternCount.put(randomPattern, counter + 1);
                    if (patternCount.get(randomPattern) <= getNumberOfPatchesPerPattern()) {
                        quilt[i][j] = randomPattern;
                    } else {
                        (patternCount.get(randomPattern) > getNumberOfPatchesP)
                        randomPattern = patterns[(int) (Math.random() * getNumberOfPatterns())];
                       
                    }
                }
                }
            }

Soweit ist meine Überlegung, damit nur die vorgegebene Anzahl an Flicken genutzt wird.
Ich müsste jetzt aber ja irgendwie den "else"-Teil so oft wiederholen und jeweils auf die Bedingung testen, bis ich alle Felder im Quilt gefüllt habe. Da steh ich jetzt aber irgendwie auf dem Schlauch. Ich dachte mir, dass ich alles in die HashMap einspeichere, damit ich auf die Werte dann beim Überprüfen der Bedingung "keine gleichen Flicken nebeneinander oder diagonal" auf die gespeicherten Werte zurückgreifen kann...

Wäre echt nett, wenn mir jemand ein bisschen zur Hand gehen könnte.

Mit freundlichen Grüßen
 

Meeresgott

Bekanntes Mitglied
Wenn ich das Richtig verstanden habe, speicherst du ja alle muster im quilt[][].

Pseudocode:
Java:
for( int x = 0; x < quilt.length; x++)
{
       for(int y = 0; y < quilt[0].length; y++
       {
            // Mach das so lange, bis es der Regel keine Musste nebeneinander entspricht.
            //ACHTUNG!! Das Programm könnte sich in einem Endloss loop aufhängen, wenn
            //Du keine Muster mehr hast
             do
             {
                    int myRandomQuilt = Math.....
                   quilt[x][y] = myRandomQuilt
             }while(!check(quilt,x,y, myRandomQuilt));
       }
}
.....

boolean check(int[][] quilt,int x,int y,int newQuilt)
{
//Hier prüfen ob es den Index auch gibt! Sonst bekommst du eine exception!
//War ich jetzt zu faul zu
´     int q1 = quilt[x-1][y];
´     int q2 = quilt[x+1][y];
´     int q3 = quilt[x][y+1];
       int q4 = quilt[x-1][y-1];
       return (q1 != newQuilt) && (q2 != newQuilt) && (q3 != newQuilt) && (q4 != newQuilt) ;
}

Wäre der einfachste Ansatz, der mir einfällt.
 

Naster

Mitglied
Hallo,
ich habs jetzt mal so probiert, wie du geschrieben hast (hab beim check geschaut, dass x und y nicht am Rand sind, da es da ja teilweise keinen "Nachbarn" gibt. )...Bekomme allerdings immer eine -1 ArrayIndexOutOfBounceException.
Verstehe jetzt aber nicht ganz wieso...
Java:
public void tailorQuilt(int[][] quilt) {
        int randomQuilt = 0;
        for( int x = 0; x < quilt.length; x++) {
       
               for(int y = 0; y < quilt[y].length; y++) {
                     do {
                         randomQuilt = (int)Math.random() * getNumberOfPatterns();
                           quilt[x][y] = randomQuilt;
                     }while
                         (!check(quilt, x, y, randomQuilt));
               }
        }
    }
   
    boolean check(int[][] quilt,int x,int y,int newQuilt)
    {
 
         int q1 = 0;
         if (x > 0) {q1 = quilt[x - 1][y];}
         int q2 = 0;
         if (y > 0) {q2 = quilt[x][y - 1];}
         int q3 = 0;
         if (x > 0 && y > 0) { q3= quilt[x - 1][y - 1];}
         int q4 = 0;
         if (x < columns && y < rows) {q4 = quilt[x + 1][y - 1];}
         return (q1 != newQuilt) && (q2 != newQuilt) && (q3 != newQuilt) && (q4 != newQuilt) ;
    }
 

Naster

Mitglied
Welchen Index muss ich denn da auf seine Existenz testen? Da es eine ArrayoutofBounceException ist, müsste ich ja logischerweise testen, ob im Array quilt für die Werte x und y ein Wert angelegt ist...
Wenn ich das über if - bevor die q1,q2,q3,q4-Tests durchgeführt werden - testen will, bekomme ich einen compile-Fehler...
 

temi

Top Contributor
Bekomme allerdings immer eine -1 ArrayIndexOutOfBounceException.
Verstehe jetzt aber nicht ganz wieso...
Falls die "-1" auf den fehlerhaften Index hinweist, dann solltest du nach einer Stelle suchen an der x-1 oder y-1 gerechnet wird, wenn x=0 oder y=0. Am einfachsten wäre es allerdings den Debugger zu bemühen...
 

JStein52

Top Contributor
if (x > 0) {q1 = quilt[x - 1][y];}
int q2 = 0;
if (y > 0) {q2 = quilt[x][y - 1];}
int q3 = 0;
if (x > 0 && y > 0) { q3= quilt[x - 1][y - 1];}
int q4 = 0;
if (x < columns && y < rows) {q4 = quilt[x + 1][y - 1];}
diese Zeilen sind alle falsch da du ja die Methode auch für x=0 bzw. y=0 aufrufst. das ergibt dann einen entsprechenden Index -1
 

mrBrown

Super-Moderator
Mitarbeiter
Nur die letzte der Zeilen ist falsch, in allen anderen gibt es den Check auf 0.
Ich denke mal, da sollte ein '+' statt dem '-' hin
 

Meeresgott

Bekanntes Mitglied
So könntest du es machen:

Java:
/**
*  Dein Quilt darf nicht den Index -1 haben.
*  Sonst tauchen hier Fehler auf.
*/
private static final int INDEX_OUTPFBOUNDS = -1;

boolean check(int[][] quilt, int x,int y, int newQuilt)
{
    int q1 = getQuiltAtIndex(quilt,x-1,y);
    int q2 = getQuiltAtIndex(quilt,x+1,y);
    int q3 = getQuiltAtIndex(quilt,x  ,y-1);
    int q4 = getQuiltAtIndex(quilt,x  ,y+1);
 
    return isNotEqualQuilt(newQuilt,q1)
         &&isNotEqualQuilt(newQuilt,q2)
         &&isNotEqualQuilt(newQuilt,q3)
         &&isNotEqualQuilt(newQuilt,q4);
}

/**
*  Prüfft, ob die Übergeben Quilts identisch sind.
*  hat das übergebene Quilt den Wert 'INDEX_OUTPFBOUNDS' so wird auch
*  'true' zurückgegeben.
*  - Weil ein Quilt, dass es nicht gibt nicht identisch zu einem Existenten ist.
*/
boolean isNotEqualQuilt(int newQuilt,int quilt)
{
    return (newQuilt != quilt) || (INDEX_OUTPFBOUNDS = quilt);
}


/**
* Liefert den Index des Quilts an der Position x,y.
* Ist der Punkt ausserhalb des Arrays wird 'INDEX_OUTPFBOUNDS'
* zurückgegeben
*/
int getQuiltAtIndex(int[][] quilt,int x,int y)
{
    if(isInArry(x,quilt.length) && isInArry(y,quilt[0].length))
    {
        return quilt[x][y];
    }
    else
    {
        return INDEX_OUTPFBOUNDS;
    }
}

/**
*  Diese Methode schaut nur ob, der Wert x im Intervall [0;length[ liegt.
*/
boolean isInArry(int x,length)
{
    return ( x >= 0 && x < length)
}

Dieser Code sollte funktionieren habe ihn aber nicht getestet. Das Prinzip sollte auf jeden Fall klar sein.

Du musst auch nicht so viele Methoden verwenden. Ich persönlich finde es übersichtlicher ab zwei Argumenten für eine boolesche Operation eine neue Methode zu schreiben. Gibt aber viele die in diesem Punkt nicht meiner Meinung sind ;)
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben