Variable wird nicht verändert?

Lybrial

Bekanntes Mitglied
Hallo,

hab im nachfolgenden einen Code, für eine variante eines Münzspiels(ja erstmal
alles statisch 😀)
In diesem Code zeichne ich ein Spielfeld auf (Beschreibung steht im Code),
welches dann im Laufe des Spiels verändert werden soll. Leider wird das
nicht getan und ich finde nicht warum. Das Feld wird nach jedem Durchlauf
der Spielschlaife wieder so aufgezeichnet, als wäre noch kein Zug gemacht worden.

Java:
import java.util.Scanner;

public class MuenzSpiel
{
	public static void main(String[] args)
	{
		int anzahlStapel = 12, anzahlStapelWeg = 0;
		int playerWin = 0, cpuWin = 0;
		int spielzugSpieler = 0, spielzugComputer = 0;
		
		spielStarten();
		
		if(spielAuswahl() == 1)
		{
			do
			{
				werBeginnt();
				
				if(werBeginntAuswahl() == 1)
				{
					spielFeld(anzahlStapel, anzahlStapelWeg);
					
					do
					{
						spielzugSpieler(anzahlStapel, anzahlStapelWeg, playerWin, spielzugSpieler);
						spielzugComputer(anzahlStapel, anzahlStapelWeg, cpuWin, spielzugComputer);
						gewonnenSpieler(anzahlStapel, playerWin);
					}while(anzahlStapel != 0);
				}
				else
				{
					spielFeld(anzahlStapel, anzahlStapelWeg);
					
					do
					{
						spielzugComputer(anzahlStapel, anzahlStapelWeg, cpuWin, spielzugComputer);
						spielzugSpieler(anzahlStapel, anzahlStapelWeg, playerWin, spielzugSpieler);
						gewonnenComputer(anzahlStapel, cpuWin);
					}while(anzahlStapel != 0);
				}
				nochmal(playerWin, cpuWin);
			}while(nochmalAuswahl() == 1);
		}
		else
		{
			System.out.println("Auf wiedersehen! Bis zum naechsten mal!");
			System.exit(0);
		}
	}
	//*****************************************************************************************************************************************
	static void spielStarten()
	{
		System.out.println("*******************************************************************************");
		System.out.println("* Das Spiel wird mit zwei Spielern gespielt. Jeder der beiden Spieler setzt   *");
		System.out.println("* 1 Euro zu 10 mal 10 Cent. Diese werden in eine Reihe gelegt, wobei 11 mal   *");
		System.out.println("* 10 Cent einzeln und am Ende 1 mal 90 Cent (gestapelt) gelegt werden. Nun    *");
		System.out.println("* darf jeder abwechselnd 1, 2 oder 3 Positionen der Reihe vom Anfang          *");
		System.out.println("* beginnend entfernen. Dieses Geld gehoert ihm. Es besteht Zugzwang. Wenn     *");
		System.out.println("* alle Positionen entfernt wurden, ist das Spiel zu Ende. Natuerlich hat      *");
		System.out.println("* derjenige, der Position 12 erreicht, Gewinn gemacht, der andere den         *");
		System.out.println("* entsprechenden Verlust.                                                     *");
		System.out.println("*******************************************************************************");
		System.out.println("*                  1: Ich will spielen!!!                                     *");
		System.out.println("*                  0: Lieber nicht, ist mir zu kompliziert!!!                 *");
		System.out.println("*******************************************************************************");
	}
	//*****************************************************************************************************************************************
	static int spielAuswahl()
	{
		int auswahl = 0;
		
		do
		{
			Scanner sc = new Scanner(System.in);
			auswahl = sc.nextInt();
		}while(auswahl != 1 && auswahl != 0);
		return auswahl;
	}
	//*****************************************************************************************************************************************
	static void werBeginnt()
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                  Wer soll beginnen?                                         *");
		System.out.println("*******************************************************************************");
		System.out.println("*                  1: Ich will anfangen!!!                                    *");
		System.out.println("*                  0: Lass mal lieber den Computer, der kann das besser.      *");
		System.out.println("*******************************************************************************");
	}
	//*****************************************************************************************************************************************
	static int werBeginntAuswahl()
	{
		int auswahl = 0;
		
		do
		{
			Scanner sc = new Scanner(System.in);
			auswahl = sc.nextInt();
		}while(auswahl != 1 && auswahl != 0);
		return auswahl;
	}
	//*****************************************************************************************************************************************
	static void spielFeld(int anzahlStapel, int anzahlStapelWeg)
	{
		String letztesO = "O";
		for(int i = 0; i < anzahlStapelWeg; i++)
		{
			System.out.print("x ");
		}
		for(int i = 1; i < anzahlStapel; i++)
		{
			System.out.print("o ");
		}
		
		if(anzahlStapelWeg == 12)
		{
			letztesO = "\n";
		}
		System.out.println(letztesO);
	}
	//*****************************************************************************************************************************************
	static void spielzugSpieler(int anzahlStapel, int anzahlStapelWeg, int playerWin, int spielzugSpieler)
	{
		Scanner sc = new Scanner(System.in);
		
		do
		{	
			System.out.print("Wie viele Stapel moechtest du nehmen? ");
			spielzugSpieler = sc.nextInt();
						
			if(spielzugSpieler > anzahlStapel)
			{
				System.out.println("Nicht so gierig! Nimm weniger! ");
			}
		}while((spielzugSpieler != 1 && spielzugSpieler != 2 && spielzugSpieler != 3) || (spielzugSpieler > anzahlStapel));
			
		anzahlStapel = anzahlStapel - spielzugSpieler;
		anzahlStapelWeg = anzahlStapelWeg + spielzugSpieler;
		spielFeld(anzahlStapel, anzahlStapelWeg);
				
		gewonnenSpieler(anzahlStapel, playerWin);
	}
	//*****************************************************************************************************************************************
	static void spielzugComputer(int anzahlStapel, int anzahlStapelWeg, int cpuWin, int spielzugComputer)
	{
		do
		{
			spielzugComputer = (int)(Math.random()*3+1);
		}while(spielzugComputer > anzahlStapel);
		
		System.out.println("Der Computer zieht: " +spielzugComputer);
		anzahlStapel = anzahlStapel - spielzugComputer;
		anzahlStapelWeg = anzahlStapelWeg + spielzugComputer;
		spielFeld(anzahlStapel, anzahlStapelWeg);
		
		gewonnenComputer(anzahlStapel, cpuWin);
	}
	//*****************************************************************************************************************************************
	static int gewonnenSpieler(int anzahlStapel, int playerWin)
	{
		int gewonnen = 0;
		
		if(anzahlStapel == 0)
		{
			gewonnen = 1;
			playerWin = playerWin + 1;
			playerWin();
		}
		return gewonnen;
	}
	//*****************************************************************************************************************************************
	static int gewonnenComputer(int anzahlStapel, int cpuWin)
	{
		int gewonnen = 0;
		
		if(anzahlStapel == 0)
		{
			gewonnen = 1;
			cpuWin = cpuWin + 1;
			cpuWin();
		}
		return gewonnen;
	}
	//*****************************************************************************************************************************************
	static void playerWin()
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                                                                             *");
		System.out.println("*                  Gewonnen!!!                                                *");
		System.out.println("*                                                                             *");
		System.out.println("*                                                                             *");
		System.out.println("*                  x x x x x x x x x x x X                                    *");
	}
	//*****************************************************************************************************************************************
	static void cpuWin()
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                  Leider verloren!!!!                                        *");
	}
	//*****************************************************************************************************************************************
	static void nochmal(int playerWin, int cpuWin)
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                  Score:                                                      ");
		System.out.println("*                  Spieler    " +playerWin+ ":" +cpuWin+ "    Computer         ");
		System.out.println("*******************************************************************************");
		System.out.println("*                  1: Nochmal!!!                                              *");
		System.out.println("*                  0: Mir reichts!!!                                          *");
		System.out.println("*******************************************************************************");
	}
	//*****************************************************************************************************************************************
	static int nochmalAuswahl()
	{
		int auswahl = 0;
		
		do
		{
			Scanner sc = new Scanner(System.in);
			auswahl = sc.nextInt();
		}while(auswahl != 1 && auswahl != 0);
		return auswahl;
	}
	//*****************************************************************************************************************************************
}
 
