Você está na página 1de 32

COLEGIUL NATIONAL MIHAIL

KOGLNICEANU
GALAI

ATESTAT LA INFORMATIC
TURNURILE DIN HANOI
JOC JAVA -ANDROID

Coordonator
Prof. Muunoiu Novetschi Monica Iuliana

Realizator
Buruian Ctlin

Cuprins
Introducere..................................................................................................................................3
Android....................................................................................................................................3
Java.........................................................................................................................................4
AndEngine...............................................................................................................................5
Algoritm Turnurile din Hanoi..................................................................................................7
Implementare - AndEngine.......................................................................................................10
Setarea mediului de programare...........................................................................................10
Pornirea engine-ului.............................................................................................................10
Importarea texturilor............................................................................................................12
Crearea scenei.......................................................................................................................15
Crearea turnurilor.................................................................................................................17
Definirea inelelor..................................................................................................................18
Logica jocului.......................................................................................................................20
Tratare excepie ncheierea jocului....................................................................................25
Materializarea codului..............................................................................................................28
Distribuirea printr-un magazin specializat...........................................................................28
Distribuirea prin E-mail.......................................................................................................29
Distribuirea printr-un website..............................................................................................29
Optarea pentru aplicaii din surse necunoscute...................................................................30
Bibliografie...............................................................................................................................31

Introducere
Android
Sistemul de operare al unui telefon reprezint un ansamblu de programe, creat cu
scopul de a mijloci relaia hardware-utilizator. Ele se caracterizeaz i se difereniaz prin
vitez de lucru/procesare, stabilitate i suita de programe implicite.
Android a fost lansat n noiembrie 2007 de ctre Google ( dei iniial a fost dezvoltat
de ctre Android Inc., companie ulterior cumprat de ctre Google n 2005). Aceast lansare
a generat o mic revoluie n lumea tehnologiei mobile datorit anumitor caracteristici unice.
n primul rnd, Android este bazat pe Linux, sistem de operare arhicunoscut open source, cu o
baz mare de utilizatori i dezvoltatori. n plus, faptul c Android OS utilizeaz aplicaii ce au
c limbaj de baz Java, unul din cele mai folosite limbaje de programare, au fcut ca numrul
dezvoltatorilor att experimentai ct i nceptori s creasc iminent. Multitasking-ul
(posibilitatea de a rula mai multe aplicaii simultan) a reprezentat de asemenea un punct forte
la momentul lansrii. Platform open soruce reprezint un punct forte din prisma
dezvoltatorilor datorit anumitor avantaje printre care securitate, calitate, libertate sau
flexibilitate. Astfel, platforma Google Play , iniial Android Market ( o pia de aplicaii
pentru telefoanele n cauza) a strns un numr impresionat de peste 1.5 milioane aplicaii i un
numr la fel de impresionant de utilizatori sau dezvoltatori.
O alt caracteristic important a platformei Android este c orice companie interesat
s produc propria versiune a unui telefon Android este binevenit i poate folosi platforma
pentru dispozitivele lor. Rezultatul este un numr mare de societi concurente productoare
de telefoane Android, care produc la diferite preuri. De fapt, telefoanele Android pot varia
enorm n pre de la 99 la 600 de euro.
Una dintre cele mai mari diferene ntre telefoanele Android i alte mobile este faptul
c Android este un sistem de operare destul de complex, iar marea majoritate a OS
tradiionale sunt destul de puin dezvoltate. Cu caracteristici complete, versatil, uor de
upgradat i cu aplicaii noi, Android s-a dovedit a fi un succes din toate punctele de vedere.

Java
Java este un limbaj de programare orientat-obiect, puternic tipizat, conceput de ctre
James Gosling la Sun Microsystems (acum filial Oracle) la nceputul anilor 90, fiind lansat
n 1995. Cele mai multe aplicaii distribuite sunt scrise n Java, iar noile evoluii tehnologice
permit utilizarea sa i pe dispozitive mobile gen telefon, agenda electronic, palmtop etc. n
felul acesta se creeaz o platform unic, la nivelul programatorului, deasupra unui mediu
eterogen extrem de diversificat. Acesta este utilizat n prezent cu succes i pentru programarea
aplicaiilor destinate intranet-urilor.
Limbajul mprumut o mare parte din sintax de la C i C++, dar are un model al
obiectelor mai simplu i prezint mai puine faciliti de nivel jos. Un program Java compilat,
corect scris, poate fi rulat fr modificri pe orice platform care e instalat o main virtual
Java (englez Java Virtual Machine, prescurtat JVM). Acest nivel de portabilitate (inexistent
pentru limbaje mai vechi cum ar fi C) este posibil deoarece sursele Java sunt compilate ntr-un
format standard numit cod de octei (englez byte-code) care este intermediar ntre codul
main (dependent de tipul calculatorului) i codul surs.
Maina virtual Java este mediul n care se execut programele Java. n prezent, exist
mai muli furnizori de JVM, printre care Oracle, IBM, Bea, FSF. n 2006, Sun a anunat c
face disponibil varianta sa de JVM ca open-source.
Principalele caracteristici care au transformat intr-un interval scurt de timp limbajul Java
intr-una din cele mai populare optiuni pentru dezvoltarea de aplicatii pe o multitudine de
terminale, indiferent de domeniu sau complexitatea lor sunt:
1) Simplitate elimin suprancrcarea operatorilor, motenirea multipl i toate
facilitatilece pot provoc scrierea unui cod confuz.
2) Usurina n crearea de aplicaii complexe ce folosesc programarea n reea, fire de
execuie, interfa grafica, baze de date, etc.
3) Robustee elimin sursele frecvente de erori ce apar n programare prin renunarea la
pointeri, administrarea automat a memoriei i eliminarea pierderilor de memorie
printr-o procedur de colectare a obiectelor care nu mai sunt referite, ce ruleaz n
fundal (garbage collector).
4) Complet orientat pe obiecte elimina complet stilul de programare procedural.
4

5) Securitate este un limbaj de programare foarte sigur, furninzand mecanisme stricte


de securitate a programelor concretizate prin : versificarea dinamic a codului pentru
detectarea secvenelor periculoase, impunerea unor reguli stricte pentru rularea
proceselor de la distan, etc.
6) Neutralitate arhitectural comportamentul unei aplicaii Java nu depinde de
arhitectura fizic a mainii pe care ruleaz.
7) Portabilitate Java este un limbaj independent de platforma de lucru, aceeai
aplicaie rulnd fr nici o modificare i fr a necesita recompilarea ei pe sisteme de
operare diferite cum ar fi Windows, Linux, Mac OS, Solaris, etc., lucru care aduce
economii substaniale firmelor dezvoltatoare de aplicaii.
8) Este compilat si interpretat, aceasta fiind soluia eficient pentru obinerea
portabilitaii.
9) Performan dei mai lent dect limbajele de programare care genereaz executabile
native pentru o anumit platform de lucru, compliatorul Java asigur o performan
ridicat a codului de octei, astfel nct viteza de lucru puin mai sczut un va fi un
impediment n dezvoltarea de aplicaii orict de complexe, inclusiv grafica 3D,
animaie, etc.
10) Este modelat dup C si C++ , trecerea de la C, C++ la Java facndu-se uor.

AndEngine
AndEngine este un proiect open-source prezentat ca un ajutor pentru dezvoltarea jocurilor
2D pe platforma Android. Ca orice alt engine ( Rage , CryEngine, Uneal i altele) el prezint
avantaje i dezavantaje. Alegerea unui engine potrivit pentru jocul pe care vrei s-l dezvoli
ine mult de ideea n sine i de modul n care se dorete a se face implementarea. n cazul
AndEngine, el se prezint cu dou versiuni. Prima, AndEngine version 1 suport
OpenGLES1( subset al faimoasei aplicaie de randare grafic OpenGl ), suportat de peste 95%
din terminalele Android de pe pia.
AndEngine a fost dezvoltat i este n continuare mbunti de ctre Nicolas Gramlich ,
un dezvoltator din San Francisco. Un avantaj iminent al acestui game engine este faptul c
este simplist, reprezint un punct de plecare accesibil oricrui dezvoltator nefamiliarizat cu
5

dezvoltarea de jocuri pentru Android. Dei documentaia este considerat de unii incomplet
sau generatoare de confuzii, And Engine este nsoit cu suport tehnic extins din partea
utilizatorilor, att pe forumul propriu AndEngine Forums, o comunitate activ i ce nu ezit n
a ajut novicii, ct i pe platform StackOverflow cu o comunicate la fel de dedicat, dar mult
mai diversificat.
Un punct forte al acestui game engine este faptul c au eliminat n mare partea problema
memoriei, o problem de care se mpotmolete orice dezvoltator nceptor. Ca s o rezolve,
AndEngine a mrit heap size-ul aplicaiei. n schimb, acest engine poate fi considerat simplist,
aducndu-se n discuie anumite limitri grafice sau lipsa suportului pentru multi-touch.
Per total, consider c AndEngine este o alegere optim pentru un dezvoltator nceptor
cnd vine vorba de crearea unui joc pe o platforma Android, putnd s se familiarizeze att cu
mediul de dezvoltare ct i cu anumite paradigme, pregtindu-se astfel pentru paii urmtori dezvoltarea pe engine-uri mult mai complexe .

Algoritm Turnurile din Hanoi


Se spune c ntr-un templu din Benares(India) preoii lucreaz ncontinuu, mutnd discuri
de aur de pe un ac de diamante pe altul. Atunci cnd lumea a fost create, preoilor din Benares
le-au fost druite 3 ace de diamante i 64 discuri de aur.
Preoilor li s-a poruncit s depun pe unul din ace toate discurile, n ordine
descresctoare, apoi s mute ntregul turn astfel format pe unul din celelalte dou ace, mutnd
cte un disc o data i fr a pune un disc mai mare peste unul mai mic.
n conformitate cu legenda Dumnezeu le-a zis oamenilor:cand vei termina de mutat
turnul, atunci lumea se va sfri!
Jocul Turnurile din Hanoi( uneori numit i turnurile din Brahma ) a fost inventat de
matematicianul francez Edouard Lucas, n 1883. el s-a inspirit din legenda unui templu hindus
care folosea un astfel de joc pentru disciplin mental a tinerilor clugri.
Turnul din Hanoi sau Turnurile din Hanoi este format din trei tije i un numr variabil de
discuri, de diferite mrimi, care pot fi poziionate pe oricare din cele 3 tije. Jocul ncepe avnd
discurile aezate n stiv pe prima tij, n ordinea mrimii lor, astfel nct s formeze un turn.
Scopul jocului este acela de a muta ntreaga stiv de pe o tij pe alta, respectnd urmtoarele
reguli:

Doar un singur disc poate fi mutat, la un moment dat.


Fiecare mutare const n luarea celui mai de sus disc de pe o tija i glisarea lui pe o alt

tij, chiar i deasupra altor discuri care sunt deja prezente pe acea tij.
Un disc mai mare nu poate fi poziionat deasupra unui disc mai mic.

Algoritmul folosit pentru rezolvarea de ctre un calculator a problemei Turnurilor din


Hanoi se bazeaz pe tehnica divide et impera ( dezbin i cucerete ) .
Divide et impera se bazeaz pe un principiu extrem de simplu: descompunem problema
n dou sau mai multe subprobleme ( mai uoare ), care se rezolv, iar soluia pentru problema
iniial se obine combinnd soluiile problemelor n care a fost descompus. Se presupune c
fiecare din probleme n care a fost descompus problem iniial, se poate descompune n alte

subprobleme, la fel cum a fost descompus problem iniial. Procedeul se reia pn cnd (n
urm descompunerilor repetate) se ajunge la probleme care admit rezolvare imediat.
Evident nu toate problemele pot fi rezolvate prin utilizarea acestei tehnici. Fr team de
a grei, putem afirm c numrul lor este relativ mic, tocmai datorit cerinei c problem s
admit o descompunere repetat.
Divide et impera este o tehnic ce admite o implementare recursiv. Principiul general
prin care se elaboreaz algoritmi recursivi : ce se ntmpl la un nivel, se ntmpl la un nivel,
se ntmpl la orice nivel (avnd grij s asigurm condiiile de terminare). Tot aa, se
elaboreaz un algoritm prin divide et impera: la un anumit nivel avem dou posibiliti:
1.

