Spieleprogrammierung: Satzraten für Java-Einsteiger 2. Teil

Hier können Artikel, Tutorials, Bücherrezensionen, Dokumente aller Art, Texturen, Sprites, Sounds, Musik und Modelle zur Verfügung gestellt bzw. verlinkt werden.
Forumsregeln
Möglichst sinnvolle Präfixe oder die Themensymbole nutzen.
Antworten
Benutzeravatar
Terep
Beiträge: 53
Registriert: 17.01.2008, 21:20
Wohnort: Hannover Region

Spieleprogrammierung: Satzraten für Java-Einsteiger 2. Teil

Beitrag von Terep »

In der Überschrift steht Spieleprogrammierung.

Im ersten Teil haben wir uns mit der Java-Syntax beschäftigt.
Das Ergebnis war lauffähig, mehr nicht.

Jetzt geht es darum, herauszufinden, wie man Spielspaß generiert.
Der ist in unserem Programm noch nicht wirklich da. Wie geht man da ran?

Zauberwort Brainstorming Titel „Merkmale zum Spielspaß“ Das Ergebnis:
Bessere Steuerung, Pull-down-Menue, Tastatur nachbilden und einbinden, Satzarchiv, größere Schrift, fliegende Elfen, Story, Vorspiel, Optik verbessern, Bebildern, Sound, Animation, Wertungen einführen, Zeitbeschränkungen einführen, 2 Spieler-Modus einrichten,

Nun ja, auflisten kann man viel. Wie soll man sich entscheiden? Am besten strukturiert.
Da gibt es viele Möglichkeiten. Ich nehme die SWOT-Analyse.
Damit checken wir die eigene konkrete Situation:

W Weakness = Schwäche
Übermäßig Zeit steht nicht zur Verfügung. Nach 10 Stunden will ich mit Teil 2 fertig sein.
Programmiermäßig bin ich kein Guru.

T Threats = Risiken
Die falschen Spielerweiterungen entwickeln.
Keinen interessiert es.

O Opportunities Chancen
Macht ein Tabellenprogramm Spielspass wo doch ein Menü, Tastatureinbindung und eine gute Steuerung vorhanden ist? Nicht wirklich.
Mit Grundlagen ist schon viel möglich. Wir müssen halt die richtigen Erweiterungen auswählen.

S Strengths = Stärken
Wir denken einfach und setzen es so um.
Wir programmieren mit System. Wir setzen uns Zeitrahmen und portionieren entsprechend.
Nach jedem kleinen Teilschritt kompilieren wir und prüfen die Lauffähigkeit des Programms.

Die Ausgangssituation:
Wir wissen, wann ein Spiel gut ist. Aber im Brainstorming steht so viel.
Wie definieren wir Spielspass.
Also das Wesentliche muss am Anfang im Hintergrund stehen. Gut verpackt kann es zum Spielen und Wiederspielen reizen.
Und es muss was da sein, was wie eine Herausforderung wirkt. Man muss gewinnen und verlieren können. Es sollten Zufallselemente als auch das persönliche Wissen bzw. Können entscheidend sein.

OK jetzt wissen wir Bescheid und werden folgendes umsetzen:

- Die Anregung von Niki englische Bezeichner zu verwenden, setzen wir um.
- Wir brauchen ein Satzarchiv (einfach gestrickt reicht erst mal).
- Wir werden die Währung „Tacken“ einführen und den Spielverlauf damit bewerten.
- Eine kurze Story soll den Grund zum Spiel mit einem konkreten Ziel geben.
- Ein Joker wird das Spiel erleichtern, aber umsonst wird er nicht sein.
- Nach jeder Runde die Entscheidung ermöglichen, Weiter oder Ende.

Den Quellcode werde ich nur einmal am Ende listen. Wenn ich pro Entwicklungsstufe den Quellcode liste, blähe ich es zu sehr auf.
Wichtig ist im Vorfeld, zu wissen, was man konkret umsetzen will.
Wir haben mit Teil 1 eine Machbarkeitsstudie durchgeführt und kommen so gut rein.

Wir werden als erstes das Layout entwickeln.
Als Hauptpanel nehmen wir ein Borderlayout. Dies stellt uns 5 Bereiche zur Verfügung.
In diesen 5 Bereichen kommen unsere Grafikkomponenten. Der Quellcode und das Spielbild werden als Beschreibung reichen.

