Java 4 Gewinnt

eltonn0

Cadet 3rd Year
Registriert
Nov. 2008
Beiträge
32
Moin CB!

Ich bin dabei mir Java beizubringen und stecke nun mitten in dem Kapitel GUI.
Erste Fenster/Buttons/Textfelder/"Bewegende Elemente"/Events/... waren kein Problem.
Ich habe vor einiger zeit ein 4-Gewinnt für die konsole realisiert. Laden/Speichern und Gewinnlogik war kein Problem. Nun würde ich dafür gern eine GUI bauen, komme aber einfach nicht vorran -.-

Vielleicht könnte mir jemand helfen, sodass ich mir einen funktionierenden code mal ansehen kann => verstehe und nochmal selber versuche. Hab bisher nur codes gefunden, ohne laden/speichern oder gewinnüberprüfung und das bringt mir leider nicht viel...da ich genau bei diesen sachen hänge...

Hier zeige ich mal meine klassen die dafür interessant sind:

Code:
/**
 * Diese Klasse bildet das Spiel. Hier ist die main Methode zum Starten.
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import sonderfaelle.MyException;
public class Game {

	/**
	 * @param args
	 * @throws IOException
	 * @throws MyException
	 */

	public static void main(String[] args) throws IOException, MyException {
		
		String s = ""; // String für savegame und loadgame
		boolean spielen;
		Spieler spieler1 = new Spieler('1');
		Spieler spieler2 = new Spieler('2');

		Spielfeld gamefeld = new Spielfeld(); //neues Spielfeld
		System.out.println("Willkommen bei 4 gewinnt!");
		System.out.println("Möchten Sie einen Spielstand laden oder ein neues Spiel beginnen?");
		System.out.println("1 = Laden");
		System.out.println("2 = Neues Spiel");
		String wahl = "";
		spielen = true;

		do {
			if (wahl.equals("1") == false | wahl.equals("2") == false)
				System.out.println("Bitte 1 oder 2 eingeben");
			try {
				BufferedReader in = new BufferedReader(new InputStreamReader(
						System.in));
				wahl = in.readLine(); // String einlesen
			}
			catch (IOException ex) {
				System.out.println("Es ist ein Fehler aufgetreten");
			}
			if (wahl.equals("1")) { // Spiel Laden
				while (s.length() < 7) {

				        System.out.println("Bitte Name des Spielstandes eingebender geladen werden soll:");
					try {
						BufferedReader in = new BufferedReader(
								new InputStreamReader(System.in));
						s = in.readLine() + ".txt"; 
                                                // String einlesen und mit .txt
						// erweitern um eine txt Datei erstellen
						// zu können
					} catch (IOException ex) {
						System.out.println("Es ist ein Fehler aufgetreten");
					}
					if (s.length() < 7) {
						System.out
								.println("Bitte 3 Zeichen für den Spielstand eingeben");
					}

				}
				gamefeld.loadGame(s);

			}
			if (wahl.equals("2")) { // Neues Spiel
				System.out.println("Neues Spiel!");
				gamefeld.setAktuellerSpieler('1');
			} else { //keine gültige eingabe
				wahl = "";
				try {
					throw new sonderfaelle.MyException();
				} catch (MyException ex) {
					System.out.println("Keine Gültige Eingabe!");
				}
			}
		} while (wahl.length() < 1);

		while (spielen) { // spielroutine

			System.out.println("Spieler " + gamefeld.getAktuellerSpieler() + " du bist dran!");
			gamefeld.printtoscreen();
			System.out.println("Bitte die Spalte angeben in die dein Steinchen soll");
			char spalte = 'f';
			String temp = "";
			do {
				try {

					BufferedReader in = new BufferedReader(
							new InputStreamReader(System.in));
					temp = in.readLine();
				}

				catch (IOException ex) {
					System.out.println("Es ist ein Fehler aufgetreten");
				}
				try {
					spalte = temp.charAt(0);
				} catch (StringIndexOutOfBoundsException ex) {
				}
			} while (temp.length() > 1 || temp == "");

			if (spalte == 's') {
				spielen = false;
				try {
					System.out.println("Bitte den Namen für den Spielstand eingeben");
					BufferedReader in = new BufferedReader(
							new InputStreamReader(System.in));

					s = in.readLine() + ".txt"; // String einlesen und mit .txt
					// erweitern um eine txt Datei erstellen
					// zu können
				} catch (IOException ex) {
					System.out.println("Es ist ein Fehler aufgetreten");
				}
				gamefeld.saveGame(s);
			}
			if (spielen) {
				switch (gamefeld.getAktuellerSpieler()) {
				case '1': {
					spieler1.setzeStein((spalte - 48), gamefeld);
					if (gamefeld.hatgewonnen() == '1') {
						System.out.println("Spieler 1 hat gewonnen");
						gamefeld.printtoscreen();
						spielen = false;
					}
					gamefeld.setAktuellerSpieler('2');
					break;
				}
				case '2': {
					spieler2.setzeStein((spalte - 48), gamefeld);
					if (gamefeld.hatgewonnen() == '2') {
						System.out.println("Spieler 2 hat gewonnen");
						gamefeld.printtoscreen();
						spielen = false;
					}
					gamefeld.setAktuellerSpieler('1');
					break;
				}
				}
			}
		}
	}// while spielen
}// class