am ajuns la o problem care admite o rezolvare imediat, caz n care se rezolv

2.

i se revine din apel ( condiia de terminare );


nu am ajuns n situaia de la punctul 1. , caz n care descompunem problema n
dou sau mai multe subprobleme, pentru fiecare din ele reapetam funcia,
combinm rezultatele i revnim din apel.

Astfel rezolvarea problemei Turnurilor din Hanoi se va baza pe urmtorul algoritm:


Se dau 3 tije simbolizate prin a,b,c. Pe tija a se gsesc n discuri de diametre diferite,
aezate n ordine descresctoare a diametrelor. Se cere s se mute de pe tija a pe b, utiliznd
ca tij intermediar tija c, toate cele n discuri, respectnd urmtoarele reguli:

La fiecare pas se mut un singur disc.


Nu este permis s se aeze un disc cu diametrul mai mare peste un disc cu
diametrul mai mic.

Rezolvare:
Dac n=1 se face mutarea ab, adic se muta discul de pe tija a pe tija b.
Dac n=2 se fac mutarile a-c,a-b,c-b.
Pentru n=3 avem :
H(3,a,b,c ) = H(2,a,c,b),ab,H(2,c,b,a) = H(1,a,b,c),ac,H(1,b,c,a),ab,H(1,c,a,b),cb,H(1,a,b,c) =

a-b,a-c,b-c,a-b,c-a,c-b,a-b.
Dac n>2 . Notm cu H(n,a,b,c) irul mutrilor celor n discuri de pe tija a pe tija b ,
utiliznd ca tij intermediar, tija c.

Conform strategiei Divide et impera ncercam s descompunem problema n alte dou


subprobleme de acelai tip, urmnd apoi combinarea soluiilor. Deci mutarea celor n discuri
de pe tija a pe tija b,utiliznd c tij intermediar tija c, este echivalent cu: muatrea a n-1
discuri de pe tija a pe tija c , utilizand ca tija intermediara tija b;

mutarea discului rmas de pe tija a pe tija b;


mutarea a n-1 discuri de pe tija c pe tija b , utiliznd ca tij intermediar tija a.

Algoritmul prezentat in limbajul C++ :

Algoritmul prezentat in limbajul Java:

