通过C语言程序设计开发的一款飞行小鸟游戏,拥有3种游戏模式:玩家操作模式,自动游戏模式,人工智能模式 #include #include #include #include #include #define DIS 22 #define BLAN 9 #define M 16 #define N 16 typedef struct bird { COORD pos; int score; }BIRD; void CheckWall(COORD wall[]); void PrtBird(BIRD *bird); int CheckWin(COORD *wall, BIRD *bird); void Begin(void); void Gotoxy(int x,int y); BOOL SetConsoleColor(unsigned int wAttributes); void HideCursor(); void GameInfo(BIRD *bird,int count,int bestSocre,char op); int Learning(double a[30][50][2],COORD state, COORD newState,int action, BIRD *bird); int ChooseAction(double a[30][50][2],COORD state); void Menu(void); void AIPlayer(void); void AutoGame(void); void RolePlayer(void); int main(void) { Menu(); char op; op=getchar(); switch(op) { case '1': RolePlayer(); break; case '2': srand(time(NULL)); AutoGame(); break; case '3': srand(time(NULL)); AIPlayer(); } return 0; } void Menu(void) { Begin(); Gotoxy(5,5); printf("欢迎来到飞行小鸟游戏!"); Gotoxy(5,7); printf("请选择游戏模式:"); Gotoxy(5,9); printf("1——玩家操作模式\n"); Gotoxy(5,11); printf("2——自动飞行模式\n"); Gotoxy(5,13); printf("3——人工智能模式\n"); } //设置颜色 BOOL SetConsoleColor(unsigned int wAttributes) { HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE); if (hOutput==INVALID_HANDLE_VALUE) { return FALSE; } return SetConsoleTextAttribute(hOutput,wAttributes); } //隐藏光标 void HideCursor() { HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO CursorInfo; GetConsoleCursorInfo(handle,&CursorInfo); CursorInfo.bVisible=0; SetConsoleCursorInfo(handle,&CursorInfo); } //定位光标 void Gotoxy(int x,int y) { COORD pos={x,y}; HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOutput,pos); } //显示柱子墙体 void CheckWall(COORD wall[]) { int i; HideCursor(); srand(time(NULL)); COORD temp={wall[2].X+DIS,rand()%13+5}; //随机产生一个新的柱子 if (wall[0].X<20) { wall[0]=wall[1]; wall[1]=wall[2]; wall[2]=temp; //第3个柱子换成新柱子 } for (i=0;i<3;++i) { //显示上半部分柱子墙 temp.X=wall[i].X+1; SetConsoleColor(0x0C); //设置黑色背景,亮红色前景 for (temp.Y=2;temp.Ypos.X,bird->pos.Y); printf("o->"); //显示小鸟 } //检测小鸟是否碰撞墙体 int CheckWin(COORD *wall, BIRD *bird) { if (bird->pos.X>=wall->X) { if (bird->pos.Y<=wall->Y||bird->pos.Y>=wall->Y+BLAN) { return 0; } } if (bird->pos.Y<1||bird->pos.Y>26) { return 0; } (bird->score)++; return 1; } //显示边界 void Begin(void) { system("cls"); Gotoxy(0,26); //第26行显示下边界 for (int i=0;i<100;i++) printf("~"); Gotoxy(0,1); //第1行显示下边界 for (int i=0;i<100;i++) printf("~"); for (int i=2;i<26;i++) { Gotoxy(0,i); printf("~"); Gotoxy(99,i); printf("~"); } SetConsoleColor(0x0E); } //显示游戏信息 void GameInfo(BIRD *bird,int count,int bestSocre,char op) { SetConsoleColor(0x0D); Gotoxy(5,5); printf("飞行小鸟游戏"); Gotoxy(5,7); switch(op) { case '1': printf("玩家操作模式"); break; case '2': printf("自动游戏模式"); break; case '3': printf("AI人工智能模式"); break; } Gotoxy(5,9); printf("回合数:%d",count); Gotoxy(5,11); if (op=='1'||op=='2') printf("当前分:%d",bestSocre); else printf("最高分:%d",bestSocre); } //自主学习 int Learning(double a[30][50][2],COORD state, COORD newState,int action, BIRD *bird) { double rate=0.3; double decay=0.4; double st=0; int reward=1; if (bird->pos.Y<1 || bird->pos.Y>25|| (newState.X>0 && (newState.Y<0 || newState.Y>=BLAN))) reward = -100; bird->score++; st=(a[newState.X+M][newState.Y+N][0]+a[newState.X+M][newState.Y+N][1])/2; a[state.X+M][state.Y+N][action] += rate*((reward+decay*st)-a[state.X+M][state.Y+N][action]); return reward==1; } //选择操作 int ChooseAction(double a[30][50][2],COORD state) { double eGreedy=0.9; double action=a[state.X+M][state.Y+N][1]- a[state.X+M][state.Y+N][0]; if ((double)rand()/RAND_MAX>eGreedy||action==0) return rand()%2; return action>0; } //AI模式 void AIPlayer(void) { double table[30][50][2]={0}; int count=1; int bestScore=0; while (1) { BIRD bird={{17,10},0}; COORD wall[3]={{30,4},{55,13},{80,8}}; int action = 0; COORD state={0,0}; COORD newState={bird.pos.X-wall[0].X,bird.pos.Y-wall[0].Y}; do{ state=newState; Begin(); GameInfo(&bird,count,bestScore,'3'); CheckWall(wall); action=ChooseAction(table,state); if (action) bird.pos.Y--; else bird.pos.Y++; for (int i=0;i<3;i++) wall[i].X--; newState.X = bird.pos.X-wall[0].X; newState.Y = bird.pos.Y-wall[0].Y; PrtBird(&bird); Sleep(200); }while(Learning(table,state,newState,action,&bird)); if (bird.score>bestScore) bestScore=bird.score; count++; } } //自动游戏模式 void AutoGame(void) { int count=1; int bestScore=0; BIRD bird={{22,10},0}; //小鸟的初始位置 COORD wall[3]={{40,10},{60,6},{80,8}}; //柱子的初始位置和高度 int i; while (CheckWin(wall,&bird)) { Begin(); //清屏并显示上下边界和分数 GameInfo(&bird,count,bestScore,'2'); //显示游戏信息 CheckWall(wall); //显示柱子墙 PrtBird(&bird); //显示小鸟 Sleep(200); bestScore++; if (bird.pos.Y>wall[0].Y+BLAN/2) bird.pos.Y--; else bird.pos.Y++; for (i=0;i<3;i++) { wall[i].X--; //柱子墙左移一格 } } } //玩家操作模式 void RolePlayer(void) { int count=1; int bestScore=0; int i; char ch,ch1; do{ bestScore=0; BIRD bird={{22,10},0}; //小鸟的初始位置 COORD wall[3]={{40,10},{60,6},{80,8}}; //柱子的初始位置和高度 while (CheckWin(wall,&bird)) { Begin(); //清屏并显示上下边界和分数 GameInfo(&bird,count,bestScore,'1'); //显示游戏信息 CheckWall(wall); //显示柱子墙 PrtBird(&bird); //显示小鸟 Sleep(200); bestScore++; if (kbhit()) { ch=getch(); if (ch==' ') bird.pos.Y--; } else bird.pos.Y++; for (i=0;i<3;i++) { wall[i].X--; //柱子墙左移一格 } } printf("游戏结束,是否继续下一局?\n"); printf("继续请按Y,结束请按其它键。\n"); ch1=getch(); count++; }while(ch1=='y'||ch1=='Y'); }