/* * KkkgPro.java v1 * a Kincskereső Kisgömböc játék prototípusa. JDK1.1 application * mainly by pts@fazekas.hu at Sun Apr 22 18:45:17 CEST 2001 * további doksi: a README-ben és e file legkülső class-ának fejkommentjében * * Kincskereső Kisgömböc (C) Early May 2001 by eNTitánok (Rév Szilvia, * Szabó Péter <pts@inf.bme.hu>, Szurdi Miklós, Weizengruber Attila). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* A grafikához erősen kötődő, a prototípusban nem megvalósítandó részeket * kikommenteztem `perjel *-*-' és `* perjel' közé. Néhány, a kirajzolást * végző objektumot az eNTitanok.fake package adapter-jellegű objektumaival * helyettesítettem. */ // by pts@fazekas.hu at 2001.04.26 [e filemeret ma lepte tul a 100k-t :-)] // by pts@fazekas.hu at 2001.04.22 [tul 2 db zh-n] // by pts@fazekas.hu at 2001.03.01 [uristen, mar marcius van??] // by pts@fazekas.hu at 2001.03.03 // by pts@fazekas.hu at 2001.03.09 [tok jo, otos lett a digit szigorlat] // by pts@fazekas.hu at 2001.03.15 [nemzeti ünnep, megnéztem A költő visszatér-t (1988)] // by pts@fazekas.hu at 2001.03.16 [23:15: össze lehet szedni a gyémántokat] package eNTitanok.kkkg; import java.util.Hashtable; import java.util.Vector; import java.util.Calendar; // import eNTitanok.util.Idozito; // import eNTitanok.util.Idozito.Idozitett; import eNTitanok.util.Rgb; import eNTitanok.util.Util; import eNTitanok.util.Veletlen; import eNTitanok.util.Sor; import eNTitanok.util.SorOlvaso; import eNTitanok.kkkg.Csucslista; // import java.awt.Graphics; // import java.awt.GridLayout; // import java.awt.FlowLayout; // import java.awt.Color; // import java.awt.Frame; // // ^^^ menüsorral, kerettel rendelkező _ablak_. Csak Application-ként futva // // használjuk // import java.awt.event.MouseAdapter; // import java.awt.event.KeyAdapter; // import java.awt.event.FocusAdapter; // import java.awt.event.WindowAdapter; // import java.awt.event.MouseListener; // import java.awt.event.KeyListener; // import java.awt.event.FocusListener; // import java.awt.event.WindowListener; // import eNTitanok.gfx.Kepek; // import eNTitanok.gfx.Kepek.Kep; // import eNTitanok.gfx.Kepek.Kepbetolto; // import eNTitanok.gfx.Kepek.Sdpts; // import eNTitanok.gfx.Kepek.Utkozteto; // import eNTitanok.gfx.Kepek.Betutipus; // import eNTitanok.gfx.Kepek.SdRajzolo; import eNTitanok.fake.Kepek.Kep; import eNTitanok.fake.Kepek.Kepbetolto; import eNTitanok.fake.Kepek.SdRajzolo; import eNTitanok.fake.Kepek.Sdpts; import eNTitanok.fake.Kepek; import eNTitanok.fake.Applet; import eNTitanok.fake.Graphics; import eNTitanok.fake.Idozito.Idozitett; import eNTitanok.fake.Idozito; import java.io.InputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.PrintWriter; // prefer to java.io.PrintStream import java.io.IOException; /** * A Kicskereső Kisgömböc játék prototípusa. JDK1.1 application */ public final class KkkgPro extends Applet { public static class HibasAllapotException extends Error {} public static class AtmeretezesNemSikerultException extends Error {} /** * Akkor váltódik ki, ha egy objektum olyan attribútumát akarjuk * megváltoztatni, melyet csak egyszer szabad. */ public static class MarErtekesError extends Error { public MarErtekesError(String s) { super(s); } public MarErtekesError() { super(); } } /** * Akkor váltódik ki, ha a program futás közben bugot talál magában. */ public static class AsserttError extends Error { public AsserttError(String s) { super(s); } public AsserttError() { super(); } } public static class Konst { /** * D_*: A .gif-ekben szereplő RGB konstansok. A prototípusban azért van * rájuk szükség, mert a tesztfile-ban levő pályaleírást egy RGB képpé * alakítjuk, majd abból építjük fel a labirintust. */ public static final int D_FAL=Rgb.C_FEKETE; public static final int D_UT=Rgb.C_FEHER; public static final int D_GYEMANT=Rgb.C_PIROS; public static final int D_AJANDEK=Rgb.C_SARGA; // keletkezési hely public static final int D_SZORNY=Rgb.C_ZOLD; // keletkezési hely public static final int D_MEROPONT=Rgb.C_KEK; public static final int D_KOMMENT=Rgb.C_LILA; public static final int D_KISGOMBOC=Rgb.C_TURKIZ; /** * K_*: A tesztfile-ban szereplő karakterek konstansai. * Minden, amit nem soroltunk fel (beleértve a szóközt), * K_FAL-nak minősül. */ public static final char K_FAL='F'; public static final char K_UT='.'; public static final char K_GYEMANT='g'; public static final char K_AJANDEK='a'; public static final char K_SZORNY='s'; public static final char K_KISGOMBOC='k'; public static final char K_MEROPONT='p'; /** * Egy K_* konstanst alakít a megfelelő D_* konstansba. */ public static int k2d(char k) { return k==K_UT ? D_UT : k==K_GYEMANT ? D_GYEMANT : k==K_AJANDEK ? D_AJANDEK : k==K_SZORNY ? D_SZORNY : k==K_KISGOMBOC ? D_KISGOMBOC : k==K_MEROPONT ? D_MEROPONT : D_FAL ; } } /// class Konst /** * Az őt implementáló objektum string-eket tud naplózni. */ public interface Naplozo { public void naploz(String sor); } /** * A :Kísérő egyetlen példánya program futását végigkíséri, több játékot * is. Itt tárolódnak a véletlenszám-generátorok, az ütközésvizsgálók * engedélyező bitjei stb. A :Kísérő ezen implementációja főleg a * prototípushoz és nem az egész * projecthez tartozik. A végleges változatban a :Kiésérő ugyanezekkel az * attribútumokkal és metódusokkal fog bírni, viszont az implementáció * teljesen más lesz. */ public static class Kisero extends Thread implements Naplozo { /** * A prototípus futásának egyik lehetséges kimenetele. */ public static class HibasBemenetError extends Error { public HibasBemenetError(String s) { super(s); } } /** * A prototípus futásának egyik másik lehetséges kimenetele. Ugyanezzel * egyenértékű, ha valami váratlan, általános kivétel lép fel. */ public static class VegzetesError extends Error { public VegzetesError(String s) { super(s); } } /** * A prototípus futásának harmadik lehetséges kimenetele. */ public static class MeghiusultError extends Error { public MeghiusultError(String s) { super(s); } } /** * A prototípus futásának negyedik lehetséges kimenetele. */ public static class SikerultError extends Error { public SikerultError(String s) { super(s); } } /** * Ebbe a file-ba mentjük el a :Csúcslistát. `null' esetén egyáltalán nem * mentjük el (ez történik a prototípusban). */ // public static final String CSUCSLISTA_FILENEV="kkkg.csl"; public static final String CSUCSLISTA_FILENEV=null; /** * A :Csúcslista. */ public Csucslista csucslista=Csucslista.betolt(CSUCSLISTA_FILENEV); /** * Ez a program futása során már nem változik. */ public Labirintus.LabirintusRajzolo labirintusRajzolo; /** * Ez a program futása során már nem változik. */ public JobboldalRajzolo jobboldalRajzolo; /** * Ez a program futása során már nem változik. */ public Kepbetolto kepbetolto; /** * Ez a program futása során már nem változik. */ public Idozitett idozitett; /** * Hányadik ciklusban járunk? Ez néha nullázódik (pl. új Labirintus * betöltésekor). */ int ciklus=0; /** * Pontosan akkor `true', ha ezeddig még nem derült ki, hogy a teszt * meghiúsult. */ public boolean sikerult=true; /** * Pontosan akkor true, ha nem generálunk valódi véletlenszámokat, hanem * mindent a tesztfile-ból veszünk. */ public boolean csakDet=true; /** * Pontosan akkor true, ha a megfelelő ütközést figyeljük. */ public boolean Kisgomboc_Ajandek=true; /** * Pontosan akkor true, ha a megfelelő ütközést figyeljük. */ public boolean Kisgomboc_Szorny=true; /** * Pontosan akkor true, ha a megfelelő ütközést figyeljük. */ public boolean Kisgomboc_Gyemant=true; /** * Pontosan akkor true, ha a megfelelő ütközést figyeljük. */ public boolean Kisgomboc_KetyegoBomba=true; /** * Pontosan akkor true, ha a megfelelő ütközést figyeljük. */ public boolean Szorny_KetyegoBomba=true; /** * A prototípus tesztfile-jának a neve. */ public String teszt; /** * A prototípus naplófile-jának a neve. */ public String naplo; /** * A prototípus ellenörzőfile-jának a neve. */ public String ellenorzo; /** * A prototípus tesztfile-ja olvasásra megnyitva. */ protected SorOlvaso tesztf; /** * A prototípus naplófile-ja írásra megnyitva. */ protected PrintWriter naplof; /** * A prototípus ellenörzőfile-ja írásra megnyitva. */ protected PrintWriter ellenorzof; /** * A `palya' egyetlen karakterének ,,mérete'', pixelben. */ public static final int KOCKAMERET=25; /** * A labirintussor egyetlen eleme. Azért nem `static', hogy a csakDet * látszódjon. */ public class Labielem { /** * String-ekből álló Sor, lényegében a tesztfile-ban leírt labirintus * sorai. Soremelés-karakter nélkül. */ protected Sor palya=new Sor(); /** * Milyen hosszú a `palya' leghosszabb sora? */ protected int palyaMaxx=0; /** * Új sort vesz fel `palya' végére. */ public void vegehezRak(String s) { if (s.length()>palyaMaxx) palyaMaxx=s.length(); palya.vegehezFuz(s); } /** * Egy RGB színmodellű képtömböt ad vissza a pályáról (úgy, mintha * .gif-ből töltöttük volna). A `t[y][x]' érték az adott * pont (R<<16)+(G<<8)+B értéke, ahol a komponensek 0..255-ig futnak. * Mellékhatásként kiüríti `palya'-t. */ public synchronized int[][] getPix() { if (palya.length()<1 || palyaMaxx<0) throw new HibasBemenetError("palya tul kicsi"); // !! Imp: chk for s,a,k,?? int h=(palya.length()+2)*KOCKAMERET+1; int w=(palyaMaxx+2)*KOCKAMERET+1; char c[]=new char[palyaMaxx]; int t[][]=new int[h][]; int x, y; for (y=h-1;y>=0;y--) t[y]=new int[w]; // ^^^ mindenki 0-s, vagyis Konst.D_FAL int alap=KOCKAMERET; String sor1; int i, k; y=alap; for (y=alap;null!=(sor1=(String)palya.elsoTorol());y+=KOCKAMERET) { sor1.getChars(0,sor1.length(),c,0); for (i=sor1.length();i<c.length;i++) c[i]=Konst.K_FAL; int u[]=t[y]; x=alap; for (i=0;i<c.length;i++) { // System.out.println(w-x); if ((u[x]=Konst.k2d(c[i]))!=Konst.D_FAL) { if (u[x-KOCKAMERET]!=Konst.D_FAL) for (k=x-KOCKAMERET+1;k<x;k++) u[k]=Konst.D_UT; if (u[x+KOCKAMERET]!=Konst.D_FAL) for (k=x+KOCKAMERET-1;k>x;k--) u[k]=Konst.D_UT; if (t[y-KOCKAMERET][x]!=Konst.D_FAL) for (k=y-KOCKAMERET+1;k<y;k++) t[k][x]=Konst.D_UT; if (t[y+KOCKAMERET][x]!=Konst.D_FAL) for (k=y+KOCKAMERET-1;k>y;k--) t[k][x]=Konst.D_UT; } /// IF x+=KOCKAMERET; } /// NEXT i } /// NEXT y return t; } /// getPix() private int bonbomsimszu_alap[]= { 42, 42, 42, 42 }; /** * Milyen eloszlásban keletkezzenek az :Ajándék-ok? */ public Veletlen.Generalo bonbomsimszu=new Veletlen.Veges(null, csakDet, bonbomsimszu_alap); private int okosbutabaljobbbfjl_alap[]= { 28, 28, 28, 28, 28, 28 }; /** * Milyen eloszlásban keletkezzenek az :Szörny-ek? */ public Veletlen.Generalo okosbutabaljobbbfjl=new Veletlen.Veges(null, csakDet, okosbutabaljobbbfjl_alap); /** * Hányadik szinten járunk?. Csak tájékoztatásul, nem írjuk ki sehol. */ int szintszam=1; /** * Mikor keletkezzen a következő :Ajándék?. A véletlenszám relatív, * ciklusban mérendő. */ public Veletlen.Generalo ajandek=new Veletlen.Normalis(null, csakDet, 680, 760, 720, 20); /** * Mikor keletkezzen a következő :Szörny?. A véletlenszám relatív, * ciklusban mérendő. */ public Veletlen.Generalo szorny=new Veletlen.Normalis(null, csakDet, 680, 760, 720, 20); /** * Mekkora legyen a keletkező szörny sebessége? */ public Veletlen.Generalo szornyseb=new Veletlen.Normalis(null, csakDet, 20, 40, 30, 5); /** * Hol (melyik keletkezési helyen) keletkezzen :Ajándék? Ezt a :Labirintus * betöltésekor a megfelelő egyenletes eloszlásra állítjuk. */ public Veletlen.Egyenletes ajandekhol=new Veletlen.Egyenletes(null, csakDet, 0, 1); /** * A megadott ajándékhelyek számából előállítja a véletlenszám-generátort. */ public void ajandekholMeret(int meret) { ajandekhol.setB(meret); } /** * Hol (melyik keletkezési helyen) keletkezzen :Szörny? Ezt a :Labirintus * betöltésekor a megfelelő egyenletes eloszlásra állítjuk. */ public Veletlen.Egyenletes szornyhol=new Veletlen.Egyenletes(null, csakDet, 0, 1); /** * Merre forduljon a következő :Szörny a következő döntési helyzetben?. */ public Veletlen.Generalo fordul=new Veletlen.Egyenletes(null, csakDet, 0, 256); /** * A megadott szörnyhelyek számából előállítja a véletlenszám-generátort. */ public void szornyholMeret(int meret) { szornyhol.setB(meret); } } /// class Labielem /** * A labirintussor, :Labielem-ekből áll. * @see Labielem */ public Sor labirintussor=new Sor(); /** * Az ellenörzősor, String-ekből (sorokból) áll. */ public Sor ellenorzosor=new Sor(); /** * A megadott, a programkód mellett található erőforrásfile-t adja vissza. * @param eroforras / jelekkel elválasztott, kiterjesztéssel rendelkező, * relatív filenév. * @return <code>null</code>, ha nincs ilyen erőforrás */ public static InputStream getEroforrasStreamOf(ClassLoader classLoader, String eroforras) { return (classLoader==null)?ClassLoader.getSystemResourceAsStream(eroforras) :classLoader.getResourceAsStream(eroforras); } /** * Létrehozza a :Kísérőt, a megadott tesztfile nevét véve paraméternek. */ public Kisero(String teszt) { this.teszt=teszt; InputStream is=null; try { is=new FileInputStream(teszt); } catch (IOException e) { is=getEroforrasStreamOf(getClass().getClassLoader(), "eNTitanok/kkkg/t/"+teszt); if (is==null) throw new VegzetesError("IO: "+e.getMessage()); } tesztf=new SorOlvaso(is); } /// Kisero() /** * Kiírja a megadott sort a naplófile-ba, és azonnal ellenőrzi, hogy * megegyezik-e a várttal. A `sor' ne tartalmazzon soremelést. */ public synchronized void naploz(String sor) { if (naplof==null) throw new HibasBemenetError("`naplo' sor nem szerepelt"); sor=ciklus+" "+sor; naplof.println(sor); if (naplof.checkError()) throw new VegzetesError("IO: "+naplo); if (sikerult) { // még van remény, hogy a teszt sikerüljön String sor2=(String)ellenorzosor.elsoTorol(); if (sor2==null || !sor2.equals(sor)) sikerult=false; } } /// naploz() /** * Csakúgy, mint `this.naploz()', de minden hibát elhallgat, nem vált ki * kivételt. */ public void naplozHibatlan(String sor) { try { naploz(sor); } catch (Throwable e) {} } /// naploz() /** * Az időpont, amikor ez az objektum létrejött. */ Calendar calendar=Calendar.getInstance(); /** * A hátralevő olyan ciklusok száma, melyek során nem olvasunk a * tesztfile-ból. */ protected int hatra=0; public static final String FIGYELJUK="figyeljuk"; public static final String TITKOLJUK="titkoljuk"; /** * Egyetlen ciklust előrelép az időben. Közben olvassa a tesztfile-t, tölti * a sorokat stb. */ public void gyerunk() { ciklus++; while (hatra==0) { String sor; try { sor=tesztf.readLine(); } catch (IOException e) { throw new VegzetesError("IO: "+e.getMessage()); } // System.out.println(sor); if (null==sor) throw new HibasBemenetError("hianyzo `vege' utasitas"); int i=sor.indexOf(' '); if (i==-1) i=sor.length(); String utasitas=sor.substring(0,i); while (i<sor.length() && sor.charAt(i)==' ') i++; sor=sor.substring(i); String rosszpar="rossz parameter `"+utasitas+"' utasitasnak"; boolean sorszokoz=sor.indexOf(' ')!=-1; if (utasitas.equals("kell")) { if (ellenorzo==null) throw new HibasBemenetError("`ellenorzo' korabban szerepeljen"); ellenorzof.println(sor); if (ellenorzof.checkError()) throw new VegzetesError("IO: "+ellenorzo); ellenorzosor.vegehezFuz(sor); } else if (utasitas.equals("vege")) { naploz("vege"); if (sor.length()!=0) throw new HibasBemenetError(rosszpar); if (sikerult && ellenorzosor.isUres()) throw new SikerultError(""); // System.err.println(sikerult); throw new MeghiusultError(""); } else if (utasitas.equals("fordul")) { if (sor.length()!=1) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); char c=sor.charAt(0); if (c=='<') ((Labielem)labirintussor.utolso()).fordul.sorba(Csucs.BAL); else if (c=='>') ((Labielem)labirintussor.utolso()).fordul.sorba(Csucs.JOBB); else if (c=='^') ((Labielem)labirintussor.utolso()).fordul.sorba(Csucs.FEL); else if (c=='v') ((Labielem)labirintussor.utolso()).fordul.sorba(Csucs.LE); else throw new HibasBemenetError(rosszpar); } else if (utasitas.equals("leut")) { if (sor.length()!=1) throw new HibasBemenetError(rosszpar); if (jatek==null) throw new HibasBemenetError("`leut' kesobb szerepeljen"); char c=sor.charAt(0); if (c=='<') jatek.fordulj(Csucs.BAL); else if (c=='>') jatek.fordulj(Csucs.JOBB); else if (c=='^') jatek.fordulj(Csucs.FEL); else if (c=='v') jatek.fordulj(Csucs.LE); else if (c=='-') jatek.bombatLerak(); else if (c=='?') jatek.megallit(); else if (c=='!') jatek.lezar(); else jatek.hozzafuz(c); } else if (utasitas.equals("ciklus")) { try { hatra=Integer.parseInt(sor); if (hatra<0) throw new NumberFormatException(); } catch (NumberFormatException e) { throw new HibasBemenetError(rosszpar); } } else if (utasitas.equals("szintszam")) { int ia; try { ia=Integer.parseInt(sor); if (ia<0) throw new NumberFormatException(); } catch (NumberFormatException e) { throw new HibasBemenetError(rosszpar); } ((Labielem)labirintussor.utolso()).szintszam=ia; } else if (utasitas.equals("naplo")) { if (sor.length()<1 || sorszokoz) throw new HibasBemenetError(rosszpar); if (naplo!=null) throw new HibasBemenetError("`naplo' egyszer szerepeljen"); naplo=sor; try { naplof=new PrintWriter(new FileOutputStream(naplo)); } catch (IOException e) { throw new VegzetesError("IO: "+e.getMessage()); } naplof.println("#\n# naplofile "+naplo+"\n"+ "# (tesztfile "+teszt+")\n"+ "# generalva "+Util.mysqlDateFormat(calendar)+ "\n# ebbe kerul a program tenyleges futasi eredmenye\n#\n"); if (naplof.checkError()) throw new VegzetesError("IO: "+naplo); } else if (utasitas.equals("ellenorzo")) { if (sor.length()<1 || sorszokoz) throw new HibasBemenetError(rosszpar); if (ellenorzo!=null) throw new HibasBemenetError("`ellenorzo' egyszer szerepeljen"); ellenorzo=sor; try { ellenorzof=new PrintWriter(new FileOutputStream(ellenorzo)); } catch (IOException e) { throw new VegzetesError("IO: "+e.getMessage()); } ellenorzof.println("#\n# ellenorzofile "+ellenorzo+"\n"+ "# (tesztfile "+teszt+")\n"+ "# generalva "+Util.mysqlDateFormat(calendar)+ "\n# ebbe kerul a vart futasi eredmeny\n#\n"); if (ellenorzof.checkError()) throw new VegzetesError("IO: "+naplo); } else if (utasitas.equals("labirintus")) { if (sor.length()!=0) throw new HibasBemenetError(rosszpar); labirintussor.vegehezFuz(new Labielem()); } else if (utasitas.equals("palya")) { if (sor.length()<1 || sorszokoz) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); ((Labielem)labirintussor.utolso()).vegehezRak(sor); } else if (utasitas.equals("ajandek")) { int t[]=Util.szamokInt(sor); if (t.length!=2) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); ((Labielem)labirintussor.utolso()).ajandek=new Veletlen.Normalis(null, csakDet, t[0]-2*t[1], t[0]+2*t[1], t[0], t[1]); } else if (utasitas.equals("szorny")) { int t[]=Util.szamokInt(sor); if (t.length!=2) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); ((Labielem)labirintussor.utolso()).szorny=new Veletlen.Normalis(null, csakDet, t[0]-2*t[1], t[0]+2*t[1], t[0], t[1]); } else if (utasitas.equals("szornyseb")) { int t[]=Util.szamokInt(sor); if (t.length!=2) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); ((Labielem)labirintussor.utolso()).szornyseb=new Veletlen.Normalis(null, csakDet, t[0]-2*t[1], t[0]+2*t[1], t[0], t[1]); } else if (utasitas.equals("bonbomsimszu")) { int t[]=Util.szamokInt(sor); if (!Util.eloszlasp(t,4)) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); ((Labielem)labirintussor.utolso()).bonbomsimszu=new Veletlen.Veges(null, csakDet, t); } else if (utasitas.equals("okosbutabaljobbbfjl")) { int t[]=Util.szamokInt(sor); if (!Util.eloszlasp(t,6)) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); ((Labielem)labirintussor.utolso()).okosbutabaljobbbfjl=new Veletlen.Veges(null, csakDet, t); } else if (utasitas.equals("Bonusz")) { int t[]=Util.szamokInt(sor); if (t.length!=2) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.bonbomsimszu.sorba(0); le.ajandek.sorbaDelta(t[0]); le.ajandekhol.sorba(t[1]); } else if (utasitas.equals("FelvehetoBomba")) { int t[]=Util.szamokInt(sor); if (t.length!=2) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.bonbomsimszu.sorba(1); le.ajandek.sorbaDelta(t[0]); le.ajandekhol.sorba(t[1]); } else if (utasitas.equals("SimaElixir")) { int t[]=Util.szamokInt(sor); if (t.length!=2) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.bonbomsimszu.sorba(2); le.ajandek.sorbaDelta(t[0]); le.ajandekhol.sorba(t[1]); } else if (utasitas.equals("SzuperElixir")) { int t[]=Util.szamokInt(sor); if (t.length!=2) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.bonbomsimszu.sorba(3); le.ajandek.sorbaDelta(t[0]); le.ajandekhol.sorba(t[1]); } else if (utasitas.equals("OkosSzorny")) { int t[]=Util.szamokInt(sor); if (t.length!=3) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.okosbutabaljobbbfjl.sorba(0); le.szorny.sorbaDelta(t[0]); le.szornyhol.sorba(t[1]); le.szornyseb.sorba(t[2]); } else if (utasitas.equals("ButaSzorny")) { int t[]=Util.szamokInt(sor); if (t.length!=3) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.okosbutabaljobbbfjl.sorba(1); le.szorny.sorbaDelta(t[0]); le.szornyhol.sorba(t[1]); le.szornyseb.sorba(t[2]); } else if (utasitas.equals("BalraSzorny")) { int t[]=Util.szamokInt(sor); if (t.length!=3) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.okosbutabaljobbbfjl.sorba(2); le.szorny.sorbaDelta(t[0]); le.szornyhol.sorba(t[1]); le.szornyseb.sorba(t[2]); } else if (utasitas.equals("JobbraSzorny")) { int t[]=Util.szamokInt(sor); if (t.length!=3) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.okosbutabaljobbbfjl.sorba(3); le.szorny.sorbaDelta(t[0]); le.szornyhol.sorba(t[1]); le.szornyseb.sorba(t[2]); } else if (utasitas.equals("BalraFelSzorny")) { int t[]=Util.szamokInt(sor); if (t.length!=3) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.okosbutabaljobbbfjl.sorba(4); le.szorny.sorbaDelta(t[0]); le.szornyhol.sorba(t[1]); le.szornyseb.sorba(t[2]); } else if (utasitas.equals("JobbraLeSzorny")) { int t[]=Util.szamokInt(sor); if (t.length!=3) throw new HibasBemenetError(rosszpar); if (labirintussor.isUres()) throw new HibasBemenetError("`labirintus' korabban szerepeljen"); Labielem le=((Labielem)labirintussor.utolso()); le.okosbutabaljobbbfjl.sorba(5); le.szorny.sorbaDelta(t[0]); le.szornyhol.sorba(t[1]); le.szornyseb.sorba(t[2]); } else if (utasitas.equals("Kisgomboc-Ajandek")) { if (sor.equals(FIGYELJUK)) Kisgomboc_Ajandek=true; else if (sor.equals(TITKOLJUK)) Kisgomboc_Ajandek=false; else throw new HibasBemenetError(rosszpar); } else if (utasitas.equals("Kisgomboc-Szorny")) { if (sor.equals(FIGYELJUK)) Kisgomboc_Szorny=true; else if (sor.equals(TITKOLJUK)) Kisgomboc_Szorny=false; else throw new HibasBemenetError(rosszpar); } else if (utasitas.equals("Kisgomboc-Gyemant")) { if (sor.equals(FIGYELJUK)) Kisgomboc_Gyemant=true; else if (sor.equals(TITKOLJUK)) Kisgomboc_Gyemant=false; else throw new HibasBemenetError(rosszpar); } else if (utasitas.equals("Kisgomboc-KetyegoBomba")) { if (sor.equals(FIGYELJUK)) Kisgomboc_KetyegoBomba=true; else if (sor.equals(TITKOLJUK)) Kisgomboc_KetyegoBomba=false; else throw new HibasBemenetError(rosszpar); } else if (utasitas.equals("Szorny-KetyegoBomba")) { if (sor.equals(FIGYELJUK)) Szorny_KetyegoBomba=true; else if (sor.equals(TITKOLJUK)) Szorny_KetyegoBomba=false; else throw new HibasBemenetError(rosszpar); } else { throw new HibasBemenetError("ismeretlen utasitas: `"+utasitas+"'"); } /// IF } /// WHILE hatra--; } /// gyerunk() /** * Az aktuális :Játék. */ protected Jatek jatek; private static String vvh="varatlan vegzetes hiba"; /** * Ez fut a főszálban. */ public void run() { super.setPriority(Thread.MIN_PRIORITY); // ^^^ Dat: fontos az allando sebesseghez. Miert?? try { // gyerunk(); // ^^^ a tesztfile elejének beolvasása, első lépésre várás. Ez nem // kell külön, mert a Jatek.fut() elején rögtön megtesszük. while (true) { jatek=new Jatek(this); jatek.fut(); } } catch (Labirintus.HibasGrafError e) { System.out.println("hibas bemenet"); System.err.println("a megadott labirintusgraf hibas"); e.printStackTrace(System.err); } catch (HibasBemenetError e) { System.out.println("hibas bemenet"); e.printStackTrace(System.err); } catch (SikerultError e) { System.out.println("teszt sikerult"); } catch (MeghiusultError e) { System.out.println("teszt meghiusult"); sikerult=false; } catch (Veletlen.CsakDetException e) { System.out.println(vvh); System.out.println("tul keves veletlenszamot adtal meg"); naplozHibatlan(vvh); sikerult=false; e.printStackTrace(System.err); } catch (VegzetesError e) { System.out.println(vvh); naplozHibatlan(vvh); sikerult=false; e.printStackTrace(System.err); } catch (Throwable e) { System.out.println(vvh); naplozHibatlan(vvh); e.printStackTrace(System.err); sikerult=false; } System.exit(sikerult?0:1); } /// run() /** * A felhasználó által utoljára leütött billentyűt (betűt) adja vissza, * vagy 0-t, ha nem volt ilyen. */ public char utolsoBillentyu() { return 0; } } /// class Kisero public static class Csucs { /** * Hányadik mérőpont ez a csúcs?. Ha nem mérőpont, akkor -1. */ protected int meropont=-1; public int getMeropont() { return meropont; } public void setMeropont(int meropont) { if (this.meropont!=-1) throw new MarErtekesError(); this.meropont=meropont; } public static class NincsRajtaException extends Error {} public static class NemKothetoOsszeException extends Error {} public static final int LE=0, FEL=2, JOBB=1, BAL=3, PIHI=4, SEMERRE=5; /** * A négy szomszéd :Csúcs. */ protected Csucs szomsz[]; protected int x, y; /** * Milyen messza van innen a :Kisgömböc?. A lehető legrövidebb út * távolsága. */ protected int legkoztav; public void setTavolsag(int legkoztav) { this.legkoztav=legkoztav; } public int getTavolsag() { return legkoztav; } public Csucs(int x, int y) { this.x=x; this.y=y; szomsz=new Csucs[4]; } public Csucs getSzomsz(int merre) { return szomsz[merre]; } public Csucs getSzomsz0(int merre) { return szomsz[merre]!=null ? szomsz[merre]: this; } public int getX() { return x; } public int getY() { return y; } public void felold() { szomsz[FEL]=szomsz[LE]=szomsz[JOBB]=szomsz[BAL]=null; } public void osszekot(Csucs masik) { /* összeköti ezt a csúcsot egy másikkal */ if (masik.x==x) { if (masik.y<y) { szomsz[FEL]=masik; masik.szomsz[LE]=this; } else if (masik.y>y) { szomsz[LE]=masik; masik.szomsz[FEL]=this; } else throw new NemKothetoOsszeException(); } else if (masik.y==y) { if (masik.x<x) { szomsz[BAL]=masik; masik.szomsz[JOBB]=this; } else if (masik.x>x) { szomsz[JOBB]=masik; masik.szomsz[BAL]=this; } else throw new NemKothetoOsszeException(); } else throw new NincsRajtaException(); } /** * Segédtömb `merreLegrovidebb()'-nek. */ int merret[]=new int[5]; /** * Segédtömb `merreLegrovidebb()'-nek és `merreVeletlen()'-nek. */ int merrei[]=new int[5]; /** * Azt az irányt adja vissza, amelyen a :Kisgömböc-öt leghamarabb el * lehet érni. `generalo'-t csak akkor használja, ha több irányba is * ugyanolyan messze van a :Kisgömböc. */ int merreLegrovidebb(Veletlen.Generalo generalo) { merret[FEL]=(szomsz[FEL]!=null)?szomsz[FEL].legkoztav+tavolsag(szomsz[FEL]):Integer.MAX_VALUE; merret[LE]=(szomsz[LE]!=null)?szomsz[LE].legkoztav+tavolsag(szomsz[LE]):Integer.MAX_VALUE; merret[JOBB]=(szomsz[JOBB]!=null)?szomsz[JOBB].legkoztav+tavolsag(szomsz[JOBB]):Integer.MAX_VALUE; merret[BAL]=(szomsz[BAL]!=null)?szomsz[BAL].legkoztav+tavolsag(szomsz[BAL]):Integer.MAX_VALUE; // System.err.println(merret[FEL]+" "+merret[LE]+" "+merret[JOBB]+" "+merret[BAL]+"."); // DBG merrei[FEL]=FEL; merrei[LE]=LE; merrei[JOBB]=JOBB; merrei[BAL]=BAL; boolean g=false; // vvv 4 elem egy lehetséges rendezőhálózata :-) do { g=!g; if (merret[2]<merret[1]) { merrei[4]=merrei[2]; merrei[2]=merrei[1]; merrei[1]=merrei[4]; merret[4]=merret[2]; merret[2]=merret[1]; merret[1]=merret[4]; } if (merret[1]<merret[0]) { merrei[4]=merrei[1]; merrei[1]=merrei[0]; merrei[0]=merrei[4]; merret[4]=merret[1]; merret[1]=merret[0]; merret[0]=merret[4]; } if (merret[3]<merret[2]) { merrei[4]=merrei[3]; merrei[3]=merrei[2]; merrei[2]=merrei[4]; merret[4]=merret[3]; merret[3]=merret[2]; merret[2]=merret[4]; } } while (g); // System.err.println("M"+merret[0]+" "+merret[1]+" "+merret[2]+" "+merret[3]+"."); // DBG if (merret[0]==merret[1]) { int mod=2; if (merret[1]==merret[2]) { mod++; if (merret[2]==merret[3]) mod++; } int gen=generalo.general()%4; if (gen>=mod) throw new Kisero.HibasBemenetError("arra nem legrovidebb"); return gen; } else return merrei[0]; } /// merreLegrovidebb() /** * A megadott `generalo' segítségével egy véletlenszerű indulási irányt * jelöl meg ebből a csúcsból, ami lehetőleg nem `elkerul'. */ int merreVeletlen(Veletlen.Generalo generalo, int elkerul) { int lehet=(szomsz[0]==null?0:1)+(szomsz[2]==null?0:1)+ (szomsz[1]==null?0:1)+(szomsz[3]==null?0:1); if (lehet<2) elkerul=Csucs.PIHI; int irany=generalo.general(); if (irany>=0 && irany<4 && irany!=elkerul) return irany; // if (irany==elkerul) System.err.println("elkerul "+elkerul); // DBG // else System.err.println("RIRI"); // DBG // if (true) throw new AsserttError("riri"); // DBG int j=0; for (int i=0;i<4;i++) if (i!=elkerul && szomsz[i]!=null) merrei[j++]=i; // if (j==0 && elkerul<4 && szomsz[elkerul]!=null) merrei[j++]=elkerul; if (j==0) throw new AsserttError("elszigetelt :Csucs"); return merrei[generalo.general()%j]; } /** * A szomszédai `legkoztav'-ját próbálja csökkenteni; ha sikerül, felveszi * őket a :Sor-ba. */ public void kozelit(Sor sor) { int tav; for (int i=0;i<4;i++) if (szomsz[i]!=null && szomsz[i].legkoztav>(tav=legkoztav+tavolsag(szomsz[i]))) { szomsz[i].legkoztav=tav; sor.vegehezFuz(szomsz[i]); } } /** * A szomszédai `legkoztav'-ját próbálja növelni Integer.MAX_VALUE-ra; * ha sikerül, felveszi őket a :Sor-ba. */ public void tavolit(Sor sor) { for (int i=0;i<4;i++) if (szomsz[i]!=null && szomsz[i].legkoztav!=Integer.MAX_VALUE) { szomsz[i].legkoztav=Integer.MAX_VALUE; sor.vegehezFuz(szomsz[i]); } } /** * Összeköti ezt a csúcsot egy másikkal, ha ennek a csúcsnak még nincs * közelebbi szomszédja a megfelelő irányban. */ public void osszekot_kozelit(Csucs masik) { // Imp: régi szomsz-ot is átláncolni if (masik.x==x) { if (masik.y<y) { if (szomsz[FEL]==null || szomsz[FEL].y<masik.y) { szomsz[FEL]=masik; masik.szomsz[LE]=this; } } else if (masik.y>y) { if (szomsz[LE]==null || szomsz[LE].y>masik.y) { szomsz[LE]=masik; masik.szomsz[FEL]=this; } } else throw new NemKothetoOsszeException(); } else if (masik.y==y) { if (masik.x<x) { if (szomsz[BAL]==null || szomsz[BAL].x<masik.x) { szomsz[BAL]=masik; masik.szomsz[JOBB]=this; } } else if (masik.x>x) { if (szomsz[JOBB]==null || szomsz[JOBB].x>masik.x) { szomsz[JOBB]=masik; masik.szomsz[BAL]=this; } } else throw new NemKothetoOsszeException(); } else throw new NincsRajtaException(); } public int tavolsag(Csucs masik) { /* milyen messze van this és masik -- feltesszük, hogy szomszédosak */ if (x==masik.x) return Math.abs(y-masik.y); else if (y==masik.y) return Math.abs(x-masik.x); else throw new NincsRajtaException(); } public int tavolsag(int merre) { return szomsz[merre]==null ? 0 : tavolsag(szomsz[merre]); } public Csucs uj_csucs(int ux, int uy) { /* egy új csúcsot hoz létre this szomszédságában * Imp: Helyzet-eket update-elni! */ if (ux==x && uy==y) return this; Csucs uj=new Csucs(ux, uy); int arra; if (ux==x) { if (uy<y) { arra=FEL; } else if (uy>y) { arra=LE; } else throw new NemKothetoOsszeException(); // Assert: never happens } else if (uy==y) { if (ux<x) { arra=BAL; } else if (ux>x) { arra=JOBB; } else throw new NemKothetoOsszeException(); // Assert: never happens } else throw new NincsRajtaException(); if (szomsz[arra]!=null) { int ta=tavolsag(szomsz[arra]); int tu=tavolsag(uj); if (ta==tu) return szomsz[arra]; // uj-t fel lehet szabadítani if (ta<tu) throw new NemKothetoOsszeException(); uj.szomsz[arra]=szomsz[arra]; } uj.szomsz[arra^2]=this; return uj; } /* az innen kitörölt szetvag() függvény bugos volt, és sosem használtuk. */ } public static class Helyzet { /* Helyzet: egy mozgó lény (Kisgömböc vagy Szörny) helyét tárolja */ public static final int H_C1BEN=1, H_JOBBRA=2, H_LEFELE=3; /** * H_* konstansok valamelyike. */ private int hol; protected int x, y; private int ex, ey; // maximum koordinatak c1-bol; c1.getX()<=x<=ex, hasonloan y-ra private Csucs c1; // ^^^ c2 lejjebb/jobbrább van, mint c1 // ^^^ (x,y) c1-re eshet, de c2-re csak akkor, ha c2!=c1 public int getX() { return x; } public int getY() { return y; } /** * Visszadja azt a csúcsot, ahol éppen vagyunk. Ha épp két csúcs között * vagyunk, akkor <code>null</code>-t ad vissza. */ public Csucs getCsucsban() { return hol==H_C1BEN?c1:null; } /** * Visszadja, hányadik mérpontbank. Ha épp két csúcs között * vagyunk, vagy az aktuális csúcs nem mérőpont, akkor -1-et * ad vissza. */ public int getMeropontban() { // if (hol==H_C1BEN) System.err.println("HC1"); return hol==H_C1BEN?c1.getMeropont():-1; } /** * Visszaadja `csucs' és `this' síkon mért távolságának négyzetét. */ int ferdeTavolsag(Csucs cs) { int dx=x-cs.getX(); int dy=y-cs.getY(); return dx*dx+dy*dy; } /** * Visszaadja `helyzet' és `this' síkon mért távolságának négyzetét. */ int ferdeTavolsag(Helyzet helyzet) { int dx=x-helyzet.x; int dy=y-helyzet.y; return dx*dx+dy*dy; } public void ugrik() { // ex-et, ey-t, hol-t a semmibol ujraszamolja; c1,x,y mar helyes. Csucs c2; c2=c1.getSzomsz0(Csucs.JOBB); ex=c2.getX(); c2=c1.getSzomsz0(Csucs.LE); ey=c2.getY(); if (x>c1.getX()) hol=H_JOBBRA; else if (y>c1.getY()) hol=H_LEFELE; else hol=H_C1BEN; } public Helyzet() { /* gagyi, kamu konstruktor, kesobb csucsba-val lehet korrigalni */ this.c1=null; } public Helyzet(Csucs c1) { this.c1=c1; x=c1.getX(); y=c1.getY(); ugrik(); } /** * Copy konstruktor. */ public Helyzet(Helyzet h) { athelyez(h); } /** * A megadott :Csúcs-ba helyezi át this-t. */ public void athelyez(Csucs c1) { this.c1=c1; x=c1.getX(); y=c1.getY(); ugrik(); } /** * A megadott :Helyzet-be helyezi át this-t. */ public void athelyez(Helyzet h) { c1=h.c1; hol=h.hol; x=h.x; y=h.y; ex=h.ex; ey=h.ey; } /** * A két szomszéd :Csúcs-ot helyezi el a :Sor-ba, és beállítja a * távolságukat this-től. */ public void ketSzomszed(Sor sor) { sor.vegehezFuz(c1); if (hol==H_C1BEN) { c1.setTavolsag(0); } else if (hol==H_JOBBRA) { int xx=c1.getX(); c1.setTavolsag(x-xx); Csucs c2=c1.getSzomsz(Csucs.JOBB); sor.vegehezFuzNemNull(c2); c2.setTavolsag(ex-x); } else if (hol==H_LEFELE) { int yy=c1.getY(); c1.setTavolsag(y-yy); Csucs c2=c1.getSzomsz(Csucs.LE); sor.vegehezFuzNemNull(c2); c2.setTavolsag(ey-y); } } /// ketSzomszed() protected int halad_alap(int merre, int mennyit) { // ne ezt hívd, hanem Mozgo.halad(*,*)-ot. Az ellenőriz és callback-kel is. // if (hol==H_C1BEN) System.out.println("Hudok "+merre+" "+mennyit+"."); // Imp: clean this up (code works, but is ugly) int menyi=mennyit; if (merre==Csucs.FEL || merre==Csucs.BAL) menyi*=-1; if (hol==H_JOBBRA) { x+=menyi; if (x==ex) { c1=c1.getSzomsz0(merre); ugrik(); } else if (x==c1.getX()) hol=H_C1BEN; return mennyit; } if (hol==H_LEFELE) { y+=menyi; if (y==ey) { c1=c1.getSzomsz0(merre); ugrik(); } else if (y==c1.getY()) hol=H_C1BEN; return mennyit; } if (menyi<0) c1=c1.getSzomsz(merre); if (merre==Csucs.FEL || merre==Csucs.LE) { y+=menyi; if (y==ey) c1=c1.getSzomsz0(merre); } else { x+=menyi; if (x==ex) c1=c1.getSzomsz0(merre); } ugrik(); return mennyit; } public int mennyit_mehet(int merre) { /* @return: innen mennyit mehet az akt. élen a megadott irányba */ if (hol==H_JOBBRA) { if (merre==c1.BAL) return x-c1.getX(); else if (merre==c1.JOBB) return ex-x; // c1.tavolsag(c1.JOBB)-x+c1.getX(); else return 0; } else if (hol==H_LEFELE) { if (merre==c1.FEL) return y-c1.getY(); else if (merre==c1.LE) return ey-y; // c1.tavolsag(c1.LE)-y+c1.getY(); else return 0; } //: hol==H_C1BEN // System.out.println("MM:"+merre); // try { Thread.sleep(1000); } catch (InterruptedException e) {} return c1.tavolsag(merre); } } /// class Helyzet // --- public abstract static class Lathato extends Helyzet { /** * Egyedi azonosító. A :Labirintus osztja ki és használja. Ha kisebb * nullánál, akkor a :Látható még nem jelent meg a labirintusban, vagy * egy korábbi ciklusban már eltűnt belőle. */ protected int id=-2; protected Kep[] kepek; protected Kep aktkep; protected int akti; /** * A naplóba írandó osztálynév (például mérőpont elérésekor). * Felüldefiniálandó. */ private static String klassz="Lathato"; /** * Visszadja a naplóba írandó osztálynevet. Azért nem `static', hogy * virtuális lehessen. */ public String getKlassz() { return klassz; } /** * Ő végzi ezen :Láthatóval történtek naplózását. */ protected Naplozo naplozo; public void setNaplozo(Naplozo naplozo) { if (this.naplozo!=null) throw new MarErtekesError(); this.naplozo=naplozo; } /** * Egy sort naplóz, eléfűzve `this.getKlassz()'-t. * @see eNTitanok.kkkg.KkkgPro.Lathato#getKlassz */ public void naploz(String s, Naplozo naplozo) { naplozo.naploz(getKlassz()+s); } /** * Egy sort naplóz `this.naplozo'-val, eléfűzve `this.getKlassz()'-t. * @see eNTitanok.kkkg.KkkgPro.Lathato#getKlassz */ public void naploz(String s) { naplozo.naploz(getKlassz()+s); } public void setId(int id) { this.id=id; } public int getId() { return id; } public String[] getKepnevek() { int i; String[] t=new String[kepek.length]; for (i=0;i<kepek.length;i++) t[i]=kepek[i].getFilenev(); return t; } // public void setKep(int i, Image kep) { kepek[i].setKep(kep); } public void mozgat(int ujx, int ujy) { x=ujx; y=ujy; } public void rarajzolArnyek(Sdpts sd) { //sd.drawImage(aktkep.kep, x/24+aktkep.bx1, y/24+aktkep.bx1); // sd.drawShadow(x/24+aktkep.bx1-5, y/24+aktkep.bx1-5, aktkep.kep.getWidth(null)+10, aktkep.kep.getHeight(null)+10); aktkep.felrajzol_arnyek(x/24,y/24); } public void rarajzol(Sdpts sd) { //sd.drawImage(aktkep.kep, x/24+aktkep.bx1, y/24+aktkep.bx1); // sd.drawImageCover(aktkep.kep, x/24+aktkep.bx1, y/24+aktkep.bx1); // ^^^ még mindig érezhetően lassít aktkep.felrajzol_kep(x/24,y/24); } // public void tisztit() { dirty=false; } public boolean utkozik_e(Lathato masik) { // CsakPro // vvv Imp: / 0 felé kerekítsen!! (x>=0??) // return aktkep.utkozik_e(masik.aktkep, -x/24+masik.x/24, -y/24+masik.y/24); if (this instanceof KetyegoBomba && ((KetyegoBomba)this). getRobban() ||masik instanceof KetyegoBomba && ((KetyegoBomba)masik).getRobban()) { // System.err.println("ROBI"); // DBG return Math.abs(x-masik.x)<63*24 && Math.abs(y-masik.y)<63*24; } return Math.abs(x-masik.x)<23*24 && Math.abs(y-masik.y)<23*24; } /// utkozik_e() /** * Labirintus hívja meg új :Látható felvételekor (az újra és a régiekre is); * pontosan akkor ad vissza true-t, ha kell ütközésvizsgálatot végezni this * és `masik' között. Az ütközésvizsgálatot Labirintus végzi this.utkozik_e * módszeres hivogatásával. * Érdemes átdefiniálni. */ public boolean akarsz_e_utkozni(Lathato masik) { return false; } /** * Egy lépes egy ciklusban. Nem feltétlenül mozgás, lehet ütközésvizsgálat * és más :Láthatókra hatás stb. */ protected abstract void halad(); } /// class Lathato /** * A :Tárgy fő jellemzője, hogy egy helyben áll a pályán, és az egyetlen * dolog, ami történhet vele, az az, hogy a :Kisgömböc felveszi. */ public static abstract class Targy extends Lathato { /** * Figyeljük-e az ütközést :Kisgömböc-cel? */ protected boolean kutk; protected Labirintus labirintus; abstract protected void felveve(); /** * Egy helyben áll, és várja :Kisgömböcöt. Amint ütközik vele, meghívja * `this.felveve()'-t, majd eltűnik. */ protected void halad() { Lathato ut[]=labirintus.getUtkozesek(this); if (ut!=null) for (int i=0;i<ut.length;i++) { if (ut[i] instanceof Kisgomboc) { felveve(); labirintus.removeLathato(this); } } } /// halad() protected Targy(Labirintus labirintus, boolean kutk) { this.labirintus=labirintus; this.kutk=kutk; } public boolean akarsz_e_utkozni(Lathato masik) { return kutk && masik instanceof Kisgomboc; } } /// class Targy /** * A :Gyémánt azért nem Ajándék, mert nem véletlenszerűen jelenik meg, és * nem tűnik el. */ public static class Gyemant extends Targy { private static String klassz="Gyemant"; public String getKlassz() { return klassz; } public Gyemant(Labirintus l, boolean kutk) { super(l, kutk); kepek=new Kep[1]; kepek[0]=l.getKepbetolto().betolt("gyemant.gif").initi(l.getSd(),-12,-12,0); aktkep=kepek[akti=0]; } public void felveve() { labirintus.getJatek().novelPontszam(23); } } /// class Gyemant public static class KetyegoBomba extends Lathato { private static String klassz="KetyegoBomba"; public String getKlassz() { return klassz; } /** * Figyeljük-e az ütközést :Szörny-nyel? */ protected boolean sutk; /** * Figyeljük-e az ütközést :Kisgömböc-cel? */ protected boolean kutk; protected Labirintus labirintus; /** * Hány ciklust ért meg? (0, ha ebben a ciklusban született) */ protected int eletkor=0; protected boolean robban=false; public boolean getRobban() { return robban; } public KetyegoBomba(Labirintus labirintus, boolean kutk, boolean sutk) { this.labirintus=labirintus; this.kutk=kutk; this.sutk=sutk; kepek=new Kep[2]; kepek[0]=labirintus.getKepbetolto().betolt("kbomba.gif").initi(labirintus.getSd(),-30,-30,0); kepek[1]=labirintus.getKepbetolto().betolt("kbombar.gif").initi(labirintus.getSd(),-30,-30,0); aktkep=kepek[akti=0]; } public boolean akarsz_e_utkozni(Lathato masik) { return kutk && masik instanceof Kisgomboc || sutk && masik instanceof Szorny; } public void halad() { if (eletkor>=63) { // 1 másodperc Lathato ut[]=labirintus.getUtkozesek(this); if (!robban && (eletkor>=313 || ut!=null)) { // 5 másodperc naploz(" felrobban"); robban=true; aktkep=kepek[akti=1]; eletkor=313; // labirintus.removeLathato(this); } if (ut!=null) for (int i=0;i<ut.length;i++) { if (ut[i] instanceof Mozgo) { // System.err.println("DDD"); // DBG labirintus.removeLathato(ut[i]); } } if (eletkor>=438) labirintus.removeLathato(this); // 7 másodperc } eletkor++; } /// halad() } /// class KetyegoBomba /** * Az :Ajándék-ok közös jellegzetessége, hogy véletlenszerűen jelennek meg * a :Labirintusban, és véletlenszerűen tűnnek is el. */ public static abstract class Ajandek extends Targy { /** * Hány ciklus van még hátra, mielőtt az ajándék magától eltűnik?. */ protected int hatralevo=313; // 5 másodperc protected Ajandek(Labirintus labirintus, boolean kutk) { super(labirintus, kutk); } /** * Csökkenti a hátralevő időt, és magától eltűnik, ha nulla lesz. * `this.felveve()'-t természetesen meghívja. */ protected void halad() { super.halad(); if (--hatralevo<0) labirintus.removeLathato(this); } /** * Pontosan akkor `true', ha `this' szeretne keletkezni Kisgömböc-től * (a középpontokat tekintve) * a folyosókon mérve `tavolsag'-ra, a síkon mérve `ferdeTavolsag' * négyzetére. Implementáció: ha a `tavolsag' nem végtelen, és a síkon * mért távolság legalább 100 pixel. */ public boolean alkalmasKel(int tavolsag, int ferdeTavolsag) { // CsakPro return tavolsag!=Integer.MAX_VALUE && ferdeTavolsag>=(24*25)*(24*25); } } /// class Ajandek public static class FelvehetoBomba extends Ajandek { private static String klassz="FelvehetoBomba"; public String getKlassz() { return klassz; } public FelvehetoBomba(Labirintus l, boolean kutk) { super(l, kutk); kepek=new Kep[1]; kepek[0]=l.getKepbetolto().betolt("fbomba.gif").initi(l.getSd(),-12,-12,0); aktkep=kepek[akti=0]; hatralevo=313; } public void felveve() { labirintus.getJatek().novelPontszam(3); labirintus.getJatek().novelBombaszam(); } } /// class FelvehetoBomba public static class Bonusz extends Ajandek { private static String klassz="Bonusz"; public String getKlassz() { return klassz; } public Bonusz(Labirintus l, boolean kutk) { super(l, kutk); kepek=new Kep[1]; kepek[0]=l.getKepbetolto().betolt("bonusz.gif").initi(l.getSd(),-12,-12,0); aktkep=kepek[akti=0]; hatralevo=313; } public void felveve() { labirintus.getJatek().novelPontszam(137); } } /// class Bonusz public static class SimaElixir extends Ajandek { private static String klassz="SimaElixir"; public String getKlassz() { return klassz; } public SimaElixir(Labirintus l, boolean kutk) { super(l, kutk); kepek=new Kep[1]; kepek[0]=l.getKepbetolto().betolt("sielixir.gif").initi(l.getSd(),-12,-12,0); aktkep=kepek[akti=0]; hatralevo=313; } public void felveve() { labirintus.getJatek().novelPontszam(2); labirintus.getJatek().novelEletszam(1); } } /// class SimaElixir public static class SzuperElixir extends Ajandek { private static String klassz="SzuperElixir"; public String getKlassz() { return klassz; } public SzuperElixir(Labirintus l, boolean kutk) { super(l, kutk); kepek=new Kep[1]; kepek[0]=l.getKepbetolto().betolt("szelixir.gif").initi(l.getSd(),-12,-12,0); aktkep=kepek[akti=0]; hatralevo=313; } public void felveve() { labirintus.getJatek().novelPontszam(17); labirintus.getJatek().novelEletszam(0); } } /// class SzuperElixir // --- public static abstract class Mozgo extends Lathato { protected abstract void elfordult(); // ^^^ akkor hivodik meg, ha a haladasi irany megvaltozik. Feluldefinialando. protected int ero; // mennyit lephet most protected int max_ero; // mennyi a max sebessege protected int irany=Csucs.PIHI; // milyen iranyba lepett legutoljara >=1-et public int setMax_ero(int max_ero) { return this.max_ero=max_ero; } public int setEro() { return this.ero=this.max_ero; } /** * Az adott irányba próbál az adott egységnyit haladni. Siker esetén * `this.elfordult()' meghívódik -- és ha még mérőpontra is ér, akkor * ez a tény naplózódik. */ public int halad(int merre, int mennyit) { if (merre>=4 || mennyit==0) return 0; // System.out.println("Halad "+merre+" "+mennyit+"."); mennyit=Math.min(mennyit, mennyit_mehet(merre)); if (mennyit==0) return 0; if (irany!=merre) { irany=merre; // vvv CsakPro switch (irany) { case Csucs.FEL: naploz(" ^ fordul"); break; case Csucs.LE: naploz(" v fordul"); break; case Csucs.JOBB:naploz(" > fordul"); break; case Csucs.BAL: naploz(" < fordul"); break; } elfordult(); } mennyit=halad_alap(merre, mennyit); if (mennyit==0) throw new AsserttError(); // vvv CsakPro // System.err.println("DBGMP "+getKlassz()+" "+x); int meropont=getMeropontban(); if (meropont!=-1) naploz(" meropontban "+meropont); return mennyit; } public int halad(int merre) { // annyit halad az adott iranyba, amennyi az erejebol tellik int sikerult=halad(merre, ero); ero-=sikerult; return sikerult; } void halad_balra_fordul() { if (irany==Csucs.PIHI) irany=Csucs.FEL; int erobk=0; while (erobk!=ero) { // atugorja a csomopontokat erobk=ero; for (int i=5;i>=2;i--) { if (0<halad((irany+i)%4)) break; } } } void halad_jobbra_fordul() { if (irany==Csucs.PIHI) irany=Csucs.FEL; int erobk=0; while (erobk!=ero) { // atugorja a csomopontokat erobk=ero; for (int i=3;i<=6;i++) { if (0<halad((irany+i)%4)) break; } } } } /// class Mozgo public static abstract class Szorny extends Mozgo { protected Labirintus labirintus; /** * Ezzel generáljuk a kanyarodáshoz esetlegesen szükséges véletlenszámokat. */ Veletlen.Generalo generalo; /** * Figyeljük-e az ütközést :Kisgömböc-cel? */ protected boolean kutk; protected Szorny(Labirintus labirintus, int max_ero, Veletlen.Generalo generalo, boolean kutk) { this.labirintus=labirintus; this.max_ero=max_ero; this.generalo=generalo; this.kutk=kutk; } protected void elfordult() { aktkep=kepek[irany]; akti=irany; } public boolean akarsz_e_utkozni(Lathato masik) { return kutk && masik instanceof Kisgomboc; } /** * Ha ütközik :Kisgömböc-cel, megöli. */ protected void megoli() { Lathato ut[]=labirintus.getUtkozesek(this); if (ut!=null) for (int i=0;i<ut.length;i++) if (ut[i] instanceof Kisgomboc) labirintus.removeLathato(ut[i]); } /** * Pontosan akkor `true', ha `this' szeretne keletkezni Kisgömböc-től * (a középpontokat tekintve) * a folyosókon mérve `tavolsag'-ra, a síkon mérve `ferdeTavolsag' * négyzetére. Implementáció: ha a `tavolsag' nem végtelen, és a síkon * mért távolság legalább 100 pixel. */ public boolean alkalmasKel(int tavolsag, int ferdeTavolsag) { // CsakPro return tavolsag!=Integer.MAX_VALUE && ferdeTavolsag>=(24*100)*(24*100); } } /// class Szorny public static class BalraSzorny extends Szorny { private static String klassz="BalraSzorny"; public String getKlassz() { return klassz; } protected void halad() { setEro(); halad_balra_fordul(); } public BalraSzorny(Labirintus labirintus, int max_ero, Veletlen.Generalo generalo, boolean kutk) { super(labirintus, max_ero, generalo, kutk); Kepbetolto kepbetolto=labirintus.getKepbetolto(); Sdpts sd=labirintus.getSd(); kepek=new Kep[5]; // vvv nincs árnyéka kepek[Csucs.JOBB]=kepbetolto.betolt("szornyj.gif").initi(sd,-12,-12); kepek[Csucs.BAL]=kepbetolto.betolt("szornyb.gif").initi(sd,-12,-12); kepek[Csucs.FEL]=kepbetolto.betolt("szornyf.gif").initi(sd,-12,-12); kepek[Csucs.LE]=kepbetolto.betolt("szornyl.gif").initi(sd,-12,-12); kepek[Csucs.PIHI]=kepek[Csucs.JOBB]; aktkep=kepek[akti=Csucs.JOBB]; } } /// BalraSzorny public static class JobbraSzorny extends Szorny { private static String klassz="JobbraSzorny"; public String getKlassz() { return klassz; } protected void halad() { setEro(); halad_jobbra_fordul(); } public JobbraSzorny(Labirintus labirintus, int max_ero, Veletlen.Generalo generalo, boolean kutk) { super(labirintus, max_ero, generalo, kutk); Kepbetolto kepbetolto=labirintus.getKepbetolto(); Sdpts sd=labirintus.getSd(); kepek=new Kep[5]; // vvv nincs árnyéka kepek[Csucs.JOBB]=kepbetolto.betolt("szornyj.gif").initi(sd,-12,-12); kepek[Csucs.BAL]=kepbetolto.betolt("szornyb.gif").initi(sd,-12,-12); kepek[Csucs.FEL]=kepbetolto.betolt("szornyf.gif").initi(sd,-12,-12); kepek[Csucs.LE]=kepbetolto.betolt("szornyl.gif").initi(sd,-12,-12); kepek[Csucs.PIHI]=kepek[Csucs.JOBB]; this.max_ero=max_ero; aktkep=kepek[akti=Csucs.JOBB]; } } /// JobbraSzorny public static class OkosSzorny extends Szorny { private static String klassz="OkosSzorny"; public String getKlassz() { return klassz; } protected void halad() { setEro(); int erobk=0, haladt; while (ero>0 && erobk!=ero) { // áthalad a csomopontokon erobk=ero; Csucs cs=getCsucsban(); haladt=cs==null ? halad(irany) : halad(cs.merreLegrovidebb(generalo)); if (haladt==0) throw new AsserttError(); } megoli(); } public OkosSzorny(Labirintus labirintus, int max_ero, Veletlen.Generalo generalo, boolean kutk) { super(labirintus, max_ero, generalo, kutk); Kepbetolto kepbetolto=labirintus.getKepbetolto(); Sdpts sd=labirintus.getSd(); kepek=new Kep[5]; // vvv nincs árnyéka kepek[Csucs.JOBB]=kepbetolto.betolt("szornyj.gif").initi(sd,-12,-12); kepek[Csucs.BAL]=kepbetolto.betolt("szornyb.gif").initi(sd,-12,-12); kepek[Csucs.FEL]=kepbetolto.betolt("szornyf.gif").initi(sd,-12,-12); kepek[Csucs.LE]=kepbetolto.betolt("szornyl.gif").initi(sd,-12,-12); kepek[Csucs.PIHI]=kepek[Csucs.JOBB]; aktkep=kepek[akti=Csucs.JOBB]; } } /// OkosSzorny public static class ButaSzorny extends Szorny { private static String klassz="ButaSzorny"; public String getKlassz() { return klassz; } protected void halad() { setEro(); int erobk=0, haladt; while (ero>0 && erobk!=ero) { // áthalad a csomopontokon erobk=ero; Csucs cs=getCsucsban(); haladt=cs==null ? halad(irany) : halad(cs.merreVeletlen(generalo, irany^2)); // !! irany^2 if (haladt==0) throw new AsserttError(); // !! } megoli(); } public ButaSzorny(Labirintus labirintus, int max_ero, Veletlen.Generalo generalo, boolean kutk) { super(labirintus, max_ero, generalo, kutk); Kepbetolto kepbetolto=labirintus.getKepbetolto(); Sdpts sd=labirintus.getSd(); kepek=new Kep[5]; // vvv nincs árnyéka kepek[Csucs.JOBB]=kepbetolto.betolt("szornyj.gif").initi(sd,-12,-12); kepek[Csucs.BAL]=kepbetolto.betolt("szornyb.gif").initi(sd,-12,-12); kepek[Csucs.FEL]=kepbetolto.betolt("szornyf.gif").initi(sd,-12,-12); kepek[Csucs.LE]=kepbetolto.betolt("szornyl.gif").initi(sd,-12,-12); kepek[Csucs.PIHI]=kepek[Csucs.JOBB]; aktkep=kepek[akti=Csucs.JOBB]; } } /// ButaSzorny public static class BalraFelSzorny extends Szorny { private static String klassz="BalraFelSzorny"; public String getKlassz() { return klassz; } protected void halad() { setEro(); int erobk=0; while (ero>0 && erobk!=ero) { // áthalad a csomopontokon erobk=ero; if (0==halad(Csucs.BAL)) halad(Csucs.FEL); } megoli(); } public BalraFelSzorny(Labirintus labirintus, int max_ero, Veletlen.Generalo generalo, boolean kutk) { super(labirintus, max_ero, generalo, kutk); Kepbetolto kepbetolto=labirintus.getKepbetolto(); Sdpts sd=labirintus.getSd(); kepek=new Kep[5]; // vvv nincs árnyéka kepek[Csucs.JOBB]=kepbetolto.betolt("szornyj.gif").initi(sd,-12,-12); kepek[Csucs.BAL]=kepbetolto.betolt("szornyb.gif").initi(sd,-12,-12); kepek[Csucs.FEL]=kepbetolto.betolt("szornyf.gif").initi(sd,-12,-12); kepek[Csucs.LE]=kepbetolto.betolt("szornyl.gif").initi(sd,-12,-12); kepek[Csucs.PIHI]=kepek[Csucs.JOBB]; aktkep=kepek[akti=Csucs.JOBB]; } } /// BalraFelSzorny public static class JobbraLeSzorny extends Szorny { private static String klassz="JobbraLeSzorny"; public String getKlassz() { return klassz; } protected void halad() { setEro(); int erobk=0; while (ero>0 && erobk!=ero) { // áthalad a csomopontokon erobk=ero; if (0==halad(Csucs.JOBB)) halad(Csucs.LE); } megoli(); } public JobbraLeSzorny(Labirintus labirintus, int max_ero, Veletlen.Generalo generalo, boolean kutk) { super(labirintus, max_ero, generalo, kutk); Kepbetolto kepbetolto=labirintus.getKepbetolto(); Sdpts sd=labirintus.getSd(); kepek=new Kep[5]; // vvv nincs árnyéka kepek[Csucs.JOBB]=kepbetolto.betolt("szornyj.gif").initi(sd,-12,-12); kepek[Csucs.BAL]=kepbetolto.betolt("szornyb.gif").initi(sd,-12,-12); kepek[Csucs.FEL]=kepbetolto.betolt("szornyf.gif").initi(sd,-12,-12); kepek[Csucs.LE]=kepbetolto.betolt("szornyl.gif").initi(sd,-12,-12); kepek[Csucs.PIHI]=kepek[Csucs.JOBB]; aktkep=kepek[akti=Csucs.JOBB]; } } /// JobbraLeSzorny public static class Kisgomboc extends Mozgo { private static String klassz="Kisgomboc"; public String getKlassz() { return klassz; } protected Labirintus labirintus; /** * Megpróbál kanyarodni arra, amerre a játékos szeretné; ha nem * sikerül, megy tovább egyenesen. Továbbá itt kezdeményezzük a * legrövidebbút-keresést és a bombalerakást. Ütközésvizsgálatot nem * végzünk, azt végez helyettünk mindenki más. */ protected void halad() { if (labirintus.getJatek().isMostBombaLe()) { naploz(" bombat rak le"); labirintus.bombatLerak(this); } setEro(); int erobk=0; while (erobk!=ero) { // áthalad a csomopontokon erobk=ero; if (0==halad(labirintus.getJatek().getUjIrany())) halad(irany); if (getCsucsban()!=null) labirintus.kitablazando(); } } Kisgomboc(Labirintus l) { this.labirintus=l; Kepbetolto kepbetolto=l.getKepbetolto(); Sdpts sd=l.getSd(); kepek=new Kep[5]; kepek[Csucs.JOBB]=kepbetolto.betolt("gombocj.gif").initi(sd,-12,-12,5); kepek[Csucs.BAL]=kepbetolto.betolt("gombocb.gif").initi(sd,-12,-12,5); kepek[Csucs.FEL]=kepbetolto.betolt("gombocf.gif").initi(sd,-12,-12,5); kepek[Csucs.LE]=kepbetolto.betolt("gombocl.gif").initi(sd,-12,-12,5); kepek[Csucs.PIHI]=kepbetolto.betolt("gombocp.gif").initi(sd,-12,-12,5); max_ero=40; aktkep=kepek[Csucs.PIHI]; akti=Csucs.PIHI; // System.err.println(klassz); // mindig "Kisgomboc" } protected void elfordult() { aktkep=kepek[irany]; akti=irany; } // akarsz_e_utkozni()-nek jo a default `return false;'-sa } /// Kisgomboc // --- public static class Jatek { // nyílbillentyűk: haladás // szóköz: bomba lerakása // Esc: játék felfüggesztés ki/be // betűk: csúcslistába beírás // Enter: csúcslistába beírás vége/ játék vége // Imp: flag-ek, thread safety?? // public static final int A_JATEKKEZDODIK=0; /** * A következő :Labirintus betöltése folyamatban. */ public static final int A_SZINTLEPES=1; /** * A :Labirintus már be van töltve, az első billentyű leütésére várunk. */ public static final int A_LABKEZDODIK=2; /** * A játék folyik (fut). */ public static final int A_FOLYIK=3; /** * A játék fel van függesztve (várakozik). */ public static final int A_FELFUGGESZTVE=4; /** * A játék véget ért, az esetleges csúcslistába beírás folyik. */ public static final int A_BEIRAS=5; /** * A játék teljesen véget ért, a csúcslistába beírás is megtörtént. */ public static final int A_LEGVEGE=6; protected Kisero kisero; // protected Kepbetolto kepbetolto; protected Labirintus.LabirintusRajzolo lr; protected JobboldalRajzolo jr; protected Labirintus labirintus; protected Idozitett idozitett; protected int eletszam, maxeletszam, bombaszam, maxbombaszam, pontszam, szint; protected int status; // a `status'-t csak this.run() módosíthatja // vvv kívülről jövő, aszinkron ingerek volatile protected char uj_karakter; public static final int F_BOMBALERAKANDO=1, F_MEGHALT=2, F_MEGALLITANDO=4, F_HOZZAFUZENDO=8, F_LEZARANDO=16, F_SZINTLEPENDO=32, F_INDITANDO=64; volatile protected int inger; // public Jatek(Kepbetolto kepbetolto, Labirintus.LabirintusRajzolo lr, JobboldalRajzolo jr, Idozitett idozitett) public Jatek(Kisero kisero) { this.kisero=kisero; this.lr=kisero.labirintusRajzolo; this.jr=kisero.jobboldalRajzolo; this.idozitett=kisero.idozitett; idozitett.ujraindit(); // !! stat-okat nulláz stb. maxeletszam=5; maxbombaszam=3; eletszam=maxeletszam; bombaszam=0; // !! maxbombaszam; pontszam=0; // `szint=0;' esetén fog az első szintről indulni szint=0; status=A_SZINTLEPES; } public Sdpts getLabSd() { return lr.getSd(); } public Kepbetolto getKepbetolto() { return kisero.kepbetolto; } public Labirintus getLabirintus() { return labirintus; } // public synchronized int getStatus() { return status; } // protected synchronized void setStatus(int uj_status) { this.uj_status=status; } /** * Jelzi, hogy a következő lépésben szintet kell lépni. */ public synchronized void szintlepes() { inger|=F_SZINTLEPENDO; } /** * Az előírt haladási irány. */ volatile protected int ujIrany; /** * Jelzi, hogy a következő lépésben merre kell (kéne) fordulni. */ public synchronized void fordulj(int irany) { if (status==A_LABKEZDODIK) { ujIrany=irany; inger|=F_INDITANDO; } else if (status==A_FOLYIK) { ujIrany=irany; } } /** * Visszadja, hogy merre akart menni legutoljára a játékos. */ public int getUjIrany() { return ujIrany; } /** * Jelzi, hogy a következő lépésben bombát kell lerakni. */ public synchronized void bombatLerak() { if (status==A_FOLYIK) inger|=F_BOMBALERAKANDO; } /** * Pontosan akkor `true', ha ebben a lépésben bombát kell lerakni (és van * is bomba felvéve). Miután * egyszer visszatért `true'-val, legközelebb `false'-t ad vissza. Ha * `true'-t ad vissza, egyben csökkenti is a rendelkezésre álló bombák * számát. Ezt csak a `Kisgomboc.halad()' hívja. * @see eNTitanok.kkkg.KkkgPro.Kisgomboc#halad() */ public synchronized boolean isMostBombaLe() { if (0!=(inger&F_BOMBALERAKANDO)) { inger&=~F_BOMBALERAKANDO; if (bombaszam>0) { bombaszam--; return true; } } return false; } /** * Jelzi, hogy a csúcslistához egy karaktert hozzá kell fűzni. */ public synchronized void hozzafuz(char c) { if (status==A_BEIRAS) { inger|=F_HOZZAFUZENDO; uj_karakter=c; } } /** * Jelzi, hogy a csúcslista módosítása véget ért. */ public synchronized void lezar() { if (status==A_BEIRAS) inger|=F_LEZARANDO; } /** * A játék felfüggesztettségét ellentétesre változtatja. */ public synchronized void megallit() { if (status==A_FOLYIK) inger|=F_MEGALLITANDO; else if (status==A_FELFUGGESZTVE) inger|=F_INDITANDO; } // ^^^ Imp: szinkronizálás... protected synchronized int ingerTorles() { int i=inger; inger=0; return i; } /** * Ez az egyetlen hely, ahol módosítjuk a this.status-t, this.inger * alapján. Mivel `synchronized', ezért az ide írt kódot gyorsra kell * tervezni. * @see status * @see inger */ public synchronized void statusLeptet() { if (status==A_BEIRAS) { if (0!=(inger&F_HOZZAFUZENDO)) { kisero.naploz("csucslistaba "+uj_karakter); kisero.csucslista.hozzafuz(uj_karakter); inger&=~F_HOZZAFUZENDO; // statRajzolando=true; } if (0!=(inger&F_LEZARANDO)) { String debug=kisero.csucslista.lezar(); kisero.naploz(debug==null?"csucslista marad":"csucslistaba: "+debug); kisero.csucslista.kiment(); inger=0; status=A_LEGVEGE; // statRajzolando=true; labirintus.feloszlat(); labirintus=null; } } else if (status==A_FELFUGGESZTVE) { if (0!=(inger&F_INDITANDO)) { inger=0; status=A_FOLYIK; } } else if (status==A_LABKEZDODIK) { if (0!=(inger&F_INDITANDO)) { kisero.naploz("jatekos elindult"); inger=0; status=A_FOLYIK; } } else if (status==A_FOLYIK) { if (0!=(inger&F_SZINTLEPENDO)) { // System.out.println("DDD"); inger=0; status=A_SZINTLEPES; labirintus.feloszlat(); labirintus=null; } else if (0!=(inger&F_MEGHALT)) { inger=0; if (eletszam==0) { status=A_BEIRAS; kisero.naploz("jatek vege, csucslista jon"); kisero.csucslista.felvesz(pontszam); } else { status=A_LABKEZDODIK; kisero.naploz("eletvesztes. maradt "+eletszam); labirintus.alaphelyzetbe(); } // statRajzolando=true; } else if (0!=(inger&F_MEGALLITANDO)) { inger=0; status=A_FELFUGGESZTVE; } } /// IF } /// statusLeptet() public void fut() { // ez _volt_ a KkkgPro run() metodusa, ami kulon szalban fut. // ez a szal frissiti a jatekallast (,,mozgatja'' a jatekot), // tovabba ez a szal rajzol az `sd'-re. while (true) { // System.out.println("megint "+status+";;"+ujIrany); // Imp: sync, Thread safe kisero.gyerunk(); statusLeptet(); if (status==A_LEGVEGE) { kisero.naploz("jatek legvege"); statRajzolando=true; statRajzol(); break; } else if (status==A_SZINTLEPES) { kisero.naploz("szintlepes"); // System.out.println("Szintlépés!"); // status=A_SZINTLEPES; // Imp: érvénytelenítés előtt várakozás stb. lr.ervenytelenit("Szintlépés"); lr.paintMost(); // Idozito.alszik(1000); szint++; statRajzolando=true; if (labirintus!=null) throw new HibasAllapotException(); // labirintus=null; // System.out.println("SZISZ"); labirintus=new Labirintus(this, szint); // bombaszam=0; // 8.1-es teszteset miatt nem nullázunk ujIrany=Csucs.PIHI; kisero.kepbetolto.mind_meglegyen(); labirintus.palya_betoltve(); lr.ervenyesit(labirintus); lr.setDebugUzenet("csuhaj"); labirintus.elorajzol(); // !!! statRajzol(); // jr.paintMost(); // Imp: nem mindig !! // jr.repaint(); lr.paintMost(); status=A_LABKEZDODIK; // !!! az egészet újrarajzolni, nem csak a labirintust idozitett.ujraindit(); // idozito.kezdd_ujra(); kisero.ciklus=0; kisero.naploz("uj szint"); // System.out.println("HUH."); } else if (status==A_FELFUGGESZTVE) { statRajzol(); idozitett.altass_el(); } else if (status==A_LABKEZDODIK) { statRajzol(); idozitett.altass_el(); } else if (status==A_BEIRAS) { // statRajzolando=true; // statRajzol(); } else if (status==A_FOLYIK) { lr.setDebugUzenet("megt="+idozitett.getMegteve()+" lass="+idozitett.getSikerultPeriodus()+"/"+ idozitett.getEloirtPeriodus()+" "+idozitett.getLassuMuveletSzazalek()+"%/100%"); // labirintus.getKisgomboc().fordul(ujIrany); // ^^^ ehelyett a :Kisgömböc maga hívja a getUjIrany-t labirintus.mozgat(); if (idozitett.lehet_lassu_muvelet()) { // most jön a rajzolás sd-re. Ez egy lassú művelet, úgyhogy csak // akkor végezzük, ha jól állunk időben labirintus.elorajzol(); statRajzol(); // jr.paintMost(); lr.paintMost(); idozitett.lassu_muvelet(); //rajzoltunk_osszesen++; //nem_rajzoltunk=0; idozito.altass_el(this); } else { idozitett.gyors_muvelet(); // nem_rajzoltunk++; nem_rajzoltunk_osszesen++; idozito.altass_el(this); } } else throw new HibasAllapotException(); } // WHILE(true) } /// run() protected boolean statRajzolando; protected void statValtozott() { statRajzolando=true; } protected void statRajzol(Graphics g) { /*-*- g.setColor(Color.black); g.fillRect(0,0,160,100); g.setColor(Color.white); g.drawString("gy.mar: "+labirintus.getGyemantc(),10,20); g.drawString("pontszám: "+pontszam,10,40); g.drawString("bombaszám: "+bombaszam,10,60); g.drawString("életszám: "+eletszam,10,80); */ // vvv CsakPro kisero.naploz("elet="+eletszam+" pont="+pontszam+" szint="+szint+" bomba="+bombaszam); jr.paintMost(); } /// statRajzol() protected void statRajzol() { // if (true) return; if (!statRajzolando) return; /*-*- Graphics g=jr.getSd().getBackgroundGraphics(); jr.getSd().dirtyClear(); */ Graphics g=null; statRajzol(g); /*-*- // g.dispose(); // tilos hívni! jr.getSd().dirtyAddClear(); // statRajzol(jr.getGraphics()); // jr.getSd().dirtyAddMax(); */ // System.out.println("KKK: "+labirintus.getGyemantc()); statRajzolando=false; } /// statRajzol() /** * A megadott értékkel növeli a szerzett pontszámot. */ protected void novelPontszam(int mennyivel) { pontszam+=mennyivel; statRajzolando=true; } /** * Eggyel csökkenti az életek számát. A :Labirintus hívja egyszer, nem a * :Láthatók külön-külön. */ public synchronized void csokkentEletszam() { if ((inger&F_MEGHALT)!=0) return; if (eletszam--==0) throw new AsserttError(); statRajzolando=true; inger|=F_MEGHALT; } /** * A megadott értékkel (vagy maximumra) növeli az életek számát. Akkor * növel maximumra, ha a megadott érték kisebb, mint 1. */ public void novelEletszam(int mennyivel) { if (mennyivel<1 && eletszam<maxeletszam) eletszam=maxeletszam; else if (mennyivel<1) eletszam++; else eletszam+=mennyivel; statRajzolando=true; } /** * Eggyel növeli a felvett bombák számát. */ public void novelBombaszam() { bombaszam++; statRajzolando=true; } public Kisero getKisero() { return kisero; } } /// class Jatek public static class JobboldalRajzolo extends SdRajzolo { // nem statikus. Kell neki: `betűtípus'. /*-*- Betutipus betutipus; // !! ezt nem inicializálja senki. */ JobboldalRajzolo() { /*-*- super.atmeretez(160, 480); this.setBackground(Color.red); init_sd(); */ } public void paint(Graphics g) { // Canvas újrarajzolás /*-*- g.setColor(Color.white); g.drawString("Csiribá", 10, 50); if (betutipus!=null) { betutipus.nyomtat(g,10,80,"Tősgyökeres Űrkikötőkerülő"); } */ } } /// class Jobboldalrajzolo public static class Labirintus { /** * Legfeljebb ennyi :Látható lehet egyszerre a :Labirintusban. Értéke: 42. * Értékét nem érdemes túl nagyra venni, mert négyzetesen lassul a játék * és nő a memóriaszükséglet. */ public static final int MAX_LATHATOK=42; public static final int U_MINDEGY=0, U_NEMUTKOZIK=1, U_UTKOZIK=2; protected Kisero.Labielem le; protected Kep palya_alja; protected Kep palya_teteje; protected Kep palya_arnyeka; protected Kep palya_grafja; protected Sdpts sd; protected Jatek jatek; protected Csucs kezdocsucs; /** * A következő ciklus bombalerakással kezdődik, mégpedig a megadott * :Helyzet-be. */ protected Helyzet bombaLerakando; /** * Bombalerakást kezdeményez (a kovetkezo ciklusra) a megadott :Helyzet-be. */ public void bombatLerak(Helyzet h) { bombaLerakando=new Helyzet(h); } /** * A :Labirintusban található :Gyémánt-ok száma. */ protected int gyemantc; // private Vector csucsok; // num->Csucs int getGyemantc() { return gyemantc; } protected Lathato lathatok[]; /** * A vele azonos indexű `this.lathatok'-beli elem törlendő-e? */ protected boolean torlendo[]; protected int utkozesek[][]; protected int utkozesc[]; protected int addLathatoI; // a legutolsó index, ahova addLathato adott /** * Ellenőrzi, hogy a `lathatok' és a `torlendo' tömb (és az egyéb * attribútumok) konzisztensek-e. * `AsserttError' kivételt vált ki, ha nem. */ public void assertt() { if (gyemantc<0) throw new AsserttError(); int c=gyemantc; int cc=0; if (lathatok==null) throw new AsserttError(); if (torlendo==null || lathatok.length!=torlendo.length) throw new AsserttError(); for (int i=0;i<lathatok.length;i++) { if (torlendo[i] && lathatok[i]==null) throw new AsserttError(); if (lathatok[i]==null) continue; if (lathatok[i].getId()!=i) throw new AsserttError(); if (lathatok[i] instanceof Gyemant) c--; if (lathatok[i] instanceof Kisgomboc) cc++; } if (c!=0) throw new AsserttError(c+" +Gyemant ("+gyemantc+")"); if (cc>1) throw new AsserttError(cc+" db :Kisgomboc"); } /** * Akkor váltódik ki, ha `this.lathatok[]' betelt. */ public static class NincsHelyError extends Error {} /** * Egy új :Látható-t helyez el this.lathatok-ban. */ protected Lathato addLathato(Lathato lathato) { int i=addLathatoI+1; lathato.setNaplozo(jatek.getKisero()); lathato.naploz(" keletkezik"); if (lathato instanceof Gyemant) gyemantc++; while (i!=addLathatoI) { i%=lathatok.length; if (lathatok[i]==null) { lathato.setId(i); lathatok[i]=lathato; for (int j=0;j<lathatok.length;j++) if (i!=j && lathatok[j]!=null) { utkozesek[i][j]=lathatok[i].akarsz_e_utkozni(lathatok[j])?U_NEMUTKOZIK:U_MINDEGY; utkozesek[j][i]=lathatok[j].akarsz_e_utkozni(lathatok[i])?U_NEMUTKOZIK:U_MINDEGY; } addLathatoI=i; return lathato; } } throw new NincsHelyError(); } /** * A `Lathato.halad()'-ok hívják, ha valakit el akarnak távolítani. * Egyelőre csak feljegyzi, hogy el kell távolítani, és a tényleges * munkat `Labirintu.eltunnek()'-re hagyja. * @see eNTitanok.kkkg.KkkgPro.Labirintus#eltunnek() */ public void removeLathato(Lathato lathato) { int id=lathato.getId(); if (id>=0) torlendo[id]=true; } /** * A `removeLathato()'-val elvett :Láthatókat tünteti el végleg. * @see eNTitanok.kkkg.KkkgPro.Labirintus#removeLathato */ public void eltunnek() { for (int i=0;i<lathatok.length;i++) if (torlendo[i]) { Lathato lathato=lathatok[i]; if (lathato==null) throw new AsserttError(); lathato.setId(-1); lathato.naploz(" eltunik"); if (lathato instanceof Gyemant) { if (--gyemantc<1) jatek.szintlepes(); } else if (lathato instanceof Kisgomboc) jatek.csokkentEletszam(); int u[]=utkozesek[i]; for (int j=0;j<lathatok.length;j++) u[j]=U_MINDEGY; for (int j=0;j<lathatok.length;j++) utkozesek[j][i]=U_MINDEGY; lathatok[i]=null; torlendo[i]=false; } } /// eltunnek() /** * Eltörli a szörnyeket és az ajándékokat, továbbá a kezdőcsúcsba mozgatja * a :Kisgömböc-öt. `this.mozgat()'-on belülről tilos hívni. */ public void alaphelyzetbe() { bombaLerakando=null; for (int i=0;i<lathatok.length;i++) if (lathatok[i]!=null) { Lathato lathato=lathatok[i]; if (lathato instanceof Ajandek) removeLathato(lathato); else if (lathato instanceof Szorny) removeLathato(lathato); else if (lathato instanceof KetyegoBomba) removeLathato(lathato); else if (lathato instanceof Kisgomboc) throw new AsserttError(); } eltunnek(); addLathato(new Kisgomboc(this)).athelyez(kezdocsucs); } /** * Akkor hívódik meg, amikor a :Játék-nak már nincs szüksége this-re. * Csak az a dolga, hogy felszabadítson némi memóriát. */ public void feloszlat() { kezdocsucs=null; } public void elorajzol() { sd.dirtyClear(); for (int i=0;i<lathatok.length;i++) if (lathatok[i]!=null) lathatok[i].rarajzolArnyek(sd); // ^^^ előbb az _összes_ árnyékot felrajzoljuk for (int i=0;i<lathatok.length;i++) if (lathatok[i]!=null) lathatok[i].rarajzol(sd); // sd.dirtyCover(); // az sprite-okat fedje a falrács // sd.fullCover(); // az egészet fedje a falrács // KkkgPro.this.repaint(); // rögtön visszatér, de összevissza bufferel } public Labirintus(Jatek jatek, int sorszam) { Kepbetolto kepbetolto=jatek.getKepbetolto(); this.jatek=jatek; this.sd=jatek.getLabSd(); this.le=(Kisero.Labielem)jatek.getKisero().labirintussor.elsoTorol(); if (this.le==null) throw new HibasGrafError("szintlepeshez nincs kov. palya"); String ss=Util.decformat(sorszam, 3); palya_alja= kepbetolto.betolt("p_"+ss+"h.gif").initi(sd,0,0); palya_teteje= kepbetolto.betolt("p_"+ss+"e.gif").initi(sd,0,0); palya_arnyeka=kepbetolto.betolt("p_"+ss+"g.gif").initi(sd,0,0); palya_grafja= kepbetolto.betolt("p_"+ss+"g.gif").initi(sd,0,0); lathatok=new Lathato[MAX_LATHATOK]; torlendo=new boolean[lathatok.length]; addLathatoI=lathatok.length-1; utkozesek=new int[lathatok.length][]; utkozesc=new int[lathatok.length]; for (int i=0;i<lathatok.length;i++) utkozesek[i]=new int[lathatok.length]; // addLathato(new Kisgomboc(this)); new Gyemant(this,false); // csak azért, hogy a képét letöltse //addLathato(new BalraSzorny(this,40)); //for (int i=0;i<8;i++) addLathato(new RepuloGyemant(this,48-i,24-i)).mozgat(50*24,50*24); // a képek betöltődésére várni kell, a további inicializalast a // palya_betoltve() vegzi } public Jatek getJatek() { return jatek; } public Kepbetolto getKepbetolto() { return jatek.getKepbetolto(); } public Sdpts getSd() { return sd; } //-- public Kisgomboc getKisgomboc() { return (Kisgomboc)lathatok[0]; } //-- public void kezdocsucsba(Helyzet h) { h.athelyez(kezdocsucs); } // ^^^ public void kezdocsucsba(Helyzet h) { h.athelyez((Csucs)csucsok.get(0)); } public int getUtkozesc(int id) { return utkozesc[id]; } /** * Azokat a :Láthatókat adja vissza, akikkel `lathato' éppen * ütközik. (Persze `lathato' nem szerepel a visszaadott listában.) */ public Lathato[] getUtkozesek(Lathato lathato) { int id=lathato.getId(); if (id<0 || utkozesc[id]<1) return null; Lathato t[]=new Lathato[utkozesc[id]]; int i=0; int u[]=utkozesek[id]; for (int j=0;j<u.length;j++) if (u[j]==U_UTKOZIK) t[i++]=lathatok[j]; return t; } public void palya_betoltve() { /* inicializálás miután a pálya már betöltődött */ jatek.getKepbetolto().elfelejt(palya_alja.getFilenev()); jatek.getKepbetolto().elfelejt(palya_teteje.getFilenev()); jatek.getKepbetolto().elfelejt(palya_arnyeka.getFilenev()); jatek.getKepbetolto().elfelejt(palya_grafja.getFilenev()); grafot_felepit(); // lathatok[0].utkozes_teszt(lathatok[2]); //--System.out.println(lathatok[0].mennyit_mehet(Csucs.BAL)); //--System.out.println(lathatok[0].mennyit_mehet(Csucs.FEL)); //--this.kezdocsucsba((Helyzet)lathatok[0]); //--this.kezdocsucsba((Helyzet)lathatok[1]); } /** * Hány ciklus múlva fog keletkezni :Szörny. `-1', ha még nem döntöttük * el. */ int szornyHatra=-1; /** * Hány ciklus múlva fog keletkezni :Ajándék. `-1', ha még nem döntöttük * el. */ int ajandekHatra=-1; /** * Itt keletkeznek az új :Szörny-ek és :Ajándék-ok és :Bombák. */ public void keletkeznek() { // System.err.println("KK"); Kisero kisero=jatek.getKisero(); if (bombaLerakando!=null) { addLathato(new KetyegoBomba( this, kisero.Kisgomboc_KetyegoBomba, kisero.Szorny_KetyegoBomba )).athelyez(bombaLerakando); bombaLerakando=null; } // System.err.println("SH="+szornyHatra); // DBG if (szornyHatra<1 || ajandekHatra<1) { Kisgomboc kisgomboc=getKisgomboc(); int maradt=10; // legfeljebb ennyiszer próbálkozunk lerakni while (szornyHatra<1) { // System.err.println("SS"); // DBG if (szornyHatra<0 || maradt--<=0) szornyHatra=Math.max(0,le.szorny.general()); // System.err.println("SS h="+szornyHatra); // DBG if (szornyHatra==0) { // :Szörny keletkezik épp most int milyen=le.okosbutabaljobbbfjl.general(); int seb=le.szornyseb.general(); Szorny sz=null; switch (milyen) { case 0: sz=new OkosSzorny(this, seb, le.fordul, kisero.Kisgomboc_Szorny); break; case 1: sz=new ButaSzorny(this, seb, le.fordul, kisero.Kisgomboc_Szorny); break; case 2: sz=new BalraSzorny(this, seb, le.fordul, kisero.Kisgomboc_Szorny); break; case 3: sz=new JobbraSzorny(this, seb, le.fordul, kisero.Kisgomboc_Szorny); break; case 4: sz=new BalraFelSzorny(this, seb, le.fordul, kisero.Kisgomboc_Szorny); break; case 5: sz=new JobbraLeSzorny(this, seb, le.fordul, kisero.Kisgomboc_Szorny); break; default: throw new AsserttError(); } int hely; Csucs cs=(Csucs)szornyhelyek.elementAt(hely=le.szornyhol.general()); if (sz.alkalmasKel(cs.getTavolsag(), kisgomboc.ferdeTavolsag(cs))) { addLathato(sz).athelyez(cs); szornyHatra=-1; } else sz.naploz(" nem keletkezik "+hely+". helyen", kisero); } // IF } // WHILE maradt=10; // legfeljebb ennyiszer próbálkozunk lerakni while (ajandekHatra<1) { // System.err.println("AA"); // DBG if (ajandekHatra<0 || maradt--<=0) ajandekHatra=Math.max(0,le.ajandek.general()); // System.err.println("AA h="+ajandekHatra); // DBG if (ajandekHatra==0) { // :Ajándék keletkezik épp most int milyen=le.bonbomsimszu.general(); Ajandek aj=null; switch (milyen) { case 0: aj=new Bonusz(this, kisero.Kisgomboc_Ajandek); break; case 1: aj=new FelvehetoBomba(this, kisero.Kisgomboc_Ajandek); break; case 2: aj=new SimaElixir(this, kisero.Kisgomboc_Ajandek); break; case 3: aj=new SzuperElixir(this, kisero.Kisgomboc_Ajandek); break; default: throw new AsserttError(); } int hely; Csucs cs=(Csucs)ajandekhelyek.elementAt(hely=le.ajandekhol.general()); if (aj.alkalmasKel(cs.getTavolsag(), kisgomboc.ferdeTavolsag(cs))) { addLathato(aj).athelyez(cs); // aj.naploz("NNN"); ajandekHatra=-1; } else aj.naploz(" nem keletkezik "+hely+". helyen", kisero); } // IF } // WHILE } // IF szornyHatra--; ajandekHatra--; } /// keletkeznek() /** * Megvizsgálja az összes érdekes ütközést az összes lehetséges * :Látható-párra, és az eredményt * `this.utkozesek'-be gyűjti. */ public void utkozesvizsgalat() { int i, j, u[], uc; for (i=0;i<lathatok.length;i++) { u=utkozesek[i]; uc=0; for (j=0;j<lathatok.length;j++) if (u[j]!=U_MINDEGY) if (lathatok[i].utkozik_e(lathatok[j])) { u[j]=U_UTKOZIK; uc++; // vvv CsakPro lathatok[i].naploz(" utkozik "+lathatok[j].getKlassz()+"-vl"); } else { u[j]=U_NEMUTKOZIK; } utkozesc[i]=uc; } } /// utkozesvizsgalat() /** * Egyetlen ciklusnyi időnek megfelelően mozgatja a labirintus :Látható-it. */ public void mozgat() { // System.err.println("0=>"+((Csucs)meropontok.elementAt(0)).getTavolsag()); // DBG // System.err.println("1=>"+((Csucs)meropontok.elementAt(1)).getTavolsag()); // DBG // System.err.println("3=>"+((Csucs)meropontok.elementAt(3)).getTavolsag()); // DBG assertt(); // CsakPro kitablaz(); keletkeznek(); // kitablaz() eredményét már felhasználjuk assertt(); // CsakPro utkozesvizsgalat(); // vvv meghívjuk a halad-ot minden :Látható-ra (a halad már felhasználja az ütközési táblázatot for (int i=0;i<lathatok.length;i++) if (lathatok[i]!=null) lathatok[i].halad(); // ((Helyes)lathatok[0]).halad_amerre_fordul(); eltunnek(); assertt(); // CsakPro } // --- most jönnek a gráfot felépítő segédrutinok public static class HibasGrafError extends Error { public HibasGrafError(String s) { super(s); } } // public static class KisgombocHianyzikException extends HibasGrafException {} /** * Pontosan akkor `true', ha a megadott pozíción határcsúcs van, vagyis * olyan csúcs, melyet :Csúcs-nak fel kell vennünk a gráfba. Csak a * grafot_felepit() hívja. */ private boolean hatarcsucs_e(int[][] tt, int x, int y) { if (tt[y][x]==Konst.D_FAL) return false; if (tt[y][x]!=Konst.D_UT) return true; boolean fel=tt[y-1][x]!=Konst.D_FAL; boolean le=tt[y+1][x]!=Konst.D_FAL; boolean jobb=tt[y][x+1]!=Konst.D_FAL; boolean bal=tt[y][x-1]!=Konst.D_FAL; return !((fel&&le&&!jobb&&!bal) || (!fel&&!le&&jobb&&bal)); } /** * :Csucs-okból álló Vector, a lehetséges :Szörny keletkezési helyeket * tárolja. */ protected Vector szornyhelyek; /** * :Csucs-okból álló Vector, a lehetséges :Ajándék keletkezési helyeket * tárolja. */ protected Vector ajandekhelyek; /** * Csak hibakeresés céljára. */ private Vector meropontok=new Vector(); /** * Pontosan akkor true, ha a ciklus végén `this.kitablaz()'-t kell * futtatni. A :Kisgömböc állítja be néha true-ra * @see eNTitanok.kkkg.KkkgPro.Labirintus#kitablazando() */ protected boolean kitablazando_e=true; /** * `this.kitablazando=true'. */ public void kitablazando() { kitablazando_e=true; } /** * A :Kisgömböc felé vezető legrövidebb utat keresi meg. Az összes :Csúcs * irány- és távolságjelző tábláját frissíti. Implementáció: ez egy * legrövidebbút-kereső gráfalgoritmus, amit tipikusan Dijkstra módszerével * szoktak leprogramozni. Mi kihasználjuk, hogy a labirintusgráfunk * euklideszi síkon van, így egy gyorsabb, egyszerűbb szélességi keresés * is jó (optimális, legrövidebb) eredményt ad. */ public void kitablaz() { if (!kitablazando_e) return; // vvv először is mindenkit kinyomunk plusz végtelenbe Sor szurke=new Sor(); // :Csúcs-okból áll kezdocsucs.setTavolsag(Integer.MAX_VALUE); szurke.vegehezFuz(kezdocsucs); Csucs csucs; while (null!=(csucs=(Csucs)szurke.elsoTorol())) csucs.tavolit(szurke); // vvv megkeressük a legrövidebb utat szélességi kereséssel // Dat: szurke most üres. getKisgomboc().ketSzomszed(szurke); while (null!=(csucs=(Csucs)szurke.elsoTorol())) csucs.kozelit(szurke); } /** * A :Labirintusban található egyetlen :Kisgömböc objektumot adja vissza. * Csak a :Labirintusból hívható, külsősöknek semmi közük hozzá. */ protected Kisgomboc getKisgomboc() { for (int i=0;i<lathatok.length;i++) if (lathatok[i] instanceof Kisgomboc) return (Kisgomboc)lathatok[i]; throw new AsserttError(); } /** * A `palya_grafja' kép alapján felépíti a labirintusgráfot. */ public void grafot_felepit() { int tt[][]=null; // tt=palya_grafja.getPixelttnot(); // !! tt=le.getPix(); Csucs ki[][]=new Csucs[tt.length][]; kezdocsucs=null; ajandekhelyek=new Vector(); szornyhelyek=new Vector(); // Hashtable ht=new Hashtable(); // (y<<16+x)->Csucs; SUXX: nem lehet int-tel indexelni // System.out.println(tt.length); // System.out.println(tt[0].length); //for(i=1;i<=10;i++) cout<<i<<"\n"; // by Szilvi int meropontc=0; gyemantc=0; Csucs cs=null; for (int y=tt.length-2;y>=1;y--) { int uu[]=tt[y]; ki[y]=new Csucs[uu.length]; for (int x=uu.length-2;x>=1;x--) { if (uu[x]==Konst.D_KOMMENT) uu[x]=Konst.D_FAL; if (!hatarcsucs_e(tt, x, y)) continue; cs=new Csucs(x*24, y*24); if (uu[x]==Konst.D_KISGOMBOC) { if (kezdocsucs!=null) throw new MarErtekesError(); kezdocsucs=cs; addLathato(new Kisgomboc(this)).athelyez(cs); } else if (uu[x]==Konst.D_AJANDEK) { ajandekhelyek.addElement(cs); } else if (uu[x]==Konst.D_SZORNY) { szornyhelyek.addElement(cs); } else if (uu[x]==Konst.D_MEROPONT) { cs.setMeropont(meropontc++); meropontok.addElement(cs); } else if (uu[x]==Konst.D_GYEMANT) { addLathato(new Gyemant(this, jatek.getKisero().Kisgomboc_Gyemant)).athelyez(cs); } ki[y][x]=cs; // csucsok.addElement(cs); if (uu[x+1]!=Konst.D_FAL) { // összekötünk jobbra int i=x+1; while (!hatarcsucs_e(tt, i, y)) i++; cs.osszekot(ki[y][i]); } if (tt[y+1][x]!=Konst.D_FAL) { // összekötünk le int i=y+1; while (!hatarcsucs_e(tt, x, i)) i++; cs.osszekot(ki[i][x]); } } // NEXT x } // NEXT y if (szornyhelyek.size()<1) throw new HibasGrafError("nincs Szorny keletkezesi hely"); if (ajandekhelyek.size()<1) throw new HibasGrafError("nincs Ajandek keletkezesi hely"); le.szornyholMeret(szornyhelyek.size()); le.ajandekholMeret(ajandekhelyek.size()); if (kezdocsucs==null) kezdocsucs=cs; if (kezdocsucs==null) throw new HibasGrafError("Kisgomboc hianyzik"); // System.exit(42); // applet-ből SecurityException-t ad palya_grafja.pixelt_felejt(); } public static class LabirintusRajzolo extends SdRajzolo { protected String miertErvenytelen; protected String debugUzenet; public LabirintusRajzolo() { super.atmeretez(320, 480); init_sd(); miertErvenytelen="Inicializálok..."; } public void ervenytelenit(String miert) { miertErvenytelen=miert; } public void setDebugUzenet(String miert) { debugUzenet=miert; } public void ervenyesit(Labirintus l) { /*-*- Graphics g=this.sd.getBackgroundGraphics(); l.palya_alja.rarajzol(g,0,0); // g.setColor(Color.pink); g.fillRect(100,100,200,200); // sd.dirtyAdd(0,0,screenW,screenH); this.sd.dirtyAddClear(); // g.dispose(); // Tilos hívni! // g=this.sd.getCoverGraphics(); l.palya_teteje.rarajzol(g,0,0); g.dispose(); this.sd.setCover(l.palya_teteje.getImage()); // g=this.sd.getShadowGraphics(); l.palya_arnyeka.rarajzol(g,0,0); g.dispose(); this.sd.setShadow(l.palya_grafja.getImage()); this.sd.dirtyAdd(0,0,this.sd.getWidth(),this.sd.getHeight()); this.sd.dirtyClear(); */ miertErvenytelen=null; } public void paint(Graphics g) { // Canvas újrarajzolás /*-*- // if (true) { } else if (miertErvenytelen!=null) { g.setColor(Color.green.darker()); g.fillRect(0, 0, this.sd.getWidth(), this.sd.getHeight()); g.setColor(Color.red.brighter()); // g.drawString("Épp töltögetek...", 10, 20); g.drawString(miertErvenytelen, 10, 20); } else { this.sd.renderAll(g, 0, 0); // ^^^ az egész ablakot cakumpakk újrarajzoljuk // g.setColor(Color.white); // for (int i=0;i<elek.length;i++) { elek[i].rarajzol(g); } // ^^^ csak debug, már nem kell // if (sebesseg!=0) {} if (debugUzenet!=null) { // if (true) throw new NullPointerException(); g.setColor(Color.white); //g.drawString("Lassúság: eddig="+sebesseg+"/"+1000*idozito.getInterval()+ // " rajzolás="+(100*(rajzoltunk_osszesen)/(rajzoltunk_osszesen+nem_rajzoltunk_osszesen))+ // "%.",10,20); g.drawString(debugUzenet, 10, 20); } //frissitesre_varunk=false; } //palya_teteje.rarajzol(g, 0, 0); */ } /// paint() } /// class LabirintusRajzolo } /// class Labirintus public void update(Graphics g) { this.paint(g); } // ^^^ Panel.this.paint()-et meghagyjuk private boolean application_e; // pontosan akkor true, ha Java Application-ként futunk // private Jatek jatek; private Kisero kisero; private Labirintus.LabirintusRajzolo labirintusRajzolo; private JobboldalRajzolo jobboldalRajzolo; public KkkgPro() {} private KkkgPro(boolean application_e) { this.application_e=application_e; } public java.net.URL getCodeBase() { return application_e?null:super.getCodeBase(); } /** * A tesztfile neve, mielőtt létrehozzuk a :Kísérő-.t * @see Kisero */ protected String teszt; public void setTeszt(String teszt) { this.teszt=teszt; } /** * mindhárom komponenshez hozzáadja a *Listener-eket. Elvileg elég lenne * csak az applet-hez, de Java 1.1.7, Linux alatt mindegyikhez kell, * különben nem működik. */ public void initFigyelok() { /*-*- FocusListener myFocusListener=new FocusAdapter() { public void focusGained(java.awt.event.FocusEvent e) { System.out.println("Fokk"); } }; this.addFocusListener(myFocusListener); labirintusRajzolo.addFocusListener(myFocusListener); jobboldalRajzolo.addFocusListener(myFocusListener); MouseListener myMouseListener=new MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent e) { // nem hívódik meg, mert az al-komponensek kapják meg az üzenetet // ,elfelejtodik'' meghivodni, ha az eger elmozdult a gomblenyomas // es a felengedes kozott //KkkgPro.this.repaint(teglalap_x-40,teglalap_y-25,80,50); //teglalap_x=e.getX(); teglalap_y=e.getY(); System.out.println("Klitty x="+Integer.toString(e.getX())+ " y="+Integer.toString(e.getY())+"."); // KkkgPro.this.repaint(teglalap_x-40,teglalap_y-25,80,50); // KkkgPro.this.repaint(); KkkgPro.this.requestFocus(); } }; this.addMouseListener(myMouseListener); labirintusRajzolo.addMouseListener(myMouseListener); jobboldalRajzolo.addMouseListener(myMouseListener); KeyListener myKeyListener=new KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent e) { // csak olyan billentyukre hivodik meg, amelyek karakter beszurasat eredemenyezik. // tehat peldaul meghivodik A, ó, Enter, szóköz stb-re, de nem hivodik meg // pl. Home, Shift, NumLock stb.-re // java.text.DecimalFormat f; // f=new java.text.DecimalFormat("U+0000"); // System.out.println("Potty karakter Unicode U+"+Integer.toHexString(e.getKeyChar())+"."); // ^^^ jo, de neha tul rovid // System.out.println("Potty karakter Unicode "+new java.text.DecimalFormat("U+0000").format(e.getKeyChar())+"."); // ^^^ jo lenne, de 16-os szamrendszerben kellene // if (e.getKeyChar==27) // SUXX: appletből nem lehet kilépni... System.out.println("Potty karakter Unicode U+"+Util.hexformat(e.getKeyChar(),4)+"."); // ^^^ jo lenne, de 16-os szamrendszerben kellene } // vvv for Java version 1.1.7 compatibility public final int VK_KP_UP=0xE0; public final int VK_KP_DOWN=0xE1; public final int VK_KP_LEFT=0xE2; public final int VK_KP_RIGHT=0xE3; public void keyPressed(java.awt.event.KeyEvent e) { // minden billenyure meghivodik int kc=e.getKeyCode(); // if (kc==e.VK_UP) { menne_fel=true; menne_le=false; } // if (kc==e.VK_DOWN) { menne_le=true; menne_le=false; } // if (kc==e.VK_UP || kc==e.VK_KP_UP) jatek.getLabirintus().getKisgomboc().fordul(Csucs.FEL); //else if (kc==e.VK_DOWN || kc==e.VK_KP_DOWN) jatek.getLabirintus().getKisgomboc().fordul(Csucs.LE); //else if (kc==e.VK_LEFT || kc==e.VK_KP_LEFT) jatek.getLabirintus().getKisgomboc().fordul(Csucs.BAL); //else if (kc==e.VK_RIGHT || kc==e.VK_KP_RIGHT) jatek.getLabirintus().getKisgomboc().fordul(Csucs.JOBB); if (kc==e.VK_UP || kc==VK_KP_UP) jatek.fordulj(Csucs.FEL); else if (kc==e.VK_DOWN || kc==VK_KP_DOWN) jatek.fordulj(Csucs.LE); else if (kc==e.VK_LEFT || kc==VK_KP_LEFT) jatek.fordulj(Csucs.BAL); else if (kc==e.VK_RIGHT || kc==VK_KP_RIGHT) jatek.fordulj(Csucs.JOBB); else System.out.println("Potty le bilkod="+new Integer(e.getKeyCode()).toString()+"."); } public void keyReleased(java.awt.event.KeyEvent e) { // minden billentyure meghivodik System.out.println("Potty fel bilkod="+new Integer(e.getKeyCode()).toString()+"."); // teglalap_x=KkkgPro.this.getSize().width/2; // teglalap_y=KkkgPro.this.getSize().height/2; KkkgPro.this.repaint(); } }; this.addKeyListener(myKeyListener); labirintusRajzolo.addKeyListener(myKeyListener); jobboldalRajzolo.addKeyListener(myKeyListener); */ } /** * Az ablak első megjelenése <I>előtti</I> inicializálásokat végzi el, * például háttérszín és méret beállítás, pakolási stratégia és a két * komponens felvétele. */ public void initAblak() { labirintusRajzolo=new Labirintus.LabirintusRajzolo(); jobboldalRajzolo=new JobboldalRajzolo(); /*-*- Kepek.setMainComponent(this); // először a megjelenítést inicializáljuk this.setBackground(Color.yellow); // sose szabadna látszania!! this.resize(480, 480); // ^^^ appletviewer-nek kell. application-ként nagyobbra?! if (this.getSize().width<480 || this.getSize().height<480) throw new AtmeretezesNemSikerultException(); //this.setLayout(new GridLayout(1,2,0,0)); // SUXX, fix méret nem állítható be this.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); this.add(labirintusRajzolo); this.add(jobboldalRajzolo); this.requestFocus(); // ^^^ enelkul nem kapnank meg a billentyuleuteseket appletviewer-ben this.repaint(); this.requestFocus(); */ } /** * Megtesz minden tőle telhetőt, hogy megragadja a billentyűzetfókuszt. */ public void fokusztKer() { /*-*- this.requestFocus(); this.repaint(); this.requestFocus(); // nincs hatása JDK1.1.7-ben // Thread.yield(); Idozito.alszik(2000); labirintusRajzolo.requestFocus(); */ } /** * Ezt a fuggvenyt hívná az Appletviewer a program indulasakor. Mi kézzel * hívjuk a main()-ból. */ public void init() { // System.out.println("HEELO!"); initAblak(); Kepbetolto kepbetolto=new Kepbetolto(); // ezt még bármilyen kép előtt Idozito idozito=new Idozito(16); // 16. idozito.setDaemon(true); idozito.start(); // Object idozito=null; // kamu /*-*- gfx Kep k=kepbetolto.betolt("ss13.gif"); kepbetolto.mind_meglegyen(); betutipus=new Betutipus(k,0xFFFFFF); */ kisero=new Kisero(teszt); kisero.labirintusRajzolo=labirintusRajzolo; kisero.jobboldalRajzolo=jobboldalRajzolo; kisero.kepbetolto=kepbetolto; kisero.idozitett=new Idozitett(idozito); jobboldalRajzolo.repaint(); this.initFigyelok(); // Jatek jatek=new Jatek(kepbetolto, labirintusRajzolo, jobboldalRajzolo, new Idozitett(idozito)); this.fokusztKer(); kisero.start(); } public void start() { /* Applet.start() felülírva */ // this.requestFocus(); // itt sincs hatása JDK1.1.7-ben /* Csucslista cs=Csucslista.betolt(CSUCSLISTA_FILENEV); cs.felvesz(new Csucslista.CsucslistaBejegyzes("Szilvi", 888)); cs.kiir(); cs.kiment(CSUCSLISTA_FILENEV); */ } public void stop() { /* Applet.stop() felülírva */ } public static void main(String argv[]) { System.err.println("Kincskereso Kisgomboc Prototipus, 2. verzio\n(C) Spring 2001 by eNTitanok. http://www.inf.bme.hu/~pts/entitanok/\nTHIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!\n"); if (argv.length!=1) { System.err.println("Egyetlen tesztfile nevet varom parameterkent."); System.exit(2); } System.err.println("tesztfile "+argv[0]); try { KkkgPro a=new KkkgPro(true); a.setTeszt(argv[0]); /*-*- Frame f=new Frame("eNTitánok: Kincskereső Kisgömböc"); // ^^^ esetleg hullámvonalas ő jelenhet meg. \u0151 se lenne jobb, mert // az nem Unicode-os rendszerekben Q betűt eredményezne. f.setResizable(false); f.setSize(480,480); f.setBackground(Color.pink); f.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); // csak semmi kihagyás! f.addWindowListener(new WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { ((Frame)e.getComponent()).setVisible(false); // ^^^ engedi bezárni az ablakot, de ez nem elég. Mi ki akarunk lépni. System.exit(0); } }); f.show(); System.out.println("Megmutattam."); f.add(a); */ a.init(); a.start(); // Azért nem lép ki a program a main-ből való visszatérés után, mert // vannak még ,,elvarratlan'' szálak. } catch (Throwable e) { System.out.println("varatlan vegzetes hiba"); e.printStackTrace(System.err); System.exit(1); } } } /// class KkkgPro