益智游戏作为人类社会发展和创新的必然产物,已经被越来越多的人们所重视它寓教于乐,以轻松愉快的方式让人们在娱乐中学习,在学习中娱乐,在欢乐中得到思维能力的训练我国目前正处在素质教育改革的风头浪尖,益智游戏因其特殊性便成为了非常行之有效的辅助工具,其发展前景良好市场相当广阔。
1.设计题目
使用C语言及VC绘图库,在VC环境下,设计一个双人五子棋对战单机游戏,双方各执黑白一子,黑白双方轮流落子,直到某一方首先在棋盘的横线、纵线或斜线上形成连续五子,则该方就算获胜,游戏过程可以悔棋一步;要求友好的图形化界面、方便操作。
2.功能设计要求
根据五子棋游戏规则,项目设计有以下几点要求:
2.要求动态画出棋盘大小;
3.画棋子并确定其颜;
4.提示下棋规则;
5.玩家轮流下棋;
7.允许且只允许悔棋一步;
8.判断每局游戏输赢,显示每局游戏的获胜者及分数;
9.判断是否进行下一局;
10.判最终赢家(三局两胜)。
3.详细设计
功能模块图
根据功能设计要求,双人对战五子棋参考功能模块图如下所示:
图 201 双人对战功能模块图
数据结构
本项目涉及到的主要数据是存放棋局的二维数组,棋盘大小可以改变,利用宏定义实现如下:
#define N 10
int chess[N][N]={0};/*初值为0*/
chess的初值为0,chess[i][j]值为1表示该处落的是白子;chess[i][j]值为2,表示该处落的是黑子。白棋子率先在一条直线上值都为1,白棋子赢;黑棋子率先一条直线上值都为2,黑子赢。当完成当前局,开始下一局时,chess重新赋值为0。
系统流程图
根据系统功能设计要求,系统参考流程图如下所示:
图 202 双人对战单机游戏系统流程图
主要函数及算法的设计与实现
1.判断是否五子相连函数
函数原型:
⑴ int Game_Over1( int a[10][10],int chess_symbol )/* 判断五子相连是否是"—"形或者"|"形(事实上"-"与"|"关于"\"对称) */
⑵ int Game_Over2( int a[10][10],int chess_symbol )/*判断五子相连是否是"\"形*/
⑶ int Game_Over3( int a[10][10],int chess_symbol )/*判断五子相连是否是"/"形*/
功能:判断某一方是否有5个棋子在一条直线上,分别有“—”,“ |”, “/”,“ \”四种情况。
参数:存方棋盘信息的参数a;判断是不是四种直线“—”,“ |”, “/”,“ \”中的一种chess_symbol。
返回值:如果判断的确是某一方五子相连,则返回1,否则返回0。
要求:棋盘是用二维数组来存放的,利用双重循环遍历整个二维数组。
参考函数如下:
int Game_Over1( int a[10][10],int chess_symbol )/* "—"形或者"|"形(事实上"-"超级管道与"|"关于"\"对称) */
{
int i,j,k,l,r;
for( i=0; i < N; i++ )
for( k=0; k < N-4; k++ )
{
l=r=0;
for( j=k; j < k+5; j++ )
{
if( a[i][j] == chess_symbol )/* "-"形*/
l++;
if( a[j][i] == chess_symbol )/* "|"形*/
r++;
}
if( l == 5 || r == 5 )/*连续的个棋子在一条直线上时,游戏结束*/
return 1; }
return 0;
}
int Game_Over2( int a[10][10] ,int chess_symbol )/* "\"形*/
{
int i,j,k,m,LeftDown,RightUp;
for( m=0; m < N-4; m++ )
光栅化
for( k=0; k < N-4-m; k++ )
{
RightUp=LeftDown=0;
for( i=k ,j=k+m; i < k+5; i++ ,j++ )
半有源电子标签
{
if( a[i][j] == chess_symbol )/* 对角线"\"上及其右上方的"\"形*/
RightUp++;
if( a[j][i] == chess_symbol )/* 对角线"\"上及其左下方的"\"形*/
LeftDown++;
}
if( RightUp == 5 || LeftDown == 5 )
return 1;
}
return 0;
}
int Game_Over3( int a[10][10] ,int chess_symbol )/* "/"形*/
{
int i,j,k,m,LeftUp,RightDown;
for( m=N-1; m >= 4; m-- )
for( k=0; k < m + 1 - 4; k++ )
{
RightDown=LeftUp=0;
for( i=k ,j= m - k; i < k+5; i++ ,j-- )
{
if( a[i][j] == chess_symbol )/*对角线"/"上及其左上方的"/"形*/
LeftUp++;
if视频直播技术方案( a[N-1-j][N-1-i] == chess_symbol )/*对角线"/"上及其右下方的"/"形*/
RightDown++;
}
if( RightDown == 5 || LeftUp == 5 )
return 1;
}
return 0;
}
2.画棋盘
函数原型:void MainFace( )
功能:画五子棋棋盘。
要求:利用第二章VC绘图库知识,画五子棋和棋盘。
参考代码:
void MainFace()
{
int x;
initgraph(500,500);/*生成一个,区域*/
setbkcolor(LIGHTGRAY); cleardevice();/*背景设置为白*/
setcolor(RED);/*画图颜是红*/
for(x=0;x<=500;x=x+50)/*画棋盘格波盘*/
{
line(x,0,x,500);
line(0,x,500,x);
}
}
五子棋游戏界面如下图所示:
图 203 五子棋图形界面设计
3.鼠标相应操作算法
算法思想:判断该谁下棋?落子后是否悔棋?落子后该局是否胜出?落子后是否确的最后胜利?
参考代码实现:
while (true)/*响应鼠标操作*/
{
m = GetMouseMsg();
if(m.uMsg==WM_LBUTTONDOWN)
{
x=m.x%50;if(x<=25)m.x=m.x-x;else m.x=m.x+(50-x);
y=m.y%50;if(y<=25)m.y=m.y-y;else m.y=m.y+(50-y);
i=m.x/50;j=m.y/50;
if (chess[i][j]!=0)/*防止在一个地方重复下棋子chess[i][j]==1 为白子 chess[i][j]==1 为黑子*/
continue;
if(n==1)/*判断该谁下棋*/
{
setcolor(WHITE);
setfillstyle(WHITE);
fillellipse(m.x,m.y,10,10);
chess[i][j]=1; if(Game_Over1(chess,1)==1||Game_Over2(chess,1)==1||Game_Over2(chess,1)==1)
{
setcolor(BLACK);outtextxy(200,200,"此局白子胜利");
v[0]++; if(v[0]==2)
{ outtextxy(200,300,"3局胜,白子胜局,白子胜出"); break;}
outtextxy(250,250,"是否继续下棋:Y OR N");
ch= getch();
if(ch=='N') break;
else{
for(i=0;i<N;i++)
for(j=0;j<N;j++)
chess[i][j]=0;
setbkcolor(LIGHTGRAY); cleardevice();/*背景设置为白*/
setcolor(RED);/*画图颜是红*/
for(x=0;x<=500;x=x+50)/*画棋盘格*/
{ line(x,0,x,500);
line(0,x,500,x);
}
}
}
n=2;/*换方下子*/
}
else
{ chess[i][j]=2;
setcolor(BLACK);
setfillstyle(BLACK);
fillellipse(m.x,m.y,10,10); if(Game_Over1(chess,2)==1||Game_Over2(chess,2)==1||Game_Over2(chess,2)==1)
{
setcolor(BLACK);outtextxy(200,200,"此局黑子胜利"); v[1]++;
if(v[1]==2){ outtextxy(200,200,"3局胜,黑子胜局,黑子胜出"); break;}
outtextxy(250,250,"是否继续下棋:Y OR N");
ch= getch();
if(ch=='N') break;
else{
for(i=0;i<N;i++)
for(j=0;j<N;j++)
chess[i][j]=0;
3d眼镜制作
setbkcolor(LIGHTGRAY); cleardevice();/*背景设置为白*/
setcolor(RED);/*画图颜是红*/
for(x=0;x<=500;x=x+50)/*画棋盘格*/
{ line(x,0,x,500);
line(0,x,500,x);
}
}
}
n=1;
}
}
if(m.uMsg==WM_RBUTTONUP) break;/*右键结束*/