c小游戏课程设计
1. 一种C语言小游戏程序设计(程序已经附上)
"扫雷"小游戏C代码
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
main( )
{char a[102][102],b[102][102],c[102][102],w;
int i,j; /*循环变量*/
int x,y,z[999]; /*雷的位置*/
int t,s; /*标记*/
int m,n,lei; /*计数*/
int u,v; /*输入*/
int hang,lie,ge,mo; /*自定义变量*/
srand((int)time(NULL)); /*启动随机数发生器*/
leb1: /*选择模式*/
printf("
请选择模式:
1.标准 2.自定义
");
scanf("%d",&mo);
if(mo==2) /*若选择自定义模式,要输入三个参数*/
{do
{t=0; printf("请输入
行数 列数 雷的个数
");
scanf("%d%d%d",&hang,&lie,&ge);
if(hang<2){printf("行数太少
"); t=1;}
if(hang>100){printf("行数太多
");t=1;}
if(lie<2){printf("列数太少
");t=1;}
if(lie>100){printf("列数太多
");t=1;}
if(ge<1){printf("至少要有一个雷
");t=1;}
if(ge>=(hang*lie)){printf("雷太多了
");t=1;}
}while(t==1);
}
else{hang=10,lie=10,ge=10;} /*否则就是选择了标准模式(默认参数)*/
for(i=1;i<=ge;i=i+1) /*确定雷的位置*/
{do
{t=0; z[i]=rand( )%(hang*lie);
for(j=1;j<i;j=j+1){if(z[i]==z[j]) t=1;}
}while(t==1);
}
for(i=0;i<=hang+1;i=i+1) /*初始化a,b,c*/
{for(j=0;j<=lie+1;j=j+1) {a[i][j]='1'; b[i][j]='1'; c[i][j]='0';} }
for(i=1;i<=hang;i=i+1)
{for(j=1;j<=lie;j=j+1) {a[i][j]='+';} }
for(i=1;i<=ge;i=i+1) /*把雷放入c*/
{x=z[i]/lie+1; y=z[i]%lie+1; c[x][y]='#';}
for(i=1;i<=hang;i=i+1) /*计算b中数字*/
{for(j=1;j<=lie;j=j+1)
{m=48;
if(c[i-1][j-1]=='#')m=m+1; if(c[i][j-1]=='#')m=m+1;
if(c[i-1][j]=='#')m=m+1; if(c[i+1][j+1]=='#')m=m+1;
if(c[i][j+1]=='#')m=m+1; if(c[i+1][j]=='#')m=m+1;
if(c[i+1][j-1]=='#')m=m+1; if(c[i-1][j+1]=='#')m=m+1;
b[i][j]=m;
}
}
for(i=1;i<=ge;i=i+1) /*把雷放入b中*/
{x=z[i]/lie+1; y=z[i]%lie+1; b[x][y]='#';}
lei=ge; /*以下是游戏设计*/
do
{leb2: /*输出*/
system("cls");printf("
");
printf(" ");
for(i=1;i<=lie;i=i+1)
{w=(i-1)/10+48; printf("%c",w);
w=(i-1)%10+48; printf("%c ",w);
}
printf("
|");
for(i=1;i<=lie;i=i+1){printf("---|");}
printf("
");
for(i=1;i<=hang;i=i+1)
{w=(i-1)/10+48; printf("%c",w);
w=(i-1)%10+48; printf("%c |",w);
for(j=1;j<=lie;j=j+1)
{if(a[i][j]=='0')printf(" |");
else printf(" %c |",a[i][j]);
}
if(i==2)printf(" 剩余雷个数");
if(i==3)printf(" %d",lei);
printf("
|");
for(j=1;j<=lie;j=j+1){printf("---|");}
printf("
");
}
scanf("%d%c%d",&u,&w,&v); /*输入*/
u=u+1,v=v+1;
if(w!='#'&&a[u][v]=='@')
goto leb2;
if(w=='#')
{if(a[u][v]=='+'){a[u][v]='@'; lei=lei-1;}
else if(a[u][v]=='@'){a[u][v]='?'; lei=lei+1;}
else if(a[u][v]=='?'){a[u][v]='+';}
goto leb2;
}
a[u][v]=b[u][v];
leb3: /*打开0区*/
t=0;
if(a[u][v]=='0')
{for(i=1;i<=hang;i=i+1)
{for(j=1;j<=lie;j=j+1)
{s=0;
if(a[i-1][j-1]=='0')s=1; if(a[i-1][j+1]=='0')s=1;
if(a[i-1][j]=='0')s=1; if(a[i+1][j-1]=='0')s=1;
if(a[i+1][j+1]=='0')s=1; if(a[i+1][j]=='0')s=1;
if(a[i][j-1]=='0')s=1; if(a[i][j+1]=='0')s=1;
if(s==1)a[i][j]=b[i][j];
}
}
for(i=1;i<=hang;i=i+1)
{for(j=lie;j>=1;j=j-1)
{s=0;
if(a[i-1][j-1]=='0')s=1; if(a[i-1][j+1]=='0')s=1;
if(a[i-1][j]=='0')s=1; if(a[i+1][j-1]=='0')s=1;
if(a[i+1][j+1]=='0')s=1; if(a[i+1][j]=='0')s=1;
if(a[i][j-1]=='0')s=1; if(a[i][j+1]=='0')s=1;
if(s==1)a[i][j]=b[i][j];
}
}
for(i=hang;i>=1;i=i-1)
{for(j=1;j<=lie;j=j+1)
{s=0;
if(a[i-1][j-1]=='0')s=1; if(a[i-1][j+1]=='0')s=1;
if(a[i-1][j]=='0')s=1; if(a[i+1][j-1]=='0')s=1;
if(a[i+1][j+1]=='0')s=1; if(a[i+1][j]=='0')s=1;
if(a[i][j-1]=='0')s=1; if(a[i][j+1]=='0')s=1;
if(s==1)a[i][j]=b[i][j];
}
}
for(i=hang;i>=1;i=i-1)
{for(j=lie;j>=1;j=j-1)
{s=0;
if(a[i-1][j-1]=='0')s=1; if(a[i-1][j+1]=='0')s=1;
if(a[i-1][j]=='0')s=1; if(a[i+1][j-1]=='0')s=1;
if(a[i+1][j+1]=='0')s=1;if(a[i+1][j]=='0')s=1;
if(a[i][j-1]=='0')s=1; if(a[i][j+1]=='0')s=1;
if(s==1)a[i][j]=b[i][j];
}
}
for(i=1;i<=hang;i=i+1) /*检测0区*/
{for(j=1;j<=lie;j=j+1)
{if(a[i][j]=='0')
{if(a[i-1][j-1]=='+'||a[i-1][j-1]=='@'||a[i-1][j-1]=='?')t=1;
if(a[i-1][j+1]=='+'||a[i-1][j+1]=='@'||a[i-1][j+1]=='?')t=1;
if(a[i+1][j-1]=='+'||a[i+1][j-1]=='@'||a[i+1][j-1]=='?')t=1;
if(a[i+1][j+1]=='+'||a[i+1][j+1]=='@'||a[i+1][j+1]=='?')t=1;
if(a[i+1][j]=='+'||a[i+1][j]=='@'||a[i+1][j]=='?')t=1;
if(a[i][j+1]=='+'||a[i][j+1]=='@'||a[i][j+1]=='?')t=1;
if(a[i][j-1]=='+'||a[i][j-1]=='@'||a[i][j-1]=='?')t=1;
if(a[i-1][j]=='+'||a[i-1][j]=='@'||a[i-1][j]=='?')t=1;
}
}
}
if(t==1)goto leb3;
}
n=0; /*检查结束*/
for(i=1;i<=hang;i=i+1)
{for(j=1;j<=lie;j=j+1)
{if(a[i][j]!='+'&&a[i][j]!='@'&&a[i][j]!='?')n=n+1;}
}
}
while(a[u][v]!='#'&&n!=(hang*lie-ge));
for(i=1;i<=ge;i=i+1) /*游戏结束*/
{x=z[i]/lie+1; y=z[i]%lie+1; a[x][y]='#'; }
printf(" ");
for(i=1;i<=lie;i=i+1)
{w=(i-1)/10+48; printf("%c",w);
w=(i-1)%10+48; printf("%c ",w);
}
printf("
|");
for(i=1;i<=lie;i=i+1){printf("---|");}
printf("
");
for(i=1;i<=hang;i=i+1)
{w=(i-1)/10+48; printf("%c",w);
w=(i-1)%10+48; printf("%c |",w);
for(j=1;j<=lie;j=j+1)
{if(a[i][j]=='0')printf(" |");
else printf(" %c |",a[i][j]);
}
if(i==2)printf(" 剩余雷个数");
if(i==3)printf(" %d",lei); printf("
|");
for(j=1;j<=lie;j=j+1) {printf("---|");}
printf("
");
}
if(n==(hang*lie-ge)) printf("你成功了!
");
else printf(" 游戏结束!
");
printf(" 重玩请输入1
");
t=0;
scanf("%d",&t);
if(t==1)goto leb1;
}
/*注:在DEV c++上运行通过。行号和列号都从0开始,比如要确定第0行第9列不是“雷”,就在0和9中间加入一个字母,可以输入【0a9】三个字符再按回车键。3行7列不是雷,则输入【3a7】回车;第8行第5列是雷,就输入【8#5】回车,9行0列是雷则输入【9#0】并回车*/
2. 如何使用C语言编写简单小游戏
C语言是计算机专业都要学习的一门基础学科。一般来说,是比较枯燥的.那么,我们能不能通过编一些小游戏来提高它的趣味性呢?这样学习程序设计,就不会是一件艰苦 ,枯燥的事,它变得象电脑游戏一样充满好奇,富有乐趣。
例如2048这款游戏:
方法/步骤:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include<windows.h>
#define SIZE 4
static int score=0;
void putn(int n[][SIZE]);
void getn(int n[][SIZE]);
int isempty(int n[][SIZE]);
int isfull(int n[][SIZE]);
void math(int n[][SIZE],char c);
void tow(int n[][SIZE]);
void toa(int n[][SIZE]);
void tos(int n[][SIZE]);
void tod(int n[][SIZE]);
//主函数
int main()
{
int i,j;
int n[SIZE][SIZE];
char c=' ';
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
n[i][j]=0;
}
}
printf( "*********************** "
" 2048(%dX%d) "
" control:W/A/S/D "
"press any key to begin "
"*********************** ",SIZE,SIZE);
getch();
system("cls");
//n[0][1]=2048;
//n[0][3]=2048;
while(1)
{
if(isempty(n))
getn(n);
putn(n);
if(!isempty(n)&&isfull(n))
break;
sleep(200);
c=getch();
while(c!='w'&&c!='a'&&c!='s'&&c!='d')
c=getch();
math(n,c);
system("cls");
}
printf(" Game Over! ",score);
return 0;
}
//函数
void putn(int n[][SIZE])
{
int i,j;
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
printf("| ");
printf("| ");
for(j=0;j<SIZE;j++)
{
if(n[i][j]==0)
printf("| ");
else
printf("|%4d ",n[i][j]);
}
printf("| ");
for(j=0;j<SIZE;j++)
printf("|_____");
printf("| ");
}
printf("score: %d",score);
}
void getn(int n[][SIZE])
{
int a,b;
a=rand()%SIZE;
b=rand()%SIZE;
while(n[a][b]!=0)
{
a=rand()%SIZE;
b=rand()%SIZE;
}
n[a][b]=2;
}
int isempty(int n[][SIZE])
{
int i,j,count=0;
for(i=0;i<SIZE;i++)
for(j=0;j<SIZE;j++)
if(n[i][j]==0)
count++;
return count;
}
int isfull(int n[][SIZE])
{
int i,j,count=0;
for(i=0;i<SIZE;i++)
{
for(j=1;j<SIZE-1;j++)
{
if(n[i][j]==n[i][j+1]||n[i][j]==n[i][j-1])
count++;
}
}
for(j=0;j<SIZE;j++)
{
for(i=1;i<SIZE-1;i++)
{
if(n[i][j]==n[i+1][j]||n[i][j]==n[i-1][j])
count++;
}
}
return count>0?0:1;
}
void math(int n[][SIZE],char c)
{
switch(c)
{
case 'w':tow(n);break;
case 'a':toa(n);break;
case 's':tos(n);break;
case 'd':tod(n);break;
default :;
}
}
void tow(int n[][SIZE])
{
int i,j,a;
int m[SIZE];
for(a=0;a<SIZE;a++)
m[a]=0;
for(j=0;j<SIZE;j++)
{
for(a=0;a<SIZE;a++)
{
for(i=0;i<SIZE-1;i++)
{
if(n[i][j]==0)
{
n[i][j]=n[i+1][j];
n[i+1][j]=0;
}
}
}
}
for(j=0;j<SIZE;j++)
{
for(a=0,i=0;i<SIZE;i++)
{
if(n[i][j]!=n[i+1][j]&&n[i][j]!=0||n[i][j]==2048)
{
m[a++]=n[i][j];
n[i][j]=0;
}
else if(n[i][j]==n[i+1][j])
{
m[a++]=n[i][j]+n[i+1][j];
score+=m[a-1];
n[i][j]=0,n[i+1][j]=0;
}
}
for(i=0;i<SIZE;i++)
{
n[i][j]=m[i];
m[i]=0;
}
}
}
void toa(int n[][SIZE])
{
int i,j,a;
int m[SIZE];
for(a=0;a<SIZE;a++)
m[a]=0;
for(i=0;i<SIZE;i++)
{
for(a=0;a<SIZE;a++)
{
for(j=0;j<SIZE-1;j++)
{
if(n[i][j]==0)
{
n[i][j]=n[i][j+1];
n[i][j+1]=0;
}
}
}
}
for(i=0;i<SIZE;i++)
{
for(a=0,j=0;j<SIZE;j++)
{
if(n[i][j]!=n[i][j+1]&&n[i][j]!=0||n[i][j]==2048)
{
m[a++]=n[i][j];
n[i][j]=0;
}
else if(n[i][j]==n[i][j+1])
{
m[a++]=n[i][j]+n[i][j+1];
score+=m[a-1];
n[i][j]=0,n[i][j+1]=0;
}
}
for(j=0;j<SIZE;j++)
{
n[i][j]=m[j];
m[j]=0;
}
}
}
void tos(int n[][SIZE])
{
int i,j,a;
int m[SIZE];
for(a=0;a<SIZE;a++)
m[a]=0;
for(j=SIZE-1;j>=0;j--)
{
for(a=SIZE-1;a>=0;a--)
{
for(i=SIZE-1;i>0;i--)
{
if(n[i][j]==0)
{
n[i][j]=n[i-1][j];
n[i-1][j]=0;
}
}
}
}
for(j=SIZE-1;j>=0;j--)
{
for(a=SIZE-1,i=SIZE-1;i>=0;i--)
{
if(n[i][j]!=n[i-1][j]&&n[i][j]!=0||n[i][j]==2048)
{
m[a--]=n[i][j];
n[i][j]=0;
}
else if(n[i][j]==n[i-1][j])
{
m[a--]=n[i][j]+n[i-1][j];
score+=m[a+1];
n[i][j]=0,n[i-1][j]=0;
}
}
for(i=SIZE-1;i>=0;i--)
{
n[i][j]=m[i];
m[i]=0;
}
}
}
void tod(int n[][SIZE])
{
int i,j,a;
int m[SIZE];
for(a=0;a<SIZE;a++)
m[a]=0;
for(i=SIZE-1;i>=0;i--)
{
for(a=SIZE-1;a>=0;a--)
{
for(j=SIZE-1;j>0;j--)
{
if(n[i][j]==0)
{
n[i][j]=n[i][j-1];
n[i][j-1]=0;
}
}
}
}
for(i=SIZE-1;i>=0;i--)
{
for(a=SIZE-1,j=SIZE-1;j>=0;j--)
{
if(n[i][j]!=n[i][j-1]&&n[i][j]!=0||n[i][j]==2048)
{
m[a--]=n[i][j];
n[i][j]=0;
}
else if(n[i][j]==n[i][j-1])
{
m[a--]=n[i][j]+n[i][j-1];
score+=m[a+1];
n[i][j]=0,n[i][j-1]=0;
}
}
for(j=SIZE-1;j>=0;j--)
{
n[i][j]=m[j];
m[j]=0;
}
}
}
3. 教你如何使用C语言编写简单小游戏
编写程序,实现如下表所示的5-魔方阵。
17
24
1
8
15
23
5
7
14
16
4
6
13
20
22
10
12
19
21
3
11
18
25
2
9
5-魔方阵
问题分析
所谓“n-魔方阵”,指的是使用1〜n2共n2个自然数排列成一个n×n的方阵,其中n为奇数;该方阵的每行、每列及对角线元素之和都相等,并为一个只与n有关的常数,该常数为n×(n2+1)/2。
例如5-魔方阵,其第一行、第一列及主对角线上各元素之和如下:
第一行元素之和:17+24+1+8+15=65
第一列元素之和:17+23+4+10+11=65
主对角线上元素之和:17+5+13+21+9=65
而
n×(n2+1)/2=5×(52+1)/2=65
可以验证,5-魔方阵中其余各行、各列及副对角线上的元素之和也都为65。
假定阵列的行列下标都从0开始,则魔方阵的生成方法为:在第0行中间置1,对从2开始的其余n2-1个数依次按下列规则存放:
(1)
假定当前数的下标为(i,j),则下一个数的放置位置为当前位置的右上方,即下标为(i-1,j+1)的位置。
(2)
如果当前数在第0行,即i-1小于0,则将下一个数放在最后一行的下一列上,即下标为(n-1,j+1)的位置。
(3)
如果当前数在最后一列上,即j+1大于n-1,则将下一个数放在上一行的第一列上,即下标为(i-1,0)的位置。
(4)
如果当前数是n的倍数,则将下一个数直接放在当前位置的正下方,即下标为(i+1,j)的位置。
算法设计
在设计算法时釆用了下面一些方法:
定义array()函数,array()函数的根据输入的n值,生成并显示一个魔方阵,当发现n不是奇数时,就加1使之成为奇数。
使用动态内存分配与释放函数malloc()与free(),在程序执行过程中动态分配与释放内存,这样做的好处是使代码具有通用性,同时提高内存的使用率。
在分配内存时还要注意,由于一个整型数要占用两个内存,因此,如果魔方阵中要存放的数有max个,则分配内存时要分配2*max个单元,从而有malloc(max+max)。在malloc()函数中使用max+max而不是2*max是考虑了程序运行的性能。
显然应该使用二维数组来表示魔方阵,但虽然数组是二维形式的,而由于内存是一维线性的,因此在存取数组元素时,要将双下标转换为单个索引编号。在程序中直接定义了指针变量来指向数组空间,即使用malloc()函数分配的内存。
4. 抢三十两人小游戏C语言程序编写简单程序
1.先学习C语言的基础知识。现在正在学C语言的在校学生可以直接进入第2步学习。
2.按照《C语言程序设计入门学习六步曲》进行上机练习。
3.在上机练习时要养成良好的编程风格。点击查看C语言的编程风格
4.积极参加C、C++兴趣小组,养成和老师与同学交流习惯,从而相互收益。有时别人不经意的一句话可能使你茅塞顿开--“一句话点醒梦中人”。
5.及时总结自己的学习经验,养成写C语言日记的习惯。软件有编程日记功能。
6.从网上或教材上找一个自己感兴趣的题目(选题时根据自己的能力,可先易后难,培养自己的成就感,如果有了成就感,即使再苦再累还是感觉C语言学习是一件快乐的事,同学们喜欢打游戏,经常通宵达旦地玩游戏也乐而不疲就是这个道理)进行实战训练,提高自己的C语言综合应用能力。
7. 由于C语言灵活、强大,初学者要全面地掌握它是不可能的,因此在学习C语言的过程中,不要在细枝末节上浪费精力(比如++、--用于表达式的计算,实际上是没有意义的),但一定要熟练掌握C语言的流程控制语句、数组、函数、指针等基础知识的应用,为学习面向对象程序设计打下坚实的基础。如果这些知识你学不好,要后续学习好C++、可视化的程序设计Visual C++或C++Builder就像空中楼阁,是不现实的。
C语言程序设计入门学习六步曲
笔者在从事教学的过程中,听到同学抱怨最多的一句话是:老师,上课我也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手。发生这种现象的原因有三个:
一、所谓的看懂听明白,只是很肤浅的语法知识,而我们编写的程序或软件是要根据要解决问题的实际需要控制程序的流程,如果你没有深刻地理解C语言的语句的执行过程(或流程),你怎么会编写程序解决这些实际问题呢?
二、用C语言编程解决实际问题,所需要的不仅仅是C语言的编程知识,还需要相关的专业知识。例如,如果你不知道长方形的面积公式,即使C语言学得再好你也编不出求长方形的面积的程序来。
三、C语言程序设计是一门实践性很强的课程,“纸上谈兵”式的光学不练是学不好C语言的。例如,大家都看过精彩自行车杂技表演,假如,你从来没有骑过自行车,光听教练讲解相关的知识、规则、技巧,不要说上台表演、就是上路你恐怕都不行。
出现问题原因清楚了,那么如何学习呢?请你看【C语言学习六步曲】
在程序开发的过程中,上机调试程序是一个不可缺少的重要环节。“三分编程七分调试”,说明程序调试的工作量要比编程大得多。这里以如何上机调试C程序来说明C语言的学习方法。
第一步、验证性练习
在这一步要求按照教材上的程序实例进行原样输入,运行一下程序是否正确。在这一步基本掌握C语言编程软件的使用方法(包括新建、打开、保存、关闭C程序,熟练地输入、编辑C程序;初步记忆新学章节的知识点、养成良好的C语言编程风格)。
初学者最容易犯的错误是:
1、没有区分开教材上的数字1和字母l,字母o和数字0的区别,造成变量未定义的错误。另一个易错点是将英文状态下的逗号,分号;括号()双引号""输入出入成中文状态下的逗号,分号;括号(),双引号“”造成非法字符错误。
2、C语言初学者易犯语法错误:使用未定义的变量、标示符(变量、常量、数组、函数等)不区分大小写、漏掉“;”、“{”与“}”、“(”与“)”不匹、控制语句(选择、分支、循环)的格式不正确、调用库函数却没有包含相应的头文件、调用未C声明的自定义函数、调用函数时实参与形参不匹配、数组的边界超界等。
3、修改C语言语法错误时要注意以下两点:
(1)、由于C语言语法比较自由、灵活,因此错误信息定位不是特别精确。例如,当提示第10行发生错误时,如果在第10行没有发现错误,从第10行开始往前查找错误并修改之。
(2)、一条语句错误可能会产生若干条错误信息只要修改了这条错误,其他错误会随之消失。特别提示:一般情况下,第一条错误信息最能反映错误的位置和类型,所以调试程序时务必根据第一条错误信息进行修改,修改后,立即运行程序,如果还有很多错误,要一个一个地修改,即,每修改一处错误要运行一次程序。
第二步、照葫芦画瓢
在第一步输入的C程序的基础上进行试验性的修改,运行一下程序看一看程序结果发生了什么变化,分析结果变化的原因,加深新学知识点的理解。事实上这和第一步时同步进行的,实现“输入”加深知识的记忆,“修改”加深对知识的理解。记忆和理解是相辅相成的,相互促进。
例如:将最简单的Hello World!程序
#include "stdio.h"
int main()
{
printf("Hello World!\n");
return 0;
}
中的
printf("Hello World!\n");
中的Hello World!改成你的姓名,运行一下程序,看有什么变化?
再如求1+2+3...+100的和的程序
#include
main()
{
int i,sum=0;
for(i=1;i<=100;i++)
{
sum=sum+i;
}
printf("sum=%d\n",sum);
}
第1次将for(i=1;i<=100;i++)中的100改成50,运行一下程序,看有什么变化?
第2次将for(i=1;i<=100;i++)中的i++改成i=i+2,运行一下程序,看有什么变化?
找出程序结果变化的原因,就加深了对C语句的理解。
第三步、不看教材看是否能将前两步的程序进行正确地输入并运行。
在这一步要求不看教材,即使程序不能运行,看能否将其改正,使其能正确运行。目的是对前两步的记忆、理解进一步强化。
第四步、增强程序的调试能力
在教材中每章都有C语言初学者易犯的错误,按照易出错的类型,将教材中的正确的程序改成错误的程序,运行一下程序,看出现的错误信息提示,并记下错误信息,再将程序改成正确的,运行一下程序。这样反复修改,就能够学习C语言程序发生错误的原因和修改错误的能力。
注意:每次只改错一个地方,目的是显示发生该错误的真正原因,避免一次改动多个地方,搞清发生错误的真正原因,切记!!!!
注意:上机调试程序时要带一个记录本,记下英文错误提示信息和解决该错误问题的方法,积累程序调试经验,避免在编程犯同样的错误,切记!!!!。
例如,将Hello World程序中语句
printf("Hello World!\n");
中的;改成中文的分号;
运行一下程序,看有什么结果?
调试程序是一种实践性很强的事,光纸上谈兵是是没用的,就像游泳运动员只听教练讲解示范,而不亲自下水练习,是永远学不会游泳的。
即使在优秀的程序员编写程序也会犯错误的,可能事最低级的语法错误,但他能快速发现错误并改正错误,而我们C语言初学者面对错误提示,不知道发生了什么错误,如何改正,这就事差别。
第五步、研究典型的C语言程序,提高程序设计能力
C语言初学者遇到最多的困惑是:上课也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手。发生这种现象的原因是:所谓的看懂听明白,只是很肤浅的语法知识,而没有深刻地理解C语言的语句的执行过程(或流程)。
计算机是按照人的指令(编写的程序)去执行的,如果不知道这些C语句在计算机中是如何执行的,你怎么回灵活运用这些知识去解决实际问题呢?
解决问题的方法是要先理解C语言各种语句的流程(即计算机是如何执行这些语句的过程),然后研读现成C语言经典程序,看懂别人事如何解决问题的,以提高自己的程序设计能力。
第六步、研究课程设计源成序,提高C语言的综合应用能力.
5. 用C语言编写小游戏
用c语言编写一个五子棋吧,不怎么难,给你程序,自己参考一下
/*3.3.4 源程序*/
#include "graphics.h" /*图形系统头文件*/
#define LEFT 0x4b00 /*光标左键值*/
#define RIGHT 0x4d00 /*光标右键值*/
#define DOWN 0x5000 /*光标下键值*/
#define UP 0x4800 /*光标上键值*/
#define ESC 0x011b /* ESC键值*/
#define ENTER 0x1c0d /* 回车键值*/
int a[8][8]={0},key,score1,score2;/*具体分数以及按键与存放棋子的变量*/
char playone[3],playtwo[3];/*两个人的得分转换成字符串输出*/
void playtoplay(void);/*人人对战函数*/
void DrawQp(void);/*画棋盘函数*/
void SetPlayColor(int x);/*设置棋子第一次的颜色*/
void MoveColor(int x,int y);/*恢复原来棋盘状态*/
int QpChange(int x,int y,int z);/*判断棋盘的变化*/
void DoScore(void);/*处理分数*/
void PrintScore(int n);/*输出成绩*/
void playWin(void);/*输出胜利者信息*/
/******主函数*********/
void main(void)
{
int gd=DETECT,gr;
initgraph(&gd,&gr,"c:\\tc"); /*初始化图形系统*/
DrawQp();/*画棋盘*/
playtoplay();/*人人对战*/
getch();
closegraph();/*关闭图形系统*/
}
void DrawQp()/*画棋盘*/
{
int i,j;
score1=score2=0;/*棋手一开始得分都为0*/
setbkcolor(BLUE);
for(i=100;i<=420;i+=40)
{
line(100,i,420,i);/*画水平线*/
line(i,100,i,420); /*画垂直线*/
}
setcolor(0);/*取消圆周围的一圈东西*/
setfillstyle(SOLID_FILL,15);/*白色实体填充模式*/
fillellipse(500,200,15,15); /*在显示得分的位置画棋*/
setfillstyle(SOLID_FILL,8); /*黑色实体填充模式*/
fillellipse(500,300,15,15);
a[3][3]=a[4][4]=1;/*初始两个黑棋*/
a[3][4]=a[4][3]=2;/*初始两个白棋*/
setfillstyle(SOLID_FILL,WHITE);
fillellipse(120+3*40,120+3*40,15,15);
fillellipse(120+4*40,120+4*40,15,15);
setfillstyle(SOLID_FILL,8);
fillellipse(120+3*40,120+4*40,15,15);
fillellipse(120+4*40,120+3*40,15,15);
score1=score2=2; /*有棋后改变分数*/
DoScore();/*输出开始分数*/
}
void playtoplay()/*人人对战*/
{
int x,y,t=1,i,j,cc=0;
while(1)/*换棋手走棋*/
{
x=120,y=80;/*每次棋子一开始出来的坐标,x为行坐标,y为列坐标*/
while(1) /*具体一个棋手走棋的过程*/
{
PrintScore(1);/*输出棋手1的成绩*/
PrintScore(2);/*输出棋手2的成绩*/
SetPlayColor(t);/*t变量是用来判断棋手所执棋子的颜色*/
fillellipse(x,y,15,15);
key=bioskey(0);/*接收按键*/
if(key==ESC)/*跳出游戏*/
break;
else
if(key==ENTER)/*如果按键确定就可以跳出循环*/
{
if(y!=80&&a[(x-120)/40][(y-120)/40]!=1
&&a[(x-120)/40][(y-120)/40]!=2)/*如果落子位置没有棋子*/
{
if(t%2==1)/*如果是棋手1移动*/
a[(x-120)/40][(y-120)/40]=1;
else/*否则棋手2移动*/
a[(x-120)/40][(y-120)/40]=2;
if(!QpChange(x,y,t))/*落子后判断棋盘的变化*/
{
a[(x-120)/40][(y-120)/40]=0;/*恢复空格状态*/
cc++;/*开始统计尝试次数*/
if(cc>=64-score1-score2) /*如果尝试超过空格数则停步*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
break;
}
else
continue;/*如果按键无效*/
}
DoScore();/*分数的改变*/
break;/*棋盘变化了,则轮对方走棋*/
}
else/*已经有棋子就继续按键*/
continue;
}
else /*四个方向按键的判断*/
if(key==LEFT&&x>120)/*左方向键*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
SetPlayColor(t);
x-=40;
fillellipse(x,y,15,15);
}
else
if(key==RIGHT&&x<400&&y>80)/*右方向键*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
SetPlayColor(t);
x+=40;
fillellipse(x,y,15,15);
}
else
if(key==UP&&y>120)/*上方向键*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
SetPlayColor(t);
y-=40;
fillellipse(x,y,15,15);
}
else
if(key==DOWN&&y<400)/*下方向键*/
{
MoveColor(x,y);
fillellipse(x,y,15,15);
SetPlayColor(t);
y+=40;
fillellipse(x,y,15,15);
}
}
if(key==ESC)/*结束游戏*/
break;
if((score1+score2)==64||score1==0||score2==0)/*格子已经占满或一方棋子为0判断胜负*/
{
playWin();/*输出最后结果*/
break;
}
t=t%2+1; /*一方走后,改变棋子颜色即轮对方走*/
cc=0; /*计数值恢复为0*/
} /*endwhile*/
}
void SetPlayColor(int t)/*设置棋子颜色*/
{
if(t%2==1)
setfillstyle(SOLID_FILL,15);/*白色*/
else
setfillstyle(SOLID_FILL,8);/*灰色*/
}
void MoveColor(int x,int y)/*走了一步后恢复原来格子的状态*/
{
if(y<100)/*如果是从起点出发就恢复蓝色*/
setfillstyle(SOLID_FILL,BLUE);
else/*其他情况如果是1就恢复白色棋子,2恢复黑色棋子,或恢复蓝色棋盘*/
switch(a[(x-120)/40][(y-120)/40])
{
case 1:
setfillstyle(SOLID_FILL,15);break; /*白色*/
case 2:
setfillstyle(SOLID_FILL,8);break; /*黑色*/
default:
setfillstyle(SOLID_FILL,BLUE); /*蓝色*/
}
}
int QpChange(int x,int y,int t)/*判断棋盘的变化*/
{
int i,j,k,kk,ii,jj,yes;
yes=0;
i=(x-120)/40; /*计算数组元素的行下标*/
j=(y-120)/40; /*计算数组元素的列下标*/
SetPlayColor(t);/*设置棋子变化的颜色*/
/*开始往8个方向判断变化*/
if(j<6)/*往右边*/
{
for(k=j+1;k<8;k++)
if(a[i][k]==a[i][j]||a[i][k]==0)/*遇到自己的棋子或空格结束*/
break;
if(a[i][k]!=0&&k<8)
{
for(kk=j+1;kk<k&&k<8;kk++)/*判断右边*/
{
a[i][kk]=a[i][j]; /*改变棋子颜色*/
fillellipse(120+i*40,120+kk*40,15,15);
}
if(kk!=j+1) /*条件成立则有棋子改变过颜色*/
yes=1;
}
}
if(j>1)/*判断左边*/
{
for(k=j-1;k>=0;k--)
if(a[i][k]==a[i][j]||!a[i][k])
break;
if(a[i][k]!=0&&k>=0)
{
for(kk=j-1;kk>k&&k>=0;kk--)
{
a[i][kk]=a[i][j];
fillellipse(120+i*40,120+kk*40,15,15);
}
if(kk!=j-1)
yes=1;
}
}
if(i<6)/*判断下边*/
{
for(k=i+1;k<8;k++)
if(a[k][j]==a[i][j]||!a[k][j])
break;
if(a[k][j]!=0&&k<8)
{
for(kk=i+1;kk<k&&k<8;kk++)
{
a[kk][j]=a[i][j];
fillellipse(120+kk*40,120+j*40,15,15);
}
if(kk!=i+1)
yes=1;
}
}
if(i>1)/*判断上边*/
{
for(k=i-1;k>=0;k--)
if(a[k][j]==a[i][j]||!a[k][j])
break;
if(a[k][j]!=0&&k>=0)
{
for(kk=i-1;kk>k&&k>=0;kk--)
{
a[kk][j]=a[i][j];
fillellipse(120+kk*40,120+j*40,15,15);
}
if(kk!=i-1)
yes=1;
}
}
if(i>1&&j<6)/*右上*/
{
for(k=i-1,kk=j+1;k>=0&&kk<8;k--,kk++)
if(a[k][kk]==a[i][j]||!a[k][kk])
break;
if(a[k][kk]&&k>=0&&kk<8)
{
for(ii=i-1,jj=j+1;ii>k&&k>=0;ii--,jj++)
{
a[ii][jj]=a[i][j];
fillellipse(120+ii*40,120+jj*40,15,15);
}
if(ii!=i-1)
yes=1;
}
}
if(i<6&&j>1)/*左下*/
{
for(k=i+1,kk=j-1;k<8&&kk>=0;k++,kk--)
if(a[k][kk]==a[i][j]||!a[k][kk])
break;
if(a[k][kk]!=0&&k<8&&kk>=0)
{
for(ii=i+1,jj=j-1;ii<k&&k<8;ii++,jj--)
{
a[ii][jj]=a[i][j];
fillellipse(120+ii*40,120+jj*40,15,15);
}
if(ii!=i+1)
yes=1;
}
}
if(i>1&&j>1)/*左上*/
{
for(k=i-1,kk=j-1;k>=0&&kk>=0;k--,kk--)
if(a[k][kk]==a[i][j]||!a[k][kk])
break;
if(a[k][kk]!=0&&k>=0&&kk>=0)
{
for(ii=i-1,jj=j-1;ii>k&&k>=0;ii--,jj--)
{
a[ii][jj]=a[i][j];
fillellipse(120+ii*40,120+jj*40,15,15);
}
if(ii!=i-1)
yes=1;
}
}
if(i<6&&j<6)/* 右下*/
{
for(k=i+1,kk=j+1;kk<8&&kk<8;k++,kk++)
if(a[k][kk]==a[i][j]||!a[k][kk])
break;
if(a[k][kk]!=0&&kk<8&&k<8)
{
for(ii=i+1,jj=j+1;ii<k&&k<8;ii++,jj++)
{
a[ii][jj]=a[i][j];
fillellipse(120+ii*40,120+jj*40,15,15);
}
if(ii!=i+1)
yes=1;
}
}
return yes;/*返回是否改变过棋子颜色的标记*/
}
void DoScore()/*处理分数*/
{
int i,j;
score1=score2=0;/*重新开始计分数*/
for(i=0;i<8;i++)
for(j=0;j<8;j++)
if(a[i][j]==1)/*分别统计两个人的分数*/
score1++;
else
if(a[i][j]==2)
score2++;
}
void PrintScore(int playnum)/*输出成绩*/
{
if(playnum==1)/*清除以前的成绩*/
{
setfillstyle(SOLID_FILL,BLUE);
bar(550,100,640,400);
}
setcolor(RED);
settextstyle(0,0,4);/*设置文本输出样式*/
if(playnum==1)/*判断输出哪个棋手的分,在不同的位置输出*/
{
sprintf(playone,"%d",score1);
outtextxy(550,200,playone);
}
else
{
sprintf(playtwo,"%d",score2);
outtextxy(550,300,playtwo);
}
setcolor(0);
}
void playWin()/*输出最后的胜利者结果*/
{
settextstyle(0,0,4);
setcolor(12);
if(score2>score1)/*开始判断最后的结果*/
outtextxy(100,50,"black win!");
else
if(score2<score1)
outtextxy(100,50,"white win!");
else
outtextxy(60,50,"you all win!");
}
6. C语言课程设计,贪吃蛇应该怎么做
2.1程序功能介绍
贪吃蛇游戏是一个经典小游戏,一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,同时记10分,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。
2.2程序整体设计说明
一个游戏要有开始部分,运行部分,结束部分(实际上开始部分与运行部分是一体的)。
2.2.1设计思路
这个程序的关键是表示蛇的图形以及蛇的移动。用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示。移动时必须从蛇头开始,所以蛇不能向相反方向移动,也就是蛇尾不能改作蛇头。如果不按任何键,蛇自行在当前方向上前移,当游戏者按了有效的方向键后,蛇头朝着指定的方向移动,一步移动一节身体,所以当按了有效的方向键后,先确定蛇头的位置,然后蛇身体随着蛇头移动,图形的实现是从蛇头的新位置开始画出蛇,这时由于没有庆平的原因,原来蛇的位置和新蛇的位置差一个单位,所以看起来社会多一节身体,所以将蛇的最后一节用背景色覆盖。食物的出现和消失也是画矩形块和覆盖矩形块
2.2.2数据结构设计及用法说明
开始部分:
游戏是运行在图形模式下的,所以第一步一定是初始化图形模式,接着要有开始的界面,就像书有封面一样,我设置了一个游戏的标题画面,除了游戏标题画面我还设置了一个欢迎画面。标题画面以后,还要为游戏的运行部分作初始化,包括绘制游戏运行时的背景,对游戏某些重 要变量的初始化。
运行部分:
作为游戏的核心部分,这里包括的函数比较多,也就是模块比较多,首先让我模拟一下贪吃蛇的游戏模式:某个世界上突然出现一条蛇,它很短,它的运动神经异常,它没法停止自己的多动症在它的世界里就只有食物,它很饿,也很贪吃;同样在不明原因的情况下,食物从天而降,可惜的是没有落到嘴边;饥饿的主人公,不管它有没有毒,也不问食物的来历,径直向食物爬去;它吃到食物啦,它超出想象的同化能力让食物很快的成为自己身体的一部分,它的身子变长啦。当它吃到第一颗食物时,上帝有给它第二颗,于是它吃了第二颗,于是又变长了,于是又有第三颗……它的身子是一直的加长,它不管自己过长身体的麻烦——转身不便,继续吃下去,现在它是直接把巴张大,好让食物有个绿色通道。但是在某天的下午,它咬到了自己,它才想起自己是一条毒蛇,于是晕死过去(不是毒死);又或者它往食物冲锋的时候,它失去控制,撞到了墙上。
第一轮循环:第一步,出现食物;第二步,蛇不停运动;第三步,检查蛇是撞到自己或墙壁;由第四步起游戏有两条支线(A、B):
A :第四步,蛇没有碰到自己或墙壁,蛇继续前进,绘制蛇的动作;第五步,判断蛇是否吃到食物,如果蛇吃到食物,身子变长,原来的食物消失;第六步,让玩家输入控制指令,让蛇在下一轮循环的第二步改变运动方向;第七步,第二轮循环的第一步,重复第一轮的步骤;
B:第四步,蛇碰到自己或墙壁,终止游戏。
结束部分:
游戏结束时,显示“GAME OVER”,已经是约定俗成的规律了,我的游戏也不例外。除了游戏结束画面外,我还设置了一个游戏退出画面,“善始善终”嘛。
有了上述的大致划分,我把整个程序划分成(13+2)个模块(其实就是函数)
2.2.3程序结构(流程图)
图2.1流程图
依据所需要处理的任务要求,规划输入数据和输出结果,决定存放数据的数据结构。
C语言中数据结构集中体现在数据类型上,因此在进行C语言程序设计时,应统筹规划程序中所使用的变量,数组,指针等,以及它们的类型等。这点是很重要的,如果在此期间选择不合适的变量或者数组,将来修改就十分困难。
现在分析一下贪吃蛇游戏中的元素,继而得出与它们对应的在程序中的描述:
蛇:
基本描述:长度,颜色,位置。
对应数据与数据类型:长度—虽然可以用坐标表示,但是这样的话,运算量将很大,所以换算成较大的单位—节数,以固定长度的每节描述;坐标--整型;颜色--整型; 位置--X,Y坐标。
增加的描述:蛇运动的方向,蛇的生命。
对应数据与数据类型:这些描述是为了与程序的按键的输入部分与判断游戏结束部分相联系而设的。方向只有四个方向:上下左右。可以设置与之对应的四个整型数:3、4、2、1。生命就只有两种情况:死或生,对应0或1。
食物:
基本描述:颜色,位置。
对应数据与数据类型:由于颜色设成固定的,所以不再讨论。位置—X、Y坐标。
增加的描述:食物的存在。
对应数据与数据类型:这是为了避免重复出现食物而设置的,与绘制食物的函数有联系。只有两个值:0或1(没有食物或有食物)
其他的元素:墙,由于它在显示上是作为背景而存在的,所以并没有什么说明实际的墙壁就是四条直线组成的边框,由坐标描述。
还需要的变量:键盘键入的键值(作为全局变量,整型);经常要使用的循环变量;自定义的填充图案;说明文字的字符数组;游戏的记分;游戏的速度(蛇的速度)。
图2.2蛇的不停运动的关键算法的流程图
2.2.4各模块的功能及程序说明
主要模块的实现思路和算法的流程图说明:
关键所在——蛇不停移动的Snakemove():
蛇的不停移动,就是蛇的下一节取代前一节的位置,在计算机中就是蛇下一节的位置坐标变成前一节的位置坐标。在上文中,已定义蛇的位置坐标为数组类型,一组坐标对应一节的位置,假设有i+1节,由0到i节,第i节的坐标取第i-1节的坐标,第i-1节的坐标取第i-2节的坐标……直到第1节取第0节的坐标。而第0节的坐标,即蛇头的坐标要往某个方向变化,变化量为蛇每节的长度。蛇的这种坐标轮换需要循环语句使其继续下去。
2.2.5程序结果
运行程序得到如下初始界面图:
图2.3程序结果图
用一个小矩形表示蛇的一节身体,身体每长一节,增加一个矩形块,蛇头用两节表示:
图2.4程序结果图
蛇没有碰到自己或墙壁,蛇继续前进:
图2.5程序结果图
游戏结束时,显示“GAME OVER”
图2.6程序结果图
2.3程序源代码及注释
#define N 200
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
int i,key;
int score=0;/*得分*/
int gamespeed=50000;/*游戏速度自己调整*/
struct Food{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
struct Snake{
int x[N];
int y[N];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
}snake;
void Init(void);/*图形驱动*/
void Close(void);/*图形结束*/
void DrawK(void);/*开始画面*/
void GameOver(void);/*结束游戏*/
void GamePlay(void);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
/*主函数*/
void main(void){
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/}
/*图形驱动*/
void Init(void){
int gd=DETECT,gm;
registerbgidriver(EGAVGA_driver);
initgraph(&gd,&gm,"c:\program files\winyes\tc20h\bgi");
cleardevice();}
/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/
void DrawK(void){
/*setbkcolor(LIGHTGREEN);*/
setcolor(11);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
for(i=50;i<=600;i+=10)/*画围墙*/ {
rectangle(i,40,i+10,49); /*上边*/
rectangle(i,451,i+10,460);/*下边*/ }
for(i=40;i<=450;i+=10) {
rectangle(50,i,59,i+10); /*左边*/
rectangle(601,i,610,i+10);/*右边*/ }}
/*玩游戏具体过程*/
void GamePlay(void){
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=100;snake.y[0]=100;/*蛇头*/
snake.x[1]=110;snake.y[1]=100;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/ {
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/ {
if(food.yes==1)/*需要出现新食物*/ {
food.x=rand()%400+60;
food.y=rand()%350+60;
while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*画面上有食物了*/ }
if(food.yes==0)/*画面上有食物了就要显示*/ {
setcolor(GREEN);
rectangle(food.x,food.y,food.x+10,food.y-10); }
for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/ {
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1]; }
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction) {
case 1:snake.x[0]+=10;break;
case 2: snake.x[0]-=10;break;
case 3: snake.y[0]-=10;break;
case 4: snake.y[0]+=10;break; }
for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/ {
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]) {
GameOver();/*显示失败*/
snake.life=1;
break; } }
if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||
snake.y[0]>455)/*蛇是否撞到墙壁*/ {
GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/ }
if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/ {
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,food.y,food.x+10,food.y-10);
snake.x[snake.node]=-20;snake.y[snake.node]=-20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
PrScore();/*输出新得分*/ }
setcolor(4);/*画出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+10,
snake.y[i]-10);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+10,snake.y[snake.node-1]-10); } /*endwhile(!kbhit)*/
if(snake.life==1)/*如果蛇死就跳出循环*/
break;
key=bioskey(0);/*接收按键*/
if(key==ESC)/*按ESC键退出*/
break;
else
if(key==UP&&snake.direction!=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
}/*endwhile(1)*/}
/*游戏结束*/
void GameOver(void){
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(200,200,"GAME OVER");
getch();}
/*输出成绩*/
void PrScore(void){
char str[10];
setfillstyle(SOLID_FILL,YELLOW);
bar(50,15,220,35);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:%d",score);
outtextxy(55,20,str);}
/*图形结束*/
void Close(void){
getch();
closegraph();
}
7. 怎样用C语言编写一个小游戏
“贪吃蛇”C代码:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <Windows.h>
#define W 78 //游戏框的宽,x轴
#define H 26 //游戏框的高,y轴
int dir=3; //方向变量,初值3表示向“左”
int Flag=0; //吃了食物的标志(1是0否)
int score=0; //玩家得分
struct food{ int x; //食物的x坐标
int y; //食物的y坐标
}fod; //结构体fod有2个成员
struct snake{ int len; //身长
int speed; //速度
int x[100];
int y[100];
}snk; //结构体snk有4个成员
void gtxy( int x,int y) //控制光标移动的函数
{ COORD coord;
coord.X=x;
coord.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void gtxy( int x,int y); //以下声明要用到的几个自编函数
void csh( ); //初始化界面
void keymove( ); //按键操作移动蛇
void putFod( ); //投放食物
int Over( ); //游戏结束(1是0否)
void setColor(unsigned short p, unsigned short q); //设定显示颜色
int main( ) //主函数
{ csh( );
while(1)
{ Sleep(snk.speed);
keymove( );
putFod( );
if(Over( ))
{system(“cls”);
gtxy(W/2+1,H/2); printf(“游戏结束!T__T”);
gtxy(W/2+1,H/2+2); printf(“玩家总分:%d分”,score);
getch( );
break;
}
}
return 0;
}
void csh( ) //初始化界面
{ int i;
gtxy(0,0);
CONSOLE_CURSOR_INFO cursor_info={1,0}; //以下两行是隐藏光标的设置
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
for(i=0;i<=W;i=i+2) //横坐标要为偶数,因为这个要打印的字符占2个位置
{ setColor(2, 0); //设定打印颜色为绿字黑底
gtxy(i,0); printf("■"); //打印上边框
gtxy(i,H); printf("■"); //打印下边框
}
for(i=1;i<H;i++)
{ gtxy(0,i); printf("■"); //打印左边框
gtxy(W,i); printf("■"); //打印右边框
}
while(1)
{ srand((unsigned)time(NULL)); //初始化随机数发生器srand( )
fod.x=rand()%(W-4)+2; //随机函数rand( )产生一个从0到比”(W-4)”小1的数再加2
fod.y=rand()%(H-2)+1; //随机函数rand( )产生一个从0到比”(H-2)”小1的数再加1
if (fod.x%2==0) break; //fod.x是食物的横坐标,要是2的倍数(为偶数)
}
setColor(12, 0); //设定打印颜色为淡红字黑底
gtxy(fod.x,fod.y); printf("●"); //到食物坐标处打印初试食物
snk.len=3; //蛇身长
snk.speed=350; //刷新蛇的时间,即是移动速度
snk.x[0]=W/2+1; //蛇头横坐标要为偶数(因为W/2=39)
snk.y[0]=H/2; //蛇头纵坐标
setColor(9, 0); //设定打印颜色为淡蓝字黑底
gtxy(snk.x[0], snk.y[0]); printf("■"); //打印蛇头
for(i=1;i<snk.len;i++)
{ snk.x[i]=snk.x[i-1]+2; snk.y[i]=snk.y[i-1];
gtxy(snk.x[i],snk.y[i]); printf("■"); //打印蛇身
}
setColor(7, 0); //恢复默认的白字黑底
return;
}
void keymove( ) //按键操作移动蛇
{ int key;
if( kbhit( ) ) //如有按键输入才执行下面操作
{ key=getch( );
if (key==224) //值为224表示按下了方向键,下面要再次获取键值
{ key=getch( );
if(key==72&&dir!=2)dir=1; //72表示按下了向上方向键
if(key==80&&dir!=1)dir=2; //80为向下
if(key==75&&dir!=4)dir=3; //75为向左
if(key==77&&dir!=3)dir=4; //77为向右
}
if (key==32)
{ while(1) if((key=getch( ))==32) break; } //32为空格键,这儿用来暂停
}
if (Flag==0) //如没吃食物,才执行下面操作擦掉蛇尾
{ gtxy(snk.x[snk.len-1],snk.y[snk.len-1]); printf(" "); }
int i;
for (i = snk.len - 1; i > 0; i--) //从蛇尾起每节存储前一节坐标值(蛇头除外)
{ snk.x[i]=snk.x[i-1]; snk.y[i]=snk.y[i-1]; }
switch (dir) //判断蛇头该往哪个方向移动,并获取最新坐标值
{ case 1: snk.y[0]--; break; //dir=1要向上移动
case 2: snk.y[0]++; break; //dir=2要向下移动
case 3: snk.x[0]-=2; break; //dir=3要向左移动
case 4: snk.x[0]+=2; break; //dir=4要向右移动
}
setColor(9, 0);
gtxy(snk.x[0], snk.y[0]); printf("■"); //打印蛇头
if (snk.x[0] == fod.x && snk.y[0] == fod.y) //如吃到食物则执行以下操作
{ printf("