TU Wien:Programmkonstruktion VU (Puntigam)/2015S Adhoc Aufgaben
Adhoc Aufgabe 1[Bearbeiten | Quelltext bearbeiten]
di15[Bearbeiten | Quelltext bearbeiten]
Mögl. Lösung #1:
public class Aufgabe1 {
public static int laenge(int wert) {
//345 /10 -> 34 /10
if (wert==0) return 1;
int count = 0;
while (wert > 0) {
wert /= 10;
count++;
}
return count;
}
public static void main(String[] args) {
System.out.println(laenge(123456));
System.out.println(laenge(12));
System.out.println(laenge(0));
}
}
Adhoc Aufgabe 2[Bearbeiten | Quelltext bearbeiten]
di15[Bearbeiten | Quelltext bearbeiten]
2. Byte variable deklarieren und einmal 1, einmal 1000 zuweisen
Mögl. Lösung #1/1:
public class Aufgabe1 {
//longish Aufgabenblatt1/Aufgabe1 (zusatz zur Angabe)
private static long longish(short n) {
long result = 0L;
while (n > 0) {
switch (n % 10) {
case 0:
result += 1L;
break;
case 1:
result += 10L;
break;
case 2:
result += 100L;
break;
case 3:
result += 1000L;
break;
case 4:
result += 10000L;
break;
case 5:
result += 100000L;
break;
case 6:
result += 1000000L;
break;
case 7:
result += 10000000L;
break;
case 8:
result += 100000000L;
break;
case 9:
result += 1000000000L;
break;
}
n /= 10;
}
return result;
}
private static long simpler(short n) {
long result = 0L;
while (n > 0) {
if (n % 10 == 0) {
result += 1L;
} else if (n % 10 == 1) {
result += 10L;
} else if (n % 10 == 2) {
result += 100L;
} else if (n % 10 == 3) {
result += 1000L;
} else if (n % 10 == 4) {
result += 10000L;
} else if (n % 10 == 5) {
result += 100000L;
} else if (n % 10 == 6) {
result += 1000000L;
} else if (n % 10 == 7) {
result += 10000000L;
} else if (n % 10 == 8) {
result += 100000000L;
} else if (n % 10 == 9) {
result += 1000000000L;
}
}
return result;
}
public static void main(String[] args) {
//just for testing
for (int i = 0; i < Short.MAX_VALUE; i++) {
if (longish((short)i) != simpler((short)i)) System.out.println("Fehler bei " + i);
}
}
}
Mögl. Lösung #1/2:
public class Aufgabe2 {
public static void main(String[] args) {
byte wert = (byte)1;
System.out.println("Wert (byte)1 ist: " + wert);
wert = (byte)1000;
System.out.println("Wert (byte)1000 ist: " + wert + ", weil Byte als MAX_VALUE " + Byte.MAX_VALUE + " hat " +
"und einen Überlauf erzeugt");
}
}
Adhoc Aufgabe 3[Bearbeiten | Quelltext bearbeiten]
di15[Bearbeiten | Quelltext bearbeiten]
Schreiben Sie eine statische Methode 'rec', die das Gleiche macht
wie iter (gleiches Input-Output-Verhalten), aber ohne Schleifen auskommt.
In 'rec' darf eine weitere selbst geschriebene Methode aufgerufen werden,
die ebenfalls ohne Schleifen auskommt. Alle Variablen und Parameter in
'rec' und den von 'rec' aufgerufenen Methoden sollten als 'final' deklariert
sein.
Mögl. Lösung #1:
public class Aufgabe1 {
//Angabe Methode iter:
private static String iter(int n) {
String s = "";
int i = 2;
while (i != n) {
if (n % i == 0) {
s += i + "*";
n /= i;
} else {
i++;
}
}
return s+i;
}
//Beginn der Lösung:
private static String rec(final int n) {
return rec2(n,2);
}
private static String rec2(final int n, final int i) {
if (n == i) return n+"";
if (n % i == 0) return i+"*"+rec2(n/i, 2);
return rec2(n, i+1);
}
public static void main(String[] args) {
//just for testing ...
System.out.println(rec(25) + " = " + iter(25));
System.out.println(iter(2) + " = " + rec(2));
System.out.println(iter(4) + " = " + rec(4));
System.out.println(iter(5) + " = " + rec(5));
System.out.println(iter(9) + " = " + rec(9));
System.out.println(iter(12) + " = " + rec(12));
System.out.println(iter(100) + " = " + rec(100));
}
}
Adhoc Aufgabe 4[Bearbeiten | Quelltext bearbeiten]
di15[Bearbeiten | Quelltext bearbeiten]
Mögl. Lösung #1/1:
public class Aufgabe1 {
public static void rev(char[] arr) {
char temp;
if (arr != null) {
for (int i = 0; i < arr.length/2; i++) {
temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
}
}
public static void main(String[] args) {
//just for testing...
char[] arr = new char[] {'a', 'b', 'c', 'd'};
rev(arr);
System.out.println("");
}
}
Mögl. Lösung #1/2:
public class Aufgabe2 {
public static char[] lin(char[][] arr) {
int faul = 0;
for (int i = 0; i < arr.length; i++) {
faul += arr[i].length;
}
char[] temp = new char[faul];
faul = 0;
for (int i = arr.length - 1; i >= 0; i--) {
for (int j = 0; j < arr[i].length; j++) {
temp[faul] = arr[i][j];
faul++;
}
}
return temp;
}
public static void main(String[] args) {
//just for testing...
char[][] a = new char[][] {new char[]{'a', 'b', 'c'}, new char[]{'x','y'}};
lin(a);
System.out.printf("done");
}
}
Adhoc Aufgabe 5[Bearbeiten | Quelltext bearbeiten]
di15[Bearbeiten | Quelltext bearbeiten]
Interval: Ein Intervall mit int-Grenzen.
Methoden:
toString() liefert einen String mit einer lesbaren Repräsentation des Intervalls zB:
[-1, 5]. Im Fall des leeren Intervalls wird [] geliefert.
intersect(Interval other) liefert den Durchschnitt von zwei Intervallen. Wenn der Durchschnitt
leer ist, soll ein spezielles, klassenweit eindeutifes Objekt EMPTY
vom Typ Interval gegeben
werden.
Der Durchschnitt des leeren Intervalls mit jedem anderen Intervall ist wieder das leere
Interval.
hull(Interval other) liefert die Hülle. zB
[-1,5].hull([7,8]) == [-1,8]
Die Hülle des leeren Intervalls mit jedem anderen Intervall ist das andere Intervall.
isValid() liefert true, wenn die untere Intervallgrenze kleiner oder gleich der oberen
Intervallgrenze ist, oder wenn das Intervall das leere Intervall ist, sonst false.
Zusätzliche Anforderungen: entsprechende Konstruktoren. Ein Programm
zum Testen der gefragten Klassen mit entsprechenden Ausgaben.
Zusatzfragen: Wie könnte man beliebige Zahlenmengen bestehend aus mehreren
Intervallen repräsentieren?
mo11[Bearbeiten | Quelltext bearbeiten]
Ingredient: Zutat mit Namen
Methoden:
toString() liefert einen String mit dem Namen
power() liefert einen int-Wert mit der Stärke
der Zutat (= Länge des Namen).
Potion: Ein Zaubertrank mit einer beliebigen Anzahl an Zutaten. Alle Zutaten werden beim
Erzeugen eines Zaubertrankes festgelegt und können nicht mehr verändert werden.
Methoden:
toSgtring() liefert einen string mit allen Zutaten und der Stärke des Zaubertranks und der
Information, ob er fertig ist
Beispiel: [fly, lizard, herbs] - 14 - not ready
[lizard, fly, herbs] - 28 - ready
power() ist die Stärke des Zaubertranks, entspricht der Summe der Stärke aller Zutaten
Wenn der Zaubertrank "fertig" ist, wirkt er doppelt so stark. Er ist fertig, wenn er mindestens
5 mal umgerührt wurde.
stir() rührt den Zaubertrank einmal um
stir(int n rührt in n-mal um
ready() liefert true wenn er fertig ist, sonst false
Zusätzliche Anforderungen: entsprechende Konstruktoren. Ein Programm
zum Testen der gefragten Klassen mit entsprechenden Ausgaben.
mo/di??[Bearbeiten | Quelltext bearbeiten]
- Erstellen Sie ein neues Modul "Aufgabe6" mit einer neuen Klasse
- "Raum", die folgende Member-Variablen beinhalten: String Name, int
- Area und int Height
- Die Klasse "Raum" hat einen Konstruktor mit dem alle Member-
- Variablen initialisiert bzw. beschrieben werden können.
- Die Klasse Raum bietet zwei Methoden an, um Name getName() und
- das Volumen getVolume() des Raumes auszulesen.
- In der main-Methode sollen 10 Objekte der Klasse "Raum" angelegt
- und in einem Array gespeichert werden
- Name der Räume: "Raum0...Raum9"
- Area und Height der Räume: Zufallszahl zwischen 1-10.
- (Math.random(), etc.)
- Geben Sie den Namen aller Räume und das jeweilige Volumen des
- Raumes in folgendem Format aus:
- Raum0 hat 12 Kubikmeter!
- ...
- Raum9 hat 34 Kubikmeter!
class CharListNode{
//Implementieren Sie eine Klasse CharlistNode die Character als Elemente speichert und einen Verweis auf den
// nächsten Knoten in der Liste hat.
private char elem;
private CharListNode next;
//Konstruktor
public CharListNode(char elem, CharListNode next){
/*TODO Code ergänzen*/
}
//Gibt das Element des Knoten zurück
public char getElem(){
/*TODO Code ergänzen*/
}
//Gibt den nächsten Knoten zurück
public CharListNode getNext(){
/*TODO Code ergänzen*/
}
}
class CharStack{
//Implementieren Sie eine Klasse CharStack der Objekte der Klasse CharListNode verwaltet
private CharListNode top = null;
//Mit push wird ein neuer Knoten auf den Stack gelegt.
public void push(char elem){
/*TODO Code ergänzen*/
}
//Mit pop wird ein Knoten vom Stack entfernt und das Element zuückgegeben.
public char pop(){
/*TODO Code ergänzen*/
}
//Methode liefert true zurück falls der Stack leer ist.
public boolean empty(){
/*TODO Code ergänzen*/
}
}
public class Aufgabe7 {
//Implementieren Sie eine Methode "check", die eine Klammersequenz mit runden Klammern () überprüft.
//Die Methode gibt true zurück falls die Klammerung stimmt, ansonsten false.
private static boolean check(String sequenz){
/*TODO Code ergänzen*/
}
public static void main(String[] args) {
String seq_true = "(())()((()))";
String seq_false = "((()())";
System.out.println(check(seq_true));
System.out.println(check(seq_false));
}
}
Adhoc Aufgabe 6[Bearbeiten | Quelltext bearbeiten]
di15[Bearbeiten | Quelltext bearbeiten]
1.) Schreiben Sie eine Methode in der Klasse Box, die die Länge der Liste
beginnend mit diesem Knoten zurückgibt.
Methode "indexOf":
2.) Schreiben Sie eine Methode, die für eine Liste aus ListItem Elementen
den Index jenes Elementes ,mit einer angegebenen Größe zurückliefert. Falls es
mehrere Elemente mit angegebener Größe gibt, soll der kleinste Index
zurückgeliefert werden (des ersten gefundenen Elements).
3.) Schreiben Sie diese Methode als Objekt Methode in Box.
Lösung:
//Anmerkung: Ausgegangen wird vom Aufgabenblatt6/Aufgabe5.java
//AdHoc6 1.):
//in der class Box
public int length() {
return this.content == null? 1 : this.content.length()+1;
}
//AdHoc6 2.)
//in class Aufgabe1 bzw. der Klasse mit main-Methode
public static int indexOf(ListItem list, int size) {
int result = 1;
if (list.getSize() == size) {
return 0;
} else if (list.getNext() == null) {
return -1;
}
if (indexOf(list.getNext(), size) == -1) {
return -1;
}
return result + indexOf(list.getNext(), size);
}
//AdHoc6 3.)
//in Box class
public int indexOf(int value) {
int result = 1;
if (this.getSize() == value) {
return 0;
} else if (this.getNext() == null) {
return -1;
}
if (this.getNext().indexOf(value) == -1) {
return -1;
}
return result + this.getNext().indexOf(value);
}
Adhoc Aufgabe 7[Bearbeiten | Quelltext bearbeiten]
di15[Bearbeiten | Quelltext bearbeiten]
Adhoc-Aufgabe: Parkplätze
Die gegebene Klasse 'Parkplatz' repräsentiert einen Parkplatz für
Fahrzeuge (KFZ) mit einer bestimmten Anzahl an Stellplätzen. Die
Stellplätze sind nummeriert und haben daher einen eindeutigen Index
(beginnend mit 0). Die Klasse besitzt Methoden um Fahrzeuge abzustellen
und zu entfernen. Ergänzen Side die fehlenden Befehle bei den
Kommentaren im Methodenrumpf
Im momentanen Zustand erhält der Benutzer keine Rückmeldung über
Verletzung von Zusicherungen (beispielsweise bei Benutzung eines
ungültigen Stellplatzindex bei 'istBelegt' oder 'stellen'). Weiters
verhält sich das 'Parkplatz'-Objekt nicht gemäß der Spezifikation (z.B.
kann ein KFZ auf einem Parkplatz mit ungültigem Index abgestellt werden). In
der ausführbaren Klasse 'ParkplatzManager' sind solche fehlerhaften
Befehle kommentiert.
Ändern Sie die Klassen so, dass im Fehlerfall eine Ausgabe erzeugt wird,
die genau dem jeweiligen Kommentar entspricht. Dies soll dadurch
erreicht werden, dass die Methoden der Klasse 'Parkplatz'
entsprechende Exceptions werfen, die die Information über den Fehlerfall
beinhaltten. Definieren Sie dazu eigene Exceptionklassen. Die Klasse
'ParkplatzManager' soll diese Exceptions fangen und die
entsprechende Ausgabe erzeugen.
Die von Ihnen geschriebenen Exception-Klassen werden bei der
Überprüfung der Zusicherungen (Vorbedingungen) der Methoden in der
Klasse 'Parkplatz' genutzt. Für die Einhaltung der Vorbedingungen einer
Methode ist der Aufrufer verantwortlich. Daher muss in der Klasse
'Parkplatz' sichergestellt sein, dass nur gültige Parameter benutzt
werden. Welche Änderungen müssen vorgenommen werden, um die
Vorbedingungen sicherzustellen und so das Auftreten von Exceptions zu
vermeiden? Beschreiben Sie dies exemplarisch für einen Methodenaufruf.
Die Ausgabe im Fall von nicht eingehaltenen Vorbedingungen soll dabei
dieselbe sein, wie im Fall des Auftretens einer Exception.
//Anmerkung: Parkplatz.java
import java.util.HashMap;
/**
* Repräsentiert einen Parkplatz.
*/
public class Parkplatz {
private HashMap<String, Integer> map;
private int stellplaetze;
/**
* Initialisiert den Parkplatz mit einer entsprechenden Anzahl
* an freien Plätzen und 0 belegten Plätzen.
* @param stellplaetze
*/
public Parkplatz(int stellplaetze) {
this.staellplaetze = stellplaetze;
this.map = new HashMap<String, Integer>();
}
/**
* @return liefert die Gesamtanzahl der Stellplätze auf diesem
* Parkplatz.
*/
public int stellplaetze() {
return stellplaetze;
}
/**
* Gibt an, ob der Stellplatz i belegt ist.
* @param i der Index des Stellplatzes
* @return true, wenn der Stellplatz i belegt ist, sonst false
*/
//TODO: Change this method according to assignment if necessary
public boolean istBelegt(int i) {
return false; //TODO: Change this expression
}
/**
* Gibt an, ob das KFZ mit dem angegebenen Kennzeichen auf dem Parkplatz
* abgestellt wurde.
* @param kennzeichen das Kennzeichen des KFZ
* @return true, wenn der das KFZ mit dem angegebenen Kennzeichen auf
* einem beliebigen Parkplatz steht, sonst false
*/
//TODO: Change this method according to assignment if necessary
public boolean istAbgestellt(String kennzeichen) {
return map.containsKey(kennzeichen);
}
/**
* Stellt das KFZ mit angegebenen Kennzeichen auf dem
* angegebenen Stellplatz ab.
* @param kennzeichen das Kennzeichen des KFZ
* @param i der Index des Stellplatzes
*/
//TODO: Change this method according to assignment if necessary
public void stellen(String kennzeichen, int i) {
if (istBelegt(i)) {
return;
}
map.put(kennzeichen, i);
}
/**
* Entfernt das KFZ mit dem angegebenen Kennzeichen
* @param kennzeichen das Kennzeichen des zu entfernenden KFZ
*/
//TODO: Change method according to assignment if necessary
public void entfernen(String kennzeichen) {
//TODO: Add lines here
}
/**
* @return eine lesbare Repräsentation des Parkplatzes, mit
* allen belegten Plätzen.
*/
public String toString() {
return map.toString() + "\n" + stellplaetze + "
Stellplätze insgesamt";
}
}
//Anmerkung: ParkplatzManager.java
import java.util.Scanner;
public class ParkplatzManager {
public static void main(String[] args) {
String befehl =
" stellen W16440 0 " +
" stellen W16440 5 " +
" stellen K345L 0 " +
" stellen WB3542L 5" + //Platz mit Index 5 bereits belegt
" entfernen W16440 " +
" entfernen SL105W " + //KFZ mit Kennzeichen SL105W nicht abgestellt
" stellen G354N 10 " + //Platz mit Index 10 gibt es nicht
" belegt 10 " + //Platz mit Index 10 gibt es nicht
" entfernen W16440 " + //KFZ miz Kennzeichen W16440 nicht abgestellt
" stellen G502K 3 ";
Scanner sc = new Scanner(befehl);
Parkplatz p = new Parkplatz(10);
while(sc.hasNext()) {
String command = sc.next();
if (command.equals("stellen")) {
p.stellen(sc.next(), sc.nextInt());
} else if (command.equals("entfernen")) {
p.entfernen(sc.next);
} else if (command.equals("belegt")) {
p.istBelegt(sc.nextInt());
}
}
System.out.println(p);
/*
* Sollausgabe:
*
* Platz mit Index 5 bereits belegt.
* KFZ mit Kennzeichen SL105W nicht abgestellt.
* Platz mit Index 10 gibt es nicht.
* Platz mit Index 10 gibt es nicht.
* KFZ mit Kennzeichen W16440 nicht abgestellt.
* {G502K=3, K345L=0}
* 10 Stellplätze insgesamt
*
*/
}
}
Lösung:
// ParkplatzManager.java
import java.util.Scanner;
public class ParkplatzManager {
public static void main(String[] args) throws InvalidStellplatzException, KfzNotFoundException {
String befehl =
" stellen W16440 0 " +
" stellen W16440 5 " +
" stellen K345L 0 " +
" stellen WB3542L 5 " +
" entfernen W16440 " +
" entfernen SL105W " +
" stellen G354N 10 " +
" belegt 10 " +
" entfernen W16440 " +
" stellen G502K 3 ";
Scanner sc = new Scanner(befehl);
Parkplatz p = new Parkplatz(10);
while (sc.hasNext()) {
String command = sc.next();
if (command.equals("stellen")) {
/* try {
p.stellen(sc.next(), sc.nextInt());
} catch (InvalidStellplatzException e) {
System.out.println(e.getMessage());
} catch (InvalidStellplatzNA e) {
System.out.println(e.getMessage());
}
*/
p.stellen(sc.next(), sc.nextInt());
} else if (command.equals("entfernen")) {
try {
p.entfernen(sc.next());
} catch (KfzNotFoundException e) {
System.out.println(e.getMessage());
}
} else if (command.equals("belegt")) {
try {
p.istBelegt(sc.nextInt());
} catch (InvalidStellplatzNA e) {
System.out.println(e.getMessage());
}
}
}
System.out.println(p);
}
}
// Parkplatz.java
import java.util.HashMap;
public class Parkplatz {
private HashMap<String, Integer> map;
private int stellplaetze;
public Parkplatz(int stellplaetze) {
this.stellplaetze = stellplaetze;
this.map = new HashMap<String, Integer>();
}
public int stellplaetze() {
return stellplaetze;
}
public boolean istBelegt(int i) throws InvalidStellplatzNA{
if (i >= this.stellplaetze) {
throw new InvalidStellplatzNA(i);
}
return map.containsValue(i);
}
public boolean istAbgestellt(String kennzeichen){
return map.containsKey(kennzeichen);
}
public void stellen(String kennzeichen, int i) throws InvalidStellplatzException, InvalidStellplatzNA {
if (istBelegt(i)) {
throw new InvalidStellplatzException(i);
}
map.put(kennzeichen, i);
}
public void entfernen(String kennzeichen) throws KfzNotFoundException{
if (!istAbgestellt(kennzeichen)) {
throw new KfzNotFoundException(kennzeichen);
}
map.remove(kennzeichen);
}
public String toString() {
return map.toString() + "\n" + stellplaetze + " Stellplätze insgesamt";
}
}
// KfzNotFoundException.java
public class KfzNotFoundException extends RuntimeException {
public KfzNotFoundException() {
super("KFZ mit Kennzeichen nicht abgestellt.");
}
public KfzNotFoundException(String kennzeichen) {
super("KFZ mit Kennzeichen " + kennzeichen + " nicht abgestellt.");
}
}
// InvalidStellplatzNA.java
public class InvalidStellplatzNA extends RuntimeException {
public InvalidStellplatzNA() {
super("Stellplatz mit Index ? gibt es nicht.");
}
public InvalidStellplatzNA(int i){
super("Stellplatz mit Index " + i + " gibt es nicht.");
}
}
// InvalidStellplatzException.java
public class InvalidStellplatzException extends RuntimeException {
public InvalidStellplatzException() {
super("Platz bereits belegt");
}
public InvalidStellplatzException(int i) {
super("Platz mit Index " + i + " bereits belegt.");
}
}
do15[Bearbeiten | Quelltext bearbeiten]
Adhoc - Aufgaben
- Erstellen sie eine Aufgabe7
- Implementieren Sie eine Klasse "Book" und folgende Methoden:
- Einen Konstruktor, der vier Parameter übergeben bekommt: Buchtitel
- Einen Konstruktor, der vier Parameter übergeben bekommt: Buchtitel
- (String), Autorenliste (String), Seitenzahl (int), Preis in Cents (long).
- Getter-Methoden für jede Objektvariable.
- Setter-Methode für eine Änderung am Preis.
- (String), Autorenliste (String), Seitenzahl (int), Preis in Cents (long).
- Der Konstruktor wirft eine "InvalidBookExceeption" wenn zumindest
- einer folgende Fälle eintritt:
- Buchtitel ist gleich "null"
- Autorenliste ist gleich "null"
- Seitenanzahl ist kleiner gleich 0
- Preis ist kleier 0
- Buchtitel ist gleich "null"
- Die Setter Methode wirft eine "InvalidPriceException", wenn der Preis
- kleiner 0 ist.
- In der main-Methode testen Sie Ihre Book Klasse und Exceptions
- entsprechend und zeigen Sie die korrekte Funktionsweise.
Lösung:
//Anmerkung: unabhängiges Beispiel als Adhoc-Aufgabe
public class Book {
public static void main(String[] args) {
try {
Book HarryPotter1 = new Book("HarryPotter", "Autor", 500, 0);
HarryPotter1.setPreis(1);
} catch (InvalidBookException e) {
System.out.println("InvalidBookException");
} catch (InvalidPriceException e) {
System.out.println("InvalidPriceException");
}
}
private String buchtitel;
private String autorenliste;
private int seitenanzahl;
private long preis;
Book(String buchtitel, String autorenliste, int seitenanzahl, long preis) throws InvalidBookException{
this.buchtitel = buchtitel;
this.autorenliste = autorenliste;
this.seitenanzahl = seitenanzahl;
this.preis = preis;
if (getBuchtitel() == null || getAutorenliste() == null || getSeitenanzahl() <= 0 || getPreis() < 0) {
throw new InvalidBookException();
}
}
public void setPreis(long preis) throws InvalidPriceException{
this.preis = preis;
if(this.preis < 0){
throw new InvalidPriceException();
}
}
public String getBuchtitel(){
return this.buchtitel;
}
public String getAutorenliste(){
return this.autorenliste;
}
public int getSeitenanzahl(){
return this.seitenanzahl;
}
public long getPreis(){
return this.preis;
}
}
class InvalidBookException extends Exception {
public InvalidBookException(){
}
}
class InvalidPriceException extends Exception {
public InvalidPriceException(){
}
}
Adhoc Aufgabe 8[Bearbeiten | Quelltext bearbeiten]
mi11[Bearbeiten | Quelltext bearbeiten]
Schreiben Sie ein Programm, das Spielzüge des Spiels "Vier gewinnt" simuliert. Schreiben Sie dazu eine Klasse ConnectFour, die ein quadratisches Spielfeld einer bestimmten Größe repräsentiert. Ein Spielfeld der Größe 8 sieht so aus:
........
........
........
........
........
........
........
........
Die Klasse soll über einen Konstruktor verfügen, dem man die Größe des Spielfelds angeben muss. Leere Plätze werden durch das Zeichen '.' dargestellt. Alle anderen Zeichen (ausgenommen Steuerzeichen wie "\n") repräsentieren Spielsteine.
Die Klasse soll folgende Methoden haben:
public void play(int column, char symbol) wirft einen Spielstein, der duch symbol repräsentiert wird, in das Spielfeld. Der Spielstein fällt dabei in der Spalte mit dem angegebenen Index column von oben nach unten und wird auf dem letzten Platz der Spalte eingefügt. Beispielsweise werden folgende Spielzüge hintereinander ausgeführt:
play(2,'#')
........
........
........
........
........
........
........
..#.....
play(2,'o')
........
........
........
........
........
........
..o.....
..#.....
play(3,'#')
........
........
........
........
........
........
..o.....
..##....
play(2,'o')
........
........
........
........
........
..o.....
..o.....
..##....
public void save(String filename) speichert das Spiel in einer Textdatei unter dem angegebenen Dateinamen. Unmittelbar nach dem Speichern wird der Datenstrom wieder geschlossen.
public void load(String filename) liest das Spiel aus einer Textdatei ein. Der bisherige Zustand wird mit dem gelandenen Spiel überschrieben. Unmittelbar nach dem Laden wird der Datenstrom wieder geschlossen. Die Datei darf nur gleich lange Zeilen beinhalten. Die erste Zeile bestimmt die Größe des Spielfelds. Die Anzahl der Zeilen muss der Größe des Spielfelds entsprechen. Wird dieses Format in der einzulesenden Datei nicht eingehalten, wird eine FileFormatException geworfen. In diesem Fall hat load keinen Effekt, d. h. der Zustand des Spielfelds bleibt unverändert.
Achten Sie darauf, das in jedem Fall (also auch bei Ausnahmen) der Datenstrom nach der Operation load/save geschlossen und alle notwendigen Operationen zum Aufräumen durchgeführt werden.