Variablen wie anzahlStapel legtst du lokal in main an. Rufst du eine Methode wie spielzugComputer auf, bekommen diese den Wert geliefert. Dass du diesen Wert auch "anzahlStapel" genannt hast, ist irrelevant, es ist trotzdem eine andere Variable. Wenn du diese in spielzugComputer änderst, bekommt das "Original" in main nichts davon mit. Das Problem hast du mit mehreren deiner Variablen.

Dein Code scheint ja bewußt auf jede Objektorientierung zu verzichten, ansonsten hätte ich vorgeschlagen, ein "Spielzustands-Objekt" oder so zu verwenden. Du kannst anzahlStapel u.s.w. aber zu Klassenvariablen machen (static int anzahlStapel = 12; außerhalb von main), die dann überall in der Klasse sichtbar und manipulierbar wären. Das ist dann das Äquivalent einer globalen Variable in Basic oder so - funktioniert, ist aber keine wirklich schöne Lösung.
 
Jo, korrekt, der Code ist bewusst nicht Objekt-orientiert.
Ich hatte eigentlich angenommen, das jede variable die Veränderungen in der
Spieleschleife mitbekommt aber das war dann wohl ein Irrtum 😀

Globale Variable bin ich jetzt auch nicht so der Fan von aber irgendwie
muss ich ja die Veränderungen immer in der selben Variable abspeichern.

