通过C语言程序设计开发的一款飞行小鸟游戏,拥有3种游戏模式:玩家操作模式,自动游戏模式,人工智能模式
代码如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <time.h>
- #include <windows.h>
- #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.Y<wall[i].Y;temp.Y++)
- {
- Gotoxy(temp.X,temp.Y);
- printf("※※※※※");
- }
- Gotoxy(temp.X,temp.Y);
- printf("※※※※※");
- //显示下半部分柱子墙
- temp.Y +=BLAN;
- Gotoxy(temp.X,temp.Y);
- printf("※※※※※");
- //temp.X++;
- temp.Y++;
- for (;(temp.Y)<26;temp.Y++)
- {
- Gotoxy(temp.X,temp.Y);
- printf("※※※※※");
- }
- }
- }
- //显示小鸟
- void PrtBird(BIRD *bird)
- {
- SetConsoleColor(0x0E);//设置黑色背景,亮黄色前景
- Gotoxy(bird->pos.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');
- }