Danach haben wir den Nachrichtentransfer neu eingerichtet.
Wir gehen Button für Button durch und checken in kurzen Intervallen durch das Kompilieren.
Teil 1 zeigt sich hier als sehr hilfreich.

Jetzt erstellen wir mit einer neuen Klasse das Satzarchiv.
Das Satzarchiv erstellen wir ohne großen Programmieraufwand in einer separaten Datei.
Wichtig ist hier, dass wir mit einer Zufallszahl den nächsten Satz finden. Je mehr Sätze hinterlegt sind, umso besser. Auch müssen wir uns merken, welcher Satz schon gezogen wurde. Der evt. Fall, dass alle Sätze einmal dran waren, soll auch berücksichtigt werden.
Das schöne am Satzarchiv ist die Separierung. Die wenigen Methoden lassen sich leicht rekonstruieren.

Weiter geht es mit der Einführung der Währung „Tacken“.
Damit schaffen wir ein Instrument, bei dem der gute Spieler gewinnt, derjenige der einfach draufklickt ohne zu denken, soll verlieren. In einer späteren Stufe kann man hier verschiedene Abstufungen vom Anfänger bis Profi spreizen. Anfangs reicht es völlig aus, das Geplante umzusetzen.

Als erste Variante habe ich hier die Markierfunktion geschaltet. Weitere könn in späteren Versionen folgen.

Für die Währung ist es wichtig, zu analysieren, welche von den 26 Buchstaben im Satz sind,
wann alle gezogen wurden.
Dies hat sich als aufwendig gestaltet. Es läuft jetzt solide, aber ich denke, dass es hier Optimierungsbedarf gibt.

Nach Ablauf einer Spielrunde steht die Entscheidung an, Weiter oder Ende.
Dies einzustellen ist nicht schwer, aber man übersieht leicht etwas.

Das wars an Erläuterungen. Interessanter ist da wohl der Quellcode.
Für Querleser. Es ist Java 7.0 und nach Kompilierung sofort spielfertig.
Die Spielanreize wie die Story sind in Teil 2 zwar vorhanden, können aber noch gut verbessert werden.
Fragen und Kommentare werden gerne gesehen.
Es folgt der Code. Zuerst die StartMain

Code: Alles auswählen


public class StartMain {
	public static void main(String[] args) {
		// Kontrollmeldung auf der Konsole
		System.out.println("Sätze raten; Start");
		
		// mit new wird immer ein Objekt erzeugt.
		// Eine Referenzvariable brauchen wir nicht
		// Kommen wir nach main zurück, ist das Spiel zu Ende
		new Satzraten();
		
		// Kontrollmeldung auf der Konsole
		System.out.println ("Sätze raten; Ende");
	}
}
Die Datei Satzraten

