黑白棋C语言课程设计

更新时间:2024-05-18 16:55:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

摘要

黑白棋(REVERSI、OTHELLO),也叫苹果棋,翻转棋,是一个经典的策略性游戏。它使用8*8的棋盘,由两人执黑子和白子轮流下棋,最后子多方为胜方。轮到一方下棋时,必须把棋下在与对方棋子相邻的空位上,要求所下的棋子和原有的已方棋子夹住对方的至少一个棋子(横竖斜夹均可),然后把被夹住的子变成己方的颜色(也叫吃子)。下棋过程中,任何棋子既不会从棋盘上拿走,也不会从一个格子移到另一个格子。

黑白棋规则简单,但是变化复杂,是典型的易学难精(A MINUTE TO LEARN, A LIFETIME TO MASTER),它看似简单,实际奥妙无穷。

一般说来,下棋过程中,你必须尽量削减对手的行动力,同时增加自己的行动力,这种策略我们称之为行动力原则(或行动力战术)。当一方达到或接近这个目标时,我们就称该棋手控制了棋局。另外,这个战术的目的是迫使对方下坏棋,如果对方虽然可选位置很少,但每一步却总有好棋,那战术目的就没有达成。记住,你必须让对方完全无好棋可下。

黑白棋规则规定只能在对方棋子相邻的空位下棋,这就可以推出另一个原则。对方棋子边上的空位越多,你下棋的选择也就越多,换句话说,你的行动力就越强;相反,如果你棋子边上的空位越少,对方可下的位置也就越少。我们把相邻位置上有空位的子称为外子,反之称为内子,连在一起的外子称为前线或墙。下棋时要尽量减少自己的外子。

关键字:黑白棋,C语言,数组,函数

1

黑白棋游戏

一、课程设计目的

1. 巩固和加深学生对C语言课程的基本知识的理解和掌握 2. 掌握C语言编程和程序调试的基本技能 3. 利用C语言进行基本的软件设计 4. 提高运用C语言解决实际问题的能力

5. 掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能。

二、实验器材及实验环境

硬件环境:装有Windows 2000或以上系统的微机系统 软件环境:Turbo C 2.0软件

三、黑白棋的总体设想

1.设计思路

从已知的黑白棋游戏中可知,应该用二维数组表示程序的数据,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格中的状态,共有三种情况,分别是空格、黑棋和白棋,这样给数组元素的取值设定为0、1、2。其中0 代表空格,1代表白色棋子,2代表黑色棋子。这样程序的主要工作是接收棋手按键操作,一旦接收到回车键,说明棋手摆子,先判定是不是有效位置,也就是能不能包围住对方棋子,如果能,便对棋子所在的位置往上下、左右、左上、左下、右上、右下8个方向寻找被包围住的所有棋子(必须是连续的,中间不能有空格),将这些被包围住的对方棋子都变成自己的棋子,然后对当前棋盘中的黑白棋个数进行统计并输出结果。如果没有这样的位置可以落子,则停步,让对方走棋,重复上述步骤,直到游戏结束。如果想提前终止游戏可以按Esc键 。

2.结构设计

棋盘状态用数组a[8][8]初值为0表示空格。函数的实体比较简单,因为要输出图形,所以应初始化图形系统,图形工作方式正确确定后,画出棋盘,调用playtoplay()人人对弈函数开始游戏。一旦游戏结束后,关闭图形系统,程序结束。 本次设计主要要设计函数有:

1.main()主函数

按照语法规则,首先定义使用到的常数、全局变量、函数原型说明。棋盘状态用数组

2

a[8][8],初值为0,表示空格。函数的实体比较简单,因为要输出图形,所以应初始化图形系统,图形工作方式正确确定后,画出棋盘,调用playtoplay()人人对弈函数开始游戏,一旦游戏结束后,关闭图形系统,程序结束。

2.DrawQp()画棋盘函数

背景颜色设为蓝色,从坐标(100,100)开始每隔40个单位用白色画一条水平直线,一条垂直线,构成棋盘,用循环语句实现.画线函数line()的参数为线的起点和终点坐标,注意要计算正确.函数 setfillstyle()可以设置填充模式和填充颜色,fillellipse(int x,int y,xradius,int yradius)以x和y为圆心,xradius和yradius为水平和垂直轴画一填充椭圆,当xradius和 yradius相等时,则画出的是圆,用它表示棋子。

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

因为是两个棋手,同时棋盘也在不断变化,所以要判断棋手和棋盘变化设置了这个函数 函数的参数为整型变量t,根据t的值来设计填充棋子的当前颜色,值为1代表白棋,值为2代表黑棋。

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

由于棋手在走棋的时候,他的棋子总是首先出现在棋盘的左上角 棋手要通过移动光标键走到要落子的位置,在经过的路程上显示当前棋子,就会覆盖原来的棋盘状态。所以,一旦棋子走过后,就应恢复原来的状态,是空格的依然显示空格,是棋子的就显示原来棋子的颜色,因为棋子移动过程并没有改变数组元素的值,所以可以根据数组元素的值判定原来的状态,如果值是1,就恢复白色棋子,值是2则恢复黑色棋子,否则恢复蓝色空格。

5.playtoplay()人人对战函数

这是游戏进行的函数,主要是接收棋手的按键消息,其处理过程如下: (1)按 Esc键程序可以随时结束。

(2)按上下左右光标键,则改变棋子移动的坐标值。 (3)按回车键后判断:

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

2)如落子位置是空格,可以将棋子落入格内,调用函数 QpChange()判断是否引起棋盘的变化,函数值为1有变化,为0没变化。如果棋盘有变化,说明将包围的对方棋子吃掉,统计当前分数,如果棋盘没有变化,则说明落子的位置无法包围对方的棋子也视为无效棋。可以继续寻找合适的位置,但开始统计其落子次数,一旦尝试次数超过当前棋盘的空格数,则说明他无棋可走,则放弃此步,让对方下棋。

3)如果棋子变化后,格子已占满64格或一方棋子为0,则游戏结束,显示胜利方信息。按任意键程序结束。

(4)重复上述步骤,直到游戏结束。 6.QpChange()判断棋盘变化

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

3

坐标,而棋子的状态是数组元素a,所以要根据落子的坐标x和y计算出对应数组元素a的下标 i和 j,i代表行,j代表列,对于8*8的棋盘,它们的值为0-7,如果j<6,往右边判断,从当前位置开始,用循环语句判断右边是否有一个或连续多个对方的棋子,遇到自己的棋子或空格则结束循环,如果循环结束不是遇到空白,且列坐标小于8,则说明这些位置的棋子是被自己包围的对方棋子,将它们吃掉 也就是改变为自己的棋子,如果有棋子发生了变化,给棋盘变化标志值yes赋值为1,同样的方法向左、上、下等 8个方向进行判断,并作相应的变化。如果所有方向都判断过,并且没有引起棋盘的变化,则棋盘变化标志值 yes为0返回yes 结束本函数。

7.DoScore()处理分数

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

8.PrintScore()输出成绩

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

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

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

3.流程图

3.1playtoplay函数流程图: 开始 换棋手 按键方向键 改变棋子坐标 统计分数 Y 按回车键 N Y 当前位置有棋子? N 调用QpChange 棋盘有变化? 图1 4

3.2主函数流程图:

开始 初始化棋盘为320*320的64方格 调用SetPlayColor 将棋子设为黑白两色 调用playtoplay 棋手走棋 Y 结束 格子已满或一方没子了或有Esc输入? N 调用MoveColor恢复格子 N 符合下子条件? 换棋手 Y 回车键落子 调用QpChange改变棋盘 图2 5

if(playnum==1)/*把分数给这个临时变量*/ for(i=0;i<2;i++) s[i]=scorewhite[i]; else

for(i=0;i<2;i++) s[i]=scoreblack[i];

if(playnum==1)/*清楚以前的成绩*/ {

setfillstyle(SOLID_FILL,BLUE); bar(550,100,640,400); }

if(playnum==1)/*判断输出的行数*/ k=200; else k=300;

setcolor(RED); settextstyle(0,0,4); for(i=0,j=550;i<2;i++,j+=40) {

switch(s[i])/*判断要输出的分数*/ {

case 0: outtextxy(j,k,\ case 1: outtextxy(j,k,\ case 2: outtextxy(j,k,\ case 3: outtextxy(j,k,\ case 4: outtextxy(j,k,\ case 5: outtextxy(j,k,\ case 6: outtextxy(j,k,\ case 7: outtextxy(j,k,\ case 8: outtextxy(j,k,\ case 9: outtextxy(j,k,\ } }

setcolor(0); }

void playwin()/*输出最后的胜利者结果*/

11

{settextstyle(0,0,4); setcolor(12);

if(scoreblack[0]>scorewhite[0]) outtextxy(100,50,\ else if(scoreblack[0]

if(scoreblack[1]==scorewhite[1]) outtextxy(60,50,\ else if(scoreblack[1]>scorewhite[1]) outtextxy(100,50,\ else if(scoreblack[1]

void playtoplay()/*人人对战*/ {int xx,yy,t=0,sum,i,j; while(1) {

xx=120,yy=80;/*每次棋子一开始出来的坐标*/ while(1) {

printscore(1);/*输出玩家1的成绩*/ printscore(2);/*输出玩家2的成绩*/ playcolor(t);

fillellipse(xx,yy,15,15); key=bioskey(0); sound(100); nosound(); if(key==ESC) break;

else if(key==ENTER)/*如果按键确定就可以跳出循环*/ {

if(yy!=80&&a[(xx-120)/40][(yy-120)/40]!=1&&a[(xx-120)/40][(yy-120)/40]!=2) /*是否已经有子*/

12

{

if(t%2==0)

a[(xx-120)/40][(yy-120)/40]=1; else

a[(xx-120)/40][(yy-120)/40]=2;

qipanchange(xx,yy,t);/*走好一步棋子后屏幕的变化*/ doscore();/*分数的改变*/ break;/*判断成功就下一个棋子走*/ } else

continue;/*不成功就等于白按回车*/ }

else if(key==LEFT&&xx>120)/*四个方向按键盘的判断*/ {

playcolortwo(xx,yy);/*判断原来位置因为画什么,这里只画蓝色是不完整的*/ fillellipse(xx,yy,15,15); playcolor(t); xx-=40;

fillellipse(xx,yy,15,15); }

else if(key==RIGHT&&xx<400&&yy>80) {

playcolortwo(xx,yy); fillellipse(xx,yy,15,15); playcolor(t); xx+=40;

fillellipse(xx,yy,15,15); }

else if(key==UP&&yy>120) {

playcolortwo(xx,yy); fillellipse(xx,yy,15,15); playcolor(t); yy-=40;

fillellipse(xx,yy,15,15);

13

}

else if(key==DOWN&&yy<400) {

playcolortwo(xx,yy); fillellipse(xx,yy,15,15); playcolor(t); yy+=40;

fillellipse(xx,yy,15,15); } }

if(key==ESC) break; sum=0;

for(i=0;i<8;i++)/*判断是否棋子填满*/ for(j=0;j<8;j++) if(a[i][j]!=0) sum++; if(sum==64) {

playwin();/*判断胜负*/ break; } t++;

if(t==11)/*如果t到了11就变成1*/ t=1; } }

void main() {

int gr,gd=DETECT;

//int graphdriver=DETECT,graphmode;

//initgraph(&graphdriver,&graphmode,\files\\WINYES\\TCPP30H\\BGI\

initgraph(&gd,&gr,\ qipan();/*画棋盘*/ playtoplay();/*人人对战*/

14

getch(); closegraph(); }

五、总结

这个黑白棋游戏原程序是基于Turbo C强大的图形处理函数下完成的,其最大特点是采用了在主函数中调用子函数思想,每一种功能都是用子函数的办法来进行处理,简洁,清晰,方便,不容易出现错误。 在输入错误时本来想用一种警告的铃声来提醒用户,由于所学的知识不多,自己的编程经验不足,按现有的知识水平有些东西暂时还无法解决,还有待于在以后的学习中不断提高和改进!

六、心得体会

C语言作为国际上广泛流行的通用程序设计语言,在计算机的研究和应用中已展现出强大的生命力。C语言兼顾了诸多高级语言的特点,是一种典型的结构化程序设计语言,它处理能力强,使用灵活方便,应用面广,具有良好的可移植性。虽然我们C语言已有半年了,但一直都重概念、轻实践,这次设计对我们来说是千载难逢的机会。高中的教育模式化倾向太强,整齐划一的教育模式使学校变成“工厂”,学生成为统一式模子加工出来的“标准件”。但大学的程序设计实践课促进我们的个性充分、健康地发展,最大限度地激发我们的学习热情和创造热情。我可以说若你一一欣赏我们的设计,你一定会眼花缭乱,因为它们各种各样、各有千秋。并且,它无形中促进我们自主学习,使我们对C语言有了更深刻地了解,对程序设计有了更高的操作水平。

参考文献

[1]张基温,C语言程序设计案例教程,清华大学出版社,2004 [2]郭翠英,C语言课程设计案例精编,中国水利水电出版社,2004

15

本文来源:https://www.bwwdw.com/article/hs17.html

Top