| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1360 人关注过本帖
标题:我的五子棋程序编好了 但是分别胜负有点问题
只看楼主 加入收藏
狂人老大
Rank: 1
来 自:杭州
等 级:新手上路
威 望:1
帖 子:394
专家分:0
注 册:2007-6-21
收藏
 问题点数:0 回复次数:8 
我的五子棋程序编好了 但是分别胜负有点问题
这是我的五子棋程序
分别胜负有点问题
#include<stdio.h>
#define N 10
void welcome();
void initqipan();
void showqi(int i);
void save(int p);
void panduan(int p);
void heqi();
void over();
int zouqihang();
int zouqilie();
/******************结构体*****************/
struct zuobiao
{
int x[N*N];
int y[N*N];
}weizhi[N*N];
/******************主函数*****************/
void main()
{
int p=0;
welcome();
initqipan();
for(p=1;p<=N*N;p++)
{
weizhi[p].x[p]=zouqihang();
weizhi[p].y[p]=zouqilie();
save(p);
showqi(p);
panduan(p);
}
if(p==N*N)
heqi();
over();
}
/******************建立棋盘*****************/
void initqipan()
{
int i,j;
for(i=0;i<N;i++)
{
printf("%d",i);
printf(" ");
}
printf("\n");
for(i=1;i<N;i++)
{
for(j=0;j<N;j++)
{
if(j==0)
printf("%d",i);
else
printf("·");
}
printf("\n");
}
}
/******************显示棋子*****************/
void showqi(int p)
{
int i,j,k,m;
int a[N*N],b[N*N];
FILE *fp;
fp=fopen("wuzi_list","rb");
for(i=1;i<=N*N;i++)
{
fread(&weizhi[i],sizeof(struct zuobiao),1,fp);
a[i]=weizhi[i].x[i];
b[i]=weizhi[i].y[i];
}
for(m=1;m<p;m++)
{
while(weizhi[p].x[p]==a[m]&&weizhi[p].y[p]==b[m])
{
printf("error!\n");
weizhi[p].x[p]=zouqihang();
weizhi[p].y[p]=zouqilie();
m=1;
}
}
for(i=0;i<N;i++)
{
printf("%d",i);
printf(" ");
}
printf("\n");
for(i=1;i<N;i++)
{
for(j=1;j<N;j++)
{
if(j==1)
printf("%d",i);
for(k=1;k<=p;k++)
{
if(i==weizhi[k].x[k]&&j==weizhi[k].y[k])
{
if(k%2==1)
{printf("○");break;}
else if(k%2==0)
{printf("●");break;}
}
}
if(k>p)printf("·");
else continue;
}
printf("\n");
}
}
/******************走棋行*****************/
int zouqihang()
{
int x;
printf("请输入要走棋子所在行数!\n");
printf("x=");
scanf("%d",&x);
while(x>N-1||x<1)
{
printf("error!\n");
printf("请输入要走棋子所在行数!\n");
printf("x=");
scanf("%d",&x);
}
return x;
}
/******************走棋列*****************/
int zouqilie()
{
int y;
printf("请输入要走棋子所在列数!\n");
printf("y=");
scanf("%d",&y);
while(y>N-1||y<1)
{
printf("error!\n");
printf("请输入要走棋子所在列数!\n");
printf("y=");
scanf("%d",&y);
}
return y;
}
/******************文件保存*****************/
void save(int i)
{
FILE *fp;
fp=fopen("wuzi_list","wb");
fwrite(&weizhi[i],sizeof(struct zuobiao),1,fp);
}
/****************判断输赢*******************/
void panduan(int p)
{
int i,j,k[8]={1,1,1,1,1,1,1,1,};
int a[N*N],b[N*N];
FILE *fp;
fp=fopen("wuzi_list","rb");
for(i=1;i<=p;i++)
{
fread(&weizhi[i],sizeof(struct zuobiao),1,fp);
a[i]=weizhi[i].x[i];
b[i]=weizhi[i].y[i];
}
/*****************判断行******************/
for(i=1;i<=p;i++)
{
if(i%2==1)
{
for(j=1;j<=p;j=j+2)
{
if((a[i]==a[j])&&(b[i]==b[j]-1))
{
k[0]++;
continue;
}
else if((a[i]==a[j])&&(b[i]==b[j]-2))
{
k[0]++;
continue;
}
else if((a[i]==a[j])&&(b[i]==b[j]-3))
{
k[0]++;
continue;
}
else if((a[i]==a[j])&&(b[i]==b[j]-4))
{
k[0]++;
continue;
}
else if(k[0]==5)
{
printf("Player 1 wins!!!\n");
}
else
continue;
}
if(k[0]==5)
break;
k[0]=1;
}
else if(k[0]==5)
break;
else if(i%2==0)
{
for(j=2;j<=p;j=j+2)
{
if((a[i]==a[j])&&(b[i]==b[j]-1))
{
k[1]++;
continue;
}
else if((a[i]==a[j])&&(b[i]==b[j]-2))
{
k[1]++;
continue;
}
else if((a[i]==a[j])&&(b[i]==b[j]-3))
{
k[1]++;
continue;
}
else if((a[i]==a[j])&&(b[i]==b[j]-4))
{
k[1]++;
continue;
}
else if(k[1]==5)
{
printf("Player 2 wins!!!\n");
}
else
continue;
}
if(k[1]==5)
break;
k[1]=1;
}
}
/**********************判断列************************/
for(i=1;i<=p;i++)
{
if(k[0]==5||k[1]==5)
break;
else if(i%2==1)
{
for(j=1;j<=p;j=j+2)
{
if((a[i]==a[j]-1)&&(b[i]==b[j]))
{
k[2]++;
continue;
}
else if((a[i]==a[j]-2)&&(b[i]==b[j]))
{
k[2]++;
continue;
}
else if((a[i]==a[j]-3)&&(b[i]==b[j]))
{
k[2]++;
continue;
}
else if((a[i]==a[j]-4)&&(b[i]==b[j]))
{
k[2]++;
continue;
}
else if(k[2]==5)
{
printf("Player 1 wins!!!\n");
}
else
continue;
}
if(k[2]==5)
break;
k[2]=1;
}
else if(k[2]==5)
break;
else if(i%2==0)
{
for(j=2;j<=p;j=j+2)
{
if((a[i]==a[j]-1)&&(b[i]==b[j]))
{
k[3]++;
continue;
}
else if((a[i]==a[j]-2)&&(b[i]==b[j]))
{
k[3]++;
continue;
}
else if((a[i]==a[j]-3)&&(b[i]==b[j]))
{
k[3]++;
continue;
}
else if((a[i]==a[j]-4)&&(b[i]==b[j]))
{
k[3]++;
continue;
}
else if(k[3]==5)
{
printf("Player 2 wins!!!\n");
}
else
continue;
}
if(k[3]==5)
break;
k[3]=1;
}
}
/****************判断对角(左上-右下)******************/
for(i=1;i<=p;i++)
{
if(k[0]==5||k[1]==5||k[2]==5||k[3]==5)
break;
else if(i%2==1)
{
for(j=1;j<=p;j=j+2)
{
if((a[i]==a[j]-1)&&(b[i]==b[j]-1))
{
k[4]++;
continue;
}
else if((a[i]==a[j]-2)&&(b[i]==b[j]-2))
{
k[4]++;
continue;
}
else if((a[i]==a[j]-3)&&(b[i]==b[j]-3))
{
k[4]++;
continue;
}
else if((a[i]==a[j]-4)&&(b[i]==b[j]-4))
{
k[4]++;
continue;
}
else if(k[4]==5)
{
printf("Player 1 wins!!!\n");
}
else
continue;
}
if(k[4]==5)
break;
k[4]=1;
}
else if(k[2]==5)
break;
else if(i%2==0)
{
for(j=2;j<=p;j=j+2)
{
if((a[i]==a[j]-1)&&(b[i]==b[j]-1))
{
k[5]++;
continue;
}
else if((a[i]==a[j]-2)&&(b[i]==b[j]-2))
{
k[5]++;
continue;
}
else if((a[i]==a[j]-3)&&(b[i]==b[j]-3))
{
k[5]++;
continue;
}
else if((a[i]==a[j]-4)&&(b[i]==b[j]-4))
{
k[5]++;
continue;
}
else if(k[5]==5)
{
printf("Player 2 wins!!!\n");
}
else
continue;
}
if(k[5]==5)
break;
k[5]=1;
}
}
/**********判断对角(左下-右上)************/
for(i=1;i<=p;i++)
{
if(k[0]==5||k[1]==5||k[2]==5||k[3]==5||k[4]==5||k[5]==5)
break;
else if(i%2==1)
{
for(j=1;j<=p;j=j+2)
{
if((a[i]==a[j]+1)&&(b[i]==b[j]-1))
{
k[6]++;
continue;
}
else if((a[i]==a[j]+2)&&(b[i]==b[j]-2))
{
k[6]++;
continue;
}
else if((a[i]==a[j]+3)&&(b[i]==b[j]-3))
{
k[6]++;
continue;
}
else if((a[i]==a[j]+4)&&(b[i]==b[j]-4))
{
k[6]++;
continue;
}
else if(k[6]==5)
{
printf("Player 1 wins!!!\n");
}
else
continue;
}
if(k[6]==5)
break;
k[6]=1;
}
else if(k[6]==5)
break;
else if(i%2==0)
{
for(j=2;j<=p;j=j+2)
{
if((a[i]==a[j]+1)&&(b[i]==b[j]-1))
{
k[7]++;
continue;
}
else if((a[i]==a[j]+2)&&(b[i]==b[j]-2))
{
k[7]++;
continue;
}
else if((a[i]==a[j]+3)&&(b[i]==b[j]-3))
{
k[7]++;
continue;
}
else if((a[i]==a[j]+4)&&(b[i]==b[j]-4))
{
k[7]++;
continue;
}
else if(k[7]==5)
{
printf("Player 2 wins!!!\n");
}
else
continue;
}
if(k[7]==5)
break;
k[7]=1;
}
}
}
/****************和棋*******************/
void heqi()
{
printf("************************************\n");
printf(" Tie!!!\n");
printf("************************************\n");
}
/****************游戏结束*******************/
void over()
{
printf("************************************\n");
printf(" game over!!!\n");
printf("************************************\n");
}
/****************游戏开始*******************/
void welcome()
{
printf("************************************\n");
printf(" Welcome!!!\n");
printf("************************************\n");
}
搜索更多相关主题的帖子: void 五子棋 int 胜负 
2007-07-05 09:01
cdmalcl
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:24
帖 子:4091
专家分:524
注 册:2005-9-23
收藏
得分:0 