Code: Alles auswählen

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class Satzraten extends JFrame{


	// Ein Objekt der inneren Klasse erzeugen
	Schalterhearer hearer = new Schalterhearer();
	// Zugriff auf das Satzarchiv schaffen
	Spielsaetze sentenceArchiv = new Spielsaetze();

	
	// Instanzvariable
	int tacken = 50;				// die Währung
	int numberLetter;				// Anzahl der Buchstaben im Ratesatz	
	int showInfoFound;				// Die gefundenen Buchstaben	
	int [] sentContent;				// Auswertungsarray
		
	String sentenceClear;		 	// für den Ratesatz in Klartext
	String sentenceMask = " ";		// Der Satz mit Sternchen getarnt.

	char [] arrKodiert;				// der Tarnsatz als char-Array
	char [] arrClear;				// der Klarsatz als char-Array

	JButton [] azButton;
	JButton [] orderButton;
	
	JLabel  [] titelLabel;			// Überschriften
	JLabel  [] infoLabel;			// linker Bildschirm
	JLabel  [] resultLabel;			// rechter Bildschirm

	boolean markiert = false;		// wenn der Schalter marken gewählt wird, dann true
	
	
	// Konstruktor
	public Satzraten ()  {		
		super("Teil zwei, Spielanreize werden geschaffen");
		setSize(1400, 800);
		setLocation(100, 1);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
		JPanel hauptPanel = new JPanel ();		// Das hauptpanel trägt alles
		BorderLayout borderLayout = new BorderLayout(20, 20);  // mit Rand
		hauptPanel.setLayout(borderLayout);
		this.add(hauptPanel);
		
		JPanel northPanel = initNorthPanel();
		hauptPanel.add(northPanel, BorderLayout.NORTH);
		
		JPanel centerPanel = initCenterPanel();
		hauptPanel.add(centerPanel, BorderLayout.CENTER);
		
		JPanel southPanel = initSouthPanel();
		hauptPanel.add(southPanel, BorderLayout.SOUTH);
		
		JPanel westPanel = initWestPanel();
		hauptPanel.add(westPanel, BorderLayout.WEST);
		
		JPanel eastPanel = initEastPanel();
		hauptPanel.add(eastPanel, BorderLayout.EAST);

		gameLoop();
	}
	
	private void gameLoop() {
		System.out.println("Start der gameLoop");
		
		sentenceClear = sentenceArchiv.getSentence();	// ein Zufallssatz wird geholt
		System.out.println( "SatzRaten.gameLoop Fragesatz als Kartext String: " + sentenceClear);
		titelLabel[1].setText("   " + maskSentence() );									// Aufruf zum Satz tarnen
		initContentArray(sentenceClear);
		printContentArray();
		tacken += 200;
		resultLabel[4].setText(" Tacken: " + tacken );  

	}
	
	
	
	private JPanel initNorthPanel () {
		JPanel panel = new JPanel ();
		GridLayout gridLayout = new GridLayout(3, 1, 10, 10);
		panel.setLayout(gridLayout);
		titelLabel = new JLabel [3];  // Titelleisten
		for (int i = 0; i < 3; i++) {
			titelLabel[i] = new JLabel(	"                                                                                                             ");  // wegen der Formatierung
			titelLabel[i].setFont(new Font ("Serif", Font.ITALIC, 30 ) );
			panel.add(titelLabel[i]);		
		}
		return panel;	
	}


	private JPanel initCenterPanel () {
		JPanel panel = new JPanel ();
		GridLayout gridLayout = new GridLayout(4, 10, 10, 10);
		panel.setLayout(gridLayout);
		
		azButton = new JButton [26];  // für 26 Buchstaben
		char ch;
		for (int i = 0; i < 26; i++) {
			ch = (char) (i+65);				// Wandeln von int in ASCII-Char-Zeichen
			azButton[i] = new JButton(String.valueOf (ch) );  // Buttons A-Z werden geschaffen
			azButton[i].addActionListener(hearer);			// jeder erhält seinen eigenen hearer
			azButton[i].setFont(new Font ("Serif", Font.ITALIC, 30 ) );
			
			panel.add(azButton[i]);		
		}
		return panel;
	}

	
	private JPanel initSouthPanel () {
		JPanel panel = new JPanel ();
		GridLayout gridLayout = new GridLayout(1, 5, 10, 10);
		panel.setLayout(gridLayout);
		
		orderButton = new JButton [5];  // für die Steuerung
		for (int i = 0; i < 5; i++) {
			orderButton[i] = new JButton("No Name" );  
			orderButton[i].addActionListener(hearer);			
			orderButton[i].setFont(new Font ("Serif", Font.ITALIC, 30 ) );
			panel.add(orderButton[i]);		
		}
		orderButton[0].setText("markieren");	
		orderButton[1].setText("Die Story");	
		orderButton[2].setText("Die Regeln");	
		orderButton[3].setText("neue Runde");	
		orderButton[3].setEnabled(false);  // wird erst nach Ende der Spielrunde aktiviert
		
		orderButton[4].setText("Ende");	
				
		return panel;
	}
	
	private JPanel initWestPanel () {
		JPanel panel = new JPanel ();
		GridLayout gridLayout = new GridLayout(5, 1, 10, 10);
		panel.setLayout(gridLayout);
		
		infoLabel = new JLabel [5];  
		for (int i = 0; i < 5; i++) {
			infoLabel[i] = new JLabel("                         " );   // Leerstring als Platzhalter
			infoLabel[i].setFont(new Font ("Serif", Font.ITALIC, 30 ) );
				
			panel.add(infoLabel[i]);		
		}
		infoLabel[0].setText("   Hier werden Infos gezeigt" );  
		return panel;
	}


	private JPanel initEastPanel () {
		JPanel panel = new JPanel ();
		GridLayout gridLayout = new GridLayout(5, 1, 10, 10);
		panel.setLayout(gridLayout);
		
		resultLabel = new JLabel [5];  
	for (int i = 0; i < 5; i++) {
			resultLabel[i] = new JLabel("                   " );  // Leerstring als Platzhalter
						resultLabel[i].setFont(new Font ("Serif", Font.ITALIC, 30 ) );
				
			panel.add(resultLabel[i]);		
		}
	resultLabel[0].setText(" Die Ergebnisse:   " );  
	resultLabel[4].setText(" Tacken: " + tacken );  

		return panel;
	}

	private String maskSentence() {
		arrClear    = new char[sentenceClear.length()];		// zwecks Auswertungsroutinen der KLarsatz in den char-Array 
		arrKodiert = new char[sentenceClear.length()];		// dto der Tarnsatz in  ein char-Array
		//aus String den Array erzeugen
		for ( int i = 0; i < sentenceClear.length(); i++) {
			arrClear[i] = sentenceClear.charAt(i);
		}
	
		// Die Kodierung durchführen
		for ( int i = 0; i < sentenceClear.length(); i++) {
			if ( ( (arrClear[i] < 91 ) && (arrClear[i] > 64) ) ||
				 ( (arrClear[i] < 123) && (arrClear[i] > 96) )  )   {
				arrKodiert[i] = '*';
				}
			else {
				arrKodiert[i] = arrClear[i];
			}
		
		}
	
		// kodierten String erzeugen
		sentenceMask = "";
		for ( int i = 0; i < arrKodiert.length; i++) {
			sentenceMask = sentenceMask + arrKodiert [i];
		}
			
		System.out.println("SatzRaten.maskSentence Fragesatz als Kartext String:: " + sentenceMask);
		return sentenceMask;
	}  // Ende maskSentence
	
	private void initContentArray (String sent) {
		sentContent = new int[26];
		int letter = 0;		// für die Buchstaben
		System.out.println("SatzRaten.initContentArray Satzlänge: " + sent.length() + " Zeichen.");
		for (int i = 0; i < sent.length(); i++) {
			letter = (int) sent.charAt(i);
			if ( ( (letter < 91 ) && (letter > 64) ) ||	 ( (letter < 123) && (letter > 96) ) )   {  // Buchstabe liegt vor
				if (letter > 96) {
					letter = letter - 32;		// nur noch Großbuchstaben
				}
				letter = letter - 65;    // die Null ist A -... 26 ist Z
				System.out.print(" " + letter);
				
				sentContent[letter]++;				// der Array wird gefüllt mit x Zeichen pro Index
			}
		}
		
		for (int i = 0; i < 26; i++) {
			if ( sentContent[i] > 0) {
				numberLetter++;						// die Anzahl der Buchstaben wird ermittelt.
			}
		}
		System.out.print("Anzahl der Buchstaben  " + numberLetter);
	}

	private void printContentArray() {
		System.out.println( "\nSatzRaten.printContentArray Auswertung von:  " + sentenceClear+ "\n");
		char ch = 'A';
		int controllNr = 0;
		for (int i = 0; i < 26; i++) {
			System.out.println( ch + " " + sentContent[i] + " Mal");
			ch++;
			controllNr += sentContent[i];
		}
		System.out.println( "Satzlänge:  " + sentenceClear.length() + " zur Kontrollzahl = " +controllNr);
		System.out.println( " Es sind " + numberLetter +  " verschiedene Buchstaben.");
	}
	
	public void initRoundEnd() {
		System.out.println( "SatzRaten.initRoundEnd Satz ist fertig");
		resultLabel[2].setText( "Die Runde ist zu Ende. ");  
		for ( int i = 0; i < 26; i++ ) {
			azButton[i].setEnabled(false);  // A-Z alles deaktivieren
			
		}
		markiert = false;
		orderButton[0].setEnabled(false);  // Weiter wird aktivier
		orderButton[1].setEnabled(false);  // deaktivieren
		orderButton[2].setEnabled(false);  // deaktivieren
		orderButton[3].setEnabled(true);  // Weiter wird aktivier
		
	
	}
	
	// alles auf Null setzen, Buttons aktivieren bzw. deaktivieren
	public void initNewRound() {
		for ( int i = 0; i < 26; i++ ) {
			azButton[i].setEnabled(true);  
		}
		orderButton[0].setEnabled(true);  
		orderButton[1].setEnabled(true);  
		orderButton[2].setEnabled(true);  
		orderButton[3].setEnabled(false);  
		
		for (int i = 1; i < 5; i++) {
			infoLabel[i].setText( "");  
			resultLabel[i].setText( ""); 
			if ( i < 3) {
				titelLabel[i].setText( "");  
			}
		}
		resultLabel[4].setText(" Tacken: " + tacken );  
			
		numberLetter = 0;				// Anzahl der Buchstaben im Ratesatz	
		showInfoFound = 0;				// Die gefundenen Buchstaben	

		
		
		
		gameLoop();
	}
	
	
	// Innere Klasse für den Nachrichtenverkehr der Buttons
		private final class Schalterhearer implements ActionListener {
			
			public void actionPerformed (ActionEvent e) {
				String s;
				s = e.getActionCommand();
				
				if (s == "Ende") {		// Button Ende geklickt?
					System.out.println( "innere Klasse Schalterhearer.actionPerformed Ende gewählt");
					System.exit(0);		// das Spiel wird beendet
				}
				
				if (s == "neue Runde") {		// Button Ende geklickt?
					System.out.println( "innere Klasse Schalterhearer.actionPerformed Weiter gewählt");
					initNewRound();		// das Spiel wird beendet
				}
				
				if (s == "Die Story") {		// Button no name geklickt?
					JOptionPane.showMessageDialog ( null, 
							"Nun, in einer Stunde geht das Schiff. Ich weiß nicht mehr, warum ich nachts mit einem dicken Schädel in der Gosse aufwachte.\n" +
							"Meiner Kleidung nach bin ich nicht arm, nur etwas verdreckt. Diese verdammte Insel. Was wollte ich hier?\n" +
							"Eins ist mir klar, dass Schiff da unten wird heute Abend ablegen. Und ich muss da drauf. Da bin ich mir sicher.\n" +
							"Man hat mich aber nicht an Bord gelassen. Man kenne mich nicht, aber für 1.000 Tacken könne ich einschiffen. \n" +
							"Ja, bloß wo bekomme ich das her. Nun, da ist ein Spielkasino. Vielleicht habe ich Glück. Und wie passend, daneben ist gleich ein Pfandleiher.\n" +
							"Also verabschiede ich mich von meiner Uhr und bin um 50 Tacken reicher. Das muss reichen.\n\n" +

							"Im Kasino sind anscheinend nicht nur Spieler. Sondern auch verdammt hübsche Ladies, die auf Gewinner warten. \n" +
							"Ich kann mir ein Grinsen nicht verkneifen, aber 50 Tacken sind nicht viel, also, wo zocke ich mit.\n" +
							"Verdammt, was kann man hier um diese Uhrzeit überhaupt zocken? O weia, nur ein Spieltisch. Naja, jedenfalls sieht die Lady hübsch aus.\n\n" +

							"Sie schaut mir in die Augen und sagt, 50 Tacken Mindesteinsatz. Die Regeln sind einfach.\n" +
							"Mach keinen Fehler und drück die richtigen Knöpfchen. Dann wirst Du mich nicht nur zum Essen einladen können. \n"); 
				}
				
				if (s == "Die Regeln") {		// Button no name geklickt?
					JOptionPane.showMessageDialog ( null, "26 Lettern sind im Einsatz\n\n." +
							"Drücke einen Button und Du wirst spüren, wie die Erkenntnis über Dich kommt.\n" +
							"Bedenke jedoch, jeder falsche Druck kostet Dich Tacken.\n\n" +
							"Ist es Dir zu schwer, wähle Markieren. Es kostet aber 100 Tacken pro Runde.\n" +
							"Wenn Du nach einer Runde ins Minus kommst, schmeißen wir Dich raus.\n" +
							"Gewinnst Du 1.000 Tacken sind heute alle Getränke für Dich frei.\n" +
							"Du wirst Dich dann garantiert wohlfühlen.");
	
				}
				
				if( markiert == true) { // true wenn der Button markieren getätigt wurde
				deactButton(s);
					
				}
				
				if (s == "markieren") {  // Button markieren geklickt?
					System.out.println( "innere Klasse Schalterhearer.actionPerformed marken gewählt");
					orderButton[0].setEnabled(false);  // wird erst nach Ende der Spielrunde aktiviert
					infoLabel[1].setText(" markieren gewählt");
					markiert = true;
					tacken -= 100;
					resultLabel[4].setText(" Tacken: " + tacken );  
				}
						
				if (s.length() == 1) {   // um nur die A-Z Button zu bekommen
					System.out.println( "innere Klasse Schalterhearer.actionPerformed Buchstabe gewählt:  "+ s.length());
					
					char ch =	s.charAt(0);
					
					System.out.println("s String:   " + s);
					System.out.println("ch Zeichen:   " + ch);
					titelLabel[1].setText(entkodieren(ch) );      // der aktualisierte Satz
					System.out.println("ch Zeichen:   " + ch);
					System.out.println("ch+26 Zeichen:   " + (ch+32));	
					
					includeResult(s);
					showInfoFound = getshowInfoFound();
					resultLabel[1].setText( "gefunden: " +  showInfoFound);  
					titelLabel[1].setText(entkodieren(ch) );      // der aktualisierte Satz
					if (showInfoFound == numberLetter ) {   // Alle Buchstaben gefunden wenn true
						if (tacken < 0) {
							resultLabel[4].setText(" Keine Tacken mehr, Ende. ");  
							orderButton[3].setEnabled(false);  // Weiter deaktiviert
							resultLabel[3].setText(" Tacken: " + tacken );  
							
						}
						else {
							initRoundEnd();
						}
					}

				}
									
			}	
			
			
			// deaktiviert geählte Buchstabentaste, wenn aktiviert
			private void deactButton ( String ss) {
				for (int i = 0; i < 26; i++ ) {
					if ( ss == azButton[i].getText() ) {
						azButton[i].setEnabled(false);  
						System.out.println( "innere Klasse Schalterhearer.deactButton gewählt "+ azButton[i] );
					}
				}
			}
			
			private String entkodieren(char c) {
				boolean inside = false;
				for ( int i = 0; i < arrKodiert.length; i++) {
					if ( (arrClear[i] == c) || (arrClear[i] == (c+32) ) )   {
						arrKodiert[i] = arrClear[i];
						inside = true;
					}
				}
				if (inside == false) {
					tacken = tacken - 10;
					resultLabel[4].setText(" Tacken: " + tacken );  
				}
		
				sentenceMask = "";
				for ( int i = 0; i < arrKodiert.length; i++) {
					sentenceMask = sentenceMask + arrKodiert [i];
				}
			
				System.out.println("Innere Klasse Schalterhearer.entkodieren "  + sentenceMask);
				return sentenceMask;
			}
		
			private void includeResult(String let) {
				int letNr = (int) let.charAt(0);
				
				if (letNr > 96) {
					letNr = letNr - 32;		// nur noch Großbuchstaben
				}
				letNr = letNr - 65;    // die Null ist A -... 26 ist Z
				System.out.println("Innere Klasse Schalterhearer.includeResult ");
				System.out.print(" Index " + letNr + "    Zeichen " + let);
				if (sentContent[letNr] > 0 ) {
					sentContent[letNr] = 10000;	// vierstellig markiert, bereits gezogen
				}
			}
	
			private int getshowInfoFound() {
				int summe = 0;
				
				for (int i = 0; i < 26; i++) {
					summe += sentContent[i];
				}
				summe = summe / 10000;
				return summe;
			}
		
		
		
		}  // Ende der inneren Klasse	

}

Die Datei Spielsätze

Code: Alles auswählen


/*
	Hier sind die Fragesätze im Klartext hinterlegt
	Eine öffentliche Zugriffsmethode
	eine interne Zufallszahl-Methode
	Methode zur Sicherstellung, dass nicht 2 mal der gleiche Satz dran kommt
*/

import java.util.*;

public class Spielsaetze {
	// die einfachste und schnellst Moeglichkeit ein Satzarchiv anzulegen
	// wir schreiben die Saetze direkt in das Array
	
	String [] sentenceBox = {
			"Du interessierst dich fuer Spieleentwicklung? Besuche ZFX developia!",	
			"Auch der laengste Marsch beginnt mit dem ersten Schritt." ,
			"Der beste Fuehrer ist der, dessen Existenz gar nicht bemerkt.",
			"Wer andere besiegt, hat Kraft. Wer sich selber besiegt, ist stark.",
			"Mit Nachdruck etwas durchfuehren bedeutet Wille.",
			"Dass ich erkenne, was die Welt im Innersten zusammenhaelt", 
			"Da steh' ich nun, ich armer Tor, und bin so klug als wie zuvor", 
			"Spielen ist Experimentieren mit dem Zufall.",
			"Der Poet versteht die Natur besser als der wissenschaftliche Kopf.",
			"Sein oder Nichtsein, das ist hier die Frage.",
			"Das bessere Teil der Tapferkeit ist Vorsicht.",
			"Wer die Wahrheit verraet, verraet sich selber.",
			"Oft ist das Denken schwer, indes das Schreiben geht auch ohne es.",
			"Dumme Gedanken hat jeder, nur der Weise verschweigt sie.",
			"Die Summe unseres Lebens sind die Stunden, in denen wir liebten.",
			"Ausdauer wird frueher oder spaeter belohnt - meistens aber spaeter.",
			"Es gibt erfuelltes Leben trotz vieler unerfuellter Wuensche.",
			"Ein Maennlein steht im Walde ganz still und stumm.",
			"Die meisten Menschen sind viel zu sehr mit sich beschaeftigt, um boshaft zu sein.",
			"Je mehr sich einer gehen laesst, um so weniger lassen ihn die anderen gehen.",
			"Mancher wird nur deshalb kein Denker, weil sein Gedaechtnis zu gut ist.",
			"Der Mohr hat seine Schuldigkeit getan; der Mohr kann gehen.",
			"Beim wunderbaren Gott - das Weib ist schoen",
			"Was sie gestern gelernt, das wollen sie heute schon lehren.",
			"Ein Langweiler ist ein Mensch, der redet, wenn du wuenschst, dass er zuhoert.",
			"Rauchen aufhoeren muss besonders leicht sein. Ich kenne viele, die das schon oefters gemacht haben.",
			"Nachdem wir das Ziel aus unseren Augen verloren hatten, verdoppelten wir unsere Anstrengungen.",
			"Gib jedem Tag die Chance, der schoenste deines Lebens zu werden.",
			"Was du heute kannst besorgen, das verschiebe nicht auf morgen.",
			"Das bekannteste an Frankfurt sind die Wuerstchen, das beruehmteste ist Goethe.",
			"Falls ich in 5 Minuten nicht zurueck sein sollte, warte einfach ein bisschen laenger.",
			"Sei realistisch versuch das Unmoegliche!",
			"Zwischen Leber und Milz passt immer ein Pils.",
			"Der Kopf tut weh, die Fuesse stinken, hoechste Zeit ein Bier zu trinken.",
			"Je mehr man schon weiss, je mehr hat man noch zu lernen.",
			"Das gute Beispiel ist nicht eine Moeglichkeit andere Menschen zu beeinflussen, es ist die einzige.",
			"Leben heisst, es mit etwas zu tun haben - mit der Welt und mit sich.",
			"Je weiser und besser ein Mensch ist, um so mehr Gutes bemerkt er in den Menschen.",
			"Sehnsucht ist das Los des Geistes, der einmal Gottes Schoenheit geschaut hat.",
			"Alle Menschen sind klug; die einen vorher - die anderen nachher.",
			"Unser automatischer Anrufbeantworter ist in Reparatur -- hier spricht ein Mensch.",
			"Gott gab die Zeit -  von Eile hat er nichts gesagt.",
			"An den Tod zu denken, ist der beste Weg, nicht staendig zu glauben, man haette etwas zu verlieren.",
			"Wir unterschaetzen das, was wir haben und ueberschaetzen das, was wir sind.",
			"Was nennen die Menschen am liebsten dumm? Das Gescheite, das sie nicht verstehen.",
			"Man muss schon etwas wissen, um verbergen zu koennen, dass man nichts weiss.",
			"Solange man selbst redet, erfaehrt man nichts.",
			"Ein stolzer Mensch verlangt von sich das Ausserordentliche. Ein hochmuetiger Mensch schreibt es sich zu.",
			"Sei deines Willens Herr und deines Gewissens Knecht.",
			"Andere erkennen ist weise. Sich selbst erkennen ist Erleuchtung.",
			"Wer viele Schaetze anhaeuft, hat viel zu verlieren.",
			"Wer gern Recht behaelt, den ueberhoert man.",
			"Lernen ist wie Rudern gegen den Strom. Hoert man damit auf, treibt man zurueck.",		
			"Das knowhow im ZFX developia ist gut.",
			"Sich regen bringt Segen.",
			"Das Kontakthaus war zu.",
			"Das Bequeme macht uns lahm.",
			"Die Konjunktur sprang spaet an.",
			"Seemann, lass das Traeumen.",
			"Wenn i nachts von der Kneip hoimgeh.",
			"Ein Vers verfuehrt zum Dichten.",
			"Mein Vater war ein Wandersmann.",
			"Das Wandern ist des Muellers Lust.",
			"Freude schoener Goetterfunken",
			"Wie schoen, dass du geboren bist.",
			"Hejo! Spann den Wagen an.",
			"In der Kuerze, liegt die Wuerze.",
			"ZFX developia ist 24 Stunden erreichbar.",
			"Eine Seefahrt, die ist lustig",
			"Meine Oma faehrt im Huehnerstall Motorrad",
			"Der Koenig und der Bettler",
			"Da hilft nur noch beten.",
			"Textmanipulation und numrische Ausdruecke.",
			"Dies Programm gibt die Nachricht hello world aus.",
			"Modulo und Dividieren ergaenzen sich.",
			"Testen Sie Ihr Koennen.",
			"Noch ist nicht aller Tage Abend.",
			"Dinge brauchen ihre Zeit.",
			"Zu Programmieren bedeutet zu verstehen.",
			"Das Glueck bevorzugt den, der vorbereitet ist.",
			"Mache die Dinge so einfach wie moeglich, aber nicht einfacher.",
			"In der Theorie ist die Praxis ganz einfach.",
			"Ein Erfolg ist niemals endgueltig.",
			"Das wichtigste Konzept in C++ ist die Klasse.",
			"Betrachten wir ein einfaches Designproblem.",
			"In einer Summe darf man die Summanden vertauschen.",
			"In einem Produkt kann man die Faktoren vertauschen.",
			"Verfolgen Sie genau den Gang der Loesung."
		};
	
