/**************** * GO BLOB * @author Louis Meckes , a sleepless night =) *****************/ partie p; int resolution = 190; // Initialize void setup() { size(resolution, resolution); // taille de l'affichage p = new partie(19); framerate(30); background(255, 217, 128); } // Drawing void draw() { smooth(); p.goban.afficher(); // �v�nements souris if (mousePressed == true) { if (mouseButton == LEFT) { cellule c = p.goban.cellule_sous_coordonnees(mouseX, mouseY); p.jouer(c.x+1, c.y+1); } else if (mouseButton == RIGHT) { p.recommencer(); background(255, 217, 128); } } // Evenements clavier if (keyPressed) { if (key == 'n') { cellule c = p.goban.cellule_sous_coordonnees(mouseX, mouseY); p.goban.poser_pierre_noire(c.x+1, c.y+1); } else if (key == 'b') { cellule c = p.goban.cellule_sous_coordonnees(mouseX, mouseY); p.goban.poser_pierre_blanche(c.x+1, c.y+1); } else if (key == 'v') { cellule c = p.goban.cellule_sous_coordonnees(mouseX, mouseY); c.retirer_pierre(); } } } /** ** classe PARTIE **/ class partie { int taille; int nb_coups; public goban goban; public partie(int taille) { this.goban = new goban(taille); } public void jouer(int x, int y) { boolean coup_valide; if(this.nb_coups%2 == 0) coup_valide = this.goban.poser_pierre_noire(x,y); else coup_valide = this.goban.poser_pierre_blanche(x,y); if (coup_valide) this.nb_coups ++; } public void recommencer() { this.goban.enlever_toutes_les_pierres(); this.nb_coups=0; } } /** ** classe GOBAN **/ class goban { int taille; cellule_p c[][]; int max_influence, min_influence; public goban(int taille) { this.taille = taille; c = new cellule_p[this.taille][this.taille]; this.construire_cellules(); } private void construire_cellules() { int x, y; for (x = 0; x< this.taille; x++) { for (y = 0; y< this.taille; y++) { this.c[x][y] = new cellule_p(x,y,this.taille); } } } public boolean poser_pierre_noire(int x, int y) // vrai si coup valide { cellule c = this.c[x-1][y-1]; if (c.etat() == 0) { c.poser_pierre_noire(); return true; } else return false; } public boolean poser_pierre_blanche(int x, int y) // vrai si coup valide { cellule c = this.c[x-1][y-1]; if (c.etat() == 0) { c.poser_pierre_blanche(); return true; } else return false; } public void enlever_toutes_les_pierres() { int x, y; for (x = 0; x< this.taille; x++) { for (y = 0; y< this.taille; y++) { this.c[x][y].retirer_pierre(); } } } public void afficher() { for (int x = 0; x< this.taille; x++) { for (int y = 0; y< this.taille; y++) { int xcoord = this.c[x][y].xcoord; int ycoord = this.c[x][y].ycoord; // Trac� des lignes if (x == 0) line(xcoord,ycoord,width-(width/this.taille)/2,ycoord); // Lignes horizontales if (y == 0) line(xcoord,ycoord,xcoord,height-(height/this.taille)/2); // Lignes verticales // Dessin des cellules this.c[x][y].afficher(); } } this.traitement_particules(); } // Traitement des particule public void traitement_particules() { // 1er passage (valeurs absolues) max_influence = 0; min_influence = 0; for (int x = 0; x< this.taille; x++) { for (int y = 0; y< this.taille; y++) { // Traitement des particules de la cellule en cours if (this.c[x][y].etat() != 0) { for (int c_par = 0; c_par< this.c[x][y].nb_particules; c_par++) { this.traitement_particule(this.c[x][y].particules[c_par]); } } } } // 2eme passage (normalisation) int limit_inf_d = (width/this.taille); // limite de l'influence affichable int ideal_inf; // inluence id�ale (norm. parfaite) int max_max_influence = max(max_influence, -min_influence); for (int x = 0; x< this.taille; x++) { for (int y = 0; y< this.taille; y++) { if (this.c[x][y].influence > 0) { ideal_inf = (this.c[x][y].influence*limit_inf_d)/(max_max_influence+1); this.c[x][y].influence = (ideal_inf + constrain(this.c[x][y].influence,0,limit_inf_d))/2; } else if (this.c[x][y].influence < 0) { ideal_inf = (this.c[x][y].influence*limit_inf_d)/(max_max_influence+1); this.c[x][y].influence = (ideal_inf + constrain(this.c[x][y].influence,-limit_inf_d,0))/2; } } } } // Traitement d'une particule private void traitement_particule(particule p) { // La particule sort du goban, meurt et rescucite a sa source if ((p.x <=0 || p.x >=width) || (p.y <=0 || p.y >=height)) { p.resusciter(); } cellule_p cell_sous_coord = this.cellule_sous_coordonnees(p.x, p.y); // La particule influence la cellule neutre travers�e if (cell_sous_coord.etat() == 0) { // Nouvelle influence pour la cellule cell_sous_coord.influence += p.etat_source; // Maj. de min/max influence du goban if (cell_sous_coord.influence > max_influence) max_influence = cell_sous_coord.influence; else if (cell_sous_coord.influence < min_influence) min_influence = cell_sous_coord.influence; } // La particule heurte une pierre adverse, meurt et rescucite a sa source else if (cell_sous_coord.etat() != p.etat_source) { //p.resusciter(); } // La particule heurte une pierre amie, meurt et rescucite a sa source else if (cell_sous_coord.etat() == p.etat_source && (p.x != p.source_x || p.y != p.source_y)) { p.resusciter(); } } public cellule_p cellule_sous_coordonnees(int xcoord, int ycoord) { int x,y; x = floor(xcoord/(width/this.taille)); y = floor(ycoord/(height/this.taille)); if (y > this.taille -1) y = this.taille -1; if (x > this.taille -1) x = this.taille -1; return this.c[x][y]; } } /** ** classe CELLULE generique **/ abstract class cellule { int x, y; int stone; int taille_goban; int xcoord, ycoord; cellule(int x, int y, int taille_goban) { this.x = x; this.y = y; this.stone = 0; this.taille_goban = taille_goban; this.xcoord = ((width/this.taille_goban)*x)+(width/this.taille_goban)/2; this.ycoord = ((height/this.taille_goban)*y)+(height/this.taille_goban)/2; } public void poser_pierre_noire() { this.stone = 1; } public void poser_pierre_blanche() { this.stone = -1; } public void retirer_pierre() { this.stone = 0; } public int etat() { return(this.stone); } public boolean hoshi() { if ( (this.x == 3 && this.y == 3) || (this.x == 9 && this.y == 3) || (this.x == 15 && this.y == 3) || (this.x == 3 && this.y == 9) || (this.x == 9 && this.y == 9) || (this.x == 15 && this.y == 9) || (this.x == 3 && this.y == 15) || (this.x == 9 && this.y == 15) || (this.x == 15 && this.y == 15) ) { return true; } else return false; } void afficher() { int taille_cellule; switch (this.stone) { case 1 : taille_cellule = (width/this.taille_goban); fill(0); break; case -1 : taille_cellule = (width/this.taille_goban); fill(230); break; default : taille_cellule = 0; fill(0); break; } if (taille_cellule > 0) // Si une pierre est pr�sente { ellipse(this.xcoord, this.ycoord, taille_cellule, taille_cellule); } else if (hoshi()) // Sinon, si hoshi { ellipse(this.xcoord, this.ycoord, (width/this.taille_goban)/4, (width/this.taille_goban)/4); } } } /** ** classe CELLULE avec gestion des particules **/ class cellule_p extends cellule { public particule[] particules; int nb_particules = 150; // nombre de particules par cellule int influence = 0; // influence en valeur absolue int influence_d = 0; // influence affichable cellule_p(int x, int y, int taille_goban) { super(x,y,taille_goban); this.particules = new particule[nb_particules]; for (int i = 0; i< this.nb_particules; i++) this.particules[i] = new particule(this.xcoord, this.ycoord, this.etat()); } public void afficher() { if (this.etat() != 0) for (int i = 0; i< nb_particules; i++) this.particules[i].afficher(); // affichage influence int d_inf = influence; int alpha = 32; int cell_size = (width/taille_goban); noStroke(); if (this.influence >0) { fill(255,0,0,alpha); ellipse(this.xcoord, this.ycoord, cell_size*1.5, cell_size*1.5); //fill(255,0,0,255); //ellipse(this.xcoord, this.ycoord, d_inf, d_inf); //fill(255,0,0,25); //rect((this.xcoord-cell_size/2),(this.ycoord-cell_size/2),cell_size,cell_size); } else if (this.influence <0) { fill(0,0,255,alpha); ellipse(this.xcoord, this.ycoord, cell_size*1.5, cell_size*1.5); //fill(0,0,255,255); //ellipse(this.xcoord, this.ycoord, d_inf, d_inf); //fill(0,0,255,25); //rect((this.xcoord-cell_size/2),(this.ycoord-cell_size/2),cell_size,cell_size); } fill(255, 217, 128,alpha/2); ellipse(this.xcoord, this.ycoord, cell_size*1.5, cell_size*1.5); stroke(0); // fin affichage influence super.afficher(); } public void poser_pierre_noire() { super.poser_pierre_noire(); for (int i = 0; i< this.nb_particules; i++) this.particules[i].etat_source = 1; } public void poser_pierre_blanche() { super.poser_pierre_blanche(); for (int i = 0; i< this.nb_particules; i++) this.particules[i].etat_source = -1; } public void retirer_pierre() { super.retirer_pierre(); for (int i = 0; i< this.nb_particules; i++) this.particules[i].etat_source = 0; this.influence = 0; } } /** ** Classe particule **/ class particule { int source_x, source_y; int x, y; int etat_source; int unit = width/19; particule(int source_x, int source_y, int couleur) { this.source_x = source_x; this.x = source_x; this.source_y = source_y; this.y = source_y; this.etat_source = couleur; } public void afficher() { this.propulser(); if (this.etat_source == 1) fill(255,75,75); else fill(75,75,255); } public void resusciter() { this.x = this.source_x; this.y = this.source_y; } private void propulser() { this.x += round(random(-this.unit,this.unit)); this.y += round(random(-this.unit,this.unit)); } }