通过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;
switch(op)
{
case '1':
RolePlayer();
break;
case '2':
AutoGame();
break;
case '3':
AIPlayer();
}
return 0;
}
void Menu(void)
{
Begin();
Gotoxy(5,5);
Gotoxy(5,7);
Gotoxy(5,9);
Gotoxy(5,11);
Gotoxy(5,13);
}
//设置颜色
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();
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);
}
Gotoxy(temp.X,temp.Y);
//显示下半部分柱子墙
temp.Y +=BLAN;
Gotoxy(temp.X,temp.Y);
//temp.X++;
temp.Y++;
for (;(temp.Y)<26;temp.Y++)
{
Gotoxy(temp.X,temp.Y);
}
}
}
//显示小鸟
void PrtBird(BIRD *bird)
{
SetConsoleColor(0x0E);//设置黑色背景,亮黄色前景
Gotoxy(bird->pos.X,bird->pos.Y);
}
//检测小鸟是否碰撞墙体
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)
{
Gotoxy(0,26); //第26行显示下边界
for (int i=0;i<100;i++)
Gotoxy(0,1); //第1行显示下边界
for (int i=0;i<100;i++)
for (int i=2;i<26;i++)
{
Gotoxy(0,i);
Gotoxy(99,i);
}
SetConsoleColor(0x0E);
}
//显示游戏信息
void GameInfo(BIRD *bird,int count,int bestSocre,char op)
{
SetConsoleColor(0x0D);
Gotoxy(5,5);
Gotoxy(5,7);
switch(op)
{
case '1':
break;
case '2':
break;
case '3':
break;
}
Gotoxy(5,9);
Gotoxy(5,11);
if (op=='1'||op=='2')
else
}
//自主学习
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 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())
{
if (ch==' ')
bird.pos.Y--;
}
else
bird.pos.Y++;
for (i=0;i<3;i++)
{
wall[i].X--; //柱子墙左移一格
}
}
count++;
}while(ch1=='y'||ch1=='Y');
}