Lunds universitet FYTA11 Institutionen för Teoretisk fysik HT 11 Tentamen FYTA11 Javaprogrammering Måndag 9:e januari 2012, 10:15 14:15 Instruktioner Hjälpmedel: enkla ritverktyg och Javadoc-genererade referensblad som delas ut med tentan. Behandla högst en uppgift per papper och sätt ditt namn på varje papper. Skriv läsligt och kommentera utförligt vad du gör det kan ge dig poäng även om resultatet blir fel. Tentamen omfattar fyra uppgifter som vardera kan ge upp till tio poäng. Uppgift 1: Korrigera felen i följande kodsnuttar där felens natur anges av kommentarer i koden. I de fall det rör sig om kompileringsfel så genererades felet av raden ovanför kommentaren. a. double x = 1/7; //sätter x till 0 istället för 1/7 b. c. d. e. public static int sum(int a[]) { int s = 0; for(int i = 1; i < a.length; ++i) s += a[i]; return s; //Metoden skall returnera summan av alla element i fältet a, men den ger fel resultat. public static char upcase(char ch) { if(ch >= a && ch <= z ) return ch - a + A ; //Kompileringsfel: possible loss of precision return ch; string str = "Poof\n"; // symbol : class string do { boolean b = Math.random() < 0.5; while(b); // symbol : variable b
f. interface A { public double f(double x); class B extends A { //Kompileringsfel: no interface expected here public double f(double x) {return Math.sin(x); public double g(double x) {return Math.cos(x); g. h. java.util.vector<int> vec; // symbol : class Int class U { public Short getid() {return 0; class V extends U { public short getid() {return 1; //Kompileringsfel: getid() in V cannot override getid() in U; // attempting to use incompatible return type i. j. final int N = 20; double s = 0; for(int i = 1; i < N; ++i) for(int j = 1; j < N; ++i) s += i*i*j; //Programmet hänger sig public static Double getmultiplier() {return 4; //Kompileringsfel: incompatible types
Uppgift 2: Spelare i en labyrint Klassen Labyrinth nedan representerar en labyrint på ett rutnät med storleken width height. Varje ruta kan antingen vara tom, ha en spelare eller utgöra ett hinder. Rutornas tillstånd lagras i state. För en tom ruta är state[x][y] en null-referens. För icke-tomma rutor anger state[x][y].isplayer() om det står en spelare på rutan, och state[x][y].isblocking() anger om det står ett hinder på rutan. Fältet playerpos anger xy-koordinaterna för spelarna och skall hållas uppdaterat så att playerpos[state[x][y].index()] anger positionen (x, y) för varje ruta där en spelare står. Metoden step försöker flytta spelaren med index player i riktningen d. Din uppgift är att fylla i step-metoden så att den uppfyller följande villkor. Om spelarens nya position faller utanför labyrinten eller hamnar på ett hinder, så skall metoden returnera false utan att ändra labyrintens tillstånd. Om spelarens nya position faller på en tom ruta, så skall den aktuella spelaren flyttas dit och metoden skall returnera true. Om det står en annan spelare på den flyttande spelarens nya position, så skall de båda spelarna byta plats och metoden skall returnera true. public class Labyrinth { private int width; private int height; private Item state[][]; private Pos playerpos[]; public static class Pos { public Pos(int x, int y) {this.x = x; this.y = y; public int x; public int y; public static interface Item { public boolean isplayer(); public boolean isblocking(); public int index(); public char getsymbol(); public boolean step(int player, Direction d) { Pos p0 = playerpos[player]; Pos p1 = new Pos(p0.x + d.x(), p0.y + d.y()); public enum Direction { NORTH(0, -1), SOUTH(0, 1), EAST(1, 0), WEST(-1, 0); private int stepx, stepy; Direction(int sx, int sy) {stepx = sx; stepy = sy; public int x() {return stepx; public int y() {return stepy;
Uppgift 3: Lösbarhet och vinst Ett antal spelare befinner sig i en labyrint och deras utmaning består i att finna varandra och samlas i en grupp. Din uppgift består i att skriva en konstruktor till Labyrinth-klassen, att definiera den inre klassen Labyrinth.NoSolution och att lägga till en metod issolved(). Metoderna resize, randomize och playersgrouped antas vara fullt implementerade och du får anropa dessa från din kod. Konstruktorn skall skapa en ny labyrint med spelare utplacerade. Labyrintens bredd och höjd samt antalet spelare skall anges som argument till konstruktorn. Konstruktorn skall anropa metoden hassolution() för att se om labyrinten är lösbar. Om lösning saknas, så skall ett undantag kastas. Detta undantag skall vara av den egendefinierade typen Labyrinth.NoSolution som ärver av Exception. Metoden issolved() skall returnera true om alla spelare är samlade så att de fyller ett sammanhängande område av angränsande rutor. Utgå från implementationen av hassolution() och gör smärre ändringar. public class Labyrinth { //Se koden i föregående uppgift * Sets the size of this Labyrinth to w times h and clears the * labyrinth state. All players and blocks are removed. */ public void resize(int w, int h) { * Places blocks in this Labyrint to form a maze and adds n * players at random locations. */ public void randomize(int n) { public int nplayers() {return playerpos.length; public static interface GroupCondition { public boolean test(item it); * Returns true if all players are found on one continous patch of * neighbouring squares that all satisfy cond.test(state[x][y]). */ public boolean playersgrouped(groupcondition cond) { Returns true if all players can meet in the labyrinth. */ public boolean hassolution() { if(state == null playerpos == null nplayers() < 2) return false; return playersgrouped(new GroupCondition() { public boolean test(item it) { return it == null!it.isblocking(); );
Uppgift 4: Hantera tangenttryckningar Ett enkelt grafiskt program skrivs för att testa Labyrinth-klassen från föregånde uppgifter. Din uppgift består i att hantera tangenttryckningar med hjälp av en anonym KeyAdapter-klass. I testet kan man välja spelare med siffertangenterna och flytta den valda spelaren med piltangenterna. En tryckning på en siffertangent 0 till 9 skall välja spelaren med aktuellt index under förutsättning att detta index är mindre än nplayers() för labyrinten. En tryckning på en piltangent skall ge ett lämpligt anrop till step-metoden i uppgift 2 för den valda spelaren. Metoden repaint() skall anropas varje gång någon spelare genomför en förflyttning i labyrinten. Om förflyttningen leder till att issolved() blir sann för labyrinten, så skall den egendefinierade metoden mazesolved() anropas. Metoden mazesolved() skall implementeras så att den visar en dialogruta med meddelandet Labyrinten är besegrad!. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MazeCanvas extends Canvas { private Labyrinth maze; private int x0, y0; //pixel coordinates of upper left corner of the grid private int side; //side of a tile static private final int prefside = 32; //default cell size in pixels static private final int minside = 16; //minimum cell size in pixels static private final int padding = 2; //minimum padding around grid //in half cell units static private final int preffontsize = 16; //default font size in pixels public MazeCanvas(int w, int h, int n) throws Labyrinth.NoSolution { maze = new Labyrinth(w, h, n); setminimumsize(new Dimension(minSide*(w + padding), minside*(h + padding))); setpreferredsize(new Dimension(prefSide*(w + padding), prefside*(h + padding))); addkeylistener(new KeyAdapter() { ); public void paint(graphics g) {