Backtracking Solohalma

N8keeper

Neues Mitglied
Hallo Leute,

ich war mir jetzt nicht sicher ob das hier ein Anfängerthema oder nicht ist, aber ich glaub schon! ;-)

Folgende Aufgabe, ich soll ein Programm schreiben, welches das Spiel Solohalma bzw. Solitär (Solitär (Brettspiel) ? Wikipedia) durch Backtracking löst.

Folgende Vorgaben sind gegeben:

1.) Man soll ein Mehrdimensionales Array bilden und in dieses das Spielfeld einfügen (siehe meine Methode setSpielfeld () )
2.) Es soll ein brute force backtracking Algorithmus verwendet werden, der in regelmäßiger Reihenfolge die Spielfelder checkt (bei mir links-oben-rechts-unten)
3.) Man gibt eine Zahl zwischen 1-33 an, welche dann das 1. leere Feld ist, mit dem er rechnet (ich habe diese Zahl der Einfachheit halber mal auf 17 gesetzt, weil das die Mitte ist)

Ich habe mir gedacht, das ich zu dem Spielfeld noch ein zusätzliches Boolean Array mache, welches für die Spielfiguren steht und dementsprechend true (Spielfigur steht auf dem Feld) oder false (Spielfigur steht nicht auf dem Feld) gesetzt wird. Außerdem habe ich mir noch zusätzlich nen paar Methoden geschrieben um mir das suchen der jeweiligen Koordinaten einfacher zu machen.

Irgendwie komm ich nicht weiter, ich habe eine Methode spielen geschrieben, in der theoretisch alle Fälle durchgegangen werden bzw. er fleißig versucht die Lösung zu finden, aber irgendwie ist da nen Fehler den ich nicht sehe.
Vll. kann mir ja jmd. nen kleinen Denkanstoß geben?

Hier mal mein bisheriger Code:

Java:
public class SoloHalma
{
	/*****Variablen*****/
	
	int hilfsvarI = 1;
	int spielfA = 32; 	//Anzahl der Spielfiguren
	int xKoord = 0;		//X-Ḱoordinate
	int yKoord = 0;		//Y-Koordinate
	int spielfeld [] [] = new int [11][11]; //ein 2 faches Feld welches das Spielfeld darstellt
	boolean spielfiguren [] = new boolean [34]; //ein boolean Feld, wobei "true" für vorhandene Spielfigur an der Postion steht und "false" für nicht vorhandene Spielfigur an der Postition. Die Postion "0" wird nicht belegt und ist immer false, deshalb auch 34 Felder(0-33).
	
	/*****Konstruktor*****/
	public SoloHalma(int eingabe)
	{
		System.out.println("Pin " +eingabe+ " entfernt");
		System.out.println();
		
		this.setSpielfeld();
		spielfiguren[eingabe] = false; //Startpunkt wird gesetzt
		spielen(spielfiguren);
				
		System.out.println("fertig");
		
	}
	/*****Methoden*****/
	/*
	 * in dieser Funktion wird das Spielfeld gesetzt, alle nicht benutzten Felder
	 *bekommen den Wert "0" zugeordnet und die benutzten Felder werden laut Vorgabe
	 *durchnummeriert:
	 *		00	01	02	03	04	05	06	07	08	09	10
	 *	00	00	00	00	00	00	00	00	00	00	00	00
	 *	01	00	00	00	00	00	00	00	00	00	00	00
	 *	02	00	00	00	00	01	02	03	00	00	00	00
	 *	03	00	00	00	00	04	05	06	00	00	00	00
	 *	04	00	00	07	08	09	10	11	12	13	00	00
	 *	05	00	00	14	15	16	17	18	19	20	00	00
	 *	06	00	00	21	22	23	24	25	26	27	00	00
	 *	07	00	00	00	00	28	29	30	00	00	00	00
	 *	08	00	00	00	00	31	32	33	00	00	00	00
	 *	09	00	00	00	00	00	00	00	00	00	00	00
	 *	10 	00	00	00	00	00	00	00	00	00	00	00		
	 *außerdem werden dazu noch alle Spielfiguren auf "true" gesetzt
	 */
	public void setSpielfeld () 
	{
		for(int y=0; y<11;y++)
		{
			for(int x=0; x<11;x++)
			{
				if((x < 4 && (y < 4 || y > 6)) || (x > 6 && (y < 4 || y > 6)))
					spielfeld[x][y] = 0;
				else if((x > 3 && x < 7) && (y < 2 || y > 8))
					spielfeld[x][y] = 0;
				else if((y > 3 && y < 7) && (x < 2 || x > 8))
					spielfeld[x][y] = 0;
				else
					spielfeld[x][y] = hilfsvarI++;
				//System.out.print(spielfeld[x][y]+" ");
			}
			//System.out.println();
		}
		for(int a =1;a<spielfiguren.length;a++)
			spielfiguren[a] = true;	
	} 
	
