TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK Lehrstuhl für Sprachen und Beschreibungsstrukturen Praktikum Grundlagen der Programmierung F. Forster, T. Gawlitza, A. Flexeder Übungen zu WS 2007/2008 Lösungsvorschläge zu Blatt 13 25. Januar 2008 Praktikum Grundlagen der Programmierung Aufgabe 58 Applets: Album (Lösungsvorschlag) a) HTML-Code: album.html <html> <head> <title> Album </title> </head> <body> <h1> Album </h1> <applet codebase="." code=" Album . class " width=500 height=300 alt=" Your browser has to be Java - enabled to see the ap <param name=" urls " value=" mac . jpeg : tux . jpeg : windows . jpeg "/ > </applet> </body> </html> b) Applet-Code: Album.java import import import import import java . applet . Applet ; java . awt .*; java . awt . event .*; java . util .*; java . util . List ; public class Album extends Applet implements ActionListener { int crt = 0; Label label; Button prev , next ; String [] names ; Image [] imgs ; public void init () { List < String > urls = new LinkedList < String >(); StringTokenizer t = new StringTokenizer ( getParameter (" urls "), ":" ); while (t. hasMoreTokens ()) urls . add (t. nextToken ()); setBackground ( Color . white ); setFont (new Font (" SansSerif " , Font . BOLD , 18)); label = new Label (); Lösung 13/ Seite 2 add (label); prev = new Button (" Prev " ); prev . setBackground ( Color . orange ); prev . addActionListener (this); add ( prev ); next = new Button (" Next " ); next . setBackground ( Color . orange ); next . addActionListener (this); add ( next ); names = new String [ urls . size ()]; imgs = new Image [ urls . size ()]; int id = 0; for( String url : urls ) { names [ id ] = url ; id ++; } label. setText ( names [0]); } public void paint ( Graphics page ) { if ( imgs [ crt ] == null) imgs [ crt ] = getImage ( getDocumentBase () , names [ crt ]); page . drawImage ( imgs [ crt ] ,100 ,100 ,this); } public void actionPerformed ( ActionEvent e) { if(e. getSource ()== next ) crt = ( crt +1)% imgs . length ; else crt = ( crt + imgs . length -1)% imgs . length ; label. setText ( names [ crt ]); repaint (); } } Test durch Aufrufen der HTML-Datei im WWW-Browser oder mit appletviewer. Aufgabe 59 (Ü) Tabellenkalkulation a) public abstract class Expr { public abstract int eval (); } public class Const extends Expr { private int value ; public Const (int v) { value = v; } public int eval () { return value ; } Lösung 13/ Seite 3 } public class Add extends Expr { private Expr lhs , rhs ; public Add ( Expr x , Expr y) { lhs =x; rhs =y; } public int eval () { return lhs . eval () + rhs . eval (); } } public class UnMinus extends Expr { private Expr e; public UnMinus ( Expr x) { e=x; } public int eval () { return -e. eval (); } } public class Ref extends Expr { private Tabelle tab ; private int col ; private int row ; public Ref ( Tabelle t , int r , int c) { tab = t; col = c; row = r; } public int eval () { return tab . evalZelle (row , col ); } } b) public class Tabelle { private private private private private final int ROWS = 30; final int COLS = 30; Expr [][] zellen = new Expr [ ROWS ][ COLS ]; int[][] values = new int[ ROWS ][ COLS ]; boolean[][] isValid = new boolean[ ROWS ][ COLS ]; public Expr get (int i , int j) { if (i >= 0 && i < ROWS && j >= 0 && j < COLS ) return zellen [i ][ j ]; Lösung 13/ Seite 4 else return null; } public int evalZelle (int i , int j) { if (i >= 0 && i < ROWS && j >= 0 && j < COLS && zellen [i ][ j] != null) { if (! isValid [i ][ j ]) { values [i ][ j] = zellen [i ][ j ]. eval (); isValid [i ][ j] = true; } return values [i ][ j ]; } throw new IllegalArgumentException (" Cell not set " ); } public void setExpression (int i , int j , Expr e) { // set cell if (i >= 0 && i < ROWS && j >= 0 && j < COLS ) zellen [i ][ j] = e; // invalid cache for (int a = 0; a < ROWS ; a ++) { for (int b = 0; b < COLS ; b ++) { isValid [a ][ b] = false; } } } public static void main ( String [] args ) { Tabelle t = new Tabelle (); t. setExpression (1 ,1 , new Const (1)); t. setExpression (2 , 3, new Ref (t ,1 ,1)); System . out . println (t. evalZelle (2 ,3)); t. setExpression (1 ,1 , new Const (3)); System . out . println (t. evalZelle (2 ,3)); } } Aufgabe 60 (H) Minensuche import import import import (15+5 Punkte) java . awt .*; java . applet . Applet ; java . awt . Frame ; java . awt . event .*; public class Minensuche extends Applet implements ActionListener { int breite , hoehe , minen ; int[] minenpos ; Feld [] felder ; boolean[] scharf ; int punktestand = 0; Button start = new Button (" Start " );; Panel p1 ; TextField t1 ,t2 ,t3 , t4 ; Image bomb , att ; Lösung 13/ Seite 5 Thread uhrThread ; private class Uhr extends Panel implements Runnable { int uhrzeit ; public Uhr (int uhrzeit ){ this. uhrzeit = uhrzeit ; } public void run (){ for(int i = uhrzeit ; i !=2*( uhrzeit /3); i - -){ try{ Thread . sleep (1000); }catch( InterruptedException ie ){} uhrzeit - -; repaint (); } for(int i =0; i < minen ;i ++){ try{ Thread . sleep ((new java . util . Random ()). nextInt (3000)); }catch( InterruptedException ie ){} felder [ minenpos [i ]]. explodiere (); } } public Dimension getMinimumSize (){ return new Dimension (100 ,20); } public Dimension getPreferredSize (){ return getMinimumSize (); } public void paint ( Graphics g ){ g. drawRect (0 ,0 , getBounds (). width , getBounds (). height ); g. drawString (""+ uhrzeit , getBounds (). width /2 , getBounds (). height /2); } } public void vermine (){ int[] m = new int[ minen ]; for(int i =0;i < minen ;i ++){ int s = (new java . util . Random ()). nextInt ( breite * hoehe ); boolean gleich = true; //vermeide doppelte eintraege while( gleich && i !=0){ for(int j =0;j <i;j ++){ if(m[j] == s ){ s = (new java . util . Random ()). nextInt ( breite * hoehe ); break; }else gleich = false; } } minenpos [i] = s; m[i] = s; } } Lösung 13/ Seite 6 public void init (){ bomb = getImage ( getCodeBase () , " bomb . jpeg " ); att = getImage ( getCodeBase () , " attention . jpeg " ); setLayout (new BorderLayout ()); setBackground ( Color . white ); Panel p2 = new Panel (new GridLayout (2 ,5)); p2 . add (new Label (" Hoehe des Spielfeldes " )); p2 . add ( t1 =new TextField (" 10 " )); p2 . add (new Label (" Breite des Spielfeldes " )); p2 . add ( t2 =new TextField (" 10 " )); p2 . add (new Label (" Anzahl der Minen " )); p2 . add ( t3 =new TextField (" 10 " )); p2 . add (new Label (" maximale Spielzeit in Sekunden " )); p2 . add ( t4 =new TextField (" 60 " )); start . addActionListener (this); add (p2 , BorderLayout . NORTH ); add ( start , BorderLayout . SOUTH ); p1 = new Panel (); add (p1 , BorderLayout . CENTER ); } public void actionPerformed ( ActionEvent e) { if (e. getSource () == start ){ p1 . removeAll (); //setze parameter hoehe, breite hoehe = new Integer ( t1 . getText ()); breite = new Integer ( t2 . getText ()); minen = new Integer ( t3 . getText ()); Uhr uhr = new Uhr (new Integer ( t4 . getText ())); add (uhr , BorderLayout . EAST ); uhrThread = new Thread ( uhr ); uhrThread . start (); minenpos = new int[ minen ]; felder = new Feld [ breite * hoehe ]; scharf = new boolean[ minen ]; p1 . setLayout (new GridLayout ( breite , hoehe )); for(int i =0;i < breite * hoehe ; i ++) p1 . add ( felder [i ]=new Feld (i )); vermine (); p1 . repaint (); } } public int berechneMinen (int s ){ int summe = 0; int x = s% breite ; int y = s/ breite ; for(int i =0; i < minenpos . length ;i ++){ Lösung 13/ Seite 7 int minenx = minenpos [i ]% breite ; int mineny = minenpos [i ]/ breite ; if( Math . abs ( minenx -x) <2 && Math . abs ( mineny -y ) <2) summe ++; } return summe ; } public class Feld extends Panel { int x; boolean aufgedeckt = false; boolean scharf = true; boolean markiert = false; boolean explodiert , gameOver = false; public void verdecke (int s ){ int xKoor = s% breite ; int yKoor = s/ breite ; for (int i = Math . max (0 , xKoor -1); i < Math . min ( xKoor +2 , breite ); i ++) { for (int j = Math . max (0 , yKoor -1); j < Math . min ( yKoor +2 , hoehe ); j ++) { if( felder [i+j* breite ]. aufgedeckt ){ punktestand -= berechneMinen (s ); felder [i+j* breite ]. aufgedeckt =false; } if(! felder [i+j* breite ]. scharf ){ punktestand -= 5; felder [i+j* breite ]. scharf =true; } if( felder [i+j* breite ]. markiert ){ punktestand -= 5; felder [i+j* breite ]. markiert =false; } } } } public void explodiere (){ if(! scharf ) return; aufgedeckt = true; explodiert = true; verdecke (x ); repaint (); } public void endExplosion (){ for(int i =0; i < minen ;i ++) felder [ minenpos [i ]]. explodiert =true; getParent (). repaint (); } public Feld (int x ){ this.x=x; addMouseListener (new MouseAdapter (){ public void mouseClicked ( MouseEvent e ){ if(e. getButton () == MouseEvent . BUTTON3 ) markiere (); else aufdecken (); Lösung 13/ Seite 8 } }); } public void markiere (){ for(int i =0;i < minen ;i ++){ if( minenpos [i ]== x ){ punktestand +=10; scharf = false; } } markiert = true; repaint (); } public void aufdecken (){ aufgedeckt = true; for(int i =0;i < minen ;i ++){ if( minenpos [i ]== x ){ explodiert = true; gameOver = true; } } punktestand += berechneMinen (x ); repaint (); } public void paint ( Graphics g ){ g. drawRect (0 ,0 , g. getClipBounds (). width , g. getClipBounds (). height ); if( gameOver ){ endExplosion (); uhrThread = null; //uhrThread.stop(); p1 . removeAll (); p1 . add (new Label (" Game over " )); } if( aufgedeckt ) { g. drawString (""+ berechneMinen (x), getBounds (). width /2 , getBounds (). height /2) } if((! scharf ) || markiert ){ if( att != null) g. drawImage (att , getBounds (). width /2 , getBounds (). height /2 , g } if( explodiert ){ if( bomb != null)g. drawImage ( bomb , getBounds (). width /4 , getBounds (). height /4 , getBounds (). width /2 , getBounds (). height /2 ,this); } } } }