commit b4fa9ed710314097366fa11a6934ad43aade24b4 Author: Stefano Rossi Date: Thu Jul 10 03:30:51 2025 +0200 first commit diff --git a/CambiaTitoloeIcona.pde b/CambiaTitoloeIcona.pde new file mode 100644 index 0000000..af32808 --- /dev/null +++ b/CambiaTitoloeIcona.pde @@ -0,0 +1,16 @@ +PImage fai_iconi; +PGraphics fai_icong; +String fai_filename; + +void frameAndIcon(String frameText, String iconFilename) { + if ( fai_filename == null || !fai_filename.equals(iconFilename) ) { + fai_iconi = loadImage(iconFilename); + fai_icong = createGraphics(16, 16, JAVA2D); + fai_filename = iconFilename; + } + surface.setTitle( frameText ); + fai_icong.beginDraw(); + fai_icong.image( fai_iconi, 0, 0 ); + fai_icong.endDraw(); + frame.setIconImage(fai_icong.image); +} \ No newline at end of file diff --git a/Celle.pde b/Celle.pde new file mode 100644 index 0000000..5626039 --- /dev/null +++ b/Celle.pde @@ -0,0 +1,83 @@ +private void creaCelle(){ + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + celle[r][c] = new Cella(r, c, lato/cellePerLato); + } + } +} + +private void risolviSudoku(){ + new thRisolutore(celle); +} + +//metodo per l inserimento del numero nella cella, questo metodo controlla se il numero è inseribile +// e lo inserisce, se non lo è ritorna r e c della cella che va in conflitto +private void inserisciNumero(int r, int c, int n){ + //println(c); + //println(r); + + Cella[] cellaConflitto = new Cella[3]; + cellaConflitto[1] = null; + cellaConflitto[1] = null; + cellaConflitto[2] = null; + + //Controllo in tutta la COLONNA se è già presente il numero che si vuole inserire + for(int iC = 0; iC < 9; iC++){ + if(n != 0 && n == celle[r][iC].getN()){ + cellaConflitto[0] = new Cella(r, iC, n); + //println("numero gia presente alla Col: " + r + " e alla rig: " + iC); + //println("n conf " + celle[c][iC].getN() + " n nuovo: " + celle[c][r].getN()); + } + } + + //Controllo in tutta la RIGA se è già presente il numero che si vuole inserire + for(int iR = 0; iR < 9; iR++){ + if(n != 0 && n == celle[iR][c].getN()){ + cellaConflitto[1] = new Cella(iR, c, n); + //println("numero gia presente alla Col: " + iR + " e alla rig: " + c); + //println("n conf " + celle[c][iR].getN() + " n nuovo: " + celle[c][r].getN()); + } + } + + //Controllo che nella regione non è già presente lo stesso numero + //trovo la regione della cella + int cR = floor(r/3); + int rR = floor(c/3); + + //println(rR); + //println(cR); + + for(int i = 0; i <3; i++){ + for(int j = 0; j <3; j++){ + if(n != 0 && n == celle[cR*3 + j][rR*3 + i].getN()){ + //controllo che cella modificata e controllata siano diverse + if(r != (cR*3 + j) && c != (rR*3 + i)){ //<>// + cellaConflitto[2] = new Cella(cR*3 + j, rR*3 + i, n); + + //println(cR*3 + j + " " + r); + //println(rR*3 + i + " " + c); + //println(); + } + //println(celle[rR*3 + j][cR*3 + i].getN()); + } + //println(rR*3 + j + " " + c); + //println(cR*3 + i + " " + r); + //println(); + } + } + + + if(cellaConflitto[0] != null){ + new ThTiming(cellaConflitto[0].getR(), cellaConflitto[0].getC()).inizia(); + } + if(cellaConflitto[1] != null){ + new ThTiming(cellaConflitto[1].getR(), cellaConflitto[1].getC()).inizia(); + } + if(cellaConflitto[2] != null){ + new ThTiming(cellaConflitto[2].getR(), cellaConflitto[2].getC()).inizia(); + } + + if(cellaConflitto[0] == null && cellaConflitto[1] == null && cellaConflitto[2] == null){ + celle[r][c].setN(n); + } +} diff --git a/Classe_Cella.pde b/Classe_Cella.pde new file mode 100644 index 0000000..2821524 --- /dev/null +++ b/Classe_Cella.pde @@ -0,0 +1,119 @@ +private class Cella{ + private int R; //Riga della cella + private int C; //Colonna della cella + private int L; //lato + private int N; //numero contenuto nella cella + private color ColCella; // colore bg della cella + private color ColN; //colore del numero + private int pntFontN; //grnadezza carattere + private color warningColor; //colore sfondo per evidenziare celle in conflitto col nuovo num da inserire + private boolean fissa; + private boolean selezionata; //true se la cella è stata cliccata + + //COSTRUTTORE + public Cella(int R, int C, int L){ + this.R = R; + this.C = C; + this.L = L; + + this.N = 0; + this.ColCella = color(0, 200, 200, 80); //Azzurro trasp + this.warningColor = color(255, 0, 0, 0); //rosso completamente trasparente + this.pntFontN = 20; + this.selezionata = false; + this.fissa = false; + this.ColN = color(0, 102, 153); //blu chiaro + } + + //METODI + public void toggleFissa(){ + this.fissa = !this.fissa; + //println(fissa); + if(this.fissa){ + this.ColN = color(0, 0, 0); //nero + this.ColCella = color(255, 128, 0, 200); //arancione + }else{ + this.ColN = color(0, 102, 153); //blu chiaro + this.ColCella = color(0, 200, 200, 80); //Azzurro trasp + } + } + + //GETTER E SETTER + public boolean isSelezionata() { + return this.selezionata; + } + + public void setSelezionata(boolean selezionata) { + this.selezionata = selezionata; + } + + public int getX() { + return this.R * this.L; + } + public int getY() { + return this.C * this.L; + } + + public int getL() { + return this.L; + } + + public void setR(int R) { + this.R = R; + } + + public int getR() { + return this.R; + } + + public void setC(int C) { + this.C = C; + } + + public int getC() { + return this.C; + } + + public void setN(int N) { + this.N = N; + } + + public int getN() { + return this.N; + } + + public void setWarningColor(color warningColor) { + this.warningColor = warningColor; + } + + public int getWarningColor() { + return this.warningColor; + } + + public void setPntFontN(int pntFontN) { + this.pntFontN = pntFontN; + } + + public int getPntFontN() { + return this.pntFontN; + } + + public void setColN(color ColN) { + this.ColN = ColN; + } + + public color getColN() { + return this.ColN; + } + public color getColCella() { + return this.ColCella; + } + + public void setFissa(boolean fissa) { + this.fissa = fissa; + } + + public boolean isFissa() { + return this.fissa; + } +} \ No newline at end of file diff --git a/Classe_ThRisolutore.pde b/Classe_ThRisolutore.pde new file mode 100644 index 0000000..ec07860 --- /dev/null +++ b/Classe_ThRisolutore.pde @@ -0,0 +1,160 @@ +public class thRisolutore extends Thread{ + private Cella[][] celleSoluzione; + private boolean esecuzione; + private boolean arretra; + + public thRisolutore(Cella[][] celleInput) { + celleSoluzione = new Cella[9][9]; + + //creao un secondo array bidim celle dove andrò a salvare i numeri della soluzione + //ora riempo l array soluzioni con i numeri gia inseriti e li metto fissi + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + celleSoluzione[c][r] = new Cella(c, r, lato/cellePerLato); + + celleSoluzione[c][r].setN(celleInput[c][r].getN()); + + if(celleSoluzione[c][r].getN() > 0){ + celleSoluzione[c][r].setFissa(true); + //println("Riga" + r + "Colonna" + c + "è fissata: " + celleSoluzione[c][r].getN()); + } + } + } + + //faccio subito partire il thread + this.inizia(); + } + + public void inizia(){ + this.esecuzione = true; + this.start(); + } + + boolean isEsecuzione() { + return this.esecuzione; + } + + private boolean inserisciVal(int r, int c, int n){ + //println("provo con " + n); + //Controllo in tutta la COLONNA se è già presente il numero che si vuole inserire + for(int iC = 0; iC < 9; iC++){ + //println("c: " + iC); + if(n != 0 && n == celleSoluzione[iC][r].getN()){ + //println(n + " gia presente in c: " + iC); + + return true; + }//else println(n + " non presente in c: " + iC); + } + + //Controllo in tutta la COLONNA se è già presente il numero che si vuole inserire + for(int iR = 0; iR < 9; iR++){ + //println("r: " + iR); + if(n != 0 && n == celleSoluzione[c][iR].getN()){ + //println(n + " gia presente in c: " + iR); + + return true; + }//else println(n + " non presente in c: " + iR); + } + + //Controllo che nella regione non è già presente lo stesso numero + //trovo la regione della cella + int cR = floor(c/3); + int rR = floor(r/3); + + for(int iR = 0; iR <3; iR++){ + for(int iC = 0; iC <3; iC++){ + if(n != 0 && n == celleSoluzione[cR*3 + iC][rR*3 + iR].getN()){ + //controllo che cella modificata e controllata siano diverse + if(c != (cR*3 + iC) && r != (rR*3 + iR)){ + return true; + } + } + } + } + + //try { + // Thread.sleep(500); + //}catch(InterruptedException e) { + // esecuzione = false; + //} + + celleSoluzione[c][r].setN(n); + return false; + } + + public void run() + { + while(esecuzione){ + celle = celleSoluzione; + boolean errore; //numero inserito non valido + int prove; + errore = true; + try { + celle = celleSoluzione; + for(int r = 0; r < 9; r++){ + for(int c = 0; c < 9; c++){ + + //println(r + " " + c); + //parto dalla prima cella in alto a sx, controlo se è non è fissa altrimenti la salto + if(!celleSoluzione[c][r].isFissa()){ + arretra = false; + //println("cella non fissa: " + c); + if(celleSoluzione[c][r].getN() < 9){ + //println("n < 9: "); + errore = true; + prove = 1; + while(errore){ + //quando arrivo a dover inserire 10 nella esco dal while e torno indietro + if(celleSoluzione[c][r].getN() + prove < 10){ + //println("controllo fattibilità"); + errore = inserisciVal(r, c, celleSoluzione[c][r].getN() + prove); + prove ++; + }else{ + //se arrivo a provare il 9 e non va allora arretro di una cella + arretra = true; + errore = false; + celleSoluzione[c][r].setN(0); + if(c!=0){ + c -= 2; + }else{ + r --; + c = 7; + } + } + } + }else{ + //se la cella in cui ho indietreggiato contiene nove allora arretro ancroa + errore = false; + arretra = true; + celleSoluzione[c][r].setN(0); + if(c!=0){ + c -= 2; + }else{ + r --; + c = 7; + } + } + }else if (arretra){ + //se ho appena arretrato e la cella è ancora fissa aretro ancora + if(c!=0){ + c -= 2; + }else{ + r --; + c = 7; + } + } + //println("nuova cella colonna"); + Thread.sleep(0); + } + + //println("nuova cella riga"); + } + println("è stato facile"); + esecuzione = false; + + }catch(InterruptedException e) { + esecuzione = false; + } + } + } +} \ No newline at end of file diff --git a/Classe_ThTiming.pde b/Classe_ThTiming.pde new file mode 100644 index 0000000..515ef32 --- /dev/null +++ b/Classe_ThTiming.pde @@ -0,0 +1,44 @@ +public class ThTiming extends Thread { + private boolean esecuzione; + int r, c; + + public ThTiming(int r, int c) { + this.esecuzione = false; + this.r = r; + this.c = c; + } + +public void inizia(){ + this.esecuzione = true; + this.start(); +} + +boolean isEsecuzione() { + return this.esecuzione; +} + +void run () { + //salvo il colore iniziale + try { + celle[r][c].setWarningColor(color(255, 0, 0, 255)); + Thread.sleep(800); + }catch(InterruptedException e) { + esecuzione = false; + } + + while (esecuzione) { + for(int i = 0; i<=255 && esecuzione; i += 5){ + try { + Thread.sleep(20); + celle[r][c].setWarningColor(color(255, 0, 0, 255 - i)); + //println(i); + } + catch(InterruptedException e) { + esecuzione = false; + } + } + esecuzione = false; + celle[r][c].setWarningColor(color(255, 0, 0, 0)); + } + } +} \ No newline at end of file diff --git a/KeyPressed.pde b/KeyPressed.pde new file mode 100644 index 0000000..28224f5 --- /dev/null +++ b/KeyPressed.pde @@ -0,0 +1,103 @@ +void keyPressed() { + //trova keyCode + //println("CODICE: " + keyCode); + + if(keyCode == 71){ + creaCelle(); + } + + //QUANDO PREMO r o R parte il ciclo della rosoluzione del sudoku + if(keyCode == 82 || keyCode == 16){ + risolviSudoku(); + } + + //QUANDO PREMO ENTER o SPAZIO confermo il numero nella cella selezionata + if(keyCode == 10 || keyCode == 32){ + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + celle[r][c].setSelezionata(false); + UCS.setSelezionata(false); + } + } + } + + //QUANDO PREMO DEL o CANC confermo il numero nella cella selezionata + if(keyCode == 8 || keyCode == 127){ + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + if(celle[r][c].isSelezionata()) celle[r][c].setN(0); + if(celle[r][c].isSelezionata()) celle[r][c].setFissa(false); + } + } + } + + //QUANDO PREMO TAB togglo lo stato fisso della cella selezionata + if(keyCode == 9){ + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + if(celle[r][c].isSelezionata()) celle[r][c].toggleFissa(); + } + } + } + + //QUANDO PREMO ESC parte la chiusura del programma nel draw + if(keyCode == 27){ + exit(); + } + + //QUANDO PREMO FRECCIA SX 37, DX 39, SU 38, GIU 40 se la cella non è stata messa fissa + if(keyCode == 37 || keyCode == 39 || keyCode == 38 || keyCode == 40){ + //println(UCS.getR()); + //println(UCS.getC()); + + if(keyCode == 37){ //sx + if(UCS.getR() - 1>= 0){ + celle[UCS.getR()][UCS.getC()].setSelezionata(false); //deseleziono la cella selezionata attualmente + celle[UCS.getR() - 1][UCS.getC()].setSelezionata(true); + UCS.setR(UCS.getR() - 1); + } + } else if(keyCode == 39){ //dx + if(UCS.getR() + 1< 9){ + celle[UCS.getR()][UCS.getC()].setSelezionata(false); //deseleziono la cella selezionata attualmente + celle[UCS.getR() + 1][UCS.getC()].setSelezionata(true); + UCS.setR(UCS.getR() + 1); + } + } else if(keyCode == 38){ //su + if(UCS.getC() - 1>= 0){ + celle[UCS.getR()][UCS.getC()].setSelezionata(false); //deseleziono la cella selezionata attualmente + celle[UCS.getR()][UCS.getC() - 1].setSelezionata(true); + UCS.setC(UCS.getC() - 1); + } + } else if(keyCode == 40) { // giu + if(UCS.getC() + 1 < 9){ + celle[UCS.getR()][UCS.getC()].setSelezionata(false); //deseleziono la cella selezionata attualmente + celle[UCS.getR()][UCS.getC() + 1].setSelezionata(true); + UCS.setC(UCS.getC() + 1); + } + } + } + + //controllo se ho cliccato un tasto numerico, in tal caso vado a vedere r e c della cella clicata + if((keyCode >= 48 && keyCode <= 57 || keyCode >= 96 && keyCode <= 105) && (!celle[UCS.getR()][UCS.getC()].isFissa() || celle[UCS.getR()][UCS.getC()].getN() == 0)){ + int rPreSelezionata = - 1; + int cPreSelezionata = - 1; + boolean trovata = false; + + //deseleziono ogni cella, trovo se ce n era una ancora cliccata e in tal caso salvo num riga e col + for(int r = 0; r < cellePerLato && !trovata; r++){ + for(int c = 0; c < cellePerLato && !trovata; c++){ + if(celle[r][c].isSelezionata()){ + rPreSelezionata = r; + cPreSelezionata = c; + trovata = true; + } + } + } + + if(trovata){ + //controllo se premo un tasto per l inserimento di numeri, e se sono tra 0 e 9 li assegno alla cella cliccata + if(keyCode - 48 <= 9) inserisciNumero(rPreSelezionata,cPreSelezionata, keyCode - 48); + else inserisciNumero(rPreSelezionata,cPreSelezionata, keyCode - 96); + } + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4002995 --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +# DON'T BE A DICK PUBLIC LICENSE + +> Version 1.1, December 2016 + +> Copyright (C) 2024 Rossi Stefano + +Everyone is permitted to copy and distribute verbatim or modified +copies of this license document. + +> DON'T BE A DICK PUBLIC LICENSE +> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +1. Do whatever you like with the original work, just don't be a dick. + + Being a dick includes - but is not limited to - the following instances: + + 1a. Outright copyright infringement - Don't just copy this and change the name. + 1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick. + 1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick. + +2. If you become rich through modifications, related works/services, or supporting the original work, +share the love. Only a dick would make loads off this work and not buy the original work's +creator(s) a pint. + +3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes +you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back. \ No newline at end of file diff --git a/MouseClicked.pde b/MouseClicked.pde new file mode 100644 index 0000000..ad50189 --- /dev/null +++ b/MouseClicked.pde @@ -0,0 +1,47 @@ +void mouseClicked() { + //println(mouseX); + //println(mouseY); + //println(mouseButton); + //deseleziono ogni cella, trovo se ce n era una ancora cliccata e in tal caso salvo num riga e col + if(mouseButton == 37){ //clic sinistro{ + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + if(celle[r][c].isSelezionata()){ + UCS.setR(r); + UCS.setC(c); + UCS.setSelezionata(true); + } + celle[r][c].setSelezionata(false); + } + } + + //inverto lo stato di selezionata della cella cliccata, se era già selezionata la deseleziono + int rigaSel = floor(mouseX / (lato/cellePerLato)); + int colonnaSel = floor(mouseY / (lato/cellePerLato)); + + if(rigaSel == UCS.getR() && colonnaSel == UCS.getC() && !UCS.isSelezionata()){ + celle[rigaSel][colonnaSel].setSelezionata(true); + UCS.setSelezionata(true); + //println("riseleziono"); + }else if(rigaSel == UCS.getR() && colonnaSel == UCS.getC()){ + celle[rigaSel][colonnaSel].setSelezionata(false); + UCS.setSelezionata(false); + //println("deseleziono"); + }else{ + celle[rigaSel][colonnaSel].setSelezionata(true); + UCS.setSelezionata(true); + //println("seleziono"); + } + + UCS.setR(rigaSel); + UCS.setC(colonnaSel); + } + else if (mouseButton == 39){ + //trovo la cella selezionata + int rigaSel = floor(mouseX / (lato/cellePerLato)); + int colonnaSel = floor(mouseY / (lato/cellePerLato)); + + celle[rigaSel][colonnaSel].toggleFissa(); + } + +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..910e215 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# SudoSolver + +## Description + +A simple sudoku solver in processing 3 + +## Instructions + +- select any cell with left click, move with arrows +- pres Del to delete any cell content +- press R to solve the sudoku +- the algorithm prevent you to insert a number in a wrong cell + +Start with an empty map. + +Write some number into the map. + +![Scheme](images/main.png) + +Press R + +![Scheme](images/resolv.png) + +Good work! + +## Executables + +You can find the executables for windows and linux, arm architecture supported: [releases](https://gitlab.com/stefanorossiti/sudosolver/-/releases). + +### Executables Requirements + +- [Java 7](https://www.oracle.com/java/technologies/javase/javase7-archive-downloads.html) + +## Development Requirement + +[Processing 3.1+](https://processing.org/download/) (best) until 3.5.4 should be fine. + +## Installation and run + +Download processing 3 + +run it in the IDE + +This is a Processing 3 Project. You need the Pframe library to compile and run the code. + +- [PFrame](https://github.com/shigeodayo/PFrame) + +Extract the library in a separate folder into sketchbook libraries folder: + +- Default libraries folder: `\Documents\Processing\libraries`. If it doesn't exist, create it. + +## License + +All my work is released under [DBAD](https://www.dbad-license.org/) license diff --git a/SudoSolver.pde b/SudoSolver.pde new file mode 100644 index 0000000..88eb259 --- /dev/null +++ b/SudoSolver.pde @@ -0,0 +1,97 @@ +import g4p_controls.*; + +int lato = 450; //lato della finestra (quadrato) +int cellePerLato = 9; //quante celle ha un lato +Cella[][] celle = new Cella[cellePerLato][cellePerLato]; +Cella UCS = new Cella(0, 0, lato/cellePerLato);; // per riferimento all Ultima Cella Selezionata + +void setup() { + println(dataPath("")); + + //chiamo il metodo per il cambio di icona e del titolo + frameAndIcon("|SudoSolver| Powered by Stefano BBC Rossi",dataPath("") + "\\me.jpg"); + + size(450, 450); // Size must be the first statement + //width(displayWidth); + //height(displayHeight); + surface.setSize(width + 5, height + 5); + frameRate(30); + //frame.setResizable(true); + + //creo array bidim di celle chiamato tabella + creaCelle(); +} + +void draw() { + background(255); + //lato = width; + //frame.setSize(lato, lato); + stampaTabella(); + stampaCelle(); + stampaWarning(); + stampaNumCelle(); +} + +private void stampaWarning(){ + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + fill(celle[r][c].getWarningColor()); //rosso in strasparenza + rect(celle[r][c].getX() + 7, celle[r][c].getY() + 7, celle[r][c].getL() -9, celle[r][c].getL() - 9, 10); + } + } +} + +private void stampaNumCelle(){ + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + if(celle[r][c].getN() != 0){ + fill(celle[r][c].getColN()); + textSize(celle[r][c].getPntFontN()); + text(str(celle[r][c].getN()), celle[r][c].getX() + 21, celle[r][c].getY() + 37); + } + } + } +} + +private void stampaCelle(){ + noStroke(); + + for(int r = 0; r < cellePerLato; r++){ + for(int c = 0; c < cellePerLato; c++){ + //se la cella è fissa stampo uno sfondo più grigio + if(celle[r][c].isFissa()){ + fill(100, 0, 0, 40); //grigio + rect(celle[r][c].getX() + 3, celle[r][c].getY() + 3, celle[r][c].getL(), celle[r][c].getL()); + } + + if(celle[r][c].isSelezionata()){ + fill(celle[r][c].getColCella()); //Azzutto + rect(celle[r][c].getX() + 13, celle[r][c].getY() + 13, celle[r][c].getL() - 20, celle[r][c].getL() - 20, 8); + }else{ + noFill(); + rect(celle[r][c].getX() + 13, celle[r][c].getY() + 13, celle[r][c].getL() - 20, celle[r][c].getL() - 20, 8); + } + } + } +} + +private void stampaTabella(){ + stroke(0); + + for(int i = 0; i < 10; i++){ + for(int j = 0; j < 10; j++){ + + if (j == 0 || j == 3 || j == 6 || j == 9){ + if (i == 0 || i == 3 || i == 6 || i == 9) strokeWeight(5); + else strokeWeight(1); + } + else strokeWeight(1); + + line(0, (lato/cellePerLato) * i + 2, lato, (lato/cellePerLato) * i + 2); + + if (i == 0 || i == 3 || i == 6 || i == 9) strokeWeight(5); + else strokeWeight(1); + line((lato/cellePerLato) * i + 2, 0, (lato/cellePerLato) * i + 2, lato + 2); + } + } +} diff --git a/data/me.jpg b/data/me.jpg new file mode 100644 index 0000000..5e174f8 Binary files /dev/null and b/data/me.jpg differ diff --git a/images/main.png b/images/main.png new file mode 100644 index 0000000..772ede9 Binary files /dev/null and b/images/main.png differ diff --git a/images/resolv.png b/images/resolv.png new file mode 100644 index 0000000..12be4df Binary files /dev/null and b/images/resolv.png differ