Irgendwie schein ich das mit dem Parameter übergeben noch nicht ganz verstanden
zu haben. Was ist denn wenn ich folgendes machen würde:

Wenn ich die beiden Variablen int anzahlStapel und int anzahlStapelWeg, statt sie
der Funktion spielzugSpieler() zu übergeben, direkt in dieser Funktion deklariere und
initialisiere. Dann könnte ich sie ja mit Return zurückgeben.
Wie kann ich allerdings die veränderte Variable dann an andere Methoden, die diese
Variable ebenfalls benötigen weitergeben, ohne die komplette Funktion aufrufen zu müssen?

Java:
static void spielzugSpieler(int anzahlStapel, int anzahlStapelWeg, int playerWin, int spielzugSpieler)
	{
		Scanner sc = new Scanner(System.in);
		
		do
		{	
			System.out.print("Wie viele Stapel moechtest du nehmen? ");
			spielzugSpieler = sc.nextInt();
						
			if(spielzugSpieler > anzahlStapel)
			{
				System.out.println("Nicht so gierig! Nimm weniger! ");
			}
		}while((spielzugSpieler != 1 && spielzugSpieler != 2 && spielzugSpieler != 3) || (spielzugSpieler > anzahlStapel));
			
		anzahlStapel = anzahlStapel - spielzugSpieler;
		anzahlStapelWeg = anzahlStapelWeg + spielzugSpieler;
		spielFeld(anzahlStapel, anzahlStapelWeg);
				
		gewonnenSpieler(anzahlStapel, playerWin);
 
Zuletzt bearbeitet:
Da das Programm ja nicht objektorientiert ist, brauch man auch nichts zurückgeben. Global benötigte Werte verwaltet man dann in globalen Variablen.

Dass sich die Variablen nicht ändern, liegt daran, dass es in Java keine Call by Reference gibt und es sich somit um unterschiedliche Variablen handelt.
 
Zuletzt bearbeitet:
Also gibt es außer variable global deklarieren keine
andere Möglichkeit?

---gut natürlich könnte ich alle abläufe in der Main-Funktion
schreiben aber das ist auch net so schön^^

Habs jetzt so gelöst:

Java:
import java.util.Scanner;

public class MuenzSpiel
{
	public static void main(String[] args)
	{
		spielStarten();
		
		if(spielAuswahl() == 1)
		{
			spielen();
		}
		else
		{
			System.out.println("Auf wiedersehen! Bis zum naechsten mal!");
			System.exit(0);
		}
	}
	//*****************************************************************************************************************************************
	static void spielStarten()
	{
		System.out.println("*******************************************************************************");
		System.out.println("* Das Spiel wird mit zwei Spielern gespielt. Jeder der beiden Spieler setzt   *");
		System.out.println("* 1 Euro zu 10 mal 10 Cent. Diese werden in eine Reihe gelegt, wobei 11 mal   *");
		System.out.println("* 10 Cent einzeln und am Ende 1 mal 90 Cent (gestapelt) gelegt werden. Nun    *");
		System.out.println("* darf jeder abwechselnd 1, 2 oder 3 Positionen der Reihe vom Anfang          *");
		System.out.println("* beginnend entfernen. Dieses Geld gehoert ihm. Es besteht Zugzwang. Wenn     *");
		System.out.println("* alle Positionen entfernt wurden, ist das Spiel zu Ende. Natuerlich hat      *");
		System.out.println("* derjenige, der Position 12 erreicht, Gewinn gemacht, der andere den         *");
		System.out.println("* entsprechenden Verlust.                                                     *");
		System.out.println("*******************************************************************************");
		System.out.println("*                  1: Ich will spielen!!!                                     *");
		System.out.println("*                  0: Lieber nicht, ist mir zu kompliziert!!!                 *");
		System.out.println("*******************************************************************************");
	}
	//*****************************************************************************************************************************************
	static int spielAuswahl()
	{
		int auswahl = 0;
		
		do
		{
			Scanner sc = new Scanner(System.in);
			auswahl = sc.nextInt();
		}while(auswahl != 1 && auswahl != 0);
		return auswahl;
	}
	//*****************************************************************************************************************************************
	static void spielen()
	{
		int anzahlStapel = 12, anzahlStapelWeg = 0;
		int playerWin = 0, cpuWin = 0;
		int spielzugSpieler = 0, spielzugComputer = 0;
		
		do
		{
			werBeginnt();
			
			if(werBeginntAuswahl() == 1)
			{
				spielFeld(anzahlStapel, anzahlStapelWeg);
				
				do
				{
					spielzugSpieler = spielzugSpieler(anzahlStapel, anzahlStapelWeg, spielzugSpieler);
					anzahlStapel = anzahlStapel - spielzugSpieler;
					anzahlStapelWeg = anzahlStapelWeg + spielzugSpieler;
					spielFeld(anzahlStapel, anzahlStapelWeg);	
					playerWin = gewonnenSpieler(anzahlStapel, playerWin);
					
					spielzugComputer = spielzugComputer(anzahlStapel, anzahlStapelWeg, spielzugComputer);
					anzahlStapel = anzahlStapel - spielzugComputer;
					anzahlStapelWeg = anzahlStapelWeg + spielzugComputer;
					spielFeld(anzahlStapel, anzahlStapelWeg);
					cpuWin = gewonnenComputer(anzahlStapel, cpuWin);
				}while(anzahlStapel != 0);
				anzahlStapel = 12; anzahlStapelWeg = 0;
			}
			else
			{
				spielFeld(anzahlStapel, anzahlStapelWeg);
				
				do
				{
					spielzugComputer(anzahlStapel, anzahlStapelWeg, spielzugComputer);
					anzahlStapel = anzahlStapel - spielzugComputer;
					anzahlStapelWeg = anzahlStapelWeg + spielzugComputer;
					spielFeld(anzahlStapel, anzahlStapelWeg);
					cpuWin = gewonnenComputer(anzahlStapel, cpuWin);
		
					spielzugSpieler(anzahlStapel, anzahlStapelWeg, spielzugSpieler);
					anzahlStapel = anzahlStapel - spielzugSpieler;
					anzahlStapelWeg = anzahlStapelWeg + spielzugSpieler;
					spielFeld(anzahlStapel, anzahlStapelWeg);	
					playerWin = gewonnenSpieler(anzahlStapel, playerWin);
				}while(anzahlStapel != 0);
				anzahlStapel = 12; anzahlStapelWeg = 0;
			}
			nochmal(playerWin, cpuWin);
		}while(nochmalAuswahl() == 1);
	}
	//*****************************************************************************************************************************************
	static void werBeginnt()
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                  Wer soll beginnen?                                         *");
		System.out.println("*******************************************************************************");
		System.out.println("*                  1: Ich will anfangen!!!                                    *");
		System.out.println("*                  0: Lass mal lieber den Computer, der kann das besser.      *");
		System.out.println("*******************************************************************************");
	}
	//*****************************************************************************************************************************************
	static int werBeginntAuswahl()
	{
		int auswahl = 0;
		
		do
		{
			Scanner sc = new Scanner(System.in);
			auswahl = sc.nextInt();
		}while(auswahl != 1 && auswahl != 0);
		return auswahl;
	}
	//*****************************************************************************************************************************************
	static void spielFeld(int anzahlStapel, int anzahlStapelWeg)
	{
		String letztesO = "O";
		for(int i = 0; i < anzahlStapelWeg; i++)
		{
			System.out.print("x ");
		}
		for(int i = 1; i < anzahlStapel; i++)
		{
			System.out.print("o ");
		}
		
		if(anzahlStapelWeg == 12)
		{
			letztesO = "\n";
		}
		System.out.println(letztesO);
	}
	//*****************************************************************************************************************************************
	static int spielzugSpieler(int anzahlStapel, int anzahlStapelWeg, int spielzugSpieler)
	{
		Scanner sc = new Scanner(System.in);
		
		do
		{	
			System.out.print("Wie viele Stapel moechtest du nehmen? ");
			spielzugSpieler = sc.nextInt();
						
			if((spielzugSpieler > anzahlStapel) || (spielzugSpieler > 3))
			{
				System.out.println("Nicht so gierig! Nimm weniger! ");
			}
		}while((spielzugSpieler != 1 && spielzugSpieler != 2 && spielzugSpieler != 3) || (spielzugSpieler > anzahlStapel));
		return spielzugSpieler;
	}
	//*****************************************************************************************************************************************
	static int spielzugComputer(int anzahlStapel, int anzahlStapelWeg, int spielzugComputer)
	{
		int rest = 0;
		rest = anzahlStapel%4;
		
		switch(rest)
		{
			case 0: spielzugComputer = 3; break;
			case 1: spielzugComputer = 1; break;
			case 2: spielzugComputer = 2; break;
			case 3: spielzugComputer = 3; break;
		}
		
		System.out.println("Der Computer zieht: " +spielzugComputer);
		return spielzugComputer;
	}
	//*****************************************************************************************************************************************
	static int gewonnenSpieler(int anzahlStapel, int playerWin)
	{
		if(anzahlStapel == 0)
		{
			playerWin = playerWin + 1;
			playerWin();
		}
		return playerWin;
	}
	//*****************************************************************************************************************************************
	static int gewonnenComputer(int anzahlStapel, int cpuWin)
	{
		if(anzahlStapel == 0)
		{
			cpuWin = cpuWin + 1;
			cpuWin();
		}
		return cpuWin;
	}
	//*****************************************************************************************************************************************
	static void playerWin()
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                                                                             *");
		System.out.println("*                  Gewonnen!!!                                                *");
		System.out.println("*                                                                             *");
		System.out.println("*                                                                             *");
		System.out.println("*                  x x x x x x x x x x x X                                    *");
	}
	//*****************************************************************************************************************************************
	static void cpuWin()
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                  Leider verloren!!!!                                        *");
	}
	//*****************************************************************************************************************************************
	static void nochmal(int playerWin, int cpuWin)
	{
		System.out.println("*******************************************************************************");
		System.out.println("*                  Score:                                                      ");
		System.out.println("*                  Spieler    " +playerWin+ ":" +cpuWin+ "    Computer         ");
		System.out.println("*******************************************************************************");
		System.out.println("*                  1: Nochmal!!!                                              *");
		System.out.println("*                  0: Mir reichts!!!                                          *");
		System.out.println("*******************************************************************************");
	}
	//*****************************************************************************************************************************************
	static int nochmalAuswahl()
	{
		int auswahl = 0;
		
		do
		{
			Scanner sc = new Scanner(System.in);
			auswahl = sc.nextInt();
		}while(auswahl != 1 && auswahl != 0);
		return auswahl;
	}
	//*****************************************************************************************************************************************
}
 