Code:
public class Spieler implements SpielerZug {
	private char nummer;
	/**
	 * Konstruktor für neuen Spieler
	 * @param nummer Die Spielernummer 
	 */
	public Spieler(char nummer) {
		this.nummer=nummer;
	}

	/**
	 * @param nummer
	 *            the Spielernummer to set
	 */
	public void setNummer(char nummer) {
		this.nummer = nummer;
	}

	/**
	 * @return the Spielernummer
	 */
	public char getNummer() {
		return nummer;
	}

	/**
	 * Ruft mit der Spalte und dem Spielfeld die Methode getfreiezeile() von
	 * Spielfeld auf, um die freie Zeile für den Spielstein zu finden
	 * 
	 * @param spalte
	 *            Spalte in die ein Stein gesetzt werden soll
	 * @param spielfeld
	 *            Spielfeld für das die Spalte überprüft werden soll
	 */
	public void setzeStein(int spalte, Spielfeld spielfeld) {
		int zeile = spielfeld.getfreiezeile(spalte+1);
		
		spielfeld.setFeld(zeile,spalte+1 ,nummer);

	}


}

Code:
/**
 * Diese Klasse stellt ein Spielfeld zur Verfügung. Als Datenstruktur ist ein Zweidimensionales Array gewählt worden.
 * Die Spieler erkennen ihr belegtes Feld durch die Symbole "X" (=Spieler 1) und "O" (=Spieler 2)
 * Die Klasse enthält folgende Methoden:
 * - getter und setter für Feldwerte
 * - eine Speicherfunktion (speichert den momentanen Zustand des Feldes mit Eingabe eines Namen)
 * - eine Ladefunktion (laden eines Feldes)
 * - eine Konsolenausgabe in ASCII Format
 * 
 */
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Spielfeld {

	private char[][] feld; // das Spielfeld
	private char aktuellerSpieler; // der aktuelle spieler
	/**
	 * Der Konstrukter erstellt ein 7x6 Spielfeld mit Unterstrichen als Eintrag
	 * um das Leere Feld darzustellen Das Spielfeld beinhaltet die Buchstaben
	 * und Zahlen am linken und oberen Rand
	 */
	public Spielfeld() {
		this.feld = new char[7][8];
		int i, j = 0;

		for (i = 0; i < 7; i++) { // X-Richtung durchlaufen

			for (j = 0; j < 8; j++) { // Y- Richtung durchlaufen
				if (i == 0 & j > 0) {
					feld[i][j] = (char) (47 + j); // X Richtung mit Zahlen
					// beschriften
				} else if (i < 7 & j == 0) {
					feld[i][j] = (char) (47 + i); // Y Richtung mit Zahlen
				} else {
					if (j > 0) {
						feld[i][j] = '_'; // Einen "_" als Leeres Feld schreiben
					}
				}
			}

		}
		feld[0][0] = '@'; // Schnittfeld kennzeichnen
	}

	/**
	 * @return the aktuellerSpieler
	 */
	public char getAktuellerSpieler() {
		return aktuellerSpieler;
	}

	/**
	 * @param aktuellerSpieler
	 *            the aktuellerSpieler to set
	 */
	public void setAktuellerSpieler(char aktuellerSpieler) {
		this.aktuellerSpieler = aktuellerSpieler;
	}

	/**
	 * @param x
	 *            X- Koordinate des Feldes
	 * @param y
	 *            Y- Koordiante des Feldes
	 * @param Val
	 *            Das Zeichen das geschrieben werden soll
	 */
	public void setFeld(int x, int y, char Val) throws ArrayIndexOutOfBoundsException{
		try{
		this.feld[x][y] = Val;
		}catch(Exception ex){System.out.println("Die Spalte ist voll oder keine Spalte. Als Strafe ist dein Zug verschenkt!");}
	}

	/**
	 * @param x
	 *            X- Koordinate des Feldes
	 * @param y
	 *            Y- Koordiante des Feldes
	 * @return Das Zeichen in dem Feld
	 */
	public char getFeld(int x, int y) throws ArrayIndexOutOfBoundsException{
		try{
			return feld[x][y];
		}catch(Exception ex){System.out.println("...ist wohl keine Spalte!");}
		return 'F';
	}

	/**
	 * Diese Methode gibt das Spielfeld aus
	 */
	public void printtoscreen() {
		for (int i = 0; i < 7; i++) { // X-Richtung durchlaufen

			for (int j = 0; j < 8; j++) { // Y- Richtung durchlaufen
				System.out.print("|" + this.feld[i][j]); // Den Inhalt des
				// Feldes auf
				// der Konsole ausgeben
			}
			System.out.print("|" + "\n"); // Zeilenumbruch nach jeder Zeile

		}
	}

	/**
	 * saveGame Speichert einen Spielstand mit einem Eingegebenen Dateinamen
	 * 
	 * @throws IOException
	 */

	public void saveGame(String filename) throws IOException {

		try {
			FileOutputStream file = new FileOutputStream(filename); // einen
			// Stream
			// erstellen
			for (int i = 1; i < 7; i++) { // y-Richtung durchlaufen

				for (int j = 1; j < 8; j++) { // x- Richtung durchlaufen

					file.write(feld[i][j]); // Den Inhalt des Feldes in die
					// Datei schreiben

				}

			}
			file.write(getAktuellerSpieler());
			file.close(); // Datei zugriff beenden
		} catch (IOException ex) {

		}
	}

	/**
	 * loadGame läd einen Spielstand aus einer Datei die angegeben wird
	 * 
	 * @throws IOException
	 */

	public void loadGame(String filename) throws IOException {

		try {
			FileInputStream file = new FileInputStream(filename); // einen
			// Stream
			// erstellen
			for (int i = 1; i < 7; i++) { // y-Richtung durchlaufen

				for (int j = 1; j < 8; j++) { // x- Richtung durchlaufen

					feld[i][j] = (char) file.read(); // Den Inhalt der Datei in
					// das Feld schreiben
				}
			}
			setAktuellerSpieler((char) file.read());
			file.close(); // Datei zugriff beenden

		} catch (IOException ex) {
			System.out.println("Es ist ein Fehler aufgetreten");
		}

	}

	/**
	 * Methode die die erste freie Zeile zurückgibt oder -1 wenn keine mehr Frei
	 * ist
	 * 
	 * @param spalte
	 *            die Spalte die zu prüfen ist
	 * @return die letzte freie Zeile oder -1 wenn keine vorhanden ist
	 */
	public int getfreiezeile(int spalte){
		
		int zeile = 1;
		if (this.getFeld(zeile,spalte)!='_')return -1;
		if (this.getFeld(6,spalte)=='_')return 6;
		for (int i = 6; i >0; i--) {
			if ((this.getFeld(zeile,spalte) == '_')) {
				zeile+=1;
			}
			
		}
		return zeile-1;
		
	}

	/**
	 * Methode die überprüft ob ein Spieler gewonnen hat
	 * 
	 * @return den Charwert des Spieler der gewonnen hat oder (char)'0' wenn
	 *         keiner gewonnen hat, bzw 'v' wenn das spielfeld voll ist
	 */
	public char hatgewonnen() {

		int s1 = 0, s2 = 0; // zähler für Spieler 1 und 2
		
		// waagerechte prüfen
		for (int i = 1; i < 7; i++) { // y richtung
			for (int j = 1; j < 8; j++) {// x richtung
				if (this.feld[i][j]=='1'){
					s1+=1;
					for (int h = 1; h<4; h++){
						if (i+h<7 && this.feld[i+h][j]=='1')s1+=1;
						else s1=0;
					}
				}
				else s1=0;
				if(s1==4)return '1';
				
				if (this.feld[i][j]=='2'){
					s2+=1;
					for (int h = 1; h<4; h++){
						if (i+h<7 && this.feld[i+h][j]=='2')s2+=1;
						else s2=0;
					}
				}
				else s2=0;
				if(s2==4)return '2';
			}	
		}
		// senkrecht prüfen
		for (int i = 1; i < 7; i++) { // y richtung
			for (int j = 1; j < 8; j++) {// x richtung
				if (this.feld[i][j]=='1'){
					s1+=1;
					for (int h = 1; h<4; h++){
						if (j+h<8 && this.feld[i][j+h]=='1')s1+=1;
						else s1=0;
					}
				}
				else s1=0;
				if(s1==4)return '1';
				
				if (this.feld[i][j]=='2'){
					s2+=1;
					for (int h = 1; h<4; h++){
						if (j+h<8 && this.feld[i][j+h]=='2')s2+=1;
						else s2=0;
					}
				}
				else s2=0;
				if(s2==4)return '2';
			}	
		}
		
		// diagonal prüfen
		for (int i = 1; i < 7; i++) { // y richtung
			for (int j = 1; j < 8; j++) {// x richtung
				if (this.feld[i][j]=='1'){
					s1+=1;
					for (int h = 1; h<4; h++){
						if (j+h<8 && i+h<7 &&this.feld[i+h][j+h]=='1')s1+=1;
						else s1=0;
					}
				}
				else s1=0;
				if(s1==4)return '1';
				
				if (this.feld[i][j]=='2'){
					s2+=1;
					for (int h = 1; h<4; h++){
						if (j+h<8 &&i+h<7&& this.feld[i+h][j+h]=='2')s2+=1;
						else s2=0;
					}
				}
				else s2=0;
				if(s2==4)return '2';
			}	
		}
		
		// diagonal prüfen rechts rum
		for (int i = 1; i < 7; i++) { // y richtung
			for (int j = 1; j < 8; j++) {// x richtung
				if (this.feld[i][j]=='1'){
					s1+=1;
					for (int h = 1; h<4; h++){
						if (j-h>0 && i+h<7 &&this.feld[i+h][j-h]=='1')s1+=1;
						else s1=0;
					}
				}
				else s1=0;
				if(s1==4)return '1';
				
				if (this.feld[i][j]=='2'){
					s2+=1;
					for (int h = 1; h<4; h++){
						if (j-h>0 &&i+h<7&& this.feld[i+h][j-h]=='2')s2+=1;
						else s2=0;
					}
				}
				else s2=0;
				if(s2==4)return '2';
			}	
		}
		
		int tmp=0; //Prüfen ob feld voll
		for (int i = 1; i<7; i++){
			for (int j = 1; j<8; j++){
				if (this.getFeld(i,j)!='_')tmp+=1;
			}
		}
		if (tmp ==42)return 'v';
		return '0';
	}
}