	public boolean [] lSpringen(boolean [] sfl,int xl, int yl) //links springen
	{
		sfl[spielfeld[xl+1] [yl]] = false;	//das uebersprungene Feld wird false gesetzt
		sfl[spielfeld[xl+2][yl]] = false;	//das gesprungene Feld wird false gesetzt
		sfl[spielfeld[xl][yl]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xl+2][yl]+"nach links");
		return sfl;
	}
	
	public boolean [] hSpringen(boolean [] sfh,int xh, int yh) //hoch springen
	{
		sfh[spielfeld[xh] [yh+1]] = false;	//das uebersprungene Feld wird false gesetzt
		sfh[spielfeld[xh][yh+2]] = false;	//das gesprungene Feld wird false gesetzt
		sfh[spielfeld[xh][yh]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xh][yh+2]+"nach oben");
		
		return sfh;
	}
	
	public boolean [] rSpringen(boolean [] sfr,int xr, int yr) //rechts springen
	{
		sfr[spielfeld[xr-1] [yr]] = false;	//das uebersprungene Feld wird false gesetzt
		sfr[spielfeld[xr-2][yr]] = false;	//das gesprungene Feld wird false gesetzt
		sfr[spielfeld[xr][yr]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xr-2][yr]+"nach rechts");
		
		return sfr;
	}
	
	public boolean [] uSpringen(boolean [] sfu,int xu, int yu) //unten springen
	{
		sfu[spielfeld[xu] [yu-1]] = false;	//das uebersprungene Feld wird false gesetzt
		sfu[spielfeld[xu][yu-2]] = false;	//das gesprungene Feld wird false gesetzt
		sfu[spielfeld[xu][yu]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xu][yu-2]+"nach unten");
		
		return sfu;
	}
	
	public void suchKoord(int c) //für den angebenen Wert c werden die jeweiligen Koordinaten im Spielfeld gesucht
	{
		System.out.println(c);
		
		xKoord = 0;
		yKoord = 0;
		
		for(int d=0;d<11;d++)
		{
			for(int e=0;e<11;e++)
			{
				if(spielfeld[e][d] == c)
				{
					xKoord = e;
					yKoord = d;
					break;
				}
				
			}
			if(yKoord !=0)
				break;
		}
	}
	
	public void spielen(boolean [] figuren)
	{
		if(spielfA == 1)
			return;
		
		for(int b = 1; b < figuren.length; b++)
			if(figuren[b] == false)
			{
				suchKoord(b);
				System.out.println(b);
				break;
			}
		
		System.out.println("x: " + xKoord + ", y: " + yKoord );
		
		if(spielfeld[xKoord+2][yKoord] != 0 && figuren[spielfeld[xKoord+2][yKoord]] == true) //links
		{
			spielen(lSpringen(figuren, xKoord, yKoord));
			spielfA--;
		}
		
		else if(spielfeld[xKoord][yKoord-2] != 0 && figuren[spielfeld[xKoord][yKoord-2]] == true) //oben
		{
			spielen(hSpringen(figuren, xKoord, yKoord));
			spielfA--;
		}
		
		else if(spielfeld[xKoord-2][yKoord] != 0 && figuren[spielfeld[xKoord-2][yKoord]] == true) //rechts
		{
			spielen(rSpringen(figuren, xKoord, yKoord));
			spielfA--;
		}
		
		else if(spielfeld[xKoord][yKoord+2] != 0 && figuren[spielfeld[xKoord][yKoord+2]] == true) //unten
		{
			spielen(lSpringen(figuren, xKoord, yKoord));
			spielfA--;
		}
		
		else
		{
			
		}
	}

	/*****Main*****/
	
	public static void main(String[] args)
	{
		int startpunkt = 17; //Integer.parseInt(args[0]);
		new SoloHalma(startpunkt);
		
		

	}

}

