TlačiťTlačiť Slovenčina English Hľadať RSS

© 2005 – 2024 Roman Horváth, všetky práva vyhradené. Dnes je 28. 3. 2024.

Stránka sa načítava, prosím čakajte…

Dátum: 6. 8. 2020, pred štyrmi rokmi

Bludisko je jednoduchá hra, v ktorej sa hráč (tulák) pohybuje bludiskom s cieľom zbierania hviezdičiek, pričom každá nová hviezdička sa vygeneruje v bludisku tak, aby cesta k nej bola najdlhšia. Bludisko je vygenerované tak, aby bolo celé priechodné a aby sa v ňom nenachádzali cyklicky priechodné miesta.

Tulák môže niektoré steny prebúrať medzerníkom, aby si cestu skrátil. Nie je to však zadarmo (a nie vždy to je možné). Za každú prerazenú stenu sa musí dať v bludisku vytvoriť taká nová priečka, ktorá zachová celé bludisko priechodné.

Medzerníkom môže tulák priečky aj stavať. Pri stavaní platí opačné pravidlo: niekde sa musí dať odobrať priečka tak, aby v bludisku nevznikla cyklicky priechodná chodba.

obrázok 
Ukážka projektu po spustení.

ikonaSúbory projektu na prevzatie. 5,61 kB (5,48 KiB), 6. 8. 2020

 

Zdrojové kódy projektu obsahujú iba veľmi málo komentárov, ale kód nie je nijakým spôsobom zašifrovaný – všetky identifikátory (názvy atribútov, metód, konštánt, premenných…) sú volené čo najvýstižnejšie. Cieľom je naučiť čitateľa čítať kód s porozumením a orientovať sa v ňom. Na konci stránky je niekoľko úloh vzťahujúcich sa k porozumeniu kódu.

~

import knižnica.GRobot;
import knižnica.Kláves;
import knižnica.ÚdajeUdalostí;
import static java.lang.Math.*;
import static knižnica.Svet.*;

public class Bludisko extends GRobot
{
	private byte[][] mapa =
	{
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	};

	private int[][] mapaHodnôt;
	{
		mapaHodnôt = new int[mapa.length][];
		for (int riadok = 0; riadok < mapa.length; ++riadok)
		{
			mapaHodnôt[riadok] = new int[mapa[riadok].length];
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapaHodnôt[riadok][stĺpec] = 0;
		}
	}

	public final static byte HORE   = 1;
	public final static byte VPRAVO = 2;
	public final static byte DOLE   = 4;
	public final static byte VĽAVO  = 8;
	public final static byte VŠADE  = 15;

	public final static byte NAVŠTÍVENÉ = 16;
	public final static byte OZNAČENÉ   = 32;

	public final static byte CENA   = 64;

	private double rozmer = 15.0;
	private double hrúbka =  2.5;
	private int početPolí = početPolí(); /*# Ak by sme zmenili rozmer
										  *# mapy počas činnosti programu,
										  *# museli by sme ešte raz spočítať
										  *# počet polí!
										  *#*/

	private Tulák tulák = new Tulák(this);

	private Bludisko()
	{
		super(800, 800);

		skry();
		nekresli();
		// vpravo(30);
		// skoč(-10, 10);

		/* * /
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapa[riadok][stĺpec] = (byte)náhodnéCeléČíslo(0, 15);
		/* */

		vybudujBludisko();
		nakresliBludisko();
		spustiČasovač();
	}


	private boolean kráčajHore = false;
	private boolean kráčajVpravo = false;
	private boolean kráčajDole = false;
	private boolean kráčajVľavo = false;
	private boolean ajPohnúť = true;

	@Override public void tik()
	{
		if (kráčajHore) tulák.kráčajHore(ajPohnúť);
		if (kráčajVpravo) tulák.kráčajVpravo(ajPohnúť);
		if (kráčajDole) tulák.kráčajDole(ajPohnúť);
		if (kráčajVľavo) tulák.kráčajVľavo(ajPohnúť);

		BludnáPoloha polohaTuláka = tulák.polohaVBludisku();
		if (jePolePlatné(polohaTuláka.riadok, polohaTuláka.stĺpec))
		{
			if (0 != (mapa[polohaTuláka.riadok][polohaTuláka.stĺpec] & CENA))
			{
				mapa[polohaTuláka.riadok][polohaTuláka.stĺpec] &= ~CENA;

				polohaTuláka = polohaMaxima(polohaTuláka);
				if (jePolePlatné(polohaTuláka.riadok, polohaTuláka.stĺpec))
					mapa[polohaTuláka.riadok][polohaTuláka.stĺpec] |= CENA;

				prekresliBludisko();
			}
		}

		if (neboloPrekreslené())
		{
			tulák.aktualizujPolohuASmer();
			prekresli();
		}
	}

	@Override public void stlačenieKlávesu()
	{
		switch (ÚdajeUdalostí.kláves())
		{
		case Kláves.HORE:
			kráčajHore = true;
			ajPohnúť = !ÚdajeUdalostí.klávesnica().isShiftDown();
			break;

		case Kláves.VPRAVO:
			kráčajVpravo = true;
			ajPohnúť = !ÚdajeUdalostí.klávesnica().isShiftDown();
			break;

		case Kláves.DOLE:
			kráčajDole = true;
			ajPohnúť = !ÚdajeUdalostí.klávesnica().isShiftDown();
			break;

		case Kláves.VĽAVO:
			kráčajVľavo = true;
			ajPohnúť = !ÚdajeUdalostí.klávesnica().isShiftDown();
			break;

		// case Kláves.MEDZERA: tulák.preraziť(); break;
		// case Kláves.ENTER: tulák.zaslepiť(); break;

		case Kláves.MEDZERA: tulák.prepnúť(); break;
		// case Kláves.ENTER: položiťBombu … (?)
		}
	}

	@Override public void uvoľnenieKlávesu()
	{
		switch (ÚdajeUdalostí.kláves())
		{
		case Kláves.HORE: kráčajHore = false; break;
		case Kláves.VPRAVO: kráčajVpravo = false; break;
		case Kláves.DOLE: kráčajDole = false; break;
		case Kláves.VĽAVO: kráčajVľavo = false; break;
		}
	}