#include<iostream.h>
char a,b,c;
int n;
void h(int n,char a,char b,
char c)
{
if(n==1) cout<<a<<b<<" ";
else
{
h(n-1,a,c,b);
cout<<a<<b<<" ";
h(n-1,c,b,a);
}
}
void main()
{
cout<<"n=";cin>>n;
h(n,'a','b','c');

public class MainClass {


public static void
main(String[] args) {
int nDisks = 3;
doTowers(nDisks, 'A', 'B',
'C');
}
public static void
doTowers(int topN, char
from, char inter, char to) {
if (topN == 1){
System.out.println("Disk 1
from " + from + " to " +
to);
}else {

doTowers(topN - 1, from,
to, inter);
System.out.println("Disk
" + topN + " from " + from +
" to " + to);
doTowers(topN - 1, inter,
from, to);
}
}
}

Implementare - AndEngine
Setarea mediului de programare
Pentru aceast aplicaie va fi necesar pregtirea mediului propice dezvoltrii. Vom
folosi cteva unelte precum Eclipse , Inteliji Idea sau Android Studio ca mediu de programare
( cu support android) , dar i codul surs pentru AndEngine gsit pentru descrcat pe pagina
de GitHub a dezvoltatorului : https://github.com/nicolasgramlich/AndEngine.
Proiectul pe care l folosesc reprezint a doua versiune AndEngine, ce folosete
OpenGL ES 2.0. Trebuie verificat faptul dac terminaul mobil sau emulatorul suport acest
lucru. n general, orice telefon care ruleaz Android cu o versiune mai mare sau egal cu 4.0.3
( API 15) suport OpenGL ES 2.0.
Urmtorul pas l reprezint importarea codului AndEngine ca un proiect separat n
mediul de programare, permindu-ne astfel s importam librriile n proiectul nostru,
necesare anumitor metode sau resurse.
Voi crea un proiect nou n Eclipse (File -> New -> Project -> Android Project),
urmnd s-l numesc TowersOfHanoi, iar numele pachetului ro.atestat.hanoi. Selectnd
proprietile (Properties) proiectului ->Android voi adug proiectul anterior importat ca o
librrie la proiectul actual.

Pornirea engine-ului
Voi crea o clas Java nou numit TowerOfHanoiActivity ce va trebuie s extind
SimpleBaseGameActivity. Pentru a putea face asta sunt necesare anumite importuri din
librria AndEngine.

import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.engine.options.EngineOptions;
import org.andengine.entity.scene.Scene;

10

Astfel, clasa noastr ce predefinit extindea Activity va extinde clasa necesar creari
unui joc. Clasa SimpleBaseGameActivity furnizeaz anumite callback-uri pentru a permite
codului AndEngie s funcioneze n concordan cu ciclul de via Android. Cum am extins
aceast clas va trebui s suprascriu (Override) trei funcii :

onCreateEngineOptions: - se creeaza instana engine-ului


onCreateResources: - se incarc resursele necesare n VRAM
onCreateScene: - se execut ultima, aici se va crea scena unde vor fi asamblate resursele

11

Voi aduga aceste callback-uri goale ce vor servi ca un cod schelet iniial :
@Override
public EngineOptions onCreateEngineOptions() {
return null;
}
@Override
protected void onCreateResources() {
}
@Override
protected Scene onCreateScene() {
return null;
}

Voi defini valorile statice ce vor servi ca dimensiunea ecranului pe care va fi jucat jocul :
private static int CAMERA_WIDTH = 800;
private static int CAMERA_HEIGHT = 480;

Aceste doua variabile reprezinta lungimea si latimea camerei pe care engine-ul o va


folosi. In continuare voi implementa initializarea instantei jocului (in interiorul metodei
onCreateEngineOptions() , necesitand inca o data anumite importuri:

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.ScreenOrientation;
import
org.andengine.engine.options.resolutionpolicy.RatioResolutionP
olicy;

////////////////////////////////////////////////////////////////////
final Camera camera = new Camera(0, 0, CAMERA_WIDTH,
CAMERA_HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
camera);

n codul precedent am creat o instanta a clasei Camera ca obiect, folosindu-l pentru a crea
un obiect EngineOptions, obiect ce definete opiunile anterioare iniializarii engine-ului.
Parametrii necesari sunt :

FullScreen variabila boolean semnificnd dac instana jocului va fi sau nu afiat pe

tot ecranul
ScreenOrientation speicifc orientarea ecranului
ResolutionPolicy definete cum engine-ul va scala resursele n functie de rezoluia

telefonului
Camera definete lungimea si laimea de baza i final a jocului

Ca o parantez trebuie s precizez arhicunoscutul fapt c Android ruleaz pe o diversitate


enorm de device-uri cu o diversistate la fel de mare a mrimii ecranului. Lund acest lucru n
vedere, este greu s redimensionam scena jocului pentru fiecare dispozitiv. AndEngine are o
soluie unic la aceast problem i va scala texturile astfel nct se vor ncadra n rezoluia
ecranului.
Dac setam CAMERA_WIDTH/CAMERA_HEIGHT la 480x320 i vom rula jocul pe
un telefon cu ecranul de rezoluie 800x480, jocul va fi scalat la 720x480 (1.5 ori) cu o
margine de 80 pixeli ( fie sus, jos, stnga sau dreapta). AndEngine pstreaz raportul
rezoluiei i scaleaz jocul la valoarea cea mai apropiat ecranului fizic.

Importarea texturilor
Avnd instana engine-ului iniializat, urmtorul pas l reprezint ncrcarea
resurselor vizuale, a texturilor necesare de ctre jocul TowersOfHanoi. Desigur c acestea vor
putea fi modificate ulterior sau schimbate ntru totul, totul innd de opiunea dezvoltatorului.
Eu voi folosi 5 texturi :

Background.png reprezinta fundalul jocului


Ring1.png reprezinta inenul de marime cea mai mica
Ring2.png inelul de marime medie
Ring3.png inelul de marime cea mai mare
Tower.png turnul pe care vor fi asezate inelele

O arhiv cu toate aceste texturi poate fi gsit la adresa :


http://cdn1.raywenderlich.com/downloads/TowerOfHanoiArt.zip .
n interiorul folderului assets , deja existent n proiect voi crea un nou folder (Right click
-> New -> Folder) numit gfx n care voi copia toate aceste texturi.
Pentru a le ncrca n joc vom modifica metoda callback onCreateResources(). Pentru a
efecuta operaiile necesare vom avea din nou nevoie de anumite importuri:

import
import
import
import

org.andengine.opengl.texture.ITexture;
org.andengine.opengl.texture.bitmap.BitmapTexture;
org.andengine.util.adt.io.in.IInputStreamOpener;
org.andengine.util.debug.Debug;

import java.io.IOException;
import java.io.InputStream;

Astfel vom putea crea texturile n cadrul jocului ( n locului codului placeholder n
metoda onCreateResources() ):

try {
ITexture backgroundTexture = new
BitmapTexture(this.getTextureManager(), new IInputStreamOpener()
{
@Override
public InputStream open() throws IOException {
return getAssets().open("gfx/background.png");
}
});
ITexture towerTexture = new
BitmapTexture(this.getTextureManager(), new IInputStreamOpener()
{
@Override
public InputStream open() throws IOException {
return getAssets().open("gfx/tower.png");
}
});
ITexture ring1 = new BitmapTexture(this.getTextureManager(), new
IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open("gfx/ring1.png");

}
});
ITexture ring2 = new BitmapTexture(this.getTextureManager(), new
IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open("gfx/ring2.png");
}
});
ITexture ring3 = new BitmapTexture(this.getTextureManager(), new
IInputStreamOpener() {
@Override
public InputStream open() throws IOException {
return getAssets().open("gfx/ring3.png");
}
});
backgroundTexture.load();
towerTexture.load();
ring1.load();
ring2.load();
ring3.load();
} catch (IOException e) {
Debug.e(e);

n codul de mai sus n prim instan am creat un obiect ITexture. Itexture este o
interfa. Un obiect de acest timp e iniializat ca un obiect BitmapTexture, ce evident ncrca
un fiier tip bitmap n VRAM (Video RAM) . Folosind metoda load, am ncrcat toate
texturile necesare n VRAM imediat dup crearea obiectelor necesare.
Avnd texturile ncrcate, trebuie s extrag regiunile de textur (TextureRegions) din
acestea. Textura este c o pnz gigantic care trebuie s aib valorile lungimii i limii o
putere de-a numrului 2 ( proprietate a OpenGL ES). O regiune de textur, deopotriv, este o
regiune dintr-o textur care nu trebuie s aib aceste dimensiuni o putere de-a numrului 2.
Urmtoarele importuri necesare acestei operaiuni sunt:

import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TextureRegionFactory;

Acum pentru a ine regiunile de textur (TextureRegion), trebuie s adaug variabilele


private n clasa pe care lucrez ( la inceputul codului langa celelate variabile private). Aceste

variabile vor fi de tip ITextureRegion , o alta interfata asemanatoare celei folosite mai
devreme.

private ITextureRegion mBackgroundTextureRegion,


TowerTextureRegion, mRing1, mRing2, mRing3;

Urmatorul pas este crearea i extragerea obiectelor TextureRegion (prin interfeele


definite) din texurile deja ncarcate n VRAM. Aceast operaiune va avea loc tot n metoda
onCreateResources(), la sfritul acesteia.

this.mBackgroundTextureRegion =
TextureRegionFactory.extractFromTexture(backgroundTexture);
this.mTowerTextureRegion =
TextureRegionFactory.extractFromTexture(towerTexture);
this.mRing1 = TextureRegionFactory.extractFromTexture(ring1);
this.mRing2 = TextureRegionFactory.extractFromTexture(ring2);
this.mRing3 = TextureRegionFactory.extractFromTexture(ring3);

Crearea scenei
A ajuns n sfrit timpul de a creea scena jocului, platforma efectiv pe care va avea
loc toata aciunea. Evident, asta necesita nca un import :

import org.andengine.entity.sprite.Sprite;

Voi nlocui codul placeholder din interiorul metodei de callback onCreateScene() cu


urmtorul:

final Scene scene = new Scene();


Sprite backgroundSprite = new Sprite(0, 0,
this.mBackgroundTextureRegion,
getVertexBufferObjectManager());
scene.attachChild(backgroundSprite);
return scene;

Codul de mai sus creaz un obiect de tip Scene. Apoi am creat un obiect de tip Sprite
numit backgroundSprite i l-am ataat de scena. A se observa c metoda necesit returnarea
unui obiect de tip scena plasat in interiorul ei.
n momentul creri unui obiect tip sprite ai nevoie de patru parametri:

xCoordinate : definete poziia pe axa X a obiectului. Sistemul de coordonate

AndEngine consider punctul maxim sus-stanga ca origine.


yCoordinate : definete poziia pe axa Y a obiectului.
TextureRegion : definete ce parte a texturii va folosi Sprite-ul pentru a se desena
VertexBufferObjectManager: vertex buffer-ul este un fel de tablou ce ine coordonatele
unei texturi. Aceste coordonate sunt trimise pe teava OpenGL ES i n final definesc ce
trebuie desenat. Un VertexBufferObjectManager ine toate nodurile tuturor texturilor ce
trebuie desenate pe scena.
Ruland aplicaia, vom fi n stare s vedem ceva pe ecran, i anume textura
background-ului ce am pasat-o scenei printr-un sprite.

Crearea turnurilor
n continuare voi defini Sprite-urile pentru turnuri i inele - ultimul pas nainte de a
crea logica jocului i modul de interaciune cu utilizatorul. Voi defini trei variabile private ( n
acelai mod, dup definirea clasei) pentru cele trei turnuri :

private Sprite mTower1, mTower2, mTower3;

n interiorul metodei onCreateScene() voi adauga urmatoarele linii de cod, chiar


inainte instruciunii de returnare a scenei :

mTower1 = new Sprite(192, 63, this.mTowerTextureRegion,


getVertexBufferObjectManager());
mTower2 = new Sprite(400, 63, this.mTowerTextureRegion,
getVertexBufferObjectManager());
mTower3 = new Sprite(604, 63, this.mTowerTextureRegion,
getVertexBufferObjectManager());
scene.attachChild(mTower1);
scene.attachChild(mTower2);
scene.attachChild(mTower3);

Am definit cele trei Sprite-uri, fiecare folosind obiectul TextureRegion al turnului ce lam incarcat n interiorul metodei onCreateResources(). Aceste turnuri vor fi plasate
corespunzator simetrieri prin hard-codarea coordonatelor X si Y necesare. Imediat apoi, am
ataat cele trei Sprite-uri obiectului Scene.
Compilnd si rulnd aplicatia se poate obsera cele trei turnuri amplasate pe scena :

Definirea inelelor
Un aspect realmente important a logicii
jocului trebuie luat acum n considerare. Cele
trei turnuri vor trebui s funcioneze ca un set de
blocuri succesive ( asemntoare stivei comune
din C++ ) . Totodat, aceast metod de
abordare va permite implementarea regulilor
jocurilor : eliminarea doar a inelului de pe
poziia cea mai de sus de pe un turn sau
adugarea lui, sau faptul c n momentul
adugrii unui element acesta va fi situat pe cea
mai ridicat poziie. Voi folosi trei stive pentru a
implementa aceast soluie.
Pentru a crea inelele, trebuie creat o
clasa Java personalizat ( custom ) ce va extinde clasa Sprite ( aceeai calsa folosit mai
devreme pentru a crea alte elemente ale jocului). Acest fapt este necesar deoarece fiecare inel
trebuie s tie crei stive aparine. Secvena de instruciuni Right-click -> New -> Class pe
folderul ce conine TowerOfHanoiActivity va declana un dialog n care voi modifica doar
numele clasei in Ring i superclasa ca org.andengine.entity.sprite.Sprite, campurile Source
foldersi Packagefiind deja completate.
Astfel, se va crea un fiier Java numit Ring.java. Voi nsera urmtorul cod n
implementarea clasei ( ntre definerea ei ca clas public i ultima parantez din fiier ) :

private int mWeight;


private Stack mStack; //this represents the stack that this
ring belongs to
private Sprite mTower;
public Ring(int weight, float pX, float pY, ITextureRegion
pTextureRegion, VertexBufferObjectManager
pVertexBufferObjectManager) {
super(pX, pY, pTextureRegion, pVertexBufferObjectManager);
this.mWeight = weight;}

public int getmWeight() {


return mWeight;}
public Stack getmStack() {
return mStack;}
public void setmStack(Stack mStack) {
this.mStack = mStack;}
public Sprite getmTower() {
return mTower;}
public void setmTower(Sprite mTower) {
this.mTower = mTower;}

Majoritatea codului este destul de explicit. Obiectul Ring de superclasa Sprite are trei
variabile private, constructorul inelului i metodele get i set specifice fiecrei variabile :

mWeight : se folosete la nregistrarea greutaii inelelor pe turn ( variabil de tip int );

de exemplu : cu ct e mai mare variabila cu att este mai mare si inelul.


mStack : definete pe ce stiv ( Stack ) se afl inelul
mTower: definete pe ce turn se afla inelul ( tip Sprite )

Pentru ca codul s fie funcionabil, vom folosi urmtoarele importuri, plasate n aceeai
manier la nceputul fiierului:

import java.util.Stack;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

Revnind la activitatea mare, urmatul pas l reprezint crearea i adugarea inelelor bazate
pe clas ce abia am definit-o. n metoda onCreateScene(), imediat naintea instruciunii de
returnare voi aduga urmtoarele linii de cod:

//se creaza inelele

Ring ring1 = new Ring(1, 139, 174, this.mRing1,


getVertexBufferObjectManager());
Ring ring2 = new Ring(2, 118, 212, this.mRing2,
getVertexBufferObjectManager());
Ring ring3 = new Ring(3, 97, 255, this.mRing3,
getVertexBufferObjectManager());
scene.attachChild(ring1);
scene.attachChild(ring2);
scene.attachChild(ring3);

Compilnd i rulnd
aplicaia, aceasta va arta n
urmtorul mod, inelele fiind
observabile. Este de observat
faptul c ele se afl pe primul
turn, dar suntem incapabili s le
mutm nc. Asta ne trimite la
urmtorul pas: implementarea
logicii jocului de plasare i
mutare a inelelor.

Logica jocului
Pentultimul pas al proiectului iniiat l reprezint logica efectiv a jocului. Menionat i
mai sus, voi crea trei stive, fiecare reprezentnd un turn. Voi ncepe prin a aduaga urmtorul
import pentru superclasa Java Stack n interiorul clasei TowerOfHanoiActivity.java :

import java.util.Stack;

Voi declara trei variabile n acelai mod cum le-am declarat pe toate pn acum,
fiecare de tipul Stack ( stiv ) i cu nume diferentiabile :

private Stack mStack1, mStack2, mStack3;

Voi iniializa aceste trei variabile n interiorul metodei onCreateResources() , n


interiorul instruciunii try-catch , imediat nainte de prinderea erorilor n scop de debugging
prin urmtoarele linii de cod :

// crearea stivelor
this.mStack1 = new Stack();
this.mStack2 = new Stack();
this.mStack3 = new Stack();

n continuare, voi cu ajutorul metodei add() specific tipului de data Stack voi adaug
cele trei inele definite anterior primei stive, adic primului turn. n plus, cu ajutorul metodelor
personalizate de setare a variabilelor specifice din clasa crea de tip Ring voi seta stiva i
respectiv turnul specific fiecrui inel ( evident prima stiva i primul turn ). Pentru a putea
nregistra i acces evenimente de tip touch necesare mutrii fiecrui inel de ctre utilizator,
voi nregistra fiecare inel ca o regiune ce poate fi atinsa ( touchable area ). Mai este nevoie
de nc o instruciune, aceast numindu-se
setTouchAreaBindingOnActionDownEnabled( boolean ) specific unei variabile de tip
scene ce permite primirea notificarilor spefice schimbrile prin accesare touch. Toate acestea
instruciuni le voi implementa n metod onCreateScene(), nainte de returnarea scenei.

// adaugarea in stiva a inelelor


this.mStack1.add(ring3);
this.mStack1.add(ring2);
this.mStack1.add(ring1);
// initializarea pozitiei initiale a fiecarui inel pe stive si
turnuri
ring1.setmStack(mStack1);
ring2.setmStack(mStack1);
ring3.setmStack(mStack1);
ring1.setmTower(mTower1);
ring2.setmTower(mTower1);
ring3.setmTower(mTower1);
// adaugarea posibilitatii de a inregistra evenimente tip Touch
scene.registerTouchArea(ring1);
scene.registerTouchArea(ring2);
scene.registerTouchArea(ring3);
scene.setTouchAreaBindingOnActionDownEnabled(true);

Pentru a face posibil mutarea inelelor de ctre utilizator, voi suprascrie o metod numit
onAreaTouch() specific clasei Sprite personalizat pentru inelele noastre, ce va verifica
dac un inel s-a ciocnit cu un turn. Definirea acestei metode o voi face mai trziu, urmrind
suprascrierea momentan. Totui, voi crea o metod goal la sfritul clasei
TowerOfHanoiActivity.java ce va arat aa:

private void checkForCollisionsWithTowers(Ring ring) {


}

Voi avea nevoie de nc un import pentru ca instruciunile specifice mutrii unui inel s
recunoasc clasele relevante:

import org.andengine.input.touch.TouchEvent;

Voi aduga instruciunilor cu ajutorul crora am creat cele trei inele n interiorul
metodei onCreateScene(), n interiorul constructorilor specifci instruciunile pentru
suprascrierea clasei despre care am vorbit.

Ring ring1 = new Ring(1, 139, 174, this.mRing1,


getVertexBufferObjectManager()) {
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (((Ring) this.getmStack().peek()).getmWeight() !=
this.getmWeight())
return false;
this.setPosition(pSceneTouchEvent.getX() this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP)
{
checkForCollisionsWithTowers(this);
}
return true;
}
};
Ring ring2 = new Ring(2, 118, 212, this.mRing2,
getVertexBufferObjectManager()) {

@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (((Ring) this.getmStack().peek()).getmWeight() !=
this.getmWeight())
return false;
this.setPosition(pSceneTouchEvent.getX() this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP)
{
checkForCollisionsWithTowers(this);
}
return true;
}
};
Ring ring3 = new Ring(3, 97, 255, this.mRing3,
getVertexBufferObjectManager()) {
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (((Ring) this.getmStack().peek()).getmWeight() !=
this.getmWeight())
return false;
this.setPosition(pSceneTouchEvent.getX() this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP)
{
checkForCollisionsWithTowers(this);
}
return true;
}
};