vielen Dank für eure Hilfe in Voraus!

Grüße, N8keeper
 
Zuletzt bearbeitet:

N8keeper

Neues Mitglied
Soooo,

ich habe mich mal weiter drann gesetzt und glaube der Lösung näher zu sein!
Aber irgendwo hängt es immer noch, er läuft etliche male durch und kommt zu keinem Ergebnis, bis sich schließlich der Debuger bei Eclipse meldet und ich terminieren muss.

Hier der aktuelle Code:

Java:
public class SoloHalma
{
	/*****Variablen*****/
	
	int hilfsvarI = 1;
	int hilfsvarII = 0;
	int leerFeldA = 0; 	//Anzahl der leeren Felder 	
	int xKoord = 0;		//X-Ḱoordinate
	int yKoord = 0;		//Y-Koordinate
	int spielfeld [] [] = new int [11][11]; //ein 2 faches Feld welches das Spielfeld darstellt
	boolean spielfiguren [] = new boolean [34]; //ein boolean Feld, wobei "true" für vorhandene Spielfigur an der Postion steht und "false" für nicht vorhandene Spielfigur an der Postition. Die Postion "0" wird nicht belegt und ist immer false, deshalb auch 34 Felder(0-33).
	
	/*****Konstruktor*****/
	public SoloHalma(int eingabe)
	{
		System.out.println("Pin " +eingabe+ " entfernt");
		System.out.println();
		
		this.setSpielfeld();
		spielfiguren[eingabe] = false; //Startpunkt wird gesetzt
		spielen(spielfiguren,32);
				
		System.out.println("fertig");
		
	}
	/*****Methoden*****/
	/*
	 * in dieser Funktion wird das Spielfeld gesetzt, alle nicht benutzten Felder
	 *bekommen den Wert "0" zugeordnet und die benutzten Felder werden laut Vorgabe
	 *durchnummeriert:
	 *		00	01	02	03	04	05	06	07	08	09	10
	 *	00	00	00	00	00	00	00	00	00	00	00	00
	 *	01	00	00	00	00	00	00	00	00	00	00	00
	 *	02	00	00	00	00	01	02	03	00	00	00	00
	 *	03	00	00	00	00	04	05	06	00	00	00	00
	 *	04	00	00	07	08	09	10	11	12	13	00	00
	 *	05	00	00	14	15	16	17	18	19	20	00	00
	 *	06	00	00	21	22	23	24	25	26	27	00	00
	 *	07	00	00	00	00	28	29	30	00	00	00	00
	 *	08	00	00	00	00	31	32	33	00	00	00	00
	 *	09	00	00	00	00	00	00	00	00	00	00	00
	 *	10 	00	00	00	00	00	00	00	00	00	00	00		
	 *außerdem werden dazu noch alle Spielfiguren auf "true" gesetzt
	 */
	public void setSpielfeld () 
	{
		for(int y=0; y<11;y++)
		{
			for(int x=0; x<11;x++)
			{
				if((x < 4 && (y < 4 || y > 6)) || (x > 6 && (y < 4 || y > 6)))
					spielfeld[x][y] = 0;
				else if((x > 3 && x < 7) && (y < 2 || y > 8))
					spielfeld[x][y] = 0;
				else if((y > 3 && y < 7) && (x < 2 || x > 8))
					spielfeld[x][y] = 0;
				else
					spielfeld[x][y] = hilfsvarI++;
				//System.out.print(spielfeld[x][y]+" ");
			}
			//System.out.println();
		}
		for(int a =1;a<spielfiguren.length;a++)
			spielfiguren[a] = true;	
	} 
	