Zuletzt bearbeitet:
Ja natürlich, das weiß ich, ist mir völlig klar, habe bisher alles
was ich gecoded habe in Klassen geschrieben und in meiner main
dann nur mit Instanzen gearbeitet.....

Das Problem war nur das ich genau diesen Code nicht Objekt-orientiert
Coden "durfte".

Hab das Ding für nen Kumpel geschrieben, der ist in einem Studiengang der
sich Medien-Informatik nennt und die sind noch nicht so weit das sie
wissen was Klassen sind^^ deswegen musste alles statisch passieren
und die Vorgabe war möglichst wenig in der Main-Funktion, naja
das Ding ist jetzt fertig und hab mich mal wieder nen Sonntag lang mit
nem Problem beschäftigt, das eigentlich soooooowas von einfach ist,
das ich mich manchmal Frage warum ich mir das antuh^^
 
Also gibt es außer variable global deklarieren keine
andere Möglichkeit?

Doch, gibt es: Ein veränderliches Objekt, das deinen Wert beinhaltet. Objekte werden nicht direkt übergeben, sondern nur Referenzen darauf. Die übergebene Referenz zeigt dann in main und in der Untermethode auf dasselbe Objekt, und main sieht alle Änderungen. Mit einem Array kannst du einen ähnlichen Effekt erzielen:

Java:
...

public static void main(String... args) {
   int[] anzahlStapel = new int[1]; //Array der Länge 1
   anzahlStapel[0] = 12;
   methode(anzahlStapel);
   System.out.println(anzahlStapel[0]); //13 
}

private static void methode(int[] anz) {
   anz[0] = anz[0] + 1;
}

...

Aaaaber: Das ist ein nützlicher Trick für den absoluten Notfall (ist z.B. manchmal für Threads ganz nützlich), aber keine Programmiertechnik, auf die man ein ganzes Programm aufbauen sollte. Der "saubere" Anzatz wäre irgendeine Form der Objektorientierung: Entweder das ganze Programm in eine Instanz verlegen (main ruft dann nur noch den Konstruktor auf) und alle "gemeinsamen" Daten als Instanzvariablen, oder ein Spielstand-Objekt, das jeder Methode übergeben wird (dieses kann wiederum veränderlich oder unveränderlich sein, wobei die Methoden es im letzteren Fall auch zurückgeben müssen).
 

Zurück
Oben