湖南大学实时操作系统 贪吃蛇.docx
《湖南大学实时操作系统 贪吃蛇.docx》由会员分享,可在线阅读,更多相关《湖南大学实时操作系统 贪吃蛇.docx(23页珍藏版)》请在冰点文库上搜索。
湖南大学实时操作系统贪吃蛇
HUNANUNIVERSITY
实时操作系统
实验报告
题目:
贪吃蛇
学生姓名:
赵桔
学生学号:
201308010324
专业班级:
计科1303
同组成员:
无
上课老师:
肖德贵
目录
一、实验内容2
二、实验目的2
三、实验设计思想和流程2
四、主要数据结构及符号说明2
五、程序初值及运行结果3
六、实验体会3
附录(源代码及注释)9
一、实验内容
1.编写贪吃蛇游戏。
2.显示姓名学号。
二、实验目的
熟悉掌握信号量的使用方法。
三、实验设计思想和流程
1、定义两个信号量FSem(产生食物),SSem(蛇吃食物)。
2、main函数:
首先调用PC_DispClrScr()函数清除整个屏幕,再利用Osinit函数启动ucOS内核,然后利用PC_VectSet()初始化上下文切换矢量;调用OSSemCreate()将FSem初始化为0,SSem初始化为1;接着利用OSTaskCreate函数创建主进程,在主进程中使用OSTaskCreateExt创建其余两个进程(实验用);最后调用OSStart()函数,把控制权交给uC/OS-II内核开始运行多任务;
2、TaskStart()函数:
调用TaskStartDispInit(),并且创建任务,并且调用PC_GetKey()将上下左右键赋值为1234给flag;
3、TaskStartDispInit()函数:
初始化屏幕显示,显示学号姓名;
4、TaskStartCreateTasks()函数:
创建任务Food,Snake;
5、Snake()函数:
初始化蛇,头部为上,身长3;调用OSSemPend(FSem,0,&err)等待食物信号,再对它的①碰到自己②超出边界③吃到食物进行一一编写,操作完成后调用OSSemPost(SSem)发出蛇吃掉食物的信号。
6、Food()函数:
调用OSSemPend(SSem,0,&err)等待蛇吃掉食物的信号;接着调用random()函数随机产生食物的位置;再调用OSSemPost(FSem)发出产生食物的信号。
四、主要数据结构及符号说明
1.Snake()蛇函数,Food()食物函数。
2.OSTaskCreate()创建进程,OSTaskCreateExt()创建进程函数的拓展版。
3.OsSemPend()信号量减一,如果执行前信号量已经为0,则进入挂起状态。
OsSemPost()信号量加一。
5、程序初值及运行结果
1.初始化产生蛇、食物;蛇吃掉食物后身体增长1,速度加快30MS(界面显示蛇的身体长度,它吃掉的食物数):
2.超出DOS边界,显示死亡,等待10s,重新开始:
3.碰到自己身体,显示死亡,等待10s,重新开始:
六、实验体会
1、使用信号量FSem判断当前是否有食物产生,使用信号量SSem判断当前蛇是否吃完食物;两个信号量之间存在协作的关系。
2、在分支判断部分需要非常缜密的思维才能做到极强的鲁棒性。
3、通过本次实验,我更加熟练掌握了信号量的使用。
附录(源代码及注释)
/*
*********************************************************************************************************
*uC/OS-II
*TheReal-TimeKernel
*
*(c)Copyright1992-2002,JeanJ.Labrosse,Weston,FL
*AllRightsReserved
*
*EXAMPLE#2
*********************************************************************************************************
*/
#include"includes.h"
/*
*********************************************************************************************************
*CONSTANTS
*********************************************************************************************************
*/
#defineTASK_STK_SIZE512/*Sizeofeachtask'sstacks(#ofWORDs)*/
#defineTASK_START_PRIO0/*ApplicationtaskCLKpriorities*/
/*
*********************************************************************************************************
*VARIABLES
*********************************************************************************************************
*/
OS_STKTaskStartStk[TASK_STK_SIZE];/*Startuptaskstack*/
OS_STKFoodStk[TASK_STK_SIZE];/*Producertaskstack*/
OS_STKSnakeStk[TASK_STK_SIZE];/*Consumertaskstack*/
OS_EVENT*FSem;/*foodtosnakesemaphore*/
OS_EVENT*SSem;/*snaketofoodsemaphore*/
INT8Ufx,fy;/*foodposition*/
intflag=1;/*1-shiftup,2-shiftdown,3-shiftleft,4-shiftright*/
#defineSNAKE_MAXLEN30
#defineLFT_X4
#defineRGT_X75
#defineTOP_Y5
#defineBTM_Y19
/*
*********************************************************************************************************
*FUNCTIONPROTOTYPES
*********************************************************************************************************
*/
voidTaskStart(void*data);/*Functionprototypesoftasks*/
staticvoidTaskStartCreateTasks(void);
staticvoidTaskStartDispInit(void);
staticvoidTaskStartDisp(void);
voidFood(void*pdata);
voidSnake(void*pdata);
/*$PAGE*/
/*
*********************************************************************************************************
*MAIN
*********************************************************************************************************
*/
voidmain(void)
{
OS_STK*ptos;
OS_STK*pbos;
INT32Usize;
PC_DispClrScr(DISP_FGND_WHITE);/*Clearthescreen*/
OSInit();/*InitializeuC/OS-II*/
PC_DOSSaveReturn();/*SaveenvironmenttoreturntoDOS*/
PC_VectSet(uCOS,OSCtxSw);/*InstalluC/OS-II'scontextswitchvector*/
PC_ElapsedInit();
FSem=OSSemCreate(0);/*食物初始化为0*/
SSem=OSSemCreate
(1);/*初始可以产生食物*/
ptos=&TaskStartStk[TASK_STK_SIZE-1];
pbos=&TaskStartStk[0];
size=TASK_STK_SIZE;
OSTaskCreateExt(TaskStart,
(void*)0,
ptos,
TASK_START_PRIO,
TASK_START_PRIO,
pbos,
size,
(void*)0,
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
OSStart();/*Startmultitasking*/
}
/*$PAGE*/
/*
*********************************************************************************************************
*STARTUPTASK
*********************************************************************************************************
*/
voidTaskStart(void*pdata)
{
#ifOS_CRITICAL_METHOD==3/*AllocatestorageforCPUstatusregister*/
OS_CPU_SRcpu_sr;
#endif
INT8Uerr;
INT16Skey;
INT16S*c;
pdata=pdata;/*Preventcompilerwarning*/
TaskStartDispInit();/*Setupthedisplay*/
OS_ENTER_CRITICAL();/*InstalluC/OS-II'sclocktickISR*/
PC_VectSet(0x08,OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);/*Reprogramtickrate*/
OS_EXIT_CRITICAL();
OSStatInit();/*InitializeuC/OS-II'sstatistics*/
TaskStartCreateTasks();/*Createallothertasks*/
for(;;){
if(PC_GetKey(&key)){/*Seeifakeyhasbeenpressed*/
*c=(INT16S)getch();//Getkeypressed
switch(*c){
case0x48:
flag=1;//向上
break;
case0x50:
flag=2;//向下
break;
case0x4b:
flag=3;//向左
break;
case0x4d:
flag=4;//向右
break;
}
if(key==0x1B){/*Yes,seeifit'stheESCAPEkey*/
PC_DOSReturn();/*Yes,returntoDOS*/
}
}
OSCtxSwCtr=0;/*Clearcontextswitchcounter*/
OSTimeDlyHMSM(0,0,0,100);/*Waitonesecond*/
}
}
/*$PAGE*/
/*
*********************************************************************************************************
*INITIALIZETHEDISPLAY
*********************************************************************************************************
*/
staticvoidTaskStartDispInit(void)
{
/*1111111111222222222233333333334444444444555555555566666666667777777777*/
/*01234567890123456789012345678901234567890123456789012345678901234567890123456789*/
PC_DispStr(0,0,"GreedySnake",DISP_FGND_WHITE+DISP_BGND_RED+DISP_BLINK);
PC_DispStr(0,1,"201308010324zhaojie",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,2,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,3,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,4,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,5,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,6,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,7,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,8,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,9,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,10,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,11,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,12,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,13,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,14,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,15,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,16,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,17,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,18,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,19,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,20,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,21,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,22,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,23,"",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
PC_DispStr(0,24,"<-PRESS'ESC'TOQUIT->",DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY+DISP_BLINK);
/*1111111111222222222233333333334444444444555555555566666666667777777777*/
/*01234567890123456789012345678901234567890123456789012345678901234567890123456789*/
}
/*$PAGE*/
/*
*********************************************************************************************************
*CREATETASKS
*********************************************************************************************************
*/
staticvoidTaskStartCreateTasks(void)
{
OSTaskCreate(Snake,
(void*)0,
&SnakeStk[TASK_STK_SIZE-1],
1);
OSTaskCreate(Food,
(void*)0,
&FoodStk[TASK_STK_SIZE-1],
2);
}
/*$PAGE*/
/*
*********************************************************************************************************
*Snake
*********************************************************************************************************
*/
voidSnake(void*pdata)
{
INT8Ux[SNAKE_MAXLEN],y[SNAKE_MAXLEN];//存储蛇的位置
INT8Ucurrlen;/*currentlengthofsnake*/
INT8Ui,j,k,x1,y1,h;
INT8Uerr;
inttx,ty;
inttt;/*delaytime*/
inttempx,tempy;
chars[100];
pdata=pdata;
//初始化蛇,蛇的头部方向为向上
currlen=3;
x1=40;
y1=15;
for(i=0;i{
x[i]=x1;
y[i]=y1;
y1=y1+1;
}
PC_DispChar(x[0],y[0],'v',DISP_FGND_DARK_GRAY+DISP_BGND_LIGHT_GRAY);//head
for(i=1;i{
PC_DispChar(x[i],y[i],'*',DISP_FGND_DARK_GRAY+DISP_BGND_LIGHT_GRAY);//body
}
for(;;)
{
tt=300-10*(currlen-3);/*蛇吃的越多跑得越快*/
OSSemPend(FSem,0,&err);/*有食物?
*/
if(fx>=x[0])
tx=fx-x[0];
else
tx=x[0]-fx;
if(fy>=y[0])
ty=fy-y[0];
else
ty=y[0]-fy;
if(tx+ty>=1){//还没有吃到食物
for(;;){
if(tx+ty==1){//准备吃食物
if(((flag==1)||(flag==2))&&(tx==0)||((flag==3)||(flag==4))&&(ty==0))
{
PC_DispChar(x[0],y[0],'*',DISP_FGND_DARK_GRAY+DISP_BGND_LIGHT_GRAY);
break;
}
}
for(i=1;iif(x[0]==x[i]&y[0]==y[i]){
PC_DispStr(5,21,"Youeatyourself,hahahayoudie",DISP_FGND_YELLOW+DISP_BGND_LIGHT_GRAY);
while(currlen){
PC_DispChar(x[0