	public boolean [] lSpringen(boolean [] sfl,int xl, int yl) //links springen
	{
		sfl[spielfeld[xl+1] [yl]] = false;	//das uebersprungene Feld wird false gesetzt
		sfl[spielfeld[xl+2][yl]] = false;	//das gesprungene Feld wird false gesetzt
		sfl[spielfeld[xl][yl]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xl+2][yl]+"nach links");
		return sfl;
	}
	
	public boolean [] hSpringen(boolean [] sfh,int xh, int yh) //hoch springen
	{
		sfh[spielfeld[xh] [yh+1]] = false;	//das uebersprungene Feld wird false gesetzt
		sfh[spielfeld[xh][yh+2]] = false;	//das gesprungene Feld wird false gesetzt
		sfh[spielfeld[xh][yh]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xh][yh+2]+"nach oben");
		
		return sfh;
	}
	
	public boolean [] rSpringen(boolean [] sfr,int xr, int yr) //rechts springen
	{
		sfr[spielfeld[xr-1] [yr]] = false;	//das uebersprungene Feld wird false gesetzt
		sfr[spielfeld[xr-2][yr]] = false;	//das gesprungene Feld wird false gesetzt
		sfr[spielfeld[xr][yr]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xr-2][yr]+"nach rechts");
		
		return sfr;
	}
	
	public boolean [] uSpringen(boolean [] sfu,int xu, int yu) //unten springen
	{
		sfu[spielfeld[xu] [yu-1]] = false;	//das uebersprungene Feld wird false gesetzt
		sfu[spielfeld[xu][yu-2]] = false;	//das gesprungene Feld wird false gesetzt
		sfu[spielfeld[xu][yu]] = true; 	//das neubelegte Feld wird true gesetzt
		
		System.out.println(spielfeld[xu][yu-2]+"nach unten");
		
		return sfu;
	}
	
	public void suchKoord(int c) //für den angebenen Wert c werden die jeweiligen Koordinaten im Spielfeld gesucht
	{
		//System.out.println(c);
		
		xKoord = 0;
		yKoord = 0;
		
		for(int d=0;d<11;d++)
		{
			for(int e=0;e<11;e++)
			{
				if(spielfeld[e][d] == c)
				{
					xKoord = e;
					yKoord = d;
					break;
				}
				
			}
			if(yKoord !=0)
				break;
		}
	}
	
	public int leereFelder(boolean [] input) //zaehlt die Anzahl der leeren Felder
	{
		for(int g = 1; g<input.length;g++)
		{
			if(input[g] == false)
			{
				hilfsvarII++; // Anzahl der leeren Felder
			}
		}
		return hilfsvarII;
	}
	
	public void nleeresFeld(boolean [] k, int h, int i) //sucht das nächste leere Feld in bei den angebenen Koordinaten
	{
		for(int j = 0;j < 33;j++)
		{
			if(k[j]==false && spielfeld[h][i] != j)
			{
				suchKoord(j);
				break;
			}
				
		}
		
	}
	
	public void spielen(boolean [] figuren, int spielfA)
	{
		if(spielfA == 1)
			return;
		
		for(int b = 1; b < figuren.length; b++)
			if(figuren[b] == false)
			{
				suchKoord(b);
				//System.out.println(b);
				break;
			}
		
		leerFeldA = leereFelder(figuren);
		System.out.println("x: " + xKoord + ", y: " + yKoord );
		
		for(int f=0; f<leerFeldA; f++)
		{
			if(spielfeld[xKoord+2][yKoord] != 0 && figuren[spielfeld[xKoord+1][yKoord]] == true) //links
			{
				spielen(lSpringen(figuren, xKoord, yKoord),spielfA--);
				
			}
		
			else if(spielfeld[xKoord][yKoord-2] != 0 && figuren[spielfeld[xKoord][yKoord-1]] == true) //oben
			{
				spielen(hSpringen(figuren, xKoord, yKoord),spielfA--);
				
			}
		
			else if(spielfeld[xKoord-2][yKoord] != 0 && figuren[spielfeld[xKoord-1][yKoord]] == true) //rechts
			{
				spielen(rSpringen(figuren, xKoord, yKoord),spielfA--);
				
			}
		
			else if(spielfeld[xKoord][yKoord+2] != 0 && figuren[spielfeld[xKoord][yKoord+1]] == true) //unten
			{
				spielen(lSpringen(figuren, xKoord, yKoord),spielfA--);
				
			}
			nleeresFeld(figuren,xKoord, yKoord);
			spielen(figuren,spielfA);
		}
		
	}

	/*****Main*****/
	
	public static void main(String[] args)
	{
		int startpunkt = 17; //Integer.parseInt(args[0]);
		new SoloHalma(startpunkt);
		
		

	}

}
 