Se observ faptul c metoda onAreaTouched() returneaz on valoare tip boolean. Cnd


returneaz true, touch-ul este consumat, iar n caz contrariu este pasat n jos la alte straturi
( layere) pn cnd cineva l consum. Primul lucru pe care l-am urmrit n aceast metod
este s verific dac greutatea inelului accesat este egalala cu greutatea primului inel din stiv.
Dac este, asta nseamn c inelul este primul element din stiv deci poate fi accesat i mutat.
Dac nu este, nseamn c nu avem voie s mutm acel inel deci instruciunea va termina
touch-ul curent.

n plus, n metoda onAreaTouched() verific dac tipul aciunii touch este un


eveniment ACTION_UP declanat n momentul ridicrii degetului. Dac este, se va apela
metoda checkForCollisonsWithTowers() a crei scop principal este s verifice dac inelul sa ciocnit ( practic, atinge ) un turn.
Urmeaz s creez aceast funcie, prin adugarea n placeholderul gol definit mai nainte
a urmtoarelor instruciuni :

private void checkForCollisionsWithTowers(Ring ring) {


Stack stack = null;
Sprite tower = null;
if (ring.collidesWith(mTower1) && (mStack1.size() == 0 ||
ring.getmWeight() < ((Ring)
mStack1.peek()).getmWeight())) {
stack = mStack1;
tower = mTower1;
} else if (ring.collidesWith(mTower2) && (mStack2.size() == 0
||
ring.getmWeight() < ((Ring)
mStack2.peek()).getmWeight())) {
stack = mStack2;
tower = mTower2;
} else if (ring.collidesWith(mTower3) && (mStack3.size() == 0
||
ring.getmWeight() < ((Ring)
mStack3.peek()).getmWeight())) {
stack = mStack3;
tower = mTower3;
} else {
stack = ring.getmStack();
tower = ring.getmTower();
}
ring.getmStack().remove(ring);
if (stack != null && tower !=null && stack.size() == 0) {
ring.setPosition(tower.getX() + tower.getWidth()/2 ring.getWidth()/2, tower.getY() + tower.getHeight() ring.getHeight());
} else if (stack != null && tower !=null && stack.size() > 0)
{
ring.setPosition(tower.getX() + tower.getWidth()/2 ring.getWidth()/2, ((Ring) stack.peek()).getY() ring.getHeight());
}
stack.add(ring);
ring.setmStack(stack);

ring.setmTower(tower);
}

