Mais de um mês sem postar, mas isso não quer dizer que nada aconteceu… muito pelo contrário, além de uma visita ao Google Belo Horizonte, alguns campeonatos do Topcoder e reviravoltas no trabalho, resolvi implementar o que tinha dito uns 2 posts passados (implementar Torre de Hanoi usando Processing). Pois é, no meio do caminho, decidi que seria mais interessante fazer somente a simulação e não imprimir o resultado do algoritmo, isso significa que tenho uma implementação de um ‘jogo’ de torre de Hanoi em Processing. O código não está nem perto de bonito, apesar de existirem classes, o conceito de information hiding não é muito aplicado, não há como partir um projeto em mais de um arquivo, portanto, entre outros entraves. Entre mortos e feridos, fiz o possível pra não deixar o código macarrônico, mas …

Um screenshot da minha primeira aplicação em Processing:
Torre de Hanoi em Processing

Caso alguém se interesse, o código segue abaixo:

class StackNode{
int value;
StackNode nextNode;

StackNode(int value){
this.value = value;
this.nextNode = null;
}
}

class Stack{
StackNode top;
int length;

Stack(){
this.top = null;
this.length = 0;
}

void push(StackNode node){
StackNode temp = this.top;
node.nextNode = temp;
this.top = node;
this.length++;
}

void pop(){
this.top = this.top.nextNode;
this.length–;
}

int getTopValue(){
if(this.length == 0){
return 1;
} else{
return this.top.value;
}
}

int getValue(int pos){
StackNode tmp = this.top;

for(int i = 0; i < pos; i++){
tmp = tmp.nextNode;
}

return tmp.value;
}
}

int size_horizontal = 800;
int size_vertical = 600;
int frame_rate = 30;

int tower_width = 200;
int tower_height = 400;

int disk_width = 200;
int disk_height = 80;

boolean isPegSelected;
int pegSelected;

class Peg{
Stack stack;

int x;
int y;

Peg(int x, int y){
this.x = x;
this.y = y;

stack = new Stack();
}

void push(int value){
this.stack.push(new StackNode(value));
}

}

Peg[] pegs;

void resetPegs(){
pegs = new Peg[3];
pegs[0] = new Peg(150, 300);
pegs[1] = new Peg(400, 300);
pegs[2] = new Peg(650, 300);

for(int i = 0; i < 1; i++){
pegs[i].push(3);
pegs[i].push(2);
pegs[i].push(1);
}
}

void printPeg(int pos){
rectMode(CENTER);
fill(255,0, 0);
rect(pegs[pos].x, pegs[pos].y, tower_width, tower_height);

int yDisk = pegs[pos].y + 200;

for(int i = pegs[pos].stack.length 1; i >= 0; i–){
yDisk -= 25 + 50;
if(pegSelected == pos && i == 0){
fill(255, 255, 255);
}else{
fill(0, 255, 0);
}
rect(pegs[pos].x, yDisk, disk_width + pegs[pos].stack.getValue(i) * 12, disk_height);
fill(200, 0, 100);
text(“” + pegs[pos].stack.getValue(i), pegs[pos].x, yDisk);
yDisk -= 25;
}
}

boolean isInsidePeg(int pos, int x, int y){
return (x >= pegs[pos].x (tower_width/2)) &&
(x <= pegs[pos].x + (tower_width/2)) &&
(y >= pegs[pos].y (tower_height/2)) &&
(y <= pegs[pos].y + (tower_height/2));
}

void setup()
{
size(size_horizontal, size_vertical);
noStroke();
frameRate(frame_rate);
smooth(); //just to draw anti-aliased edges

resetPegs();

PFont fontA = loadFont(“CourierNew36.vlw”);
textFont(fontA, 36);
textAlign(CENTER);

isPegSelected = false;
pegSelected = 1;
}

void draw()
{
background(0, 0, 255);

//draw 3 pegs
for(int i = 0; i < 3; i++){
printPeg(i);
}
}

void mouseReleased(){
boolean insidePeg = false;

int i = 1;
for(i = 0; i < 3; i++){
insidePeg = isInsidePeg(i, mouseX, mouseY);
if(insidePeg == true){ break; }
}

if(isPegSelected == true){

if(insidePeg == true){
int topValueSelected = pegs[pegSelected].stack.getTopValue();
int topValueI = pegs[i].stack.getTopValue();

if(topValueI > topValueSelected){
pegs[i].push(pegs[pegSelected].stack.getTopValue());
pegs[pegSelected].stack.pop();
}
}

isPegSelected = false;
pegSelected = 1;
} else{
if(insidePeg == true){
isPegSelected = true;
pegSelected = i;
}
}
}