Marco13

Top Contributor
Ein StackOverflowArray - das hätte man noch erwähnen können. Das jetzt auf die Schnelle nachzuvollziehen ist ein bißchen schwierig, aber grundsätzlich bedeutet der Fehler: Die Rekursion hört nicht auf. Er Trackt, aber er Backt nicht :D Bau' dir ein paar debug-Ausgaben ein, im Sinne von
Code:
System.out.println("Auf diesem Brett");
gibBrettAus();
System.out.println("versuche ich nach "+xyz+" zu gehen");
...
System.out.println("Das hat funktioniert") / System.out.println("Das hat NICHT funktioniert");
usw.

Abgesehen von "überlegen" hätte schon ein einfaches
System.out.println("Spielen "+spielfA);
am Anfang der spielen-Methode dich darauf gebracht, dass es bei den rekursiven Aufrufen nicht
spielen(lSpringen(figuren, xKoord, yKoord),spielfA--);
sondern
spielen(lSpringen(figuren, xKoord, yKoord),spielfA-1);
heißen muss.

Dann gibt's immernoch einen Fehler, aber ... (auch beim Programmieren an sich kann man "Meta-Backtracking" anwenden :D )
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Max246Sch 3D Box Filler BAcktracking Java Basics - Anfänger-Themen 1
P Frage zu Rekursion und Backtracking Java Basics - Anfänger-Themen 2
districon Backtracking Java Basics - Anfänger-Themen 2
districon Backtracking Java Basics - Anfänger-Themen 14
districon Dynamisch Programmierung/Backtracking/Memoization Java Basics - Anfänger-Themen 3
districon Backtracking funktioniert nicht ganz Java Basics - Anfänger-Themen 3
V Backtracking und Rekursion Java Basics - Anfänger-Themen 15
G Subset sum problem mit Backtracking Java Basics - Anfänger-Themen 18
O Backtracking Java Basics - Anfänger-Themen 5
C Rekursives Backtracking beim Spiel Peg Java Basics - Anfänger-Themen 22
A Backtracking Java Basics - Anfänger-Themen 56
R Backtracking Java Basics - Anfänger-Themen 1
V Feld sortieren mit Backtracking Java Basics - Anfänger-Themen 1
A Sudoku mit Backtracking lösen Java Basics - Anfänger-Themen 3
L Sudoku Backtracking Pseudocode Java Basics - Anfänger-Themen 3
N Backtracking - Labyrinth/Irrgarten Java Basics - Anfänger-Themen 14
I Backtracking Schach Java Basics - Anfänger-Themen 5
L Magisches Quadrat und Backtracking Java Basics - Anfänger-Themen 19
M Backtracking/Solve Methode Java Basics - Anfänger-Themen 7
P Labyrinth, Backtracking, verzögerte Anzeige Java Basics - Anfänger-Themen 15
D Sudoku lösen mit Backtracking Java Basics - Anfänger-Themen 20
E backtracking und Induktionsprinzip Java Basics - Anfänger-Themen 2
D Backtracking Waage Problem Java Basics - Anfänger-Themen 23
W Backtracking und Frustration Java Basics - Anfänger-Themen 6
X Sudoku Backtracking Java Basics - Anfänger-Themen 6
J Solitaire via Backtracking Java Basics - Anfänger-Themen 7
A Backtracking - kennt Java keine Rücksprungmarken? Java Basics - Anfänger-Themen 15
G Backtracking mit globaler Variable Java Basics - Anfänger-Themen 5
M BackTracking Java Basics - Anfänger-Themen 22
J Backtracking Algorithmus Java Basics - Anfänger-Themen 16

Ähnliche Java Themen

Neue Themen


Oben