Telefonboken Objektorienterad programmering Föreläsning 4 Telefonboken, igen. Telefonboken igen, en bättre version Tre klasser Vi bygger upp programmet av tre klasser: Entry, SimplePhoneBook och Main Klassen Entry Tvådimensionella fält. Exempel: femtonspelet. Instanser av Entry innehåller två strängar, ett namn och ett telefonnummer. Förutom konstrueraren finns två metoder: Modellklassen. Ett textbaserat program. Ett grafiskt program. public String getName() public String getNumber() Telefonboken Klassen SimplePhoneBook Själva telefonboken; innehåller ett fält av Entry-objekt. Metoder är public void put(String name, String phoneNr) public String get(String name) Endast en instans skapas. Klassen Main Klassen innehåller main, som sköter dialogen med användaren. Telefonboken En jämförelse Klassen SimplePhoneBook public class SimplePhoneBook { public class SimplePhoneBook { private Entry[] book; private int count; private Entry[] book; private int count; public static void main(String [] args) { Entry[] book = new Entry[100]; int count = 0; public SimplePhoneBook(int size) { book = new Entry[size]; count = 0; } Scanner in = new Scanner(System.in); prompt(); while(in.hasNext()) { String cmd = in.next(); if (cmd.equals("quit")) System.exit(0); else if (cmd.equals("put")) { String name = in.next(); String nr = in.next(); book[count] = new Entry(name,nr); count++; } else if (cmd.equals("get")) { String name = in.next(); for (int i=0; i<count;i++) if (name.equals(book[i].getName())) { System.out.println("Number is " + book[i].getNumber()); } } else System.out.println("Unknown command"); prompt(); } public SimplePhoneBook(int size) { book = new Entry[size]; count = 0; } public void put(String name, String nr) { book[count] = new Entry(name,nr); count++; } public String get(String name) { for(int i=0; i<count; i++) if (name.equals(book[i].getName())) return book[i].getNumber(); return null; } } public void put(String name, String nr) { book[count] = new Entry(name,nr); count++; } public String get(String name) { for(int i=0; i<count; i++) if (name.equals(book[i].getName())) return book[i].getNumber(); return null; } } public static voi Entry[] book int count = 0 Scanner in = prompt(); while(in.hasN String cm if (cmd.e Syste else if ( Strin Strin book[ count } else if ( Strin for ( i } } else Syste prompt(); } Telefonboken Telefonboken, återstående problem 2-dim fält Tvådimensionella fält Matriser i Java Problemet Om samma namn sätts in igen med nytt nummer, placeras denna Entry sist och det tidigare finns kvar. En matris representeras i Java som ett fält av rader, där varje rad är ett fält av tal. Till skillnad från i matten indexerar vi alltid med början från 0. Sökning ger bara det först insatta numret. Förslag till lösning 3 7 4 2 Ny insättning med samma namn ska ersätta det gamla numret. I metoden put måste vi därför börja med att se om namnet finns. 5 0 6 4 0 7 2 En sådan version (med en privat hjälpmetod getIndex) finns i lect4code.zip. . Raden a[1] 1 Elementet a[2][1] a har typen int[][]. Rita en bild över hur det ser ut i minnet! 2-dim fält 2-dim fält Att skapa matriser Att iterera över en matris Exempel Matrisen på föregående bild kan deklareras och skapas på ett av följande två sätt: Med många tilldelningar: int[][] a = new int[3][4]; a[0][0] = 3; a[0][1] = 7; ... alla element tilldelas ... a[2][3] = 1; Nollställning av alla element for (int i=0; i< a.length; i++) { for (int j=0; j < a[0].length; j++) { a[i][j] = 0; } } En sådan nästad for-sats är mycket vanlig när man arbetar med matriser. Med initieringsuttryck: Exempel int[][] a = {{3,7,4,2}, {5,0,6,4}, {0,7,2,1}}; Definiera en funktion som beräknar summan av alla element i en matris. 2-dim fält Mera linjär algebra 15-spelet Exempel: Femtonspelet Fysiskt spel Klassen LinearAlgebra Förra veckan definierade vi två funktioner double scalarProduct(double[] a, double[] b); double[] vectorSum(double[] a, double[] b); Grafisk variant i Java Lägg till en funktion som multiplicerar en matris med en (kolonn-)vektor. 15-spelet En första analys Spelets tillstånd Läget (tillståndet) i spelet kan representeras med en 4x4-matris av heltal, som innehåller talen 0–15 (0 representerar hålet). Ett drag innebär att talet 0 i matrisen byter plats med en granne (dvs något av talen över, under, till vänster eller till höger). Textbaserad variant i Java lect4code> java TextMain 1 54 d36b af67 9e2c Position of piece to move: 1 1 1354 d 6b af67 9e2c Position of piece to move: 1 2 1354 d6 b af67 9e2c Position of piece to move: 15-spelet Skiss till tänkbar lösning public class Fifteen { public static void main(String[] args) { int[][] state = new int[4][4]; for (int r=0; r<4; r++) for (int c=0; c<4; c++) state[r][c] = 4*r+c+1; state[3][3] = 0; Den textbaserade main-rutinen // Blanda slumpmässigt Vi behöver göra följande: Initiera spelmatrisen slumpmässigt. Om och om igen: - Skriv ut matrisen på lämplig form. - Läs in användarens drag. - Uppdatera matrisen med detta drag. while(true) { // Skriv ut tillståndet // Läs in användarens drag // Om draget är tillåtet, uppdatera tillståndet } } 15-spelet 15-spelet Att läsa in användarens drag ... Scanner in = new Scanner(System.in); while(true) { // Skriv ut tillståndet System.out.print("Position of piece to move: "); int row = in.nextInt(); int col = in.nextInt(); if // (row,col) granne med hålet // byt plats på hålet och talet i (row,col) else System.out.println("Cannot move piece!"); } 15-spelet Att skriva ut tillståndet for (int r=0; r<4; r++) { for (int c=0; c<4; c++) { int n = state[r][c]; if (n==0) System.out.print(" "); else if (n<=9) System.out.print(n); else // Om n=10, skriv "a", om n=11, skriv "b",... } System.out.println(); } 15-spelet Vad återstår? Delar som hittills bara är kommentarer Blanda slumpmässigt. Avgör om användarens valda bit är granne med hålet. Byt plats på den valda biten och hålet. Utskrift av bitarna 10–15. Förbättring: en objektorienterad design Vi lagrar matrisen state som tillstånd i en modellklass FifteenModel, som erbjuder endast följande metoder, förutom konstrueraren: public void shuffle(); public boolean tryMovePieceAt(int row, int col); public int getState(int row, int col); Textbaserat vs grafiskt program Det textbaserade programmet Programmet består av två klasser, FifteenModel och TextMain. Den senare innehåller main-rutinen och en hjälprutin för utskrift. Det grafiska programmet Vi kan idag inte förstå detta program fullständigt, men titta på det; strukturen återkommer gång på gång! Programmet består av fyra klasser: Samma modellklass FifteenModel. En grafisk klass FifteenPanel, för att rita upp spelet på skärmen. En styrklass FifteenListener, som beskriver hur programmet ska reagera på användarens mustryck. Klassen GraphicsMain, som innehåller main-rutinen. 15-spelet 15-spelet De två main-rutinerna Härnäst Det textbaserade programmet Labb 3 I labb 3 ska vi betrakta ett program som implementerar Game of Life, en simulering av en population celler som följer enkla regler. I main skapas och blandas ett modellobjekt. Sedan startar main en loop där man i varje varv skriver ut modellen, begär en position av användaren, samt uppdaterar modellen om positionen är OK. (med Ctrl-C). Programmet är grafiskt och händelsestyrt, består av fyra klasser, varav en modellklass – och det är den ni ska skriva. Titta gärna på de övriga klasserna, främst för att förstå modellklassens roll i programmet. Ni behöver inte förstå dessa klasser i detalj! Det grafiska programmet Nästa veckas övning I main skapas och blandas ett modellobjekt. Dessutom skapas ett panelobjekt och ett grafiskt fönster (av klassen JFrame). I panelobjektets konstruerare skapas ett styrobjekt. Panelen placeras i fönstret som görs synligt på skärmen. Därefter tar main slut – men inte programmet! Det väntar för evigt på händelser (användarens musklick). Vi övar på att definiera enkla klasser som mallar. main (och därmed programmet) fortsätter tills det avbryts av användaren Slutkommentar Vi befinner oss nu på förvirringsmaximum – de flesta nya begrepp har introducerats men inte hunnit smältas. En stor del av resterande tid används för konsolidering.