Aşağıdaki program çalışan ve bir şeye benzeyen ilk C programım diyebilirim. Tabii ilk programım olmasından dolayı optimum şekilde çalışmıyor olabilir. Ayrıca programı yazdığım zamanda görsel programlama namına bir şey bilmediğim için program konsoldan çalışıyor.
Sadece kod verip bırakmak istemedim ve az da olsa ne yaptığımı açıklayım dedim. Öncelikle programın üç ana özelliğini belirtmeliyim sanırım;
-Her seferinde rasgele bir labirent oluşturulacak
-Labirent üzerinde kapalı yani ulaşılamayan bir bölge olmayacak
-Son olarak labirent çözülecek.
Ana hatları söyledikten sonra programın çalışmasına gelelim.
Labirenti oluşturacak alan belirlendikten sonra (ör 10×10) bu çerçeve üzerinde bulunan her noktayı bir listeye ekleniyor. Daha sonra bu noktalardan biri rasgele olarak seçiliyor. Bu nokta başlangıç alınarak daha önceden belirlenen adım sayısı kadar rasgele yönlerde ilerlenerek duvar örülüyor. Rasgele yönlerde atılan bu adımlar sonrasında oluşan yeni duvarlar çerçevenin olduğu listeye ekleniyor. Başlangıç olarak seçtiğimz ilk nokta ise listeden siliniyor.Yeni bir adım atılıp duvar örüldüğünde dikkat edilmesi gereken nokta ise kapalı alan oluşturmamaktır.
Labirenti çözmek ise oluşturmaktan çok daha kolay. Klasik self avoding walk algoritmasıyla çözüme gidilmiştir. Labirentin sol en üst köşesi başlangıç, sağ en alt köşesi ise bitiş noktası olarak belirlenmiş ve çözüm ona göre çalışmaktadır. Tabii değiştirmek sizin elinizde.
/////////////////////////////////////////////////// /* HEADER DOSYALARI */ /////////////////////////////////////////////////// #include "conio.h" #include "stdlib.h" #include "stdio.h" #include "iostream.h" #define STEP 5 #define YOL 0 #define YOL2 1 #define GEREKSIZ -6 #define DUVAR -2 #define pasifDUVAR -5 #define DUGUM -1 #define eskiDUGUM -3 #define pasifDUGUM -4 #include <time.h> /////////////////////////////////////////////////// /* LISTE YAPISI */ /////////////////////////////////////////////////// struct Item { struct Item *next; int val1,val2; // Dizi iki boyutlu oldugu icin 2 elemanli liste olusturdum. }; struct List { struct Item *list; }; /////////////////////////////////////////////////// /* LISTE FONKSIYONLARININ PROTOTIPLERI */ /////////////////////////////////////////////////// struct List *liste_yarat(struct List *pl); //Liste Olusturuyor void listeye_ekle(struct List *pl,int,int); //Listeye eleman ekliyor void listeden_sil(struct List *pl,int,int); //Listeden eleman siliyor void liste_gez(struct List *pl,int ,int& , int&); //Listeden n. siradaki elemani aliyor void liste_goster(struct List *pl); //Lisde degerlerini yazdiriyor int uzunluk(struct List *pl); //Liste uzunlugunu veriyor bool arama(int,int); //listede eleman ariyor /////////////////////////////////////////////////// /* DIGER FONKSIYON PROTOTIPLERI */ /////////////////////////////////////////////////// void degeryaz(int **); //ekrana labirenti ciziyor void diziyap(); //dinamik dizi olusturuyor void duzenle(); //bos labirent olusturuyor void kontrol(int,int); //kapali alan kontrolu yapiyor void ilerle(int ,int); //duvar olusturuyor int rasgele(int); //random sayi uretiyor void devam(int, int); //adim sayisini tutuyor void ayikla(); //gereksiz dugumleri ayikliyor void labirent(); //Genel fonksiyon void yonbul(int , int ); //cikis yolunu buluyor int adim_sayisi(); //cikisa kac adim var /////////////////////////////////////////////////// /* KULLANACAGIM DEGISKENLER, GLOBAL */ /////////////////////////////////////////////////// int **dizi,**dizii,x,y,val1,val2,yon,adim=0,varmi=0; /*///////////////////////////////////////////////////// //dizi=>Labirenti tutuyor // //x,y=> labirent boyutlari // //val1,val2=>Liste degerlerini almak icin kullandim // //yon=>gidilecek yonu tutuyor // //adim=>kac adim gidildigini tutuyor // //varmi=>labirent olup olmadigini tutuyor // *////////////////////////////////////////////////////// struct List *l1; //###############################################// /* MAIN FONKSIYONU */ //###############################################// main(){ l1=liste_yarat(l1); // Listemi yaratyiyorum char ch='1'; // Kullanici arayuzu while(ch!='2') { cout<<endl<< "0-Ekrani temizle"<<endl<< "1-Yeni labirent Olustur"<<endl<< "2-Programdan Cik"<<endl; if(varmi==1){ cout<<"3-Labirenti Coz"<<endl; } ch=getch(); if(ch=='1'){ clrscr();labirent();yonbul(1,1);varmi=1; } else if (ch=='2'){ clrscr(); cout<<endl<< "Veri Yaplilari Labirent Olusturma Odevi\nYazan:Ahmet KAKICI - 150165\nCikmak icin herhangi bir tusa basiniz."; getch(); } else if(ch=='3'){ clrscr(); degeryaz(dizi); cout<<endl; degeryaz(dizii); cout<<"Labirentten "<<adim_sayisi()<<" adimda cikildi."<<endl; varmi=0; } else if(ch=='0'){ clrscr(); } } } ////////////////////////////////////////////////// /* SELF AVOIDING WALK ve LABIRENTTEN CIKIS */ ////////////////////////////////////////////////// void yonbul(int a, int b){ int xMax=x-1,yMax=y-1; if(a==x-2 && b==y-2){ for(int i=0;i<x;i++) for(int j=0;j<y;j++) dizii[i][j]=dizi[i][j]; return; } if(b+2<yMax && dizi[a][b+1]==pasifDUVAR && dizi[a][b+2]==YOL){ dizi[a][b+2]=YOL2; yonbul(a,b+2); dizi[a][b+2]=YOL; } if(a-2>0 && dizi[a-1][b]==pasifDUVAR && dizi[a-2][b]==YOL){ dizi[a-2][b]=YOL2; yonbul(a-2,b); dizi[a-2][b]=YOL; } if(b-2>1 && dizi[a][b-1]==pasifDUVAR && dizi[a][b-2]==YOL){ dizi[a][b-2]=YOL2; yonbul(a,b-2); dizi[a][b-2]=YOL; } if(a+2<xMax && dizi[a+1][b]==pasifDUVAR && dizi[a+2][b]==YOL){ dizi[a+2][b]=YOL2; yonbul(a+2,b); dizi[a+2][b]=YOL; } } /////////////////////////////////////////////////// /* LABIRENT OLUSTURMA FONKSIYONU */ /////////////////////////////////////////////////// void labirent(){ srand(time(NULL)); cout<<endl<<"Labirent boyutlarini gir"<<endl<<"x="; cin>>x; cout<<endl<<"y="; cin>>y; diziyap(); duzenle(); while((uzunluk(l1))>0){ liste_gez(l1,rasgele(uzunluk(l1)),val1,val2); ilerle(val1,val2); ayikla(); } degeryaz(dizi); } /////////////////////////////////////////////////// /* DIZI OLUSTURMA FONKSIYONU */ /////////////////////////////////////////////////// void diziyap() { x=x*2+1; y=y*2+1; dizi=new int *[x]; dizii=new int *[x]; for(int i=0;i<x;i++){ dizi[i]=new int[y]; dizii[i]=new int[y]; } } /////////////////////////////////////////////////// /* RASGELE SAYI URETEN FONKSIYON */ /////////////////////////////////////////////////// int rasgele(int n) { return rand()%n; } /////////////////////////////////////////////////// /* ADIM SAYISINI TUTAN FONKSIYON */ /////////////////////////////////////////////////// int adim_sayisi() { int adimSayisi=0; for(int i=0;i<x;i++){ for(int j=0;j<y;j++){ if(dizii[i][j]==YOL2){ adimSayisi++; } } } return adimSayisi; } /////////////////////////////////////////////////// /* DIZI DEGERLERINI YAZAN FONKSIYON */ /////////////////////////////////////////////////// void degeryaz(int **dizim){ for(int i=0;i<x;i++){ for(int j=0;j<y;j++){ if(dizim[i][j]==DUVAR) cout<<'\xDB'<<'\xDB'; else if(dizim[i][j]==YOL) cout<<" "<<" "; else if(dizim[i][j]==YOL2) cout<<"_"<<"_"; else if (dizim[i][j]==pasifDUGUM) cout<<'\xDB'<<'\xDB'; else if (dizim[i][j]==eskiDUGUM ||dizim[i][j]==GEREKSIZ || dizim[i][j]==-2 ) cout<<'\xDB'<<'\xDB'; else cout<<' '<<" "; } cout<<endl; } } /////////////////////////////////////////////////// /* LABIRENTIN BOS HALINI OLUSTURUYOR */ /* ILK DUGUM NOKTALARINI LISTEYE ATIYOR */ /////////////////////////////////////////////////// void duzenle(){ int xx,yy; xx=x-1; yy=y-1; for(int i=0;i<x;i++){ for(int j=0;j<y;j++){ if( i==0 || j==0 || i==xx || j==yy) dizi[i][j]=GEREKSIZ; //KENARLARDAKI GEREKSIZ YERLER if( ( (j==0 ||j==yy) && j%2==0)|| ( (i==0||i==xx) && i%2==0) ){ dizi[i][j]=DUGUM; //LABIRENTIN KENARLARINI listeye_ekle(l1,i,j); //LISTEYE EKLE } else if (i%2!=0 && j%2!=0){ //GIDILECEK YOLLAR dizi[i][j]=YOL; } else if( ((i%2!=0 && j!=0 && j!=yy) && j%2==0)||(i%2==0 && (i!=0 && i!=xx && j%2!=0)) ){ dizi[i][j]=pasifDUVAR; //PASIF DUVARLAR } else if(i%2==0 && j%2==0){ dizi[i][j]=pasifDUGUM; //PASIF DUGUMLER } //else dizi[i][j]=8; } } //LABIRENTIN KOSELERINDEKI DUGUMLERI LISTEDEN SIL listeden_sil(l1,0,0);dizi[0][0]=eskiDUGUM; listeden_sil(l1,xx,0);dizi[xx][0]=eskiDUGUM; listeden_sil(l1,0,yy);dizi[0][yy]=eskiDUGUM; listeden_sil(l1,xx,yy);dizi[xx][yy]=eskiDUGUM; } /////////////////////////////////////////////////// /* LABIRENTTE DUVAR OREREK ILERLEME FONKSIYONU */ /////////////////////////////////////////////////// void ilerle(int Xnokta,int Ynokta){ yon=rasgele(4); int a=Xnokta; int b=Ynokta; if(Xnokta==0)yon=3; if(Ynokta==0)yon=1; if(Xnokta==x-1)yon=0; if(Ynokta==y-1)yon=2; //liste_goster(l1); // Kuzey => 0 , dogu =>1 , bati=>2 , guney=> 3, if(yon==0){ //KUZEY if(a-2>0){ if(dizi[a-2][b]==pasifDUGUM){ dizi[a-1][b]=DUVAR; kontrol(a-2,b); kontrol(a,b); devam(a-2,b); } } } if(yon==1){ // DOGU if(b+2<y){ if(dizi[a][b+2]==pasifDUGUM){ dizi[a][b+1]=DUVAR; kontrol(a,b+2); kontrol(a,b); devam(a,b+2); } } } if(yon==2){ // BATI if(b-2<0){ if(dizi[a][b-2]==pasifDUGUM){ dizi[a][b-1]=DUVAR; kontrol(a,b-2); kontrol(a,b); devam(a,b-2); } } } if(yon==3){ // GUNEY if(a+2<x){ if(dizi[a+2][b]==pasifDUGUM){ dizi[a+1][b]=DUVAR; kontrol(a+2,b); kontrol(a,b); devam(a+2,b); } } } } //gezi func. sonu void devam(int Xnokta,int Ynokta) { if(adim<STEP){ adim++; ilerle(Xnokta,Ynokta); } else{ adim = 0; } } /////////////////////////////////////////////////// /* AYIKLA FONKSIYONU */ ////////////////////////////////////////////////// void ayikla(){ for (int i=0;i<uzunluk(l1);i++){ liste_gez(l1,i,val1,val2); kontrol(val1,val2); } } //////////////////////////////////////////////////// /* KONTROL FONKSIYONU */ ////////////////////////////////////////////////// void kontrol(int Xnokta,int Ynokta) { int cevre = 0; if(Ynokta+2<y){ if(dizi[Xnokta][Ynokta+2]==pasifDUGUM ){ cevre++; } } if(Ynokta-2>0){ if(dizi[Xnokta][Ynokta-2]==pasifDUGUM ){ cevre++; } } if(Xnokta+2<x){ if(dizi[Xnokta+2][Ynokta]==pasifDUGUM ){ cevre++; } } if(Xnokta-2>0){ if( dizi[Xnokta-2][Ynokta]==pasifDUGUM){ cevre++; } } if (cevre==0){ dizi[Xnokta][Ynokta]=eskiDUGUM; listeden_sil(l1,Xnokta,Ynokta); } else if( cevre!=0 && (dizi[Xnokta][Ynokta]!=DUGUM)){ if(!(arama(Xnokta,Ynokta))){ listeye_ekle(l1,Xnokta,Ynokta); } dizi[Xnokta][Ynokta]=DUGUM; } } /////////////////////////////////////////////////// /* LISTE FONKSIYONLARI */ /////////////////////////////////////////////////// /////////////////////////////////////////////////// /* LISTE YARATMA FONKSIYONU */ ////////////////////////////////////////////////// struct List *liste_yarat(struct List *pl){ pl=(struct List *)malloc(sizeof(struct List)); pl->list=0; return pl; } /////////////////////////////////////////////////// /* LISTE UZUNLUGUNU BULAN FONKSIYON */ /////////////////////////////////////////////////// int uzunluk(struct List *pl){ struct Item *tmp=pl->list; int uzun=0; while(tmp){ uzun++; tmp=tmp->next; } return(uzun); } /////////////////////////////////////////////////// /* LISTEDEN ELEMAN SILEN FONKSIYON */ /////////////////////////////////////////////////// void listeden_sil(struct List *pl,int val1,int val2){ struct Item *prv, *pt = pl->list; if ( (pt) && (pt->val1==val1)&&(pt->val2==val2) ){ pl->list= pt->next; free(pt); } else if (pt){ for ( prv=pt, pt= pt->next; ((pt) && ((pt->val1 != val1) || (pt->val2 != val2))); prv=prv->next, pt=pt->next); if ( (pt)&& (pt->val1==val1) && (pt->val2==val2) ){ prv->next=pt->next; free(pt); } } } /////////////////////////////////////////////////// /* LISTE ELEMANLARINI YAZDIRAN FONKSIYON */ /////////////////////////////////////////////////// void liste_goster(struct List *pl){ struct Item *tmp=pl->list; while (tmp){ printf("%d ", tmp->val1) ; printf("%d \n", tmp->val2) ; tmp=tmp->next; } } /////////////////////////////////////////////////// /* LISTE BASINA ELEMAN EKLEYEN FONKSIYON */ /////////////////////////////////////////////////// void listeye_ekle(struct List *pl,int val1, int val2) { struct Item *pt=(struct Item *)malloc(sizeof(struct Item)); pt->val1=val1; pt->val2=val2; pt->next=pl->list; pl->list=pt; } /////////////////////////////////////////////////// /* LISTEDEN n. ELEMANI ALMA FONKSIYONU */ /////////////////////////////////////////////////// void liste_gez(struct List *pl,int n,int &val1, int &val2){ struct Item *tmp=pl->list; while(n-->0){ tmp=tmp->next; } val1=tmp->val1; val2=tmp->val2; } bool arama(int xVal,int yVal){ struct Item *tmp=l1->list; int uzun=uzunluk(l1); while(uzun-->0){ if(tmp->val1==xVal && tmp->val2==yVal){ return true; } tmp=tmp->next; } return false; }