	public void nakresliBludisko()
	{
		preskočVľavo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length - 1) * rozmer);

		for (int riadok = 0; riadok < mapa.length; ++riadok)
		{
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
			{
				if (0 != (mapa[riadok][stĺpec] & NAVŠTÍVENÉ))
					kružnica(rozmer / 3);

				if (0 != (mapa[riadok][stĺpec] & OZNAČENÉ))
					kružnica(rozmer / 2);

				if (0 != (mapa[riadok][stĺpec] & CENA))
					vyplnenáHviezda(rozmer / 2);

				if (0 != mapaHodnôt[riadok][stĺpec])
					text("" + mapaHodnôt[riadok][stĺpec]);

				if (0 == (mapa[riadok][stĺpec] & VŠADE))
				{
					vyplňŠtvorec(rozmer);
				}
				else
				{
					if (0 == (mapa[riadok][stĺpec] & HORE))
					{
						skoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						odskoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VPRAVO))
					{
						preskočVpravo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVľavo(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & DOLE))
					{
						odskoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						skoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VĽAVO))
					{
						preskočVľavo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVpravo(rozmer - hrúbka);
					}
				}

				preskočVpravo(rozmer * 2);
			}

			preskočVľavo(rozmer * 2 * mapa[riadok].length);
			odskoč(rozmer * 2);
		}


		preskočVpravo(rozmer);
		skoč(2 * mapa.length * rozmer - rozmer);

		for (int riadok = 0; riadok < mapa.length - 1; ++riadok)
		{
			for (int stĺpec = 0; stĺpec < mapa[riadok].length - 1; ++stĺpec)
			{
				kruh(hrúbka * 2);
				preskočVpravo(rozmer * 2);
			}

			preskočVľavo(rozmer * 2 * (mapa[riadok].length - 1));
			odskoč(rozmer * 2);
		}


		preskočVpravo((mapa[0].length - 1) * rozmer - rozmer);
		skoč(mapa.length * rozmer);
	}

	private int početPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			počet += mapa[riadok].length;
		return počet;
	}

	private int početPlnýchPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & VŠADE)) ++počet;
		return počet;
	}

	/*# – V podstate ukážka toho, ako nájsť nejaký stav…
	private boolean jestvujePlnéPole()
	{
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & VŠADE)) return true;
		return false;
	}
	*/

	public boolean jePolePlatné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length;
	}


	private boolean jePolePlné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & VŠADE);
	}

	private boolean jePoleNenavštívené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & NAVŠTÍVENÉ);
	}

	private boolean jePoleNeoznačené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & OZNAČENÉ);
	}

	private int rozdielHodnôt(int riadok1, int stĺpec1, int riadok2, int stĺpec2)
	{
		if (riadok1 < 0 || riadok1 >= mapa.length ||
			stĺpec1 < 0 || stĺpec1 >= mapa[riadok1].length ||
			riadok2 < 0 || riadok2 >= mapa.length ||
			stĺpec2 < 0 || stĺpec2 >= mapa[riadok2].length)
			return -1;
		return mapaHodnôt[riadok1][stĺpec1] - mapaHodnôt[riadok2][stĺpec2];
	}

	/*# -------------------------------------------------------------------------------- #*/

	private boolean jeOstrov(int riadok, int stĺpec)
	{
		return !jePolePlné(riadok - 1, stĺpec) && !jePolePlné(riadok + 1, stĺpec) &&
			!jePolePlné(riadok, stĺpec - 1) && !jePolePlné(riadok, stĺpec + 1);
	}

	private void zrušOstrov(int riadok, int stĺpec, int smer)
	{
		smer %= 4; if (smer < 0) smer = -smer;

		switch (smer)
		{
			case 0: /*# „Odtiaľto“ HORE a naopak. #*/
			if (jePolePlatné(riadok - 1, stĺpec))
			{
				mapa[riadok][stĺpec]   |= HORE;
				mapa[--riadok][stĺpec] |= DOLE;
			}
			break;

			case 1: /*# „Odtiaľto“ VPRAVO a naopak. #*/
			if (jePolePlatné(riadok, stĺpec + 1))
			{
				mapa[riadok][stĺpec]   |= VPRAVO;
				mapa[riadok][++stĺpec] |= VĽAVO;
			}
			break;

			case 2: /*# „Odtiaľto“ DOLE a naopak. #*/
			if (jePolePlatné(riadok + 1, stĺpec))
			{
				mapa[riadok][stĺpec]   |= DOLE;
				mapa[++riadok][stĺpec] |= HORE;
			}
			break;

			case 3: /*# „Odtiaľto“ VĽAVO a naopak. #*/
			if (jePolePlatné(riadok, stĺpec - 1))
			{
				mapa[riadok][stĺpec]   |= VĽAVO;
				mapa[riadok][--stĺpec] |= VPRAVO;
			}
			break;
		}
	}

	private void budujKanál(int riadok, int stĺpec, int smer)
	{
		if (jeOstrov(riadok, stĺpec)) return;

		smer %= 4; if (smer < 0) smer = -smer;

		for (int maxDĺžka = (int)náhodnéCeléČíslo(1, 2); maxDĺžka > 0; --maxDĺžka)
		{
			switch (smer)
			{
				case 0: /*# „Odtiaľto“ HORE a naopak. #*/
				if (jePolePlatné(riadok - 1, stĺpec))
				{
					mapa[riadok][stĺpec]   |= HORE;
					mapa[--riadok][stĺpec] |= DOLE;
				}
				break;

				case 1: /*# „Odtiaľto“ VPRAVO a naopak. #*/
				if (jePolePlatné(riadok, stĺpec + 1))
				{
					mapa[riadok][stĺpec]   |= VPRAVO;
					mapa[riadok][++stĺpec] |= VĽAVO;
				}
				break;

				case 2: /*# „Odtiaľto“ DOLE a naopak. #*/
				if (jePolePlatné(riadok + 1, stĺpec))
				{
					mapa[riadok][stĺpec]   |= DOLE;
					mapa[++riadok][stĺpec] |= HORE;
				}
				break;

				case 3: /*# „Odtiaľto“ VĽAVO a naopak. #*/
				if (jePolePlatné(riadok, stĺpec - 1))
				{
					mapa[riadok][stĺpec]   |= VĽAVO;
					mapa[riadok][--stĺpec] |= VPRAVO;
				}
				break;
			}

			žiadajPrekreslenie();
		}

		/*# Nasledujúcimi riadkami sme schopní ovplyvniť správanie
		 *# „budovateľa kanálov“ počas procesu budovania základu
		 *# bludiska. Hodnota premennej čoĎalej má vždy po vybudovaní
		 *# krátkeho úseku bludiska rozhodnúť o tom, kam ďalej. Je
		 *# vyhodnotená bitovo. Prvý bit znamená odbočiť doľava
		 *# a druhý zase doprava. Z toho vyplýva, že hodnoty 0 až 3
		 *# znamenajú:
		 *#   0 – stoj na mieste
		 *#   1 – pokračuj – odboč doľava
		 *#   2 – pokračuj – odboč doprava
		 *#   3 – pokračuj – vybuduj T-čko (odboč doľava aj doprava)
		 *# Podľa toho sa dá určiť, ako rozdielne sa bude budovateľ
		 *# správať, keď budeme generovať hodnotu čoĎalej v rozmedzí
		 *# od 1 do 3, od 0 do 2, prípadne v inom rozmedzí…
		 */
		// int čoĎalej = (int)náhodnéCeléČíslo(1, 3);
		int čoĎalej = (int)náhodnéCeléČíslo(0, 2);
		if (0 != (čoĎalej & 1)) budujKanál(riadok, stĺpec, smer - 1);
		if (0 != (čoĎalej & 2)) budujKanál(riadok, stĺpec, smer + 1);
	}

	private void vybudujZákladBludiska()
	{
		int riadok = 0;
		int stĺpec = 0;
		int početPlnýchPolí = početPlnýchPolí();

		while (početPlnýchPolí > 0)
		{
			int početPosunov = (int)náhodnéCeléČíslo(0, početPlnýchPolí);

			while (!jePolePlné(riadok, stĺpec) || početPosunov > 0)
			{
				if (++stĺpec >= mapa[riadok].length)
				{
					stĺpec = 0;
					if (++riadok >= mapa.length)
						riadok = 0;
				}

				if (jePolePlné(riadok, stĺpec)) --početPosunov;
			}

			int smer = (int)náhodnéCeléČíslo(0, 3);
			if (jeOstrov(riadok, stĺpec))
				zrušOstrov(riadok, stĺpec, smer); /*# Nerekurzívna verzia metódy na budovanie bludiska #*/
			else
				budujKanál(riadok, stĺpec, smer); /*# Rekurzívna verzia metódy na budovanie bludiska #*/

			početPlnýchPolí = početPlnýchPolí();
		}
	}

	/*# -------------------------------------------------------------------------------- #*/

	private void vyčistiMapu()
	{
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
			{
				mapa[riadok][stĺpec] &= ~(byte)(NAVŠTÍVENÉ | OZNAČENÉ);
				mapaHodnôt[riadok][stĺpec] = 0;
			}
	}

	private int prehľadajKanál(int riadok, int stĺpec)
	{
		return prehľadajKanál(riadok, stĺpec, 0);
	}

	private int prehľadajKanál(int riadok, int stĺpec, int hodnota)
	{
		int počet = 1;
		mapa[riadok][stĺpec] |= NAVŠTÍVENÉ;

		mapaHodnôt[riadok][stĺpec] = ++hodnota;

		if (0 != (mapa[riadok][stĺpec] & HORE) &&
			jePoleNenavštívené(riadok - 1, stĺpec))
			počet += prehľadajKanál(riadok - 1, stĺpec, hodnota);

		if (0 != (mapa[riadok][stĺpec] & VPRAVO) &&
			jePoleNenavštívené(riadok, stĺpec + 1))
			počet += prehľadajKanál(riadok, stĺpec + 1, hodnota);

		if (0 != (mapa[riadok][stĺpec] & DOLE) &&
			jePoleNenavštívené(riadok + 1, stĺpec))
			počet += prehľadajKanál(riadok + 1, stĺpec, hodnota);

		if (0 != (mapa[riadok][stĺpec] & VĽAVO) &&
			jePoleNenavštívené(riadok, stĺpec - 1))
			počet += prehľadajKanál(riadok, stĺpec - 1, hodnota);

		return počet;
	}

	private boolean prerazKanál(int riadok, int stĺpec)
	{
		mapa[riadok][stĺpec] |= OZNAČENÉ;

		/*# Ak je pole nenavštívené, znamená to, že metóda
		 *# prehľadajKanál sa do neho nedostala a vtedy
		 *# prerazíme kanál…
		 *#*/

		if (jePoleNenavštívené(riadok - 1, stĺpec))
		{
			mapa[riadok][stĺpec]     |= HORE;
			mapa[riadok - 1][stĺpec] |= DOLE;
			return true;
		}

		if (jePoleNenavštívené(riadok, stĺpec + 1))
		{
			mapa[riadok][stĺpec]     |= VPRAVO;
			mapa[riadok][stĺpec + 1] |= VĽAVO;
			return true;
		}

		if (jePoleNenavštívené(riadok + 1, stĺpec))
		{
			mapa[riadok][stĺpec]     |= DOLE;
			mapa[riadok + 1][stĺpec] |= HORE;
			return true;
		}

		if (jePoleNenavštívené(riadok, stĺpec - 1))
		{
			mapa[riadok][stĺpec]     |= VĽAVO;
			mapa[riadok][stĺpec - 1] |= VPRAVO;
			return true;
		}

		/*# Volanie metódy prerazKanál spôsobuje prehľadávanie bludiska
		 *# („chodenie“ po ňom). Návratová hodnota bude true len v prípade,
		 *# že bolo vykonané prerazenie kanála – vtedy okamžite končíme
		 *# (lebo chceme preraziť len jednu stenu, aby sme to bludisko
		 *# nerozbúrali príliš).
		 *#*/

		if (0 != (mapa[riadok][stĺpec] & HORE) &&
			jePoleNeoznačené(riadok - 1, stĺpec))
			if (prerazKanál(riadok - 1, stĺpec)) return true;

		if (0 != (mapa[riadok][stĺpec] & VPRAVO) &&
			jePoleNeoznačené(riadok, stĺpec + 1))
			if (prerazKanál(riadok, stĺpec + 1)) return true;

		if (0 != (mapa[riadok][stĺpec] & DOLE) &&
			jePoleNeoznačené(riadok + 1, stĺpec))
			if (prerazKanál(riadok + 1, stĺpec)) return true;

		if (0 != (mapa[riadok][stĺpec] & VĽAVO) &&
			jePoleNeoznačené(riadok, stĺpec - 1))
			if (prerazKanál(riadok, stĺpec - 1)) return true;

		return false;
	}

	private boolean zaslepKanál(int riadok, int stĺpec)
	{
		mapa[riadok][stĺpec] |= OZNAČENÉ;

		/*# (Bludisko je pred zaslepovaním kanálov ohodnotené. Každá poloha
		 *# v rámci kanála dostane pridelené číslo, ktoré určuje jeho
		 *# vzdialenosť od miesta, z ktorého sme začali kanál prehľadávať.)
		 *#
		 *# Táto metóda zaslepí takú časť bludiska, ktorá je cyklická,
		 *# čo sa dá zistiť jednoducho: rozdiel hodnôt susediacich polí
		 *# je väčší ako dva (prehľadávanie pri ohodnocovaní sa sem
		 *# dostalo z dvoch rôznych smerov, preto je rozdiel hodnôt väčší).
		 *#*/

		if (0 != (mapa[riadok][stĺpec] & HORE) &&
			rozdielHodnôt(riadok, stĺpec, riadok - 1, stĺpec) > 2)
		{
			mapa[riadok][stĺpec]     &= ~HORE;
			mapa[riadok - 1][stĺpec] &= ~DOLE;
			return true;
		}

		if (0 != (mapa[riadok][stĺpec] & VPRAVO) &&
			rozdielHodnôt(riadok, stĺpec, riadok, stĺpec + 1) > 2)
		{
			mapa[riadok][stĺpec]     &= ~VPRAVO;
			mapa[riadok][stĺpec + 1] &= ~VĽAVO;
			return true;
		}

		if (0 != (mapa[riadok][stĺpec] & DOLE) &&
			rozdielHodnôt(riadok, stĺpec, riadok + 1, stĺpec) > 2)
		{
			mapa[riadok][stĺpec]     &= ~DOLE;
			mapa[riadok + 1][stĺpec] &= ~HORE;
			return true;
		}

		if (0 != (mapa[riadok][stĺpec] & VĽAVO) &&
			rozdielHodnôt(riadok, stĺpec, riadok, stĺpec - 1) > 2)
		{
			mapa[riadok][stĺpec]     &= ~VĽAVO;
			mapa[riadok][stĺpec - 1] &= ~VPRAVO;
			return true;
		}

		/*# Ak sa nenájde vhodné miesto na zaslepenie, hľadá sa
		 *# ďalej. (Naopak, pri prvej vybudovanej stene sa hľadanie
		 *# okamžite končí – nechceme bludisko zastavať príliš).
		 *#*/

		if (0 != (mapa[riadok][stĺpec] & HORE) &&
			jePoleNeoznačené(riadok - 1, stĺpec))
			if (zaslepKanál(riadok - 1, stĺpec)) return true;

		if (0 != (mapa[riadok][stĺpec] & VPRAVO) &&
			jePoleNeoznačené(riadok, stĺpec + 1))
			if (zaslepKanál(riadok, stĺpec + 1)) return true;

		if (0 != (mapa[riadok][stĺpec] & DOLE) &&
			jePoleNeoznačené(riadok + 1, stĺpec))
			if (zaslepKanál(riadok + 1, stĺpec)) return true;

		if (0 != (mapa[riadok][stĺpec] & VĽAVO) &&
			jePoleNeoznačené(riadok, stĺpec - 1))
			if (zaslepKanál(riadok, stĺpec - 1)) return true;

		return false;
	}


	private int platnýRiadok(int riadok)
	{
		double výška = mapa.length;

		if (riadok < 0) riadok += výška;
		riadok %= výška;
		if (riadok < 0) riadok = -riadok;

		return riadok;
	}

	private int platnýStĺpec(int riadok, int stĺpec)
	{
		if (riadok < 0 || riadok >= mapa.length) return -1;

		double šírkaRiadka = mapa[riadok].length;

		if (stĺpec < 0) stĺpec += šírkaRiadka;
		stĺpec %= šírkaRiadka;
		if (stĺpec < 0) stĺpec = -stĺpec;

		return stĺpec;
	}


	public void prerazBludisko(int riadok, int stĺpec)
	{
		riadok = platnýRiadok(riadok);
		stĺpec = platnýStĺpec(riadok, stĺpec);

		vyčistiMapu();
		while (prehľadajKanál(riadok, stĺpec) != početPolí)
		{
			prerazKanál(riadok, stĺpec);
			vyčistiMapu();
		}
		vyčistiMapu();
	}

	public void zaslepBludisko(int riadok, int stĺpec)
	{
		riadok = platnýRiadok(riadok);
		stĺpec = platnýStĺpec(riadok, stĺpec);

		int i = početPolí;
		do
		{
			vyčistiMapu();
			prehľadajKanál(riadok, stĺpec);
		}
		while (zaslepKanál(riadok, stĺpec) && --i > 0);
		vyčistiMapu();
	}


	public void vybudujBludisko()
	{
		vybudujZákladBludiska();
		prerazBludisko((int)náhodnéCeléČíslo(), (int)náhodnéCeléČíslo());
		zaslepBludisko((int)náhodnéCeléČíslo(), (int)náhodnéCeléČíslo());

		BludnáPoloha polohaMaxima = polohaMaxima(tulák.polohaVBludisku());
			// (int)náhodnéCeléČíslo(), (int)náhodnéCeléČíslo());
		if (jePolePlatné(polohaMaxima.riadok, polohaMaxima.stĺpec))
			mapa[polohaMaxima.riadok][polohaMaxima.stĺpec] |= CENA;
	}

	/*# -------------------------------------------------------------------------------- #*/

	public double rozmer()
	{
		return rozmer;
	}

	public int výška()
	{
		return mapa.length;
	}

	public int šírkaRiadka(int riadok)
	{
		if (riadok < 0 || riadok >= mapa.length) return -1;
		return mapa[riadok].length;
	}

	public boolean dáSaÍsťHore(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 != (mapa[riadok][stĺpec] & HORE);
	}

	public boolean dáSaÍsťVpravo(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 != (mapa[riadok][stĺpec] & VPRAVO);
	}

	public boolean dáSaÍsťDole(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 != (mapa[riadok][stĺpec] & DOLE);
	}

	public boolean dáSaÍsťVľavo(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 != (mapa[riadok][stĺpec] & VĽAVO);
	}


	public boolean preraziťHore(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok - 1, stĺpec) &&
			!dáSaÍsťHore(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     |= HORE;
			mapa[riadok - 1][stĺpec] |= DOLE;
			return true;
		}
		return false;
	}

	public boolean preraziťVpravo(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok, stĺpec + 1) &&
			!dáSaÍsťVpravo(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     |= VPRAVO;
			mapa[riadok][stĺpec + 1] |= VĽAVO;
			return true;
		}
		return false;
	}

	public boolean preraziťDole(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok + 1, stĺpec) &&
			!dáSaÍsťDole(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     |= DOLE;
			mapa[riadok + 1][stĺpec] |= HORE;
			return true;
		}
		return false;
	}

	public boolean preraziťVľavo(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok, stĺpec - 1) &&
			!dáSaÍsťVľavo(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     |= VĽAVO;
			mapa[riadok][stĺpec - 1] |= VPRAVO;
			return true;
		}
		return false;
	}


	public boolean zaslepiťHore(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok - 1, stĺpec) &&
			dáSaÍsťHore(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     &= ~HORE;
			mapa[riadok - 1][stĺpec] &= ~DOLE;
			return true;
		}
		return false;
	}

	public boolean zaslepiťVpravo(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok, stĺpec + 1) &&
			dáSaÍsťVpravo(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     &= ~VPRAVO;
			mapa[riadok][stĺpec + 1] &= ~VĽAVO;
			return true;
		}
		return false;
	}

	public boolean zaslepiťDole(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok + 1, stĺpec) &&
			dáSaÍsťDole(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     &= ~DOLE;
			mapa[riadok + 1][stĺpec] &= ~HORE;
			return true;
		}
		return false;
	}

	public boolean zaslepiťVľavo(int riadok, int stĺpec)
	{
		if (jePolePlatné(riadok, stĺpec - 1) &&
			dáSaÍsťVľavo(riadok, stĺpec))
		{
			mapa[riadok][stĺpec]     &= ~VĽAVO;
			mapa[riadok][stĺpec - 1] &= ~VPRAVO;
			return true;
		}
		return false;
	}


	public BludnáPoloha polohaMaxima(int riadok, int stĺpec)
	{
		riadok = platnýRiadok(riadok);
		stĺpec = platnýStĺpec(riadok, stĺpec);

		vyčistiMapu();
		prehľadajKanál(riadok, stĺpec);

		int riadokM = 0, stĺpecM = 0;
		int maximum = mapaHodnôt[riadokM][stĺpecM];

		for (int riadokC = 0; riadokC < mapa.length; ++riadokC)
			for (int stĺpecC = 0; stĺpecC < mapa[riadokC].length; ++stĺpecC)
			{
				if (mapaHodnôt[riadokC][stĺpecC] > maximum)
				{
					riadokM = riadokC; stĺpecM = stĺpecC;
					maximum = mapaHodnôt[riadokC][stĺpecC];
				}
			}

		vyčistiMapu();
		return new BludnáPoloha(riadokM, stĺpecM);
	}

	public BludnáPoloha polohaMaxima(BludnáPoloha poloha)
	{
		return polohaMaxima(poloha.riadok, poloha.stĺpec);
	}


	public void prekresliBludisko()
	{
		vymažGrafiku();
		nakresliBludisko();
	}

	public static void main(String[] args)
	{
		použiKonfiguráciu("Bludisko.cfg");
		new Bludisko();
	}
}

~

public class BludnáPoloha
{
	public int riadok, stĺpec;

	public BludnáPoloha(int riadok, int stĺpec)
	{
		this.riadok = riadok;
		this.stĺpec = stĺpec;
	}

	@Override public String toString()
	{
		return "r: " + riadok + "; s: " + stĺpec;
	}
}

~

import knižnica.GRobot;
import static java.lang.Math.*;
import static knižnica.Svet.*;

public class Tulák extends GRobot
{
	private Bludisko bludisko;
	private int x0, y0, x1, y1;
	private double s0, s1, krok;

	public Tulák(Bludisko bludisko)
	{
		this.bludisko = bludisko;
		farba(červená);
		hrúbkaČiary(2.0);
		x1 = x0 = (int)náhodnéCeléČíslo();
		y1 = y0 = (int)náhodnéCeléČíslo();
		s1 = s0 = 90;
		krok = 0.0;
		aktualizujPolohuASmer();
	}

	public void aktualizujPolohuASmer()
	{
		double výška = bludisko.výška();

		if (y0 < 0) y0 += výška;
		y0 %= výška;
		if (y0 < 0) y0 = -y0;

		double šírkaRiadka = bludisko.šírkaRiadka(y0);

		if (x0 < 0) x0 += šírkaRiadka;
		x0 %= šírkaRiadka;
		if (x0 < 0) x0 = -x0;

		if (y1 < 0) y1 += výška;
		y1 %= výška;
		if (y1 < 0) y1 = -y1;

		šírkaRiadka = bludisko.šírkaRiadka(y1);

		if (x1 < 0) x1 += šírkaRiadka;
		x1 %= šírkaRiadka;
		if (x1 < 0) x1 = -x1;

		double rozmer = bludisko.rozmer();
		double vľavo = (bludisko.šírkaRiadka(0) - 1) * rozmer;
		double hore = (výška - 1) * rozmer;

		poloha(bludisko);
		smer(bludisko);

		preskočVľavo(lineárnaInterpolácia(vľavo - 2 * rozmer * x0,
			vľavo - 2 * rozmer * x1, krok));
		skoč(lineárnaInterpolácia(hore - 2 * rozmer * y0,
			hore - 2 * rozmer * y1, krok));

		vpravo(90);
		if (s1 - s0 > 180)
			vľavo(lineárnaInterpolácia(s0 + 360, s1, krok));
		else if (s0 - s1 > 180)
			vľavo(lineárnaInterpolácia(s0 - 360, s1, krok));
		else
			vľavo(lineárnaInterpolácia(s0, s1, krok));
	}