Code:
public interface SpielerZug {
	public void setzeStein(int spalte, Spielfeld spielfeld);

}

Vielen dank schonmal :)

gruß!
 
Laden/Speichern und Gewinnlogik war kein Problem.[...]
Hab bisher nur codes gefunden, ohne laden/speichern oder gewinnüberprüfung und das bringt mir leider nicht viel...da ich genau bei diesen sachen hänge...
Äh irgendwie widersprichst du dir. Wenn du weißt wie die Gewinnlogik aussehen muss und das Laden/Speichern geht wieso brauchst du es dann? Wenn es richtig programmiert ist gibt es wenig Unterschied in der Gewinnlogik. Ob man nun auf der Konsole ausgibt oder per GUI ist ja nur ein Unterschied in der Darstellung.

Naja:
Zum Speichern würde sich als einfachste Möglichkeit die Java Serialization API anbieten (ObjectInputStream und ObjectOutputStream). Schöner aber etwas aufwändiger wäre aber XML.

Von einer GUI sehe ich in deinem Code überhaupt rein gar nichts? "Malen" kann man indem man die paintComponent-Methode einer von JComponent abgeleiteten Klasse überschreibt. Google zeigt dir hierfür genügend Beispiele.
 
Hey, zu der Spielauswertung "hatgewonnen()" habe ich eine frage.
Kann mir jemand erklären, wieso er in z.B. in Zeile 203 diese erste bedingung braucht?
if (i+h<7 && this.feld[i+h][j]=='1')s1+=1;
Ist das zum prüfen, ob das array nicht negativ wird?
Oder hat die bedingung vor dem "&&" eine logischen nutzen was die Spiellogik angeht?

Brauche ich die unbedingt?
 
Zurück
Oben