	// um Doppelziehungen zu vermeiden, Java setzt alles auf false
	boolean [] knownSentence = new boolean[sentenceBox.length];
	// Instanzvariable
	int max = sentenceBox.length;
			
	// Satzausgabe
	public String getSentence() {
		int x = getRandomnumber();		// Zufallsposition aufrufen						
		checkfreeSentence();			// prüfen, ob überhaupt noch ein Satz nicht dran war
		int mistake = 0;
		while (knownSentence[x] == true ) {
			 x = getRandomnumber();		// Zufallsposition aufrufen						
			 mistake++;
			 if ( mistake > ( 2 * max) ) {	// darf eigentlich nie passieren.
				 System.out.println ("Fehler bei Spielsaetze_getSentence, unbekannt");
				 break;
			 }
		}
		System.out.println ("Spielsaetze_getSentence: ausgewählt wurde Satz Nr: "+  x + "  " + sentenceBox[x]);
		return sentenceBox[x];
	}
	
	//Zufallsgenerator 
	private int getRandomnumber () {
		int number;
		Random generator = new Random();
		number = generator.nextInt (max);
		System.out.println ("Spielsaetze_getRandomnumber Zufallszahl: " + number);
		return number;
	}
	
	// Wenn alle Sätze einmal dran waren, gehts von vorne los
	private void checkfreeSentence() {
		boolean allsentknown = true;
		for ( int i = 0; i < sentenceBox.length; i++ )
		{
			if (knownSentence[i] == false )  {  	// sobald ein unbekannter Satz da ist, geht es mit break aus der Methode
				allsentknown = false;
				break;
			}
		}
		if (allsentknown == true) {					// für den unwahrscheinlichen Fall, dass alle Sätze dran waren
			for ( int i = 0; i < sentenceBox.length; i++ ) {   
				knownSentence[i] = false; 			// werden alle Sätze wieder frei gegeben.
			}
		}
	}
}

Terep :)
Avatar = „Odyssee im Weltraum“ Film von Stanley Kubrick (Warner Brothers);
nach dem Buch von Arthur C. Clarke. It will becoming true ?!!
Antworten