	public void kráčajHore(boolean ajPohnúť)
	{
		if (aktívny()) return;

		if (bludisko.dáSaÍsťHore(y0, x0))
		{
			s0 = 90;
			if (ajPohnúť) --y0;
			aktivuj();
		}
		else if (s0 != 90)
		{
			s0 = 90;
			aktivuj();
		}
	}

	public void kráčajVpravo(boolean ajPohnúť)
	{
		if (aktívny()) return;

		if (bludisko.dáSaÍsťVpravo(y0, x0))
		{
			s0 = 0;
			if (ajPohnúť) ++x0;
			aktivuj();
		}
		else if (s0 != 0)
		{
			s0 = 0;
			aktivuj();
		}
	}

	public void kráčajDole(boolean ajPohnúť)
	{
		if (aktívny()) return;

		if (bludisko.dáSaÍsťDole(y0, x0))
		{
			s0 = 270;
			if (ajPohnúť) ++y0;
			aktivuj();
		}
		else if (s0 != 270)
		{
			s0 = 270;
			aktivuj();
		}
	}

	public void kráčajVľavo(boolean ajPohnúť)
	{
		if (aktívny()) return;

		if (bludisko.dáSaÍsťVľavo(y0, x0))
		{
			s0 = 180;
			if (ajPohnúť) --x0;
			aktivuj();
		}
		else if (s0 != 180)
		{
			s0 = 180;
			aktivuj();
		}
	}

	public void skúsZaslepiť(int začiatočnýSmer)
	{
		BludnáPoloha polohaMaxima = bludisko.polohaMaxima(y0, x0);

		for (int i = 0; i < 4; ++i)
		{
			switch ((začiatočnýSmer + i) % 4)
			{
				case 0: // vpravo
					if (bludisko.zaslepiťVľavo(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.prerazBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}

					// if (bludisko.zaslepiťVľavo(y0, x0))
					//     bludisko.prerazBludisko(y0, x0);
					break;

				case 1: // hore
					if (bludisko.zaslepiťDole(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.prerazBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}

					// if (bludisko.zaslepiťDole(y0, x0))
					//     bludisko.prerazBludisko(y0, x0);
					break;

				case 2: // vľavo
					if (bludisko.zaslepiťVpravo(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.prerazBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}
	
					// if (bludisko.zaslepiťVpravo(y0, x0))
					//     bludisko.prerazBludisko(y0, x0);
					break;

				case 3: // dole
					if (bludisko.zaslepiťHore(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.prerazBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}
	
					// if (bludisko.zaslepiťHore(y0, x0))
					//     bludisko.prerazBludisko(y0, x0);
					break;
			}
		}
	}

	public void skúsPreraziť(int začiatočnýSmer)
	{
		BludnáPoloha polohaMaxima = bludisko.polohaMaxima(y0, x0);

		for (int i = 0; i < 4; ++i)
		{
			switch ((začiatočnýSmer + i) % 4)
			{
				case 0: // vpravo
					if (bludisko.preraziťVľavo(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.zaslepBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}
	
					// if (bludisko.preraziťVľavo(y0, x0))
					//     bludisko.zaslepBludisko(y0, x0);
					break;

				case 1: // hore
					if (bludisko.preraziťDole(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.zaslepBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}
	
					// if (bludisko.preraziťDole(y0, x0))
					//     bludisko.zaslepBludisko(y0, x0);
					break;

				case 2: // vľavo
					if (bludisko.preraziťVpravo(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.zaslepBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}

					// if (bludisko.preraziťVpravo(y0, x0))
					//     bludisko.zaslepBludisko(y0, x0);
					break;

				case 3: // dole
					if (bludisko.preraziťHore(
						polohaMaxima.riadok, polohaMaxima.stĺpec))
					{
						bludisko.zaslepBludisko(
							polohaMaxima.riadok, polohaMaxima.stĺpec);
						return;
					}

					// if (bludisko.preraziťHore(y0, x0))
					//     bludisko.zaslepBludisko(y0, x0);
					break;
			}
		}
	}

	public void preraziť()
	{
		if (aktívny()) return;

		if (s0 <= 45 || s0 > 315) // Vpravo
		{
			if (bludisko.preraziťVpravo(y0, x0))
			{
				// pípni();
				skúsZaslepiť(0);

				bludisko.zaslepBludisko(y0, x0 + 1);
				bludisko.prekresliBludisko();
			}
		}
		else if (s0 <= 135) // Hore
		{
			if (bludisko.preraziťHore(y0, x0))
			{
				// pípni();
				skúsZaslepiť(1);

				bludisko.zaslepBludisko(y0 - 1, x0);
				bludisko.prekresliBludisko();
			}
		}
		else if (s0 <= 225) // Vľavo
		{
			if (bludisko.preraziťVľavo(y0, x0))
			{
				// pípni();
				skúsZaslepiť(2);

				bludisko.zaslepBludisko(y0, x0 - 1);
				bludisko.prekresliBludisko();
			}
		}
		else if (s0 <= 315) // Dole
		{
			if (bludisko.preraziťDole(y0, x0))
			{
				// pípni();
				skúsZaslepiť(3);

				bludisko.zaslepBludisko(y0 + 1, x0);
				bludisko.prekresliBludisko();
			}
		}
	}

	public void zaslepiť()
	{
		if (aktívny()) return;

		if (s0 <= 45 || s0 > 315) // Vpravo
		{
			if (bludisko.zaslepiťVpravo(y0, x0))
			{
				// pípni();
				skúsPreraziť(0);

				bludisko.prerazBludisko(y0, x0 + 1);
				bludisko.prekresliBludisko();
			}
		}
		else if (s0 <= 135) // Hore
		{
			if (bludisko.zaslepiťHore(y0, x0))
			{
				// pípni();
				skúsPreraziť(1);

				bludisko.prerazBludisko(y0 - 1, x0);
				bludisko.prekresliBludisko();
			}
		}
		else if (s0 <= 225) // Vľavo
		{
			if (bludisko.zaslepiťVľavo(y0, x0))
			{
				// pípni();
				skúsPreraziť(2);

				bludisko.prerazBludisko(y0, x0 - 1);
				bludisko.prekresliBludisko();
			}
		}
		else if (s0 <= 315) // Dole
		{
			if (bludisko.zaslepiťDole(y0, x0))
			{
				// pípni();
				skúsPreraziť(3);

				bludisko.prerazBludisko(y0 + 1, x0);
				bludisko.prekresliBludisko();
			}
		}
	}

	public void prepnúť()
	{
		if (aktívny()) return;

		if (s0 <= 45 || s0 > 315) // Vpravo
		{
			if (bludisko.jePolePlatné(y0, x0 + 1))
			{
				if (bludisko.dáSaÍsťVpravo(y0, x0))
					zaslepiť();
				else
					preraziť();
			}
		}
		else if (s0 <= 135) // Hore
		{
			if (bludisko.jePolePlatné(y0 - 1, x0))
			{
				if (bludisko.dáSaÍsťHore(y0, x0))
					zaslepiť();
				else
					preraziť();
			}
		}
		else if (s0 <= 225) // Vľavo
		{
			if (bludisko.jePolePlatné(y0, x0 - 1))
			{
				if (bludisko.dáSaÍsťVľavo(y0, x0))
					zaslepiť();
				else
					preraziť();
			}
		}
		else if (s0 <= 315) // Dole
		{
			if (bludisko.jePolePlatné(y0 + 1, x0))
			{
				if (bludisko.dáSaÍsťDole(y0, x0))
					zaslepiť();
				else
					preraziť();
			}
		}
	}

	public BludnáPoloha polohaVBludisku()
	{
		return new BludnáPoloha(y0, x0);
	}

	@Override public void aktivácia()
	{
		if (x0 != x1 || y0 != y1 || s0 != s1) krok = 0.8;
		žiadajPrekreslenie();
	}

	@Override public void aktivita()
	{
		if (krok > 0.0)
		{
			krok -= 0.2;
			žiadajPrekreslenie();
		}

		if (krok <= 0.0)
		{
			x1 = x0;
			y1 = y0;
			s1 = s0;
			deaktivuj();
		}
	}

	@Override public void kresliTvar()
	{
		krúžok();
		vpred();
	}
}

Úlohy

  • Analyzujte kód tried BludiskoTulák a zistite na čo slúžia atribút a parameter ajPohnúť.
  • Vyhľadajte všetky riadky alebo dlhšie pasáže kódu v komentároch a zistite ako by sa hra správala, keby boli tieto časti kódu aktívne (pozor, niektoré sú alternatívou ku kódu, ktorý nasleduje za nimi).

~

import knižnica.GRobot;
import static java.lang.Math.*;
import static knižnica.Svet.*;

public class Bludisko extends GRobot
{
	private byte[][] mapa =
	{
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	};

	private final static byte HORE   = 1;
	private final static byte VPRAVO = 2;
	private final static byte DOLE   = 4;
	private final static byte VĽAVO  = 8;
	private final static byte NIKDE  = 15;

	private final static byte NAVŠTÍVENÉ = 16;
	private final static byte OZNAČENÉ   = 32;

	private double rozmer = 15.0;
	private double hrúbka =  2.5;

	private Bludisko()
	{
		// vpravo(30);

		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapa[riadok][stĺpec] = (byte)náhodnéCeléČíslo(0, 15);

		nakresliBludisko();
	}

	public void nakresliBludisko()
	{
		preskočVľavo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length - 1) * rozmer);

		for (int riadok = 0; riadok < mapa.length; ++riadok)
		{
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
			{
				if (0 != (mapa[riadok][stĺpec] & NAVŠTÍVENÉ))
					kružnica(rozmer / 3);

				if (0 != (mapa[riadok][stĺpec] & OZNAČENÉ))
					kružnica(rozmer / 2);

				if (0 == (mapa[riadok][stĺpec] & NIKDE))
				{
					vyplňŠtvorec(rozmer);
				}
				else
				{
					if (0 == (mapa[riadok][stĺpec] & HORE))
					{
						skoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						odskoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VPRAVO))
					{
						preskočVpravo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVľavo(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & DOLE))
					{
						odskoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						skoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VĽAVO))
					{
						preskočVľavo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVpravo(rozmer - hrúbka);
					}
				}

				preskočVpravo(rozmer * 2);
			}

			preskočVľavo(rozmer * 2 * mapa[riadok].length);
			odskoč(rozmer * 2);
		}


		preskočVpravo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length + 1) * rozmer);
	}

	public static void main(String[] args)
	{
		použiKonfiguráciu("Bludisko.cfg");
		new Bludisko();
	}
}

obrázok 
Táto verzia „vyrobí“ úplne náhodné (nepoužiteľné) bludisko.

~

import knižnica.GRobot;
import static java.lang.Math.*;
import static knižnica.Svet.*;

public class Bludisko extends GRobot
{
	private byte[][] mapa =
	{
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	};

	private final static byte HORE   = 1;
	private final static byte VPRAVO = 2;
	private final static byte DOLE   = 4;
	private final static byte VĽAVO  = 8;
	private final static byte NIKDE  = 15;

	private final static byte NAVŠTÍVENÉ = 16;
	private final static byte OZNAČENÉ   = 32;

	private double rozmer = 15.0;
	private double hrúbka =  2.5;

	private Bludisko()
	{
		nekresli();
		// vpravo(30);

		/* * /
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapa[riadok][stĺpec] = (byte)náhodnéCeléČíslo(0, 15);
		/* */

		vybudujBludisko();
		nakresliBludisko();
		spustiČasovač();
	}

	@Override public void tik()
	{
		if (neboloPrekreslené()) prekresli();
	}

	public void nakresliBludisko()
	{
		preskočVľavo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length - 1) * rozmer);

		for (int riadok = 0; riadok < mapa.length; ++riadok)
		{
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
			{
				if (0 != (mapa[riadok][stĺpec] & NAVŠTÍVENÉ))
					kružnica(rozmer / 3);

				if (0 != (mapa[riadok][stĺpec] & OZNAČENÉ))
					kružnica(rozmer / 2);

				if (0 == (mapa[riadok][stĺpec] & NIKDE))
				{
					vyplňŠtvorec(rozmer);
				}
				else
				{
					if (0 == (mapa[riadok][stĺpec] & HORE))
					{
						skoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						odskoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VPRAVO))
					{
						preskočVpravo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVľavo(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & DOLE))
					{
						odskoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						skoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VĽAVO))
					{
						preskočVľavo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVpravo(rozmer - hrúbka);
					}
				}

				preskočVpravo(rozmer * 2);
			}

			preskočVľavo(rozmer * 2 * mapa[riadok].length);
			odskoč(rozmer * 2);
		}


		preskočVpravo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length + 1) * rozmer);
	}

	private int početPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			počet += mapa[riadok].length;
		return počet;
	}

	private int početPlnýchPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & NIKDE)) ++počet;
		return počet;
	}

	/*# – V podstate ukážka toho, ako nájsť nejaký stav…
	private boolean jestvujePlnéPole()
	{
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & NIKDE)) return true;
		return false;
	}
	*/

	private boolean jePolePlatné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length;
	}

	private boolean jePolePlné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & NIKDE);
	}

	private boolean jePoleNenavštívené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & NAVŠTÍVENÉ);
	}

	private boolean jePoleNeoznačené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & OZNAČENÉ);
	}

	/*# -------------------------------------------------------------------------------- #*/

	private boolean jeOstrov(int riadok, int stĺpec)
	{
		return !jePolePlné(riadok - 1, stĺpec) && !jePolePlné(riadok + 1, stĺpec) &&
			!jePolePlné(riadok, stĺpec - 1) && !jePolePlné(riadok, stĺpec + 1);
	}

	private void zrušOstrov(int riadok, int stĺpec, int smer)
	{
		smer %= 4; if (smer < 0) smer = -smer;
		/*# DOKONČIŤ TU #*/
	}

	private void vybudujZákladBludiska()
	{
		int riadok = 0;
		int stĺpec = 0;
		int početPlnýchPolí = početPlnýchPolí();

		while (početPlnýchPolí > 0)
		{
			int početPosunov = (int)náhodnéCeléČíslo(0, početPlnýchPolí);

			while (!jePolePlné(riadok, stĺpec) || početPosunov > 0)
			{
				if (++stĺpec >= mapa[riadok].length)
				{
					stĺpec = 0;
					if (++riadok >= mapa.length)
						riadok = 0;
				}

				if (jePolePlné(riadok, stĺpec)) --početPosunov;
			}

			int smer = (int)náhodnéCeléČíslo(0, 3);
			/*# DOKONČIŤ TU #*/
		}
	}

	public void vybudujBludisko()
	{
		vybudujZákladBludiska();
	}

	public static void main(String[] args)
	{
		použiKonfiguráciu("Bludisko.cfg");
		new Bludisko();
	}
}

Táto verzia „vyprodukuje“ prázdne bludisko…

~

import knižnica.GRobot;
import static java.lang.Math.*;
import static knižnica.Svet.*;

public class Bludisko extends GRobot
{
	private byte[][] mapa =
	{
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	};

	private final static byte HORE   = 1;
	private final static byte VPRAVO = 2;
	private final static byte DOLE   = 4;
	private final static byte VĽAVO  = 8;
	private final static byte VŠADE  = 15;

	private final static byte NAVŠTÍVENÉ = 16;
	private final static byte OZNAČENÉ   = 32;

	private double rozmer = 15.0;
	private double hrúbka =  2.5;

	private Bludisko()
	{
		nekresli();
		// vpravo(30);

		/* * /
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapa[riadok][stĺpec] = (byte)náhodnéCeléČíslo(0, 15);
		/* */

		vybudujBludisko();
		nakresliBludisko();
		spustiČasovač();
	}

	@Override public void tik()
	{
		if (neboloPrekreslené()) prekresli();
	}

	public void nakresliBludisko()
	{
		preskočVľavo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length - 1) * rozmer);

		for (int riadok = 0; riadok < mapa.length; ++riadok)
		{
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
			{
				if (0 != (mapa[riadok][stĺpec] & NAVŠTÍVENÉ))
					kružnica(rozmer / 3);

				if (0 != (mapa[riadok][stĺpec] & OZNAČENÉ))
					kružnica(rozmer / 2);

				if (0 == (mapa[riadok][stĺpec] & VŠADE))
				{
					vyplňŠtvorec(rozmer);
				}
				else
				{
					if (0 == (mapa[riadok][stĺpec] & HORE))
					{
						skoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						odskoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VPRAVO))
					{
						preskočVpravo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVľavo(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & DOLE))
					{
						odskoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						skoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VĽAVO))
					{
						preskočVľavo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVpravo(rozmer - hrúbka);
					}
				}

				preskočVpravo(rozmer * 2);
			}

			preskočVľavo(rozmer * 2 * mapa[riadok].length);
			odskoč(rozmer * 2);
		}


		preskočVpravo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length + 1) * rozmer);
	}

	private int početPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			počet += mapa[riadok].length;
		return počet;
	}

	private int početPlnýchPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & VŠADE)) ++počet;
		return počet;
	}

	/*# – V podstate ukážka toho, ako nájsť nejaký stav…
	private boolean jestvujePlnéPole()
	{
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & VŠADE)) return true;
		return false;
	}
	*/

	private boolean jePolePlatné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length;
	}

	private boolean jePolePlné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & VŠADE);
	}

	private boolean jePoleNenavštívené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & NAVŠTÍVENÉ);
	}

	private boolean jePoleNeoznačené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & OZNAČENÉ);
	}

	/*# -------------------------------------------------------------------------------- #*/

	private boolean jeOstrov(int riadok, int stĺpec)
	{
		return !jePolePlné(riadok - 1, stĺpec) && !jePolePlné(riadok + 1, stĺpec) &&
			!jePolePlné(riadok, stĺpec - 1) && !jePolePlné(riadok, stĺpec + 1);
	}

	private void zrušOstrov(int riadok, int stĺpec, int smer)
	{
		smer %= 4; if (smer < 0) smer = -smer;

		switch (smer)
		{
			case 0: /*# „Odtiaľto“ HORE a naopak. #*/
			if (jePolePlatné(riadok - 1, stĺpec))
			{
				mapa[riadok][stĺpec]   |= HORE;
				mapa[--riadok][stĺpec] |= DOLE;
			}
			break;

			case 1: /*# „Odtiaľto“ VPRAVO a naopak. #*/
			if (jePolePlatné(riadok, stĺpec + 1))
			{
				mapa[riadok][stĺpec]   |= VPRAVO;
				mapa[riadok][++stĺpec] |= VĽAVO;
			}
			break;

			case 2: /*# „Odtiaľto“ DOLE a naopak. #*/
			if (jePolePlatné(riadok + 1, stĺpec))
			{
				mapa[riadok][stĺpec]   |= DOLE;
				mapa[++riadok][stĺpec] |= HORE;
			}
			break;

			case 3: /*# „Odtiaľto“ VĽAVO a naopak. #*/
			if (jePolePlatné(riadok, stĺpec - 1))
			{
				mapa[riadok][stĺpec]   |= VĽAVO;
				mapa[riadok][--stĺpec] |= VPRAVO;
			}
			break;
		}
	}

	private void budujKanál(int riadok, int stĺpec, int smer)
	{
		if (jeOstrov(riadok, stĺpec)) return;

		smer %= 4; if (smer < 0) smer = -smer;

		for (int maxDĺžka = (int)náhodnéCeléČíslo(1, 2); maxDĺžka > 0; --maxDĺžka)
		{
			switch (smer)
			{
				case 0: /*# „Odtiaľto“ HORE a naopak. #*/
				if (jePolePlatné(riadok - 1, stĺpec))
				{
					mapa[riadok][stĺpec]   |= HORE;
					mapa[--riadok][stĺpec] |= DOLE;
				}
				break;

				case 1: /*# „Odtiaľto“ VPRAVO a naopak. #*/
				if (jePolePlatné(riadok, stĺpec + 1))
				{
					mapa[riadok][stĺpec]   |= VPRAVO;
					mapa[riadok][++stĺpec] |= VĽAVO;
				}
				break;

				case 2: /*# „Odtiaľto“ DOLE a naopak. #*/
				if (jePolePlatné(riadok + 1, stĺpec))
				{
					mapa[riadok][stĺpec]   |= DOLE;
					mapa[++riadok][stĺpec] |= HORE;
				}
				break;

				case 3: /*# „Odtiaľto“ VĽAVO a naopak. #*/
				if (jePolePlatné(riadok, stĺpec - 1))
				{
					mapa[riadok][stĺpec]   |= VĽAVO;
					mapa[riadok][--stĺpec] |= VPRAVO;
				}
				break;
			}

			žiadajPrekreslenie();
		}

		int čoĎalej = (int)náhodnéCeléČíslo(1, 3);
		if (0 != (čoĎalej & 1)) budujKanál(riadok, stĺpec, smer - 1);
		if (0 != (čoĎalej & 2)) budujKanál(riadok, stĺpec, smer + 1);
	}

	private void vybudujZákladBludiska()
	{
		int riadok = 0;
		int stĺpec = 0;
		int početPlnýchPolí = početPlnýchPolí();

		while (početPlnýchPolí > 0)
		{
			int početPosunov = (int)náhodnéCeléČíslo(0, početPlnýchPolí);

			while (!jePolePlné(riadok, stĺpec) || početPosunov > 0)
			{
				if (++stĺpec >= mapa[riadok].length)
				{
					stĺpec = 0;
					if (++riadok >= mapa.length)
						riadok = 0;
				}

				if (jePolePlné(riadok, stĺpec)) --početPosunov;
			}

			int smer = (int)náhodnéCeléČíslo(0, 3);
			if (jeOstrov(riadok, stĺpec))
				zrušOstrov(riadok, stĺpec, smer); /*# Nerekurzívna verzia metódy na budovanie bludiska #*/
			else
				budujKanál(riadok, stĺpec, smer); /*# Rekurzívna verzia metódy na budovanie bludiska #*/

			početPlnýchPolí = početPlnýchPolí();
		}
	}

	/*# -------------------------------------------------------------------------------- #*/

	private void vyčistiMapu()
	{
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapa[riadok][stĺpec] &= ~(byte)(NAVŠTÍVENÉ | OZNAČENÉ);
	}

	private int prehľadajKanál(int riadok, int stĺpec)
	{
		int počet = 1;
		mapa[riadok][stĺpec] |= NAVŠTÍVENÉ;

		if (0 != (mapa[riadok][stĺpec] & HORE) &&
			jePoleNenavštívené(riadok - 1, stĺpec))
			počet += prehľadajKanál(riadok - 1, stĺpec);

		if (0 != (mapa[riadok][stĺpec] & VPRAVO) &&
			jePoleNenavštívené(riadok, stĺpec + 1))
			počet += prehľadajKanál(riadok, stĺpec + 1);

		if (0 != (mapa[riadok][stĺpec] & DOLE) &&
			jePoleNenavštívené(riadok + 1, stĺpec))
			počet += prehľadajKanál(riadok + 1, stĺpec);

		if (0 != (mapa[riadok][stĺpec] & VĽAVO) &&
			jePoleNenavštívené(riadok, stĺpec - 1))
			počet += prehľadajKanál(riadok, stĺpec - 1);

		return počet;
	}

	public void vybudujBludisko()
	{
		vybudujZákladBludiska();
		// vyčistiMapu
		// prehľadajKanál
		// prerazKanál
		/*# TU TREBA POKRAČOVAŤ… #*/
	}

	public static void main(String[] args)
	{
		použiKonfiguráciu("Bludisko.cfg");
		new Bludisko();
	}
}

obrázok 
Táto verzia vytvára bludisko, ktoré je síce použiteľné, ale príliš „riedke“…

~

import knižnica.GRobot;
import static java.lang.Math.*;
import static knižnica.Svet.*;

public class Bludisko extends GRobot
{
	private byte[][] mapa =
	{
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	};

	private final static byte HORE   = 1;
	private final static byte VPRAVO = 2;
	private final static byte DOLE   = 4;
	private final static byte VĽAVO  = 8;
	private final static byte VŠADE  = 15;

	private final static byte NAVŠTÍVENÉ = 16;
	private final static byte OZNAČENÉ   = 32;

	private double rozmer = 15.0;
	private double hrúbka =  2.5;
	private int početPolí = početPolí(); /*# Ak by sme zmenili rozmer mapy počas činnosti programu,
										  *# museli by sme ešte raz spočítať počet polí!
										  *#*/

	private Bludisko()
	{
		nekresli();
		// vpravo(30);

		/* * /
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapa[riadok][stĺpec] = (byte)náhodnéCeléČíslo(0, 15);
		/* */

		vybudujBludisko();
		nakresliBludisko();
		spustiČasovač();
	}

	@Override public void tik()
	{
		if (neboloPrekreslené()) prekresli();
	}

	public void nakresliBludisko()
	{
		preskočVľavo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length - 1) * rozmer);

		for (int riadok = 0; riadok < mapa.length; ++riadok)
		{
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
			{
				if (0 != (mapa[riadok][stĺpec] & NAVŠTÍVENÉ))
					kružnica(rozmer / 3);

				if (0 != (mapa[riadok][stĺpec] & OZNAČENÉ))
					kružnica(rozmer / 2);

				if (0 == (mapa[riadok][stĺpec] & VŠADE))
				{
					vyplňŠtvorec(rozmer);
				}
				else
				{
					if (0 == (mapa[riadok][stĺpec] & HORE))
					{
						skoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						odskoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VPRAVO))
					{
						preskočVpravo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVľavo(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & DOLE))
					{
						odskoč(rozmer - hrúbka);
						vyplňObdĺžnik(rozmer, hrúbka);
						skoč(rozmer - hrúbka);
					}

					if (0 == (mapa[riadok][stĺpec] & VĽAVO))
					{
						preskočVľavo(rozmer - hrúbka);
						vyplňObdĺžnik(hrúbka, rozmer);
						preskočVpravo(rozmer - hrúbka);
					}
				}

				preskočVpravo(rozmer * 2);
			}

			preskočVľavo(rozmer * 2 * mapa[riadok].length);
			odskoč(rozmer * 2);
		}


		preskočVpravo((mapa[0].length - 1) * rozmer);
		skoč((mapa.length + 1) * rozmer);
	}

	private int početPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			počet += mapa[riadok].length;
		return počet;
	}

	private int početPlnýchPolí()
	{
		int počet = 0;
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & VŠADE)) ++počet;
		return počet;
	}

	/*# – V podstate ukážka toho, ako nájsť nejaký stav…
	private boolean jestvujePlnéPole()
	{
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				if (0 == (mapa[riadok][stĺpec] & VŠADE)) return true;
		return false;
	}
	*/

	private boolean jePolePlatné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length;
	}

	private boolean jePolePlné(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & VŠADE);
	}

	private boolean jePoleNenavštívené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & NAVŠTÍVENÉ);
	}

	private boolean jePoleNeoznačené(int riadok, int stĺpec)
	{
		return riadok >= 0 && riadok < mapa.length &&
			stĺpec >= 0 && stĺpec < mapa[riadok].length &&
			0 == (mapa[riadok][stĺpec] & OZNAČENÉ);
	}

	/*# -------------------------------------------------------------------------------- #*/

	private boolean jeOstrov(int riadok, int stĺpec)
	{
		return !jePolePlné(riadok - 1, stĺpec) && !jePolePlné(riadok + 1, stĺpec) &&
			!jePolePlné(riadok, stĺpec - 1) && !jePolePlné(riadok, stĺpec + 1);
	}

	private void zrušOstrov(int riadok, int stĺpec, int smer)
	{
		smer %= 4; if (smer < 0) smer = -smer;

		switch (smer)
		{
			case 0: /*# „Odtiaľto“ HORE a naopak. #*/
			if (jePolePlatné(riadok - 1, stĺpec))
			{
				mapa[riadok][stĺpec]   |= HORE;
				mapa[--riadok][stĺpec] |= DOLE;
			}
			break;

			case 1: /*# „Odtiaľto“ VPRAVO a naopak. #*/
			if (jePolePlatné(riadok, stĺpec + 1))
			{
				mapa[riadok][stĺpec]   |= VPRAVO;
				mapa[riadok][++stĺpec] |= VĽAVO;
			}
			break;

			case 2: /*# „Odtiaľto“ DOLE a naopak. #*/
			if (jePolePlatné(riadok + 1, stĺpec))
			{
				mapa[riadok][stĺpec]   |= DOLE;
				mapa[++riadok][stĺpec] |= HORE;
			}
			break;

			case 3: /*# „Odtiaľto“ VĽAVO a naopak. #*/
			if (jePolePlatné(riadok, stĺpec - 1))
			{
				mapa[riadok][stĺpec]   |= VĽAVO;
				mapa[riadok][--stĺpec] |= VPRAVO;
			}
			break;
		}
	}

	private void budujKanál(int riadok, int stĺpec, int smer)
	{
		if (jeOstrov(riadok, stĺpec)) return;

		smer %= 4; if (smer < 0) smer = -smer;

		for (int maxDĺžka = (int)náhodnéCeléČíslo(1, 2); maxDĺžka > 0; --maxDĺžka)
		{
			switch (smer)
			{
				case 0: /*# „Odtiaľto“ HORE a naopak. #*/
				if (jePolePlatné(riadok - 1, stĺpec))
				{
					mapa[riadok][stĺpec]   |= HORE;
					mapa[--riadok][stĺpec] |= DOLE;
				}
				break;

				case 1: /*# „Odtiaľto“ VPRAVO a naopak. #*/
				if (jePolePlatné(riadok, stĺpec + 1))
				{
					mapa[riadok][stĺpec]   |= VPRAVO;
					mapa[riadok][++stĺpec] |= VĽAVO;
				}
				break;

				case 2: /*# „Odtiaľto“ DOLE a naopak. #*/
				if (jePolePlatné(riadok + 1, stĺpec))
				{
					mapa[riadok][stĺpec]   |= DOLE;
					mapa[++riadok][stĺpec] |= HORE;
				}
				break;

				case 3: /*# „Odtiaľto“ VĽAVO a naopak. #*/
				if (jePolePlatné(riadok, stĺpec - 1))
				{
					mapa[riadok][stĺpec]   |= VĽAVO;
					mapa[riadok][--stĺpec] |= VPRAVO;
				}
				break;
			}

			žiadajPrekreslenie();
		}

		/*# Nasledujúcimi riadkami sme schopní ovplyvniť správanie
		 *# „budovateľa kanálov“ počas procesu budovania základu
		 *# bludiska. Hodnota premennej čoĎalej má vždy po vybudovaní
		 *# krátkeho úseku bludiska rozhodnúť o tom, kam ďalej. Je
		 *# vyhodnotená bitovo. Prvý bit znamená odbočiť doľava
		 *# a druhý zase doprava. Z toho vyplýva, že hodnoty 0 až 3
		 *# znamenajú:
		 *#   0 – stoj na mieste
		 *#   1 – pokračuj – odboč doľava
		 *#   2 – pokračuj – odboč doprava
		 *#   3 – pokračuj – vybuduj T-čko (odboč doľava aj doprava)
		 *# Podľa toho sa dá určiť, ako rozdielne sa bude budovateľ
		 *# správať, keď budeme generovať hodnotu čoĎalej v rozmedzí
		 *# od 1 do 3, od 0 do 2, prípadne v inom rozmedzí…
		 */
		// int čoĎalej = (int)náhodnéCeléČíslo(1, 3);
		int čoĎalej = (int)náhodnéCeléČíslo(0, 2);
		if (0 != (čoĎalej & 1)) budujKanál(riadok, stĺpec, smer - 1);
		if (0 != (čoĎalej & 2)) budujKanál(riadok, stĺpec, smer + 1);
	}

	private void vybudujZákladBludiska()
	{
		int riadok = 0;
		int stĺpec = 0;
		int početPlnýchPolí = početPlnýchPolí();

		while (početPlnýchPolí > 0)
		{
			int početPosunov = (int)náhodnéCeléČíslo(0, početPlnýchPolí);

			while (!jePolePlné(riadok, stĺpec) || početPosunov > 0)
			{
				if (++stĺpec >= mapa[riadok].length)
				{
					stĺpec = 0;
					if (++riadok >= mapa.length)
						riadok = 0;
				}

				if (jePolePlné(riadok, stĺpec)) --početPosunov;
			}

			int smer = (int)náhodnéCeléČíslo(0, 3);
			if (jeOstrov(riadok, stĺpec))
				zrušOstrov(riadok, stĺpec, smer); /*# Nerekurzívna verzia metódy na budovanie bludiska #*/
			else
				budujKanál(riadok, stĺpec, smer); /*# Rekurzívna verzia metódy na budovanie bludiska #*/

			početPlnýchPolí = početPlnýchPolí();
		}
	}

	/*# -------------------------------------------------------------------------------- #*/

	private void vyčistiMapu()
	{
		for (int riadok = 0; riadok < mapa.length; ++riadok)
			for (int stĺpec = 0; stĺpec < mapa[riadok].length; ++stĺpec)
				mapa[riadok][stĺpec] &= ~(byte)(NAVŠTÍVENÉ | OZNAČENÉ);
	}

	private int prehľadajKanál(int riadok, int stĺpec)
	{
		int počet = 1;
		mapa[riadok][stĺpec] |= NAVŠTÍVENÉ;

		if (0 != (mapa[riadok][stĺpec] & HORE) &&
			jePoleNenavštívené(riadok - 1, stĺpec))
			počet += prehľadajKanál(riadok - 1, stĺpec);

		if (0 != (mapa[riadok][stĺpec] & VPRAVO) &&
			jePoleNenavštívené(riadok, stĺpec + 1))
			počet += prehľadajKanál(riadok, stĺpec + 1);

		if (0 != (mapa[riadok][stĺpec] & DOLE) &&
			jePoleNenavštívené(riadok + 1, stĺpec))
			počet += prehľadajKanál(riadok + 1, stĺpec);

		if (0 != (mapa[riadok][stĺpec] & VĽAVO) &&
			jePoleNenavštívené(riadok, stĺpec - 1))
			počet += prehľadajKanál(riadok, stĺpec - 1);

		return počet;
	}

	private boolean prerazKanál(int riadok, int stĺpec)
	{
		mapa[riadok][stĺpec] |= OZNAČENÉ;

		/*# Ak je pole nenavštívené, znamená to, že metóda
		 *# prehľadajKanál sa do neho nedostala a vtedy
		 *# prerazíme kanál…
		 *#*/

		if (jePoleNenavštívené(riadok - 1, stĺpec))
		{
			mapa[riadok][stĺpec]     |= HORE;
			mapa[riadok - 1][stĺpec] |= DOLE;
			return true;
		}

		if (jePoleNenavštívené(riadok, stĺpec + 1))
		{
			mapa[riadok][stĺpec]     |= VPRAVO;
			mapa[riadok][stĺpec + 1] |= VĽAVO;
			return true;
		}

		if (jePoleNenavštívené(riadok + 1, stĺpec))
		{
			mapa[riadok][stĺpec]     |= DOLE;
			mapa[riadok + 1][stĺpec] |= HORE;
			return true;
		}

		if (jePoleNenavštívené(riadok, stĺpec - 1))
		{
			mapa[riadok][stĺpec]     |= VĽAVO;
			mapa[riadok][stĺpec - 1] |= VPRAVO;
			return true;
		}

		/*# Volanie metódy prerazKanál spôsobuje prehľadávanie bludiska
		 *# („chodenie“ po ňom). Návratová hodnota bude true len v prípade,
		 *# že bolo vykonané prerazenie kanála – vtedy okamžite končíme
		 *# (lebo chceme preraziť len jednu stenu, aby sme to bludisko
		 *# nerozbúrali príliš).
		 *#*/

		if (0 != (mapa[riadok][stĺpec] & HORE) &&
			jePoleNeoznačené(riadok - 1, stĺpec))
			if (prerazKanál(riadok - 1, stĺpec)) return true;

		if (0 != (mapa[riadok][stĺpec] & VPRAVO) &&
			jePoleNeoznačené(riadok, stĺpec + 1))
			if (prerazKanál(riadok, stĺpec + 1)) return true;

		if (0 != (mapa[riadok][stĺpec] & DOLE) &&
			jePoleNeoznačené(riadok + 1, stĺpec))
			if (prerazKanál(riadok + 1, stĺpec)) return true;

		if (0 != (mapa[riadok][stĺpec] & VĽAVO) &&
			jePoleNeoznačené(riadok, stĺpec - 1))
			if (prerazKanál(riadok, stĺpec - 1)) return true;

		return false;
	}

	public void vybudujBludisko()
	{
		vybudujZákladBludiska();

		vyčistiMapu();
		while (prehľadajKanál(0, 0) != početPolí)
		{
			prerazKanál(0, 0);
			vyčistiMapu();
		}

		/*# Čo sme ešte chceli dopracovať?       #*/
		/*#   – Hľadanie cesty v rámci bludiska. #*/
		/*#   – Klik ľavým určí štart.           #*/
		/*#   – Klik pravým určí koniec.         #*/
		/*#   – Nejaký „panáčik“ sa bude hýbať.  #*/
	}

	public static void main(String[] args)
	{
		použiKonfiguráciu("Bludisko.cfg");
		new Bludisko();
	}
}

obrázok 
Ukážka výsledku.