这是我的五子棋胜负判断 效率一般:
/*
5 4 6
\|/
1 - - 3
/|\
7 2 8
*/
int checkChessWin(Site checkSize)
{
int i, j ;
int flagDirect = 0 ;

for(i = 1;i < 5;i++)
{
// 1
if(checkSize.x+i >= CB_LEN
|| chessMan[checkSize.x+i][checkSize.y] != chessKey+1)
{
flagDirect = flagDirect|1 ;
}
// 2
if(checkSize.y+i >= CB_LEN
|| chessMan[checkSize.x][checkSize.y+i] != chessKey+1)
{
flagDirect = flagDirect|2 ;
}
// 3
if(checkSize.x-i < 0
|| chessMan[checkSize.x-i][checkSize.y] != chessKey+1)
{
flagDirect = flagDirect|4 ;
}
// 4
if(checkSize.y-i < 0
|| chessMan[checkSize.x][checkSize.y-i] != chessKey+1)
{
flagDirect = flagDirect|8 ;
}
// 5
if(checkSize.x-i < 0 && checkSize.y-i < 0
|| chessMan[checkSize.x-i][checkSize.y-i] != chessKey+1)
{
flagDirect = flagDirect|16 ;
}
// 6
if(checkSize.x+i >= CB_LEN && checkSize.y-i < 0
|| chessMan[checkSize.x+i][checkSize.y-i] != chessKey+1)
{
flagDirect = flagDirect|32 ;
}
// 7
if(checkSize.x-i < 0 && checkSize.y+i >= CB_LEN
|| chessMan[checkSize.x-i][checkSize.y+i] != chessKey+1)
{
flagDirect = flagDirect|64 ;
}
// 8
if(checkSize.x+i >= CB_LEN && checkSize.y+i >= CB_LEN
|| chessMan[checkSize.x+i][checkSize.y+i] != chessKey+1)
{
flagDirect = flagDirect|128 ;
}
}

return flagDirect;
}