Codul de mai sus verific dac inelul asupra cruia se apeleaz instruciunea atinge un
turn. Dac da, iar n plus dac are greutatea mai mic dect a inelului de pe ultima poziie
populat a stivei ( conform regulilor ) inelul n cauza va fi mutat pe cea mai joas poziie
nepopulat a stivei n cauz. Deci, dac inelul este mutat pe alt turn i este mai mic ca inelul
de sub el acesta va fi poziionat pe turnul respectiv.
Rulnd i compilnd jocul, se observ faptul c jocul este total funcional. Mai lipsete un
singur lucru i anume modul n care jocul va fi ctigat, cnd toate inelele sunt mutate pe
ultimul turn.

Tratare excepie ncheierea jocului

Urmtorul pas i totodat ultimul pas spre a finaliza proiectul l reprezint tratarea unei
excepii, anume verificrii condiiei de ncheiere a jocului. Cnd utilizatorul va avea cele trei
inele n ordine cresctoare pe ultimul turn, el ar trebui anunat c i-a dus misiunea la sfrit,
jocul terminndu-se.
Voi aborda aceast problem ntr-un mod destul de simplist. Cnd se ndeplinete condita
enunat mai sus, jocul va nghea, nepermind utilizatorul s mai mute inelele. n plus voi
afia pe ecran un mesaj modificabil din cod. Acesta este implicit Game over.
Va fi nevoie de cteva importuri n plus, n special pentru a manipula text-ul necesar i
afiarea lui ca textur pe ecran :

