C語言貪吃蛇源代碼必須經過相應的C/C++編譯器編譯成EXE文件後才能運行。
由於我們通常使用的操作系統是Windows系統,而在該系統下最長用的C/C++編譯器是VC++編譯器,目前在大專院校常用的版本還是VC++6.0
下面就以VC++6.0來說明編譯過程:1.在VC++6.0中通過“File”菜單下的 “Open”子菜單打開貪吃蛇代碼
2.在VC++6.0中通過“Build”菜單下的 “Compile xxxx.xx”子菜單編譯貪吃蛇代碼
3.在VC++6.0中通過“Build”菜單下的 “Execute xxxx.exe”子菜單運行貪吃蛇程序
附:在VC++6環境下可運行的C/C++貪吃蛇源代碼(無版權,自己編寫,歡迎任意修改拷貝)
/*C/C++貪吃蛇遊戲,zjlj,2015.3.16
*/
#define?DEBUG?0?//當程序在調試階段時?DEBUG為?1
#include<iostream>
#include<windows.h>
#include<time.h>
#include<conio.h>
using?namespace?std;
void?readini(FILE?**fphead,?int?*score,?char?*argv[])?//創建或打開壹個和運行文件對應的ini文件,讀取最高紀錄
{
char?filename[200],*pfilename; int?flag=-1,i;strcpy(filename,argv[0]);
for(i=0;filename[i]!='\0';i++)
{ if?('.'==filename[i])flag=1; } if(1==flag) { filename[i-1]='i';filename[i-2]='n';
filename[i-3]='i'; } else { filename[i]='.'; filename[i+1]='i'; filename[i+2]='n';filename[i+3]='i';
filename[i+4]='\0';
} for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];if?(?(*fphead=fopen(pfilename,?"rb+"))==NULL)
{if?(?(*fphead=fopen(pfilename,?"wb+"))==NULL)
{printf("無法創建或打開\"%s\"文件\n",pfilename);
system("pause");
exit(0);
}}
else { fread(score,sizeof(int),1,*fphead); }}
void?writeini(FILE?**fphead,?int?*score,?char?*argv[])?//打開壹個和運行文件對應的ini文件,寫入最高紀錄
{
char?filename[200],*pfilename; int?flag=-1,i;strcpy(filename,argv[0]);
for(i=0;filename[i]!='\0';i++)
{ if?('.'==filename[i])flag=1; } if(1==flag) { filename[i-1]='i';filename[i-2]='n';
filename[i-3]='i'; } else { filename[i]='.'; filename[i+1]='i'; filename[i+2]='n';filename[i+3]='i';
filename[i+4]='\0';
} for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];if?(?(*fphead=fopen(pfilename,?"wb+"))==NULL)
{ printf("無法寫入\"%s\"文件,磁盤寫保護!\n",pfilename);system("pause");
exit(0);
} else { rewind(*fphead); fwrite(score,sizeof(int),1,*fphead); fclose(*fphead); }}
void?gotoxy(int?x,int?y)//光標定位,光標定位函數SetConsoleCursorPosition是左上角位置是0,0然後向左向下延伸
{
COORD?pos;
pos.X=2*y;
pos.Y=x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void?color(int?a)//顏色函數
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
void?Refresh(int?q[][22],?int?grade,?int?gamespeed,?int?length,int?score)?//?輸出貪吃蛇棋盤
{
int?i,j; for(i=0;i<22;i++) { for(j=0;j<22;j++) {if(q[i][j]==0)//輸出棋盤空白
{
gotoxy(i,j);
color(11);
cout<<"■";
}
if(q[i][j]==1||q[i][j]==2)//輸出棋盤墻壁
{?
gotoxy(i,j);
color(11);
cout<<"□";
}
if(q[i][j]==3)//輸出蛇頭
{?
gotoxy(i,j);
color(14);
cout<<"★";
}
if(q[i][j]==4)//輸出蛇身
{?
gotoxy(i,j);
color(12);
cout<<"◆";
}
if(q[i][j]==5)//輸出果子{?
gotoxy(i,j);
color(12);
cout<<"●";
}
} if(i==0)?cout?<<?"\t***********************"; if(i==1)?cout?<<?"\t等級為:"?<<?grade;//顯示等級 if(i==3)?cout?<<?"\t自動前進時間"; if(i==4)?cout?<<?"\t間隔為:"?<<?gamespeed?<<?"ms";//顯示時間 if(i==6)?cout?<<?"\t歷史最高分為:"?<<?score?<<?"分"; if(i==7)?cout?<<?"\t妳現在得分為:"?<<?(length+(grade-1)*8)*10?<<?"分"; if(i==8)?cout?<<?"\t**********************"; if(i==9)?cout?<<?"\t遊戲說明:"; if(i==10)?cout?<<?"\t(1)用小鍵盤方向鍵控制"; if(i==11)?cout?<<?"\t蛇頭運動方向;"; if(i==12)?cout?<<?"\t(2)蛇每吃壹個果子蛇身"; if(i==13)?cout?<<?"\t增加壹節;"; if(i==14)?cout?<<?"\t(3)蛇咬到自己或碰到墻"; if(i==15)?cout?<<?"\t壁遊戲結束。"; if(i==18)?cout?<<?"\t**********************"; if(i==19)?cout?<<?"\tC/C++語言作業:"; if(i==20)?cout?<<?"\tzjlj,2015.03.16?"; }}
int?main(int?argc,?char?*argv[]){
int?tcsQipan[22][22];?//?貪吃蛇棋盤是壹個二維數組(如22*22,包括墻壁)
int?i,j,score,directiontemp;
FILE?*fpini;//*fpini?信息文件 readini(&fpini,?&score,?argv);//讀取ini文件的最高紀錄 if?(score<0)//最高成績小於零設置為零,初建文件會是負數 score=0; while(1) { for(i=1;i<=20;i++)for(j=1;j<=20;j++)
tcsQipan[i][j]=0;//貪吃蛇棋盤相應坐標標上中間空白部分的標誌0
for(i=0;i<=21;i++)tcsQipan[0][i]?=?tcsQipan[21][i]?=?1;?//貪吃蛇棋盤相應坐標標上上下墻壁的標誌1
for(i=1;i<=20;i++)tcsQipan[i][0]?=?tcsQipan[i][21]?=?2;?//貪吃蛇棋盤相應坐標標上左右墻壁的標誌2
int?tcsZuobiao[2][500];?//蛇的坐標數組 for(i=0;?i<4;?i++) {tcsZuobiao[0][i]?=?1;//蛇身和蛇頭的x坐標
tcsZuobiao[1][i]?=?i?+?1;//蛇身和蛇頭的y坐標
} int?head?=?3,tail?=?0;//標示蛇頭和蛇尾的數組偏移量 for(i=1;i<=3;i++)tcsQipan[1][i]=4;//蛇身
tcsQipan[1][4]=3;//蛇頭 int?x1,?y1;//?隨機出果子 srand(time(0));//設置隨機種子 do {x1=rand()%20+1;
y1=rand()%20+1;
} while(tcsQipan[x1][y1]!=0);//如果不是在空白處重新出果子 tcsQipan[x1][y1]=5;//貪吃蛇棋盤相應坐標標上果子的標誌5 color(12); cout<<"\n\n\t\t\t\t貪吃蛇遊戲即將開始?!"<<endl;//準備開始 long?start,starttemp; int?grade?=?1,?length?=?4;?//設置初始等級和蛇的初始長度 int?gamespeed?=?500;?//設置初始前進時間間隔 for(i=3;i>=0;i--) {start=clock();
while(clock()-start<=1000);
system("cls");
if(i>0)
cout?<<?"\n\n\t\t\t\t進入倒計時:"?<<?i?<<?endl;?//倒計時顯示
else
Refresh(tcsQipan,grade,gamespeed,length,score);?//初始棋盤顯示
} int?timeover=1,otherkey=1;//初始化超時時間和按鍵判斷參數 char?direction?=?77;?//?設置初始情況下,向右運動 int?x=tcsZuobiao[0][head],y=tcsZuobiao[1][head];//保存蛇頭坐標到x,y變量 while(1)//運行壹局遊戲 {start?=?clock();
while((timeover=((starttemp=clock())-start<=gamespeed))&&!kbhit());//如果有鍵按下或時間超過自動前進時間間隔則終止循環
if(direction==72||direction==80||direction==75?||direction==77)
directiontemp=direction;//保留上壹次方向按鍵
//starttemp=gamespeed+start-starttemp;//保留停留時間
if(timeover)
{
#if?(DEBUG==1)
direction?=?getch();//調試代碼
#elseif((direction?=getch())==-32)
direction?=?getch();#endif
}
#if?(DEBUG==1)//調試代碼start=clock();
while(clock()-start<=2000);
gotoxy(24,4);
cout?<<?"\t按鍵ASCII代碼"<<(int)direction<<""<<endl;
#endifif(!(direction==72||direction==80||direction==75?||direction==77))
{
otherkey=0;//?按鍵非方向鍵,otherkey設置為0}
else
{
otherkey=1;//?按鍵為方向鍵,otherkey設置為1}
if(direction==72?&&?directiontemp==80)//忽略反方向按鍵{
direction=32;
otherkey=0; //start?=?clock();//while(clock()-start<=starttemp);
}
else?if(direction==80?&&?directiontemp==72)
{
direction=32;//設置按鍵為非方向鍵
otherkey=0;//?按鍵為非方向鍵,otherkey設置為0//?start?=?clock();
//while(clock()-start<=starttemp);//補償等待時間
}
else?if(direction==75?&&?directiontemp==77)
{
direction=32;
otherkey=0; //start?=?clock();//while(clock()-start<=starttemp);
}
else?if(direction==77?&&?directiontemp==75)
{
direction=32;
otherkey=0; //start?=?clock();//while(clock()-start<=starttemp);
}
switch(direction)//判斷方向鍵
{
case?72:?x=?tcsZuobiao[0][head]-1;?y=?tcsZuobiao[1][head];break;?//?向上 case?80:?x=?tcsZuobiao[0][head]+1;?y=?tcsZuobiao[1][head];break;?//?向下 case?75:?x=?tcsZuobiao[0][head];?y=?tcsZuobiao[1][head]-1;break;?//?向左 case?77:?x=?tcsZuobiao[0][head];?y=?tcsZuobiao[1][head]+1;break;?//?向右 default:?break;}
if(x==0?||?x==21?||y==0?||?y==21)?//?蛇頭碰到墻壁,結束本局遊戲
{?
gotoxy(22,12); cout?<<?"\t遊戲已結束!"?<<?endl; if(score>=(length+(grade-1)*8)*10)//判斷是否破記錄 { gotoxy(10,7); color(12); cout?<<?"闖關失敗?加油耶!"?<<?endl; fclose(fpini);//關閉ini文件 } else { gotoxy(10,7); color(12); cout?<<?"恭喜您打破記錄"?<<?endl; score=(length+(grade-1)*8)*10; writeini(&fpini,?&score,?argv);//寫入ini文件的最高紀錄 } gotoxy(23,12);cout?<<?"按回車鍵重新開始,按ESC退出遊戲"?<<?endl;//顯示的提示
break;//退出該局遊戲}
if(tcsQipan[x][y]!=0&&!(x==x1&&y==y1)&&tcsQipan[x][y]!=3)?//蛇頭碰到蛇身,結束本局遊戲
{
gotoxy(22,12); cout?<<?"\t遊戲已結束!"?<<?endl; if(score>=(length+(grade-1)*8)*10)//判斷是否破記錄 { gotoxy(10,7); color(12); cout?<<?"闖關失敗?加油耶!"?<<?endl; fclose(fpini);//關閉ini文件 } else { gotoxy(10,7); color(12); cout?<<?"恭喜您打破記錄"?<<?endl; score=(length+(grade-1)*8)*10; writeini(&fpini,?&score,?argv);//寫入ini文件的最高紀錄 } gotoxy(23,12); cout?<<?"按回車鍵重新開始,按ESC退出遊戲"?<<?endl;//顯示的提示 break;//退出該局遊戲}
/*
遊戲運行時的核心算法開始
*/
if(x==x1?&&?y==y1)?//?吃果子,長度加1
{
length?++; if(length>=8)//長度大於等於8重新計算長度,等級加1 { length?-=?8;//重新計算長度 grade?++;//等級加1 if(gamespeed>50)//控制最快速度為50gamespeed?=?550?-?grade?*?50;?//?改變自動前進時間間隔
} tcsQipan[x][y]=?3;//貪吃蛇棋盤相應坐標現在蛇頭標誌改為蛇頭標誌3 tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]]?=?4;//貪吃蛇棋盤相應坐標原來蛇頭標誌改為蛇身標誌4 head?=?(head+1)%400;//防止數組越界 tcsZuobiao[0][head]?=?x;//蛇頭的x坐標 tcsZuobiao[1][head]?=?y;//蛇頭的y坐標 do//隨機出果子 { x1=rand()%20+1; y1=rand()%20+1; } while(tcsQipan[x1][y1]!=0);//如果不是在空白處重新出果子 tcsQipan[x1][y1]=5;//貪吃蛇棋盤相應坐標標上果子的標誌5 gotoxy(22,12); cout?<<?"\t遊戲進行中!"?<<?endl; Refresh(tcsQipan,grade,gamespeed,length,score);}
else?//?不吃果子
{?
if(otherkey) { tcsQipan?[tcsZuobiao[0][tail]][tcsZuobiao[1][tail]]=0; tail=(tail+1)%400;//防止數組越界 tcsQipan?[tcsZuobiao[0][head]][tcsZuobiao[1][head]]=4; head=(head+1)%400;//防止數組越界 tcsZuobiao[0][head]=x;//蛇頭的x坐標 tcsZuobiao[1][head]=y;//蛇頭的y坐標 tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]]=3; gotoxy(22,12); cout?<<?"\t遊戲進行中!"?<<?endl; Refresh(tcsQipan,grade,gamespeed,length,score); } else { gotoxy(22,12); cout?<<?"\t遊戲暫停中!"?<<?endl; }}
/*
遊戲運行時的核心算法結束
*/
}
while(1)
{
while(!kbhit()); if((direction?=getch())==13)//按回車鍵開始下壹局 break; if(direction?==27)//按ESC退出遊戲 exit(0);}
system("cls");//清除屏幕重新開始
} return?0;}