Malmo4444 Skrevet 8. mars 2012 Del Skrevet 8. mars 2012 (endret) Hei, driver med en innlevering som omhandler spillet Sokoban. Jeg skal legge til muligheten for å undo ett eller flere flytt. Slik jeg vil løse oppgaven er å bruke en stack som legger til en kopi av spillbrettet, slik at når brukeren bruker "undo" så vil den bruke .pop() for å hente det forrige mappet. Men her kommer problemet, Java har ingen mulighet for å lage en kopi av objekter slik jeg vil uten videre..Så det er her jeg trenger litt hjelp fra dere som har litt mer kontroll i Java enn meg:) http://pastebin.com/4grixkDv Level (logikken) http://pastebin.com/U3LGyjN7 ConsoleSokoban (grafikken) Setter stor pris på all tips og hjelp:) edit: typo Endret 8. mars 2012 av Malmo4444 Lenke til kommentar
konduktans Skrevet 8. mars 2012 Del Skrevet 8. mars 2012 Det hjelper nok ikke stort, men jeg mener å huske at det er ganske komplisert å kopiere et objekt. Du får skrive på nytt i python, så er det enklere å kopiere :-P Lenke til kommentar
Kiff Skrevet 9. mars 2012 Del Skrevet 9. mars 2012 (endret) Det er vel tre måter å gjøre det på, du må uantsett skrive logikken for det selv En copy constructor En Factory Object.clone() Edit: vær forsiktig med å bruke .clone() Endret 9. mars 2012 av Kiff Lenke til kommentar
Kiff Skrevet 9. mars 2012 Del Skrevet 9. mars 2012 (endret) Du kan også serialisere objektene og lagre byte arrayet (evt også til disk hvis du vil persistere mellom kjøringer). Husk isåfall å implementere Serializable i klassen som skal serialiseres. import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class ObjectSerializer { public Serializable bytesToObject(byte[] input) { ByteArrayInputStream bais = new ByteArrayInputStream(input); ObjectInputStream ois = null; try { ois = new ObjectInputStream(bais); return (Serializable) ois.readObject(); } catch (IOException e) { // TODO Handle e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { } } } return null; } public byte[] objectToBytes(Serializable input) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(baos); oos.writeObject(input); } catch (IOException e) { // TODO Handle e.printStackTrace(); } finally { if (oos != null) { try { oos.close(); } catch (IOException e) { } } } return baos.toByteArray(); } } Endret 9. mars 2012 av Kiff Lenke til kommentar
Malmo4444 Skrevet 9. mars 2012 Forfatter Del Skrevet 9. mars 2012 Det er vel tre måter å gjøre det på, du må uantsett skrive logikken for det selv En copy constructor En Factory Object.clone() Edit: vær forsiktig med å bruke .clone() public Test(Test other) { this.level = other.level; this.playerX = other.getPlayerX(); this.playerY = other.getPlayerY(); this.targetY = other.targetY; this.targetX = other.targetX; // this.undoStack = other.undoStack; } Nå prøvde jeg å lage en copy constructor. Men når jeg kjører koden så printer den fortsatt ut det samme map'et (som skal visse forrige move).. Håper du kan hjelpe meg med å se hva jeg gjør feil og ikke forstår:) takk:) Lenke til kommentar
javanuben Skrevet 9. mars 2012 Del Skrevet 9. mars 2012 Kanskje ikke akkurat det du spør om, men det finnes andre måter i implementere undo på, som er mye mer effektiv. Hvis du f.eks. bare lagrer bevegelsesretning og om du dyttet på noe, så er det smal sak å "reversere" brettet til slik det var før forrige trekk (tastetrykk). Lenke til kommentar
Kiff Skrevet 9. mars 2012 Del Skrevet 9. mars 2012 (endret) Lag en ny Map og bruk Map.putAll(Map), ellers har du to referanser til samme objekt: public static void main(String[] args) { Map<String, String> map1 = new HashMap<String, String>(); map1.put("a", "b"); Map<String, String> firstCopy = map1; Map<String, String> secondCopy = new HashMap<String, String>(); secondCopy.putAll(map1); map1.put("c", "d"); System.out.println(map1.values().size() == firstCopy.values().size()); //^ true, begge peker på samme map System.out.println(map1.values().size() == secondCopy.values().size()); //^ false } Endret 9. mars 2012 av Kiff Lenke til kommentar
Matsemann Skrevet 10. mars 2012 Del Skrevet 10. mars 2012 Gjør som javanuben sier. Poenget med denne oppgaven er at du skal huske hvilke trekk som har blitt gjort, og så kjøre de baklengs. Ikke lagre hver eneste gamestate. Lenke til kommentar
Patton Skrevet 14. mars 2012 Del Skrevet 14. mars 2012 Kanskje ikke akkurat det du spør om, men det finnes andre måter i implementere undo på, som er mye mer effektiv. Hvis du f.eks. bare lagrer bevegelsesretning og om du dyttet på noe, så er det smal sak å "reversere" brettet til slik det var før forrige trekk (tastetrykk). Jepp, du bør sjekke ut "Command pattern", og kapsle hvert trekk inn i eget command objekt, med metoden execute() for å utføre trekket, og undo() for å reversere trekket. Hver gang du gjør et trekk, lag et "Trekk-Objekt", utfør objektets execute(), og føy "Trekk-Objektet" til en command-liste. Hver gang du bruker ønsker å bruke undo(), så henter du siste objektet i command-listen, utfører undo() på "Trekk-objektet" og fjerner det fra listen. 1 Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå