Sfat rapid carduri de amestecare (sau orice elemente) cu algoritmul Shuffle Fisher-Yates

În acest sfat rapid, vă voi arăta cum să implementați algoritmul Fisher-Yates Shuffle. Odată ce am învățat cum funcționează, o vom folosi pentru a amesteca un pachet virtual de cărți.

Notă: Deși acest tutorial este scris folosind JavaScript, ar trebui să puteți utiliza aceleași tehnici și concepte în aproape orice mediu de dezvoltare a jocului.


1. Introducere în algoritm

Există mai multe modalități de a amesteca un set de elemente, așa cum este demonstrat în acest post. În timp ce toate aceste opțiuni sunt valabile, metoda pe care am folosit-o întotdeauna este cea implementată de algoritmul Fisher-Yates Shuffle.

Îmi place această metodă deoarece efectuează un shuffle "în loc" fără a fi nevoie să creați o matrice nouă (sau orice structură de date pe care o utilizați).


2. Utilizarea algoritmului

Dacă ați dat pagina Wikipedia o citire rapidă, veți fi văzut că menționează câteva metode diferite de implementare a algoritmului. Cel pe care îl vom folosi se numește "Metoda modernă":

Pentru a amesteca o matrice a a n de elemente (indici 0 ... n-1): pentru i de la (n - 1) până la 1 face set j la un întreg aleator cu 0 ≤ j ≤ i schimb a a [j] și a [i ]
  1. Începeți cu ultimul element din listă (carte de sus în pachet, dacă doriți).
  2. Alegeți un alt element la întâmplare între primul și cel selectat.
  3. Schimbați aceste două elemente.
  4. Alegeți ultimul element din listă (al doilea card din pachet) și repetați # 1- # 3 până când ajungeți la fundul pachetului.

Am realizat o demonstrație vizuală care arată pașii pe care le ia algoritmul. Sperăm că face explicația de mai sus mai clară:


Traducerea în a pentru buclă ar arăta astfel:

var someArray = [1,2,3,4,5,6,7,8,9]; var theLength = someArray.length - 1; var toSwap; // Indicele pe care îl vom schimba (adică numărul aleatoriu) var temp; // O variabilă temporară care să dețină o referință la variabila index i indică pentru (i = TheLength; i> 0; i--) toSwap = Math.floor (Math.random () * i); temp = someArray [i]; someArray [i] = someArray [toSwap]; someArray [toSwap] = temp; 

Motivul pentru care avem nevoie de temp variabila este pentru că avem nevoie de o referire la primul element. Dacă nu am avea o referință la primul element, atunci când am schimbat al doilea element cu primul, am pierde primul element. Deoarece primul element este acum egal cu cel de-al doilea, atunci când am schimbat primul cu al doilea, ar fi "al doilea element", deoarece cel de-al doilea element este acum în primul loc. Referindu-ne la primul element, putem seta apoi al doilea element egal cu acesta.


3. Punerea algoritmului în practică

Demonstrația de mai sus este plăcută pentru o reprezentare vizuală a modului în care funcționează algoritmul, dar pentru ao pune în practică în lumea reală, vom folosi acum pentru a amesteca niște cărți virtuale. Mai jos este codul.

$ (functie () var serverString = "http://source.tutsplus.com/gamedev/authors/JamesTyner/FisherYates/src/images/"; var_card = []; var i; pentru (i = 1; i <= 13; i++)  cards.push("c" + i);  //console.log(cards); function drawCards() $("#holder").empty(); for (i = 0; i < cards.length; i++)  $("#holder").append("()) "Carduri înainte de shuffle:" + carduri); pentru (i = TheLength; i> 0; i--) toSwap = Math.floor (Math.random () * i); ] = carduri [toSwap]; carduri [toSwap] = tempCard; console.log ("Carduri după shuffle:" + carduri); drawCards (););

Aici creăm un pachet de 13 cărți și apoi amestecăm-le când este apăsat butonul Shuffle. Algoritmul Fisher-Yates Shuffle este implementat în amesteca() funcţie.

Am creat un alt demo pentru a arăta acest lucru în acțiune, dar puteți încerca și tu cu fișierele incluse în activele descărcabile ale acestui tutorial.


4. Concluzie

Algoritmul Fisher-Yates Shuffle este una din mai multe modalități de a implementa mișcarea în aplicațiile dvs. Nu este nevoie să creați noi mese, așa cum se întâmplă în amestec. Sunt un mare fan al acestui algoritm de amestecare, și poate că sunteți și acum.

Vă mulțumim pentru lectură și sper că ați găsit acest tutorial util.