import
import
import
import
import
import
import

android.graphics.Typeface;
org.andengine.entity.text.Text;
org.andengine.opengl.font.Font;
org.andengine.opengl.font.FontFactory;
org.andengine.opengl.texture.TextureOptions;
org.andengine.opengl.texture.bitmap.BitmapTextureFormat;
org.andengine.util.color.Color;

n continuare, voi defini o variabil privat de tip Font n partea de sus a clasei
principale. n plus, am definit i o variabil de tip Scene pentru a putea fi accesat pe viitor
din exteriorul metodei onCreateScene().

private Font main_font;


private Scene scene;

n metoda onCreateResources() voi iniializa variabila main_font cu ajutorul librriei


FontFactory care va crea un font cu parametri diferii dintre care i culoare, typeface sau
textur. Apoi voi ncrca acest font n resurse prin metoda superclasei Font, load():

main_font = FontFactory.create(this.getFontManager(),
this.getTextureManager(), 256, 256,
BitmapTextureFormat.RGBA_8888,
TextureOptions.BILINEAR_PREMULTIPLYALPHA, Typeface.DEFAULT,
60, true, Color.BLACK_ABGR_PACKED_INT);
main_font.load();

Modul de rezolvare a problemei tratrii excepiei pe care am ales-o const n faptul c voi
crea o metod nou numit isGameOver() care verific dac, indiferent de stiva de pe care a
fost apelat , stiva numrul 3 ( ultimul turn ) are 3 elemente ( prin metoda size() ). Dac da, se
va crea un obiect de tip Text cu mai muli parametrii dintre care font-ul descris mai sus,
nlimea i limea i evident poziia. Scenei jocului i va fi atasta acest obiect suprapus la tot
ce era nainte pe ea, iar n plus se vor dezactiva toate inputurile touch ( de pe inele ) .

private void isGameOver() {


if(mStack3.size() == 3){
Text gameOverText = new Text(0, 0, main_font,
"GameOver", this.getVertexBufferObjectManager());
gameOverText.setPosition(CAMERA_WIDTH/2 gameOverText.getWidth()/2, CAMERA_HEIGHT/2 gameOverText.getHeight()/2);
scene.attachChild(gameOverText);
scene.clearTouchAreas();
}}

Aceast funcie va fi apelat din interiorul metodei anterior concepute


checkForCollisionsWithTowers(), la sfritul ei. Practic mereu cnd vom muta un inel pe o
poziie diferit se verific dac ultima stiva are trei elemente. Dac da, atunci jocul s-a
terminat. Am adugat urmtoarea instruciune la sfritul metodei n cauza :

isGameOver();

Proiectul este finalizat. n ruma compilrii i rulrii se vor observ diferenele adus de
acest ultim pas ce permit ntiinarea utilizatorului n cazul corespunztor terminrii jocului.
Un aspect foarte important ce nu a fost menionat la modul de implementare a acestui
proiect este modularitatea lui i posibila extindere al aplicaiei fr prea mult efort. Anumite
feature-uri ce pot fi implementate fr dificulti majore pot numra :

nlocuirea textului game over cu o fereastra pop-up user friendly, ce va permite

i restartarea jocului
Numrarea si afiarea numarului total de micari
Calcularea si afiarea numarului minim de micari necesare pentru terminarea

jocului ( pentru trei inele acest numar este sapte )


Permiterea utilizatorului de a crete dificultatea jocului prin adaugarea mai multor
inele, modificrile necesare fiind minime.

Materializarea codului
n aceast seciune voi prezena metodele de distribuie a unei aplicaii Android n
urm finalizrii proiectului.
Fiind o platform open-source , Android ofer o multitudine de opiuni . Aplicaiile
android se pot distribui utilizatorilor n moduri diverse, folosindu-se o anumite abordare sau o
combinaie de abordri . Cele mai frecvente metode folosite sunt fie prin intermediul
magazinului Google Play Store sau a unor magazine private, direct de pe un web-site sau
chiar prin e-mail, nefiind astfel constrns de un anumit mod de distribuie.
Procesul de construire i mpachetare a aplicaiilor este acelai, indiferent de cum sunt
distribuite. Asta salveaz foarte mult timp i permit automatizarea prilor din proces dup
necesitate.
Seciunile de mai jos prezint pe scurt cteva metode n alternan pentru distribuirea
aplicaiilor .

Distribuirea printr-un magazin specializat


De obicei, pentru ca aplicaia s ajung la un numr ct mai larg de utilizatori, ea
trebuie distribuit printr-un magazin specializat de aplicaii, cum ar fi Google Play.
Google Play este cel mai mare i mai folosit magazin pentru aplicaii Android i este
n particular folositor pentru distribuirea catre o audiena global. Totui, aplicaie poate fi
distribuit i prin alte sau chiar multiple magazine.
Spre deosebire de alte metode de distribuie, Google Play permite utilizarea unui
sistem de plat intern aplicaiei alturi de un sistem de liceniere. Primul menionat permite
vnzarea de produse interne aplicaiei, cum ar fi upgrade-uri sau monede caracteristice
aplicaiei. Serviciul de liceniere ajut la eliminarea instalrilor i folosirii neautorizate a
aplicaiei n cauza.

Distribuirea prin E-mail


O modalitate uoar i rapid de a scoate pe pia o
aplicaie este trimiterea ei ctre utilizatori prin E-mail. Pentru a
face asta, trebuie iniial pregtit aplicaia n forma final, ataat
unui e-mail i trimis utilizatorilor. Cnd utilizatorul deschide emailul pe un dispozitiv bazat pe Android, sistemul de operare
Android recunoate fiierul tip APK ( un pachet de tip executabil
folosit la instalare ) i va afia un buton numit Install Now n
interiorul e-mailulul. Prin atingerea butonului, utilizatorii vor
putea instala aplicaia.
Not: Acest buton despre care am vorbit va aprea
numai n cazul n care utilizatorul a deschis e-mailul n aplicaia nativ Gmail i i-a
configurat device-ul pentru a-i permite instalarea din surse necunoscute, opiune despre care
voi vorbi mai trziu.
Distribuirea aplicaiei prin e-mail este convenient dac vrei s-o mpari la un numr
redus de utilizatori de ncredere, datorit faptului c protecia contra piraterie i distribuie
neautorizata este minima. Astfel, orice a primit aplicaie o poate distribui mai departe oricui.

Distribuirea printr-un website


Dac nu vrei ca aplicaia ta s fie distribuit printr-un magazin n genul Google Play, se
poate opta pentru o distribuie pe website-ul sau serverul personal, fie el privat sau tip
enterprise. Pentru a face asta, aplicaia trebuie pregtit pentru distribuie n modul normal.
Urmtorul i ultimul pas este urcarea i hostarea fiierului APK pe websiteul respectiv,
mpreun cu un link de descrcare. Fiierul APK poaste fi gsit n fiierele generate de IDE-ul
folosit ( Eclipse, Android Studio etc.) n urm compilrii i rulrii aplicaiei.
Cnd utilizatorul navigheaz pe website-ul n cauz de pe un telefon bazat pe
Android, fiierul dup downloadare este instalat automat de ctre sistemul Android. Totui,
acest proces ncepe automat doar dac utilizatorul i-a configurat setrile telefonului astfel
nct s permite instalarea aplicaiilor din surse necunoscute.

Optarea pentru aplicaii din surse necunoscute


Platforma Android protejeaz utilizatorul de descrcri i instalri de aplicaii posibil
periculoase din locaii diferite de magazinul Google Play ( cel mai sigur loc desemnat
descrcrilor ). Blocheaz aceste instalri pn cnd utilizatorul opteaz pentru instalarea din
surse necunoscute ( Unknown soruces )
din meniul Setri ( Settings ) ->
Securitate ( Security ).
Utilizatorul trebuie s fac aceast modificare nainte s descarce aplicaiile din
sursele n cauz pe deivce-ul su.
Not: Unii operatori de reea nu permit utilizatorilor s instaleze aplicaii n acest
mod.

Bibliografie

http://developer.android.com/distribute/tools/open-distribution.html
http://en.wikipedia.org/wiki/Android_%28operating_system%29
http://ro.wikipedia.org/wiki/Android_%28sistem_de_operare%29
http://uzinadeganduri.ro/internet-2/ce-este-android
http://www.hit.ro/software/android-pe-intelesul-tuturor-ce-este-si-ce-face
http://ro.wikipedia.org/wiki/Java_%28limbaj_de_programare%29
https://hrimiucr.wordpress.com/2013/03/18/java-despre/
http://www.andengine.org/
https://github.com/nicolasgramlich/AndEngine
https://beginningandengine.wordpress.com/2012/09/03/what-is-andengine/
http://www.raywenderlich.com/12065/how-to-create-a-simple-android-game
http://stackoverflow.com/
http://stackoverflow.com/questions/21433572/adding-counter-to-tower-of-hanoi-

android-andengine-app
http://google.wikia.com/wiki/Gmail
http://www.matim-dev.com/tutorials.html
http://www.andengine.org/blog/tag/tutorial/
https://www.scribd.com/doc/17773461/Java
http://www.java2s.com/Tutorial/Java/0100__Class-

Definition/TheTowersofHanoi.htm
http://www.vogella.com/tutorials/JavaAlgorithmsTowersOfHanoi/article.html
http://en.wikipedia.org/wiki/Tower_of_Hanoi
http://www.puzzle.ro/ro/play_toh.htm
http://ro.wikipedia.org/wiki/Turnul_din_Hanoi
http://informaticasite.ro/divide-et-impera/192-turnurile-din-hanoi.html
http://forum.softpedia.com/topic/908887-tema-turnurile-din-hanoi-program-c/
http://divideetimpera.wikispaces.com/Turnurile+lui+Hanoi+B
http://en.wikipedia.org/wiki/Divide_and_rule
http://ro.wikipedia.org/wiki/Divide_et_impera_%28informatic%C4%83%29

Você também pode gostar