2007-07-05 09:07
cdmalcl
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:24
帖 子:4091
专家分:524
注 册:2005-9-23
收藏
得分:0 
你怎么还在用文本模式写啊
赶紧换吧 要不测试效率会很低的
2007-07-05 09:08
狂人老大
Rank: 1
来 自:杭州
等 级:新手上路
威 望:1
帖 子:394
专家分:0
注 册:2007-6-21
收藏
得分:0 
是画出棋盘吗??
我们老师要求就是这样的啊
我想这次暑假有时间会重新弄的

ACMer的QQ群:33741351
单片机QQ群:55130117
2007-07-05 09:24
cdmalcl
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:24
帖 子:4091
专家分:524
注 册:2005-9-23
收藏
得分:0 
汗 原来是写作业 闷
2007-07-05 09:25
狂人老大
Rank: 1
来 自:杭州
等 级:新手上路
威 望:1
帖 子:394
专家分:0
注 册:2007-6-21
收藏
得分:0 
我暑假还有要写一个人机对战的任务呢

ACMer的QQ群:33741351
单片机QQ群:55130117
2007-07-06 08:10
cdmalcl
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:24
帖 子:4091
专家分:524
注 册:2005-9-23
收藏
得分:0 
老师太有想法了!!!

摘自:http://www.itzhe.com/article_html/54/48237.html


