黑白棋游戏课程设计.docx

上传人:b****3 文档编号:4980051 上传时间:2022-12-12 格式:DOCX 页数:23 大小:864.44KB
下载 相关 举报
黑白棋游戏课程设计.docx_第1页
第1页 / 共23页
黑白棋游戏课程设计.docx_第2页
第2页 / 共23页
黑白棋游戏课程设计.docx_第3页
第3页 / 共23页
黑白棋游戏课程设计.docx_第4页
第4页 / 共23页
黑白棋游戏课程设计.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

黑白棋游戏课程设计.docx

《黑白棋游戏课程设计.docx》由会员分享,可在线阅读,更多相关《黑白棋游戏课程设计.docx(23页珍藏版)》请在冰豆网上搜索。

黑白棋游戏课程设计.docx

黑白棋游戏课程设计

湖南文理学院课程设计报告

 

课程名称:

计算机软件技术基础

学院:

电气与信息工程学院

专业班级:

通信08102班

*********************************

学号:

200816020210

*************************

完成时间:

2010年12月29日

报告成绩:

 

评阅意见:

 

 

 

 

 

 

 

 

 

 

 

评阅老师:

评阅时间:

 

《黑白棋游戏》C语言课程设计

一、设计目的

本课程设计是计算机软件技术基础重要的实践性环节之一,是在学生学习完《程序设计语言(C)》课程后进行的一次全面的综合练习。

本课程设计的目的和任务:

(1)巩固和加深学生对C语言课程的基本知识的理解和掌握;

(2)掌握C语言编程和程序调试的基本技能;

(3)利用C语言进行基本的软件设计,掌握软件设计一般方法,了解软件设计的思路;

(4)掌握书写程序设计报告的能力;

(5)提高运用C语言解决实际问题的能力;

这个程序也是对编程基本功的一个训练,对于初学C语言的人,讲分支、循环、数组函数综合应用,而不仅限于编制独立的小程序,能够大大提高变成水平。

二、设计要求

(1)收集资料,全面分析课题,分解问题,形成中体编程思路;

(2)深入分析各个小问题,编写个部分程序模块;

(3)对于设计中用到的关键函数,要联系实际问题进行具体介绍;

(4)上机调试,确保程序能正确运行;

(5)设计完成后提交课程设计报告;

三、所需仪器设备

(1)硬件要求能运行Windows2000/XP操作系统的微机系统。

(2)C语言程序设计及相应的开发环境。

(本设计用的是TurboCforWindows集成实验与学习环境V6.0)

四、课题分析

编写一个《黑白棋游戏》的C程序,包括以下功能:

初始状态:

在一个8*8的棋盘中央交叉排放黑白棋子各两枚,白棋先走。

(1)每个棋手下棋时,摆子的位置必须是以自己的棋子能包围住对方一个或多个棋子,被包围住的对方棋子将成为自己的棋子。

包围的方向可以是上下左右以及斜线8个方向,只要能连成一线即可。

(2)当轮到某一个棋手下子,但是他没有可以包围对方棋子的位置时,他必须停步,让对方走棋,直到他可以走为止。

(3)当棋盘上一方的棋子为0或者下满64格,游戏结束,棋子少者输。

五、具体设计过程

5.1、设计思路

程序界面应是一个二维平面图,所以数据的表示用二维数组,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格中的状态,共有三种情况,分别是空格、黑棋和白棋。

这样给数组元素的取值设定为0、1、2,其中0代表空格,1代表白色棋子,2代表黑色棋子。

这样程序的主要工作是接收棋手按键操作,一旦接收到回车键,说明棋手摆子,先判断是不是有效位置,也就是能不能包围住对方棋子,如果能,便为棋子所在的位置往上下、左右、左上、左下、右上、右下8个方向寻找被包围住的所有棋子(必须是连续的,中间不能有空格),将这些被包围住的对方棋子都变成自己的棋子,然后对当前棋盘中的黑白棋个数进行统计并输出结果。

如果没有这样的位置可以落子,则停步,让对方走棋,重复上述步骤,直到游戏结束。

如果想提前终止游戏,可以按Esc键。

5.2、程序设计流程图

(1)程序整体组成结构框图如下图所示:

图1程序整体组成结构框图

(2)由上述设计思路可画出程序整体流程图,如下图所示:

图2程序整体流程图

(3)人人对战模块程序流程图如下图所示:

图3人人对战模块流程图

(4)成绩输出模块程序流程图如下图所示

图4成绩输出模块程序流程图

5.3、函数实现说明

(1)main()主函数

在主函数中,首先定义使用到的常数、全局变量、函数原型说明。

盘状态用数组a[8][8],初值为0,表示空格。

函数的实体部分,开始初始化图形系统,然后通过调用函数DrawQp()先画出棋盘,调用playtoplay()人人对战函数开始游戏,一旦游戏结束后,关闭图形系统,程序结束。

(2)DrawQp()画棋盘函数

背景颜色设为蓝色,从坐标(100,100)开始每隔40个单位用白色画一条水平直线,一条垂直线,构成棋盘,用循环语句实现。

函数setfillstyle()可以设置填充模式和填充颜色,fillellipse(intx,inty,xradius,intyradius)以x和y为圆心,xradius和yradius为水平和垂直轴画一填充椭圆,当xradius和yradius相等时,则画出的是圆,用它表示棋子。

(3)SetPlayColor()设置棋子的颜色

函数的参数为整型变量t,根据t的值来设计填充棋子的当前颜色,值为1代表白棋,值为2代表黑棋。

(4)MoveColor()恢复原来格子的状态

由于棋手在走棋的时候,他的棋子总是首先出现在棋盘的左上角,棋手要通过移动光标走到要落子的位置,在经过的路程上显示当前棋子,就会覆盖原来的棋盘状态,所以一旦棋子走过后,就应恢复原来的状态,是空格的依然显示空格,是棋子的就显示原来棋子的颜色。

因为棋子移动过程并没有改变数组元素的值,所以可以根据数组元素的值判定原来的状态,如果值是1,就恢复白色棋子,值是2则恢复黑色棋子,否则恢复蓝色空格。

(5)、playtoplay()人人对战函数

这是游戏进行的函数,主要是接收棋手的按键消息,其处理过程如下:

1)按Esc键程序可以随时结束。

2)按上下左右光标键,则改变棋子移动的坐标值。

3)按回车键后判断:

①如落子的位置已经有棋则无效,继续压键。

②如落子位置是空格,可以将棋子落入格内,调用函数QpChange()判断是否引起棋盘的变化,函数值为1有变化,为0没变化。

如果棋盘有变化,说明将包围的对方棋子吃掉,统计当前分数,如果棋盘没有变化,则说明落子的位置无法包围对方的棋子也视为无效棋,可以继续寻找合适的位置,但开始统计其落子次数,一旦尝试次数超过当前棋盘的空格数,则说明他无棋可走,则放弃此步,让对方下棋。

③如果棋子变化后,格子已占满64格或一方棋子为0,则游戏结束,显示胜利方信息。

按任意键程序结束。

④重复上述步骤,直到游戏结束。

(6)、QpChange()判断棋盘变化

当棋手按回车键落子后,就要分别往8个方向判断是否包围住对方棋子,如果是,则改变棋盘,也就是棋盘上黑白棋子的个数要发生变化。

如果所有方向都判断过,并且没有引起棋盘的变化,则棋盘变化标志值yes为0,返回yes,结束本函数。

(7)、DoScore()处理分数

根据当前数组元素的值判断分数,也就是各方棋子的个数,如果数组元素值为1,白棋棋子数累加;如果数组元素值为2,则黑棋棋子数累加。

(8)、PrintScore()输出成绩

利用设置实体填充模式填充矩形条清除掉前次的成绩,再利用sprintf()函数将整数转换为字符串的形式,再利用outtextxy()函数将成绩输出。

(9)、playWin()输出胜利者结果

根据分数值score1和score2的大小得出下棋的结果,输出赢者信息。

如果是白方胜就输出“whitewin!

”,黑方胜就输出“blackwin!

”,平局就输出“youallwin!

”。

5.4、图形库函数介绍

图形库是TC里面的图形库,分为:

像素函数、直线和线型函数、多边形函数、填充函数等。

在本程序中主要应用到了以下功能函数:

(1)、line()画线函数

  功能:

函数line()使用当前绘图色、线型及线宽,在给定的两点间画一直线。

  函数原型:

voidline(intstartx,intstarty,intendx,intendy);

  说明:

参数startx,starty为起点坐标,endx,endy为终点坐标,函数调用前后,图形状态下屏幕光标(一般不可见)当前位置不改变。

(2)、setcolor()图形屏幕函数

  函数原型:

voidsetcolor(intcolor)

功能:

将当前图形屏幕的当前笔画颜色置为color.

(3)、setfillstyle()设置填充图样和颜色函数

函数原型:

voidfarsetfillstyle(intpattern,intcolor);

功能:

设置填充模式和颜色

(4)、fillellipse()画椭圆区函数

  功能:

画出并填充一椭圆

  函数原型:

voidfarfillellipse(intx,inty,intxradius,intyradius);

说明:

填充边框所定义的椭圆的内部,该边框由一对坐标、一个宽度和一个高度指定。

(5)、setbkcolor()

功能:

该函数用指定的颜色值来设置当前的背景色

函数原型:

VoidfarSetBkColor(intColor);

(6)、C语言中的颜色表及填充模式如下两表所示:

 

5.5、程序源代码及注释

#include"graphics.h"/*图形系统头文件*/

#defineLEFT0x4b00/*光标左键值*/

#defineRIGHT0x4d00/*光标右键值*/

#defineDOWN0x5000/*光标下键值*/

#defineUP0x4800/*光标上键值*/

#defineESC0x011b/*ESC键值*/

#defineENTER0x1c0d/*回车键值*/

inta[8][8]={0},key,score1,score2;/*具体分数以及按键与存放棋子的变量*/

charplayone[3],playtwo[3];/*两个人的得分转换成字符串输出*/

voidplaytoplay(void);/*人人对战函数*/

voidDrawQp(void);/*画棋盘函数*/

voidSetPlayColor(intx);/*设置棋子第一次的颜色*/

voidMoveColor(intx,inty);/*恢复原来棋盘状态*/

intQpChange(intx,inty,intz);/*判断棋盘的变化*/

voidDoScore(void);/*处理分数*/

voidPrintScore(intn);/*输出成绩*/

voidplayWin(void);/*输出胜利者信息*/

/******主函数*********/

voidmain(void)

{

intgd=DETECT,gr;

initgraph(&gd,&gr,"c:

\\tc");/*初始化图形系统*/

DrawQp();/*画棋盘*/

playtoplay();/*人人对战*/

getch();

closegraph();/*关闭图形系统*/

}

voidDrawQp()/*画棋盘*/

{

inti,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();/*输出开始分数*/

}

voidplaytoplay()/*人人对战*/

{

intx,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*/

}

voidSetPlayColor(intt)/*设置棋子颜色*/

{

if(t%2==1)

setfillstyle(SOLID_FILL,15);/*白色*/

else

setfillstyle(SOLID_FILL,8);/*灰色*/

}

voidMoveColor(intx,inty)/*走了一步后恢复原来格子的状态*/

{

if(y<100)/*如果是从起点出发就恢复蓝色*/

setfillstyle(SOLID_FILL,BLUE);

else/*其他情况如果是1就恢复白色棋子,2恢复黑色棋子,或恢复蓝色棋盘*/

switch(a[(x-120)/40][(y-120)/40])

{

case1:

setfillstyle(SOLID_FILL,15);break;/*白色*/

case2:

setfillstyle(SOLID_FILL,8);break;/*黑色*/

default:

setfillstyle(SOLID_FILL,BLUE);/*蓝色*/

}

}

intQpChange(intx,inty,intt)/*判断棋盘的变化*/

{

inti,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

{

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

{

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

{

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

{

a[ii][jj]=a[i][j];

fillellipse(120+ii*40,120+jj*40,15,15);

}

if(ii!

=i+1)

yes=1;

}

}

returnyes;/*返回是否改变过棋子颜色的标记*/

}

voidDoScore()/*处理分数*/

{

inti,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++;

}

voidPrintScore(intplaynum)/*输出成绩*/

{

if(playnum==1)/*

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1