Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include<ctime>
- #include<cstdlib>
- #include<fstream>
- using namespace std;
- #define RIGHE 20
- #define COLONNE 20
- #define n_input 5
- #define n_ps 20
- #define n_ss 3
- struct blocco{
- int x;
- int y;
- struct blocco * prossimo;
- };
- struct coordinata{
- int x;
- int y;
- };
- struct rete{
- int griglia[RIGHE][COLONNE];
- float sinapsi_ps [n_input][n_ps];
- float sinapsi_ss [n_ps][n_ss];
- float neuroni_input[n_input];
- float neuroni_ps [n_ps];
- float neuroni_ss [n_ss];
- struct blocco* snake;
- struct coordinata velocita;
- struct coordinata mela;
- bool game_over = false;
- int punteggio=0;
- int mosse=0;
- };
- struct rete reti[100];
- float RandomFloat(float a, float b) {
- float random = ((float) rand()) / (float) RAND_MAX;
- float diff = b - a;
- float r = random * diff;
- return a + r;
- }
- void analizza_input(struct rete& reti){
- int x=-1;
- int y;
- //trova la testa
- for(int i=0;i<20 && x==-1;i++)
- for(int j=0;j<20 && x==-1;j++)
- if(reti.griglia[i][j]==9){
- x=i;
- y=j;
- }
- //inizializza i neuroni posizione della mela:
- //assegna al neurone 0 cosa si trova davanti al serpente, all 1 a sinstra al 2 a destra. Il neurone 3 e 1 se la mela si trova avanti -1 se dietro, il neurone 4 e 1 se la mela e a sinistra -1
- if(reti.velocita.x==-1){
- reti.neuroni_input[0] = reti.griglia[x-1][y];
- reti.neuroni_input[1] = reti.griglia[x][y-1];
- reti.neuroni_input[2] = reti.griglia[x][y+1];
- if(reti.mela.x < x)
- reti.neuroni_input[3] = 1;
- else if(reti.mela.x>x)
- reti.neuroni_input[3] = -1;
- if(reti.mela.y > y)
- reti.neuroni_input[4] = -1;
- if(reti.mela.y < y){
- reti.neuroni_input[4] = 1;
- }
- }
- else if(reti.velocita.x==1){
- reti.neuroni_input[0] = reti.griglia[x+1][y];
- reti.neuroni_input[1] = reti.griglia[x][y+1];
- reti.neuroni_input[2] = reti.griglia[x][y-1];
- if(reti.mela.x > x)
- reti.neuroni_input[3] = 1;
- else if(reti.mela.x < x)
- reti.neuroni_input[3] = -1;
- if(reti.mela.y < y)
- reti.neuroni_input[4] = -1;
- if(reti.mela.y > y)
- reti.neuroni_input[4] = 1;
- }
- else if(reti.velocita.y==-1){
- reti.neuroni_input[0] = reti.griglia[x][y-1];
- reti.neuroni_input[1] = reti.griglia[x+1][y];
- reti.neuroni_input[2] = reti.griglia[x-1][y];
- if(reti.mela.y < y)
- reti.neuroni_input[3] = 1;
- else if(reti.mela.y > y)
- reti.neuroni_input[3] = -1;
- if(reti.mela.x < x)
- reti.neuroni_input[4] = -1;
- if(reti.mela.x > x)
- reti.neuroni_input[4] = 1;
- }
- else if(reti.velocita.y==+1){
- reti.neuroni_input[0] = reti.griglia[x][y+1];
- reti.neuroni_input[1] = reti.griglia[x-1][y];
- reti.neuroni_input[2] = reti.griglia[x+1][y];
- if(reti.mela.y > y)
- reti.neuroni_input[3] = 1;
- else if(reti.mela.y < y)
- reti.neuroni_input[3] = -1;
- if(reti.mela.x > x)
- reti.neuroni_input[4] = -1;
- if(reti.mela.x < x)
- reti.neuroni_input[4] = 1;
- }
- return;
- }
- void iniz_reti_rand(struct rete reti[]){
- for(int i=0;i<100;i++){
- for(int t=0;t<5;t++)
- for(int k=0;k<20;k++)
- reti[i].sinapsi_ps[t][k] = RandomFloat(-1,1);
- for(int r=0;r<20;r++)
- for(int j=0;j<3;j++)
- reti[i].sinapsi_ss[r][j] = RandomFloat(-1,1);
- }
- return;
- }
- void iniz_neuroni(struct rete reti){
- for(int r=0;r < n_input;r++)
- reti.neuroni_input[r]=0;
- for(int r=0;r < n_ps;r++)
- reti.neuroni_ps[r]=0;
- for(int r=0;r < n_ss;r++)
- reti.neuroni_ss[r]=0;
- return;
- }
- float abs_v(float v){
- if(v >=0)
- return v;
- else return (-v);
- }
- int find_max (float v[]){
- if(v[0]>=v[1] && v[0]>=v[2])
- return 0;
- else if(v[1]>=v[0] && v[1]>=v[2])
- return 1;
- else if(v[2]>=v[0] && v[2]>=v[1])
- return 2;
- }
- int mossa (struct rete reti){
- for(int k=0;k<n_ps;k++)
- for(int i=0;i<n_input;i++)
- reti.neuroni_ps[k]+=reti.neuroni_input[i]*reti.sinapsi_ps[i][k];
- for(int i=0;i<n_ps;i++)
- reti.neuroni_ps[i] = reti.neuroni_ps[i]/(abs_v(reti.neuroni_ps[i])+1);
- for(int i=0;i<n_ss;i++)
- for(int j=0;j<n_ps;j++)
- reti.neuroni_ss[i]+= reti.neuroni_ps[j]*reti.sinapsi_ss[j][i];
- for(int i=0;i<n_ss;i++)
- reti.neuroni_ss[i] = reti.neuroni_ss[i]/(abs_v(reti.neuroni_ss[i])+1);
- int max = find_max(reti.neuroni_ss);
- return max;
- }
- void make_griglia(int griglia[][COLONNE],struct blocco* snake,int mela_x,int mela_y){
- griglia[mela_x][mela_y]=0;
- struct blocco* p = snake;
- while(p != NULL){
- if(p->prossimo != NULL)
- griglia[p->x][p->y]=4;
- else
- griglia[p->x][p->y]=9;
- p = p-> prossimo;
- }
- return;
- }
- bool death(struct blocco* snake){
- struct blocco* p = snake;
- struct blocco* q = snake;
- while(p != NULL){
- q=p;
- p = p-> prossimo;
- }
- //q punta alla testa
- if(q->x == 0 || q->y == 0 || q->x == COLONNE - 1 || q->y == RIGHE - 1)
- return true;
- p=snake;
- while(p != q){
- if(p->x == q->x && p->y == q->y)
- return true;
- p=p->prossimo;
- }
- return false;
- }
- void inizializza(int griglia[RIGHE][COLONNE]){
- for(int i=0;i<RIGHE;i++)
- for(int k=0;k<COLONNE;k++)
- if(k==0 || i == 0 || k==COLONNE-1 || i==COLONNE-1)
- griglia[i][k]=2;
- else
- griglia[i][k]=1;
- return;
- }
- void print(int griglia[RIGHE][COLONNE]){
- for(int i=0;i<RIGHE;i++){
- for(int k=0;k<COLONNE;k++)
- if(griglia[i][k]==1)
- cout <<" ";
- else if(griglia[i][k]==2)
- cout <<"x";
- else if(griglia[i][k]==0)
- cout << "a";
- else if(griglia[i][k]==4)
- cout << "#";
- else if(griglia[i][k]==9)
- cout << "O";
- cout << endl;
- }
- cout << endl;
- return;
- }
- void reti_migliori(int reti_vincenti[], struct rete reti[]){
- for (int k=0;k<25;k++){
- int m_score=0;
- int i;
- for(i=0;i<100;i++)
- if(reti[i].punteggio>=m_score){
- m_score = reti[i].punteggio;
- reti_vincenti[k] = i;
- }
- reti[reti_vincenti[k]].punteggio = -1000;
- }
- return;
- }
- void iniz_reti_everything(struct rete reti[]){
- for(int i=0;i<100;i++){
- reti[i].snake = new struct blocco;
- reti[i].snake->x = RIGHE/2;
- reti[i].snake->y = COLONNE/2;
- reti[i].snake->prossimo = NULL;
- struct blocco* p = new struct blocco;
- p->x = RIGHE/2-1;
- p->y = COLONNE/2;
- p->prossimo = reti[i].snake;
- reti[i].snake = p;
- p = new struct blocco;
- p->x = RIGHE/2-2;
- p->y = COLONNE/2;
- p->prossimo = reti[i].snake;
- reti[i].snake = p;
- reti[i].mela.x = rand() % (RIGHE-2) +1;
- reti[i].mela.y = rand() % (COLONNE-2) +1;
- reti[i].velocita.x=1;
- reti[i].velocita.y=0;
- reti[i].mosse = 0;
- reti[i].punteggio = 0;
- reti[i].game_over = false;
- inizializza(reti[i].griglia);
- }
- return;
- }
- void create_reti_from_seed(struct rete reti[],float seed_sinapsi_ps [25][5][20],float seed_sinapsi_ss [25][20][3]){
- for(int i=0;i<25;i++){
- int r = i;
- for(int x=0;x<n_input;x++)
- for(int y=0;y<n_ps;y++)
- reti[i].sinapsi_ps[x][y] = (seed_sinapsi_ps [r][x][y]);
- for(int x=0;x<n_ps;x++)
- for(int y=0;y<n_ss;y++)
- reti[i].sinapsi_ss[x][y] = seed_sinapsi_ss [r][x][y];
- }
- for(int i=25; i<75;i++){
- int r1 = rand () % 25;
- int r2 = rand () % 25;
- for(int x=0;x<n_input;x++)
- for(int y=0;y<n_ps;y++){
- if(rand() % 2 == 0)
- reti[i].sinapsi_ps[x][y] = (seed_sinapsi_ps [r1][x][y]);
- else
- reti[i].sinapsi_ps[x][y] = (seed_sinapsi_ps [r2][x][y]);
- }
- for(int x=0;x<n_ps;x++)
- for(int y=0;y<n_ss;y++){
- if(rand()%2 == 0)
- reti[i].sinapsi_ss[x][y] = seed_sinapsi_ss [r1][x][y];
- else
- reti[i].sinapsi_ss[x][y] = seed_sinapsi_ss [r2][x][y];
- }
- }
- for(int i=75; i<100;i++){
- int r1 = rand () % 25;
- int r2 = rand () % 25;
- for(int x=0;x<n_input;x++)
- for(int y=0;y<n_ps;y++){
- if(rand() % 2 == 0)
- reti[i].sinapsi_ps[x][y] = (seed_sinapsi_ps [r1][x][y])*RandomFloat(0.5,1.5);
- else
- reti[i].sinapsi_ps[x][y] = (seed_sinapsi_ps [r2][x][y])*RandomFloat(0.5,1.5);
- }
- for(int x=0;x<n_ps;x++)
- for(int y=0;y<n_ss;y++){
- if(rand()%2 == 0)
- reti[i].sinapsi_ss[x][y] = seed_sinapsi_ss [r1][x][y]*RandomFloat(0.5,1.5);
- else
- reti[i].sinapsi_ss[x][y] = seed_sinapsi_ss [r2][x][y]*RandomFloat(0.5,1.5);
- }
- }
- return;
- }
- void create_seed(float seed_sinapsi_ps [25][5][20],float seed_sinapsi_ss [25][20][3],struct rete reti[],int reti_vincenti[]){
- for(int i=0;i<25;i++)
- for(int k=0;k<5;k++)
- for(int j=0;j<20;j++)
- seed_sinapsi_ps[i][k][j] = reti[reti_vincenti[i]].sinapsi_ps[k][j];
- for(int i=0;i<25;i++)
- for(int k=0;k<20;k++)
- for(int j=0;j<3;j++)
- seed_sinapsi_ss[i][k][j] = reti[reti_vincenti[i]].sinapsi_ss[k][j];
- return;
- }
- void print_neural_scheme(struct rete reti){
- for(int i=0;i<n_ps;i++)
- for (int k=0;k<n_input;k++)
- cout << reti.sinapsi_ps[k][i] << " ";
- cout << endl;
- system("pause");
- return;
- }
- void spawn_mela(struct rete reti){
- bool ok;
- struct coordinata temp_mela;
- do{
- ok=true;
- temp_mela.x = rand() % (RIGHE-2) +1;
- temp_mela.y = rand() % (COLONNE-2) +1;
- struct blocco* p = reti.snake;
- while(p!=NULL){
- if(p->x == temp_mela.x && p->y == temp_mela.y)
- ok = false;
- p = p->prossimo;
- }
- } while(ok==false);
- return;
- }
- void memory_clear(struct blocco* p){
- struct blocco* l = p;
- while(l!=NULL){
- struct blocco* k = l;
- l = l->prossimo;
- delete k;
- }
- }
- int main(){
- srand(time(NULL));
- iniz_reti_rand(reti);
- iniz_reti_everything(reti);
- int generazione=0;
- int reti_vincenti[25];
- float seed_sinapsi_ss [25][20][3];
- float seed_sinapsi_ps [25][5][20];
- int interessato;
- cout << "Qual'e' il punteggio a cui sei interessato? le reti con un fit score fino a 20 meno sarannosalvate su un txt!" << endl;
- cin >> interessato;
- int punti_generazione = 0;
- int punti_max = 0;
- while(punti_max < interessato){
- punti_generazione = 0;
- punti_max = 0;
- for(int i=0;i<100;i++){
- //if(generazione > 1)
- //print_neural_scheme(reti[i]);
- while(reti[i].game_over == false){
- inizializza(reti[i].griglia);
- make_griglia(reti[i].griglia,reti[i].snake,reti[i].mela.x,reti[i].mela.y);
- iniz_neuroni(reti[i]);
- analizza_input(reti[i]);
- int move = mossa(reti[i]);
- if(move == 0){
- }
- else if(move == 1){
- if(reti[i].velocita.x == -1){
- reti[i].velocita.x = 0;
- reti[i].velocita.y = -1;
- }
- else if(reti[i].velocita.x == 1){
- reti[i].velocita.x = 0;
- reti[i].velocita.y = 1;
- }
- else if(reti[i].velocita.y == -1){
- reti[i].velocita.x = 1;
- reti[i].velocita.y = 0;
- }
- else if(reti[i].velocita.y == 1){
- reti[i].velocita.x = -1;
- reti[i].velocita.y = 0;
- }
- }
- else if(move == 2){
- if(reti[i].velocita.x == -1){
- reti[i].velocita.x = 0;
- reti[i].velocita.y = 1;
- }
- else if(reti[i].velocita.x == 1){
- reti[i].velocita.x = 0;
- reti[i].velocita.y = -1;
- }
- else if(reti[i].velocita.y == -1){
- reti[i].velocita.x = -1;
- reti[i].velocita.y = 0;
- }
- else if(reti[i].velocita.y == 1){
- reti[i].velocita.x = 1;
- reti[i].velocita.y = 0;
- }
- }
- struct blocco* old_head = reti[i].snake;
- while(old_head -> prossimo != NULL)
- old_head = old_head -> prossimo;
- struct blocco* n_head = new struct blocco;
- n_head -> x = old_head -> x + reti[i].velocita.x;
- n_head -> y = old_head -> y + reti[i].velocita.y;
- n_head -> prossimo = NULL;
- old_head -> prossimo = n_head;
- if(n_head -> x == reti[i].mela.x && n_head -> y == reti[i].mela.y){
- reti[i].mela.x = rand() % (RIGHE-2) +1;
- reti[i].mela.y = rand() % (COLONNE-2) +1;
- reti[i].punteggio += 1;
- //da aggiungere spawn mela
- }
- else{
- struct blocco* temp = reti[i].snake;
- reti[i].snake = reti[i].snake -> prossimo;
- delete temp;
- }
- reti[i].game_over = death(reti[i].snake);
- reti[i].mosse++;
- if(reti[i].mosse > 30 + reti[i].punteggio*50)
- reti[i].game_over = true;
- }
- if(reti[i].punteggio >= interessato-20){
- ofstream file;
- file.open("reti.txt", ios::app);
- file << "Rete " << i << " Punti " << reti[i].punteggio << endl;
- for(int t=0;t<5;t++)
- for(int k=0;k<20;k++)
- file << reti[i].sinapsi_ps[t][k] << " ";
- for(int r=0;r<20;r++)
- for(int j=0;j<3;j++)
- file << reti[i].sinapsi_ss[r][j] << " ";
- file << endl;
- file.close();
- }
- memory_clear(reti[i].snake);
- //reti[i].punteggio += reti[i].mosse;
- punti_generazione += reti[i].punteggio;
- if(reti[i].punteggio > punti_max)
- punti_max = reti[i].punteggio;
- }
- cout << "La generazione " << (int)generazione << " ha realizzato una media di " <<float(punti_generazione)/100 << " punti e il massimo e' stato " << punti_max << endl;
- reti_migliori(reti_vincenti,reti);
- create_seed(seed_sinapsi_ps,seed_sinapsi_ss,reti,reti_vincenti);
- create_reti_from_seed(reti,seed_sinapsi_ps,seed_sinapsi_ss);
- iniz_reti_everything(reti);
- generazione++;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement