C De Çift Sayı Bulma Oyunu

Kod:
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#define SIYAHKAREBAS printf("%c",219)
#define KARAKTERGOSTER printf("%c",ascii)
#define DIKEYKAYDIRMA 8
#define URETILECEK_ASCII_SAYISI 50
#define PUAN 400

// Cevap anahtarı oluşturmasını istemiyorsanız 1 i 0 ile değiştirin
#define CEVAPANAHTARIYAP 0


int YATAYKAYDIRMA, // Tablo büyüklüğüne göre imlecin kayma miktarını tutan global değişken
baslangic_sure=0; // Gecen süreyi tutan global değişken

void bilgi()
{

// Program bilgisi
system("title PAIRS II - Ibrahim GAZALOGLU//www.ckodu.com//");
system("color 4f");
printf("\t######################################## #####################\n");
printf("\t## ##\n");
printf("\t## PAIRS II ##\n");
printf("\t## ##\n");
printf("\t## Find pair of each square ##\n");
printf("\t## ##\n");
printf("\t## Press 1 to start ##\n");
printf("\t## Press 0 to exit ##\n");
printf("\t## ##\n");
printf("\t######################################## #####################\n");

}

// Seviyeler
void seviye_bilgisi()
{
printf("\n\n");
printf(" 1 = Level l \n");
printf(" 2 = Level 2 \n");
printf(" 3 = Level 3 \n");
printf(" 4 = Level 4 \n");
printf(" 5 = Level 5 \n");
printf(" 6 = Level 6 \n");
printf(" 7 = Level 7 \n");
printf("\n PLEASE SELECT LEVEL BY USING LIST ABOVE (1..7)\n");

}

// Oyunun nasıl oynanacağı hakkında bilgi
void yardim()
{
printf("\n\n INSTRUCTIONS \n");
printf("--------------------------------------------------------\n");
printf(" * Select difficulty of the game with level list\n\n");
printf(" * Type 1 for the easiest table type 7 for the hardest table\n\n");
printf(" * Program will ask you two index number to pair\n\n");
printf(" * ATTENTION -> You must type two index number of squares with one of this \n seperators : (X) or (x) or (,) or (BLANK) Ex : 5X7\n\n ");
system("pause");
system("CLS");
bilgi();
}

// Yüksek puan
void yuksek_skor(int puan,int seviye)
{
FILE *skor;
skor=fopen("skorlar.p","a+");

char isim[30],
onbellek[5],
metin[30];

int dosyadaki_skor =0,
dosyadaki_seviye =0,
en_yuksek =0,
en_yuksek_seviye =0,
i;

fscanf(skor,"%d%d%s",&dosyadaki_skor,&dosyadaki_se viye,isim);
while(!feof(skor))
{
fscanf(skor,"%d%d%s",&dosyadaki_skor,&en_yuksek_se viye,isim);
if(dosyadaki_skor>en_yuksek && seviye==dosyadaki_seviye)
{
en_yuksek=dosyadaki_skor;
en_yuksek_seviye=dosyadaki_seviye;
}
}

if(puan>en_yuksek)
{
strcpy(metin,"NEW HIGH SCORE FOR LEVEL ");
itoa(seviye,onbellek,5);
strcat(metin,onbellek);
MessageBox(NULL,metin,"PAIRS II",MB_OK | MB_ICONASTERISK);
}

for(i=0;i<9;i++)
printf("\n");
for(i=0;i<3;i++)
printf("\t");

printf(" TYPE YOUR NAME : ");
fflush(stdin);
gets(isim);
fprintf(skor,"%d %d %s\n",puan,seviye,isim);
fclose(skor);
}

// İmleci istenilen satıra konumladır
void git(int x,int y) {

COORD koordinat;
koordinat.X=x;
koordinat.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_H ANDLE),koordinat);
}

// Siyah kareleri çiz
void kare_ciz(int satir,int sutun) {

printf("\n\t\t\t\t PAIRS II\n");
printf("\n\t SEPERATE SQUARE NUMBERS BY X or , or [BLANK] (Ex : 1x2)");

YATAYKAYDIRMA=39-2*satir; // Tablo büyüklüğüne göre imlecin ne kadar kaydırılacağını hesapla

int x,y,
kare_numarasi=1; // Karelerin index numarasının tutulacağı değişken

git(YATAYKAYDIRMA-1,DIKEYKAYDIRMA-1);

for(y=0;y<sutun*5-3;y++)
{
for(x=0;x<satir*5-3;x++)
{
if(x%5==2)
x+=3;
if(y%5==2)
y+=3;

if(x%5==0 && y%5==0)
{
git(x+YATAYKAYDIRMA,y+DIKEYKAYDIRMA-1);

// Kare numarası 10 dan küçükse 0 la beraber yazdır
if(kare_numarasi<10)
printf("0");

// Kare numarasını yaz
printf("%d",kare_numarasi);
++kare_numarasi;
}

git(x+YATAYKAYDIRMA,y+DIKEYKAYDIRMA);
//Siyah kare oluştur
SIYAHKAREBAS;
}
}
git(1,y+DIKEYKAYDIRMA+1);
}

/*
Karebilgilerini oluştur ve sakla
Kare bilgilerinde ASCII kodu ve eşlenmiş kareler tutuluyor
ÖRNEĞİN SEVİYE 7 İÇİN kare_bilgileri[16][3] ŞEKLİNDE BİR
DİZİ TANIMLANIYOR VE ÜÇ ELEMANLI ALT DİZİDE KARENİN BİLGİLERİ
SAKLANIYOR.ÖRNEĞİN kare_bilgileri[2][0] elemanı karelerin ascii
kodunu tutuyor.kare_bilgileri[2][1] elemanında 15 kare_bilgileri[2][2] elemanı da 17
karesini tutuyor
*/
int kare_atamasi_yap(int kare_bilgileri[][3],int kare_sayisi)
{
int dolu_kareler[kare_sayisi], // Aynı atamayı yeniden yapmamak için karaliste
uretilen_asciiler[kare_sayisi], // Üretilen asciiyi tekrar üretmemek için karaliste
index_1, // 1. karenin indexi
index_2, // 2. karenin indexi
i=0,j=0, // Döngü değişkenleri
k=0, // Aynı atama kara listesi index numarasi
karakter_ascii=0; // Üretilen ascii

kare_sayisi/=2; // Çiftleme yapıldığı için karenin yarısına kadar ilerlemek yeterli

// ASCII listesini boşalt
for(i=0;i<kare_sayisi*2;i++)
{
uretilen_asciiler[i]=0;
}

srand(time(NULL));
for(i=0;i<kare_sayisi;i++)
{
karakter_ascii=rand()%URETILECEK_ASCII_SAYISI+123; // Rasgele 123 ve 155 arasında ascii kodu üret

for(j=0;j<i+1;j++)
{
if(uretilen_asciiler[j]==karakter_ascii)
{
// Bu ascii atandı çık
karakter_ascii=0;
break;
}
}

// Üretilen ascii tekrar üretilmişse başa dön
if(karakter_ascii==0)
{
--i;
continue;
}

index_1=rand()%(kare_sayisi*2)+1; // 1. kare için rasgele sayı üret
index_2=rand()%(kare_sayisi*2)+1; // 1. karenin çiftini rasgele belirle

// Eğer aynı kare numaraları üretilirse 2. kareyi tekrar belirle
while(index_1==index_2)
index_2=rand()%(kare_sayisi*2)+1;

// Bu kare daha önce atandı mı bak
for(j=0;j<k;j++)
{
if(index_1==dolu_kareler[j] || index_2==dolu_kareler[j])
{
index_1=0;
index_2=0;
}
}
// Kontrol sonu

// Üretilen kare tekrar üretilmişse başa dön
if(index_1==0 || index_2==0)
{
--i;
continue;
}

// Eğer tüm koşullar sağlanırsa aşağıdaki atamalar yapılacak
kare_bilgileri[i][0]=karakter_ascii; // 0. eleman ascii bilgisini tutuyor
kare_bilgileri[i][1]=index_1; // 1. eleman 1. kareyi tutuyor
kare_bilgileri[i][2]=index_2; // 2. eleman 1. karenin çiftini tutuyor
dolu_kareler[k]=index_1; // Atanan kareleri kara listeye ekle
dolu_kareler[k+1]=index_2;
uretilen_asciiler[i]=karakter_ascii; // Atanan asciiyi kara listeye ekle
k=k+2; // Kara liste değişkenini iki arttır çünkü iki atama yaptık
}

if(CEVAPANAHTARIYAP==1) {

FILE *cevap_anahtari;
cevap_anahtari=fopen("anahtar.txt","w");

for(i=0;i<kare_sayisi;i++)
{
for(j=0;j<3;j++)
{
fprintf(cevap_anahtari," %d ",kare_bilgileri[i][j]);
}
fprintf(cevap_anahtari,"\n");
}
fclose(cevap_anahtari);
}
}

// Kullanıcının girdiği kareleri açan fonksiyon
void goster(int satir,int sutun,int kare_numarasi,int ascii)
{
int i,j,kare_sayac=0,x_koord,y_koord,kare_x,kare_y;

//Kullanıcının kare numarasını bul
for(i=0;i<sutun;i++)
{
for(j=0;j<satir;j++,kare_sayac++)
{
if(kare_sayac==kare_numarasi-1) {
kare_y=i;
kare_x=j;
}
}
}

// Kullanıcının karesinin koordinatlarını bul
x_koord=kare_x*5+YATAYKAYDIRMA;
y_koord=kare_y*5+DIKEYKAYDIRMA;

// Karenin başına konumlan
git(x_koord,y_koord);
printf(" ");
git(x_koord+1,y_koord);
printf(" ");
git(x_koord,y_koord+1);
KARAKTERGOSTER; // Istenilen karenin ascii kodunu bas
git(x_koord+1,y_koord+1);
printf(" ");
git(1,DIKEYKAYDIRMA+sutun*5-2); // Imleci indexe sorgusuna konumla
}

// Açılan karelerin kapatılacağı fonksiyon
void kapat(int satir,int sutun,int kare_numarasi)
{
int i,j,
kare_sayac=0,
x_koord,
y_koord,
kare_x,
kare_y;

// Açılan kareyi bul
for(i=0;i<sutun;i++)
{
for(j=0;j<satir;j++,kare_sayac++)
{
if(kare_sayac==kare_numarasi-1) {
kare_y=i;
kare_x=j;
}
}
}
// Bulma sonu

x_koord=kare_x*5+YATAYKAYDIRMA;
y_koord=kare_y*5+DIKEYKAYDIRMA;

// Siyah kareyi tekrar oluştur
git(x_koord,y_koord);
SIYAHKAREBAS;
git(x_koord+1,y_koord);
SIYAHKAREBAS;
git(x_koord,y_koord+1);
SIYAHKAREBAS;
git(x_koord+1,y_koord+1);
SIYAHKAREBAS;
git(1,DIKEYKAYDIRMA+sutun*5-2);
}

// Kullanıcının tahminini değerlendiren fonksiyon
int kareleri_ac(int kare_bilgileri[][3],int kare_sayisi,int satir,int sutun,int seviye)
{
int kare_1 =0,
kare_2 =0,
eleman_1 =0,
eleman_2 =0,
kare_ascii =0,
kare1_ascii =0,
kare2_ascii =0,
sayac =0,
gecen_sure =0,
deneme_sayisi =0,
puan =0,
i,j =0;

int acilan_kareler[kare_sayisi]; // Açılan kareler için kara liste

char yeni,
onbellek[5],
metin[150], // Yeni oyun için değişken
str[5]; // String

char *bolunmus_string;

// Acilan kareler arrayini 0 la doldur
for(i=0;i<kare_sayisi;i++)
acilan_kareler[i]=0;

//Döngüye başla
while(1)
{
// Kujllanıcı her kare bildiğinde sayac bir artıyor ta ki karelerin yarısına eşit olana kadar
if(sayac==kare_sayisi/2)
{
gecen_sure=time(NULL)-baslangic_sure;

puan=PUAN-(100-14*(seviye));
puan-=(4-(seviye)/2)*deneme_sayisi;
puan-=gecen_sure;

if(puan<0)
puan=0;

system("CLS");
strcpy(metin," CONGRATULATIONS !\n");
strcat(metin,"\nSTATISTICS\n");
strcat(metin,"-------------------------------------\n");
strcat(metin,"Your point\t : ");
itoa(puan,onbellek,10);
strcat(metin,onbellek);
strcat(metin," pts\n");
strcat(metin,"Elapsed time\t : ");
itoa(gecen_sure,onbellek,10);
strcat(metin,onbellek);
strcat(metin," sec.\n");
strcat(metin,"Your Moves\t : ");
itoa(deneme_sayisi+kare_sayisi/2,onbellek,10);
strcat(metin,onbellek);
MessageBox(NULL,metin,"PAIRS II",MB_OK | MB_ICONASTERISK);
yuksek_skor(puan,seviye);
puan=0;

if(sayac==16)
return 1;

// Yeni Oyun sorgusu
if(MessageBox(NULL,"NEXT LEVEL ?","PAIRS II",MB_YESNO | MB_ICONASTERISK)==IDYES)
return 1;
else
return 0;
// Yeni oyun sorgusu sonu
}

eslenmis_kare:
printf("\n\t\t\t\t OPEN : ");

//Satırı temizle
for(i=0;i<33;i++)
printf(" ");
for(i=0;i<33;i++)
printf("\b");
// Temizleme sonu

//Gereksiz string girişlerini temizle
strcpy(str,"0x0");
// Kullanıcıdan tahmin ettiği karelerin index numarasini al
gets(str);

printf("\n\t\t\t Type 'end' to quit");

if(!strcmp(str,"\0") || !strcmp(str,"x") || !strcmp(str,",") || !strcmp(str," ") || !strcmp(str,"X"))
strcpy(str,"0x0");

bolunmus_string=strtok(str,"Xx, ");

// Girilen komut end ise çıkış yap (end çıkış değeri olarak belirlendi)
if(!strcmp(bolunmus_string,"end"))
exit(1);
// Çıkış kontrol sonu

kare_1=atoi(bolunmus_string);
strcpy(bolunmus_string,"\0"); // Stringi boşalt
bolunmus_string=strtok(NULL,"Xx, ");
kare_2=atoi(bolunmus_string);

// Kullanıcının girdiği karelerin geçerli olup olmadığını kontrol et geçersiz ise değişkene atama yapma
if((kare_1<=0 || kare_1>kare_sayisi || kare_1==kare_2) || (kare_2<=0 || kare_2>kare_sayisi))
{
git(1,DIKEYKAYDIRMA+sutun*5-2);
continue;
}
// Geçerli değer kontrol sonu

// Girilen kare numarası açılan karelerden biri ise girişi reddet başa dön
for(i=0;i<kare_sayisi;i++)
{
if(acilan_kareler[i]==kare_1 || acilan_kareler[i]==kare_2)
{
git(1,DIKEYKAYDIRMA+sutun*5-2);
goto eslenmis_kare;
}
}
// Girilen kare kontrol sonu


// Şayet çift bilinmemişse karelerin ascii kodunu ayrı ayrı bul
for(i=0;i<kare_sayisi/2;i++)
{
if(kare_bilgileri[i][1]==kare_1 || kare_bilgileri[i][2]==kare_1)
{
kare1_ascii=kare_bilgileri[i][0];
}
else if(kare_bilgileri[i][1]==kare_2 || kare_bilgileri[i][2]==kare_2)
{
kare2_ascii=kare_bilgileri[i][0];
}
}
// Ascii bulma sonu

// Çiftleme kontrol algoritma
for(i=0;i<kare_sayisi/2;i++)
{
// Karenin dizide sahip olduğu bilgileri bul
kare_ascii = kare_bilgileri[i][0];
eleman_1 = kare_bilgileri[i][1];
eleman_2 = kare_bilgileri[i][2];

// Eşleşti mi ?
if((eleman_1==kare_1 && eleman_2==kare_2) ||
(eleman_1==kare_2 && eleman_2==kare_1))
{
// Eşleme varsa girilen kareleri aç
goster(satir,sutun,kare_1,kare_ascii);
goster(satir,sutun,kare_2,kare_ascii);

// Kullanıcının girdiği kareleri kara listeye ekle acilan_kareler[j]=kare_1;
acilan_kareler[j]=kare_1;
acilan_kareler[j+1]=kare_2;

Beep(1700,300); // Doğru giriş Beep sesi
sayac++; // Kullanıcı bir kare daha bildi
j=j+2; // Açılan kare indexsini 2 arttır ( Kendisi ve çifti girildi)
break; // Döngüden çık yeni giriş bekle
}
// Eşleme yoksa
else if(i==kare_sayisi/2-1) { // Son elemanı kontrol etmiş ve bulamamışsa eşleşme yok demektir
//Kareleri aç 1 saniye açık tut ( For ve beep gecikmesiyle beraber 1,5 saniyeyi buluyor)
goster(satir,sutun,kare_1,kare1_ascii);
goster(satir,sutun,kare_2,kare2_ascii);
sleep(1000);

// Yanlış giriş Beep sesi
Beep(523,300);

// Açılan kareleri kapat
kapat(satir,sutun,kare_1);
kapat(satir,sutun,kare_2);

deneme_sayisi++;

break;
}
}
}
}

int main()
{
bilgi();

int X_boyut =0,
Y_boyut =0,
kare_sayisi =0,
seviye =0,
seviye_bayrak =0,
i,j;

char command,
yeni;

// Komut döngüsü
while(1)
{
printf("\n Choice -> ");
command=getche();

if(command=='0')
return 0;
else if(command=='1') {
yardim();
baslangic_sure=time(NULL);
break;
}
else {
system("CLS");
bilgi();
printf("\n\n INVALID CHOICE \n\n");
sleep(1500);
system("CLS");
bilgi();
}
}
// komut döngüsü sonu

// Döngüden çıkarsa geçerli komut demektir ekranı temizle ve hazırla
system("CLS");
bilgi();
seviye_bilgisi();

while(1)
{
// Eğer sonraki seviye için seviye_bayrak 1 olmamışsa kullanıcının hangi seviyeyi oynamak istediğini sor
if(seviye_bayrak==0)
{
printf(" ");
scanf("%d",&seviye);
fflush(stdin);
}
// Seviyeye göre kare boyutlarını oluştur (X yataydaki kare sayısı Y düşeydeki kare sayısı)
switch(seviye)
{
case 1 :
X_boyut=2;
Y_boyut=2;
break;

case 2 :
X_boyut=4;
Y_boyut=3;
break;

case 3 :
X_boyut=4;
Y_boyut=4;
break;

case 4 :
X_boyut=5;
Y_boyut=4;
break;

case 5 :
X_boyut=6;
Y_boyut=4;
break;

case 6 :
X_boyut=7;
Y_boyut=4;
break;

case 7 :
X_boyut=8;
Y_boyut=4;
break;

// Girilen seviye 1 7 arasında değilse uyarı göster tekrar giriş iste
default :
printf("\n INVALID CHOICE ! \n Please enter a number between 1 and 7\n");
seviye=0;
sleep(1800);
system("CLS");
bilgi();
seviye_bilgisi();
continue;
}

// Fonksiyona parametre olarak geçirilecek kare sayısı
kare_sayisi=X_boyut*Y_boyut;

int kare_bilgileri[kare_sayisi/2][3];

system("CLS");
kare_ciz(X_boyut,Y_boyut);
kare_atamasi_yap(kare_bilgileri,kare_sayisi);

// kareleri_ac() fonksiyonu 1 döndürürse sonraki seviye 0 döndürürse çıkış demektir
if(kareleri_ac(kare_bilgileri,kare_sayisi,X_boyut, Y_boyut,seviye)) {
// Sonraki seviye için diziyi boşalt
for(i=0;i<kare_sayisi/2;i++)
{
for(j=0;j<3;j++)
{
kare_bilgileri[i][j]=0;
}
}

if(seviye==7)
{
do
{
printf("\n \t\t\t YOU HAVE COMPLETED ALL LEVELS \n \t\t\t Do you want to play new game ?");
yeni=getch();
yeni=toupper(yeni);
} while(yeni!='Y' && yeni!='N');

if(yeni=='N')
return 0;
else if(yeni=='Y')
seviye=0;
}

time(&baslangic_sure); // Süreyi sıfırla
system("CLS");
seviye++;
seviye_bayrak=1;
}

else
return 0;
}
}