If you're seeing this message, it means we're having trouble loading external resources on our website.

Ha webszűrőt használsz, győződj meg róla, hogy a *.kastatic.org és a *.kasandbox.org nincsenek blokkolva.

Fő tartalom

Véletlen bolyongások

Mielőtt belemennénk a vektorok és a fizikai mozgás összetettségébe, gondoljuk végig mit jelent az, ha valami a képernyőn ide-oda mozog. Kezdjük az egyik legismertebb és legegyszerűbb mozgás-szimulációval: a véletlen bolyongással.
Képzeld azt, hogy egy gerenda közepén állsz. Minden 10. másodpercben feldobsz egy érmét: ha fej, előre lépsz egyet, ha írás, hátralépsz. Ez a véletlen bolyongás – olyan útvonal, amit véletlen lépések sorozata határoz meg. A gerendáról lelépve a padlóra, két dimenzióban is tudsz véletlen bolyongást csinálni: ugyanazt az érmét kétszer eldobva a következő eredményeket kaphatod:
1. dobás2. dobásEredmény
fejfejlépj előre
fejíráslépj jobbra
írásfejlépj balra
írásíráslépj hátra
Lehet, hogy ez az algoritmus kissé egyszerűnek tűnik. Mindazonáltal a véletlen bolyongások használhatóak a való világban előforduló jelenségek modellezésére, a gázok molekuláinak mozgásától kezdve a szerencsejátékos kaszinóban egy nap alatt elköltött pénzéig. Nekünk három célunk van azzal, hogy a véletlen bolyongások tanulásával kezdjük ezt a témát.

A véletlen bolyongó objektum

Először tekintsük át egy Walker (Sétáló) objektum elkészítésén keresztül az objektum-orientált programozást (OOP). Most csak röviden tekintjük ezt át, ezért ha sosem dolgoztál még OOP-vel ezelőtt, nézd végig az Objektum-orientált JavaScript tananyagainkat.
JavaScriptben az objektum egy adattípus, aminek tulajdonságai és ehhez tartozó funkcionalitása is van a prototípusán keresztül. Úgy alkotjuk meg a Walker objektumot, hogy amellett, hogy számon tartja az adatait (azt, hogy a képernyőn hol helyezkedik el), képes arra is, hogy különböző műveleteket hajtson végre (például rajzolja ki önmagát, vagy lépjen egyet).
Ahhoz, hogy Walker példányokat hozzunk létre, szükség van a Walker objektum definíciójára. Az objektumot úgy fogjuk használni, mint egy pogácsaszaggatót, minden új Walker példány egy-egy pogácsa lesz.
Kezdjük a Walker objektumtípus definiálásával. A Walker-nek csak két adatra van szüksége – egy-egy számra az x és y helyzetéhez. Ezeket az értékeket a vászon közepére állítjuk be konstruktor függvényben.
var Walker = function() {
    this.x = width/2;
    this.y = height/2;
};
Amellett, hogy számon kell tartanunk az x és y értékét, a Walker objektumunknak lesz egy metódusa is, amit meghívhatunk rajta. Az első metódus fekete pontként kirajzolja az objektumot. Ne feledd, hogy JavaScriptben úgy tudsz metódust adni az objektumhoz, ha azt az objektum prototype-jához csatolod.
Walker.prototype.display = function() {
    stroke(0, 0, 0);
    point(this.x, this.y);
};
A második metódus a Walker objektumot lépésre kényszeríti. Nos innentől válik az egész érdekesebbé. Emlékszel a padlóra, amin véletlen lépéseket tettünk? A vásznat most ugyanígy használhatjuk: hasonlóan mozoghatunk rajta. Négy lehetséges lépés van. A jobbra lépés szimulálható az x inkrementálásával (x++); a balra lépés az x dekrementálásával (x--); az előre lépés egy pixelnyi lefele lépéssel (y++); és a visszalépés egy pixelnyi felfele lépéssel ( y--). Hogyan választhatunk ebből a négy lehetőségből? Korábban azt mondtuk, hogy feldobhatunk két érmét. Viszont ProcessingJS-ben, ha egy listányi lehetőségből szeretnénk választani, használhatjuk a random() függvényt egy véletlenszám kiválasztásához.
Walker.prototype.walk = function() {
    var choice = floor(random(4));
};
A fenti kód kiválaszt egy lebegőpontos számot 0 és 4 között, egész számmá konvertálja floor() segítségével, így 0, 1, 2, vagy 3 lesz az eredmény. A legnagyobb elérhető szám sosem 4,0 lesz, sokkal inkább 3,999999999 (annyi 9-essel, amennyi tizedesjegy van); és mivel a floor() a legközelebbi egésszel tér vissza, ami kisebb, vagy egyenlő, ezért a legmagasabb eredmény, amit kaphatunk az a 3. Ezután megtesszük a megfelelő lépést (balra, jobbra, fel, vagy le) attól függően, hogy milyen véletlenszámot kaptunk.
Walker.prototype.walk = function() {
    var choice = floor(random(4));
    if (choice === 0) {
        this.x++;
    } else if (choice === 1) {
        this.x--;
    } else if (choice === 2) {
        this.y++;
    } else {
        this.y--;
    } 
};
Most, hogy elkészültünk az osztállyal, itt az idő, hogy létrehozzunk egy Walker objektumot a programunkban! Tegyük fel, hogy egy egyszerű véletlen bolyongást szeretnénk modellezni. Deklaráljunk és inicializáljunk egy globális változót Walker típussal úgy, hogy meghívjuk a konstruktor függvényt az új operátorral!
var w = new Walker();
Most vegyük rá ezt a bolyongót, hogy csináljon is valamit! Definiáljuk a draw() függvényt, amiben kérjük meg a bolyongót, hogy tegyen egy lépést, majd rajzolja ki magát minden alkalommal:
draw = function() {
    w.walk();
    w.display();
};
Mivel nem hívjuk meg a background()-ot a draw függvényben, láthatjuk a véletlen bolyongás útvonalát a vásznunkon. (A programban található megjegyzések: 1. sor: Dan Shiffman, natureofcode.com példája alapján; 13. sor: Véletlenszerűen felfelé, lefelé, jobbra vagy balra mozdul el, vagy a helyén marad.)

Fejlesszük tovább a véletlen bolyongót!

A véletlen bolyongót tovább tudjuk fejleszteni néhány módon. Vegyük például azt, hogy a bolyongó négyféle irányba léphet – felfelé, lefelé, balra és jobbra. Azonban az ablak bármely pixelének nyolc lehetséges szomszédja van, valamint egy kilencedik lehetőség, hogy nem lépünk sehova.
Kép a Nature of Code-ból
I.1. ábra
Ahhoz, hogy implementáljuk egy olyan Walker objektumot, ami bármelyik szomszédos pixelre léphet (vagy maradhat a helyén), választhatunk egy számot 0 és 8 között (kilenc lehetséges választás). Azonban ennél hatékonyabb, ha olyan kódot írunk, ami egyszerűen három lehetséges lépést választ az x-tengely mentén (-1, 0, vagy 1), és három lehetséges lépést az y-tengely mentén.
Walker.prototype.walk = function() {
  var stepx = floor(random(3))-1;
  var stepy = floor(random(3))-1;
  this.x += stepx;
  this.y += stepy;
};
Ezt akár tovább is fejleszthetjük úgy, hogy tizedesszámot használunk az x és y helyett, és egy tetszőleges -1 és 1 közötti számmal változtatjuk – ha a környezetünk képes különbséget tenni a megjelenítésben a 2,2 és 2,4 között.
Walker.prototype.walk = function() {
  var stepx = random(-1, 1);
  var stepy = random(-1, 1);
  this.x += stepx;
  this.y += stepy;
};
Egy dolog közös a „hagyományos” véletlen bolyongásnak ezen változatai között: minden időpillanatban annak a valószínűsége, hogy a Walker egy adott irányba lép (ha egyáltalán lép) egyenlő annak a valószínűségével, hogy a Walker bármelyik másik lehetőséget választja. Más szóval, ha 4 lehetséges lépés van, akkor 1 a 4-ből (vagy 25 %) a valószínűsége van annak, hogy a Walker egy adott lépést tesz. Kilenc lehetséges lépés esetén ez 1 a 9-ből (vagy 11,1%) valószínűség.
Kényelmi szempontból a random() függvény pont így működik. Ez egy véletlenszám generátor, ami ún. „egyenletes” eloszlás szerint generálja a számokat. Tesztelhetjük ezt az eloszlást egy olyan programmal, amely megszámolja és egy téglalap magasságával ábrázolja azt, hogy hány alkalommal választottunk ki véletlenszerűen egy-egy számot. (A programban található megjegyzések: 1. sor: Dan Shiffman, natureofcode.com példája alapján; 3-6. sor: Jelenítsük meg a ProcessingJS random függvénye által generált számokat! A kezdeti értékek és színek beállítása; 14. sor: A véletlen számok időbeli eloszlásának animálása.)
Ugyanaz a magassága az összes oszlopnak, ha pár percig futtatjuk? Valószínűleg nem. A minta elemszámunk (vagyis a kiválasztott véletlen számok száma) kicsi, és emiatt eltérések vannak: bizonyos számok gyakrabban kerültek kiválasztásra. Egy idő után egy jó véletlenszám generátorral ezek az eltérések kiegyenlítődnek.
A véletlenszámok, amiket a random() függvény ad, valójában nem véletlenek; ezért hívjuk „pszeudó-véletlen”-nek. Ezek egy olyan matematikai függvény eredményei, amelyek véletlenszerűséget szimulálnak. Ez a függvény idővel valamilyen mintát eredményez, de ez az időintervallum számunkra olyan hosszú, hogy ez a függvény van annyira jó, mint a tisztán véletlen!
A következő fejezetben azt fogjuk tárgyalni, hogy milyen különböző módokon készíthetünk „tendenciákat” a bolyongó számára annak érdekében, hogy valamilyen irányba sétáljon. Mielőtt azonban belevágnánk ebbe, egy feladat vár rád!

Ez a „Természetes szimulációk" tananyag a Daniel Shiffman által készített „The Nature of Code” alapján készült, a Creative Commons Attribution-NonCommercial 3.0 Unported License szerint.

Szeretnél részt venni a beszélgetésben?

Még nincs hozzászólás.
Tudsz angolul? Kattints ide, ha meg szeretnéd nézni, milyen beszélgetések folynak a Khan Academy angol nyelvű oldalán.