总的来说(我们假定您熟悉五子棋的基本规则),要让电脑知道该在哪一点下子,
就要根据盘面的形势,为每一可能落子的点计算其重要程度,也就是当这子落下后会形
成什么棋型(如:“冲四”、“活三”等),然后通览全盘选出最重要的一点,这便是
最基本的算法。当然,仅靠当前盘面进行判断是远远不够的,这样下棋很容易掉进玩家
设下的陷阱,因为它没有考虑以后的变化。所以在此基础上我们加入递归调用,即:在
电脑中预测出今后几步的各种走法,以便作出最佳选择,这也是我们下棋时常说的“想
了几步”。如此一来您的程序便具有一定的水平了。什么?不信!过来试试吧!
  总体思路弄清之后,下面进行具体讨论:
一:数据结构
  先来看看数据结构,我们需要哪些变量?
  首先得为整个棋盘建立一张表格用以记录棋子信息,我们使用一个15*15的二维数组
Table[15][15] (15*15是五子棋棋盘的大小),数组的每一个元素对应棋盘上的一个交
叉点,用‘0’表示空位、‘1’代表己方的子、‘2’代表对方的子;这张表也是今后分
析的基础。
  在此之后还要为电脑和玩家双方各建立一张棋型表Computer[15][15][4]和Player[
15][15][4],用来存放棋型数据,就是刚才所说的重要程度,比如用‘20’代表“冲四
”的点,用‘15’代表“活三”的点,那么在计算重要性时,就可以根据20>15得出前者
比后者重要,下子时电脑便会自动选择“冲四”的点。那为什么棋型表要使用三维数组
呢?因为棋盘上的每一个点都可以与横、竖、左斜、右斜四个方向的棋子构成不同的棋
型,所以一个点总共有4个记录;这样做的另一个好处是可以轻易判断出复合棋型,例如
:如果同一点上有2个‘15’就是双三、有一个‘15’和一个‘20’就是四三。
  怎么样!3个数组构成了程序的基本数据骨架,今后只要再加入一些辅助变量便可以
应付自如了。应该不会太难吧?OK!有了这么多有用的数据,我们就可以深入到程序的
流程中去了。
二:程序流程
  我们主要讨论五子棋的核心算法,即:人工智能部分,而其他像图形显示、键盘鼠
标控制等,因较为简单,所以就不作过多介绍了。
  我们看到本程序由六个基本功能模块构成,各模块的详细分析如下:
  (1)初始化:首先,建立盘面数组Table[15][15]、对战双方的棋型表Computer[1
5][15][4]和Player[15][15][4]并将它们清零以备使用;然后初始化显示器、键盘、鼠
等输入输出设备并在屏幕上画出棋盘。
  (2)主循环控制模块:控制下棋顺序,当轮到某方下子时,负责将程序转到相应的
模块中去,主要担当一个调度者的角色。
  (3)玩家下子:当轮到玩家下时,您通过键盘或鼠标在棋盘上落子,程序会根据该
点的位置,在Table[15][15]数组的相应地方记录‘2’,以表明该子是玩家下的。
  (4)盘面分析填写棋型表:本程序核心模块之一,人工智能算法的根本依据!其具
体实现方法如下:您在下五子棋时,一定会先根据棋盘上的情况,找出当前最重要的一
些点位,如“活三”、“冲四”等;然后再在其中选择落子点。但是,电脑不会像人一
样分析问题,要让它知道哪是“活三”、哪是“冲四”,就得在棋盘上逐点计算,一步
一步的教它。
  先来分析己方的棋型,我们从棋盘左上角出发,向右逐行搜索,当遇到一个空白点
时,以它为中心向左挨个查找,如果遇到己方的子则记录然后继续,如果遇到对方的子
、空白点或边界就停止查找。左边完成后再向右进行同样的操作;最后把左右两边的记
录合并起来,得到的数据就是该点横向上的棋型,然后把棋型的编号填入到Computer[x
][y][n]中就行了(x、y代表坐标,n=0、1、2、3分别代表横、竖、左斜、右斜四个方向
)。而其他三个方向的棋型也可用同样的方法得到,当搜索完整张棋盘后,己方棋型表
也就填写完毕了。然后再用同样的方法填写对方棋型表。
  注意:所有棋型的编号都要事先定义好,越重要的号数越大!
  OK! 怎么样?有点累了吧?不过千万别泄气!因为好戏还在后头。
  Let's go!
  (5)电脑下子:有了上面填写的两张棋型表,现在要作的就是让电脑知道在哪一点
下子了。其中最简单的计算方法,就是遍历棋型表Computer[15][15][4]和Player[15][
15][4]找出其中数值最大的一点,在该点下子即可。但这种算法的弱点非常明显,只顾
眼前利益,不能顾全大局,这就和许多五子棋初学者一样犯了“目光短浅”的毛病。
  要解决这个问题,我们引入‘今后几步预测法’,具体方法是这样的: 首先, 让
电脑分析一个可能的点,如果在这儿下子将会形成对手不得不防守的棋型(例如:‘冲
四’、‘活三’);那么下一步对手就会照您的思路下子来防守您,如此一来便完成了
第一步的预测。这时再调用模块4对预测后的棋进行盘面分析,如果出现了‘四三’、‘
双三’或‘双四’等制胜点,那么己方就可以获胜了(当然对黑棋而言‘双三’、‘双
四’是禁手,另当别论);否则照同样的方法向下分析,就可预测出第二步、第三步…

  等一等,要是盘面上没有对手必须防的棋型,哪该怎么办呢?进攻不成的话就得考
虑防守了,将自己和对手调换一下位置,然后用上面的方法来预测对手的棋,这样既可
以防住对手巧妙的攻击,又能侍机发动反击,何乐而不为呢!
  但是必须告诉大家的是:预测法的运算量相当之大,据我的经验,用Pentium-100预
测3步的走法平均需要15秒以上时间,所以建议预测量在5步以内。可别小瞧了这5步,有
时它甚至会走出让您拍手叫绝的妙着呢!
  (6)胜负判断:务须多言,某方形成五子连即获胜;若黑棋走出‘双三’、‘双四
’或长连即以禁手判负。
2007-07-06 09:54
狂人老大
Rank: 1
来 自:杭州
等 级:新手上路
威 望:1
帖 子:394
专家分:0
注 册:2007-6-21
收藏
得分:0 
呵呵 放假了
要编这个程序了
人机对战

ACMer的QQ群:33741351
单片机QQ群:55130117
2007-08-08 20:33
快速回复:我的五子棋程序编好了 但是分别胜负有点问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.031565 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved