五子棋程序设计
1. C语言程序设计 关于五子棋的
五子棋程序:
#include<iostream>
using namespace std;
int Hsheng(char a[][15]);//判断o子是否获胜的函数
int Bsheng(char a[][15]);//判断x子是否获胜的函数
int he(char a[][15]);//判断是否平局(也就是棋盘下满了)的函数
void qipan(char a[15][15])//执行输出棋盘命令
{ for(int i=0;i<15;i++) //打印棋盘
{ for(int j=0;j<15;j++)
cout<<a[i][j];
cout<<endl; } }
int main()
{ char a[15][15]; int x,y;
for(int i=0;i<15;i++)
for(int j=0;j<15;j++)
a[i][j]=' '; qipan(a);
while(1)//用循环语句执行o,x交替下子,这些while语句看起来似乎是个死循环~实际上都会经过break结束
{ int a1=1;
while(1)
{ for(;a1;)
{ cout<<"请输入o子下的位置:"; //输入o子的位置
cin>>x>>y; if(a[x][y]=='o'||a[x][y]=='x')//判断是否已有子
{cout<<"已有子请重下"<<",";continue;}
else if(x>=15||y>=15){cout<<"输入错误请重输"<<",";continue;}
else { a[x][y]='o'; a1=0;}
} break;}
qipan(a);//下好o子后将棋盘显示
if(Hsheng(a))//判断o子是否已经获胜
{ cout<<"o子获胜"<<endl; break; }
while(1)//下x子
{ cout<<"请输入x子下的位置:";
cin>>x>>y;
if(a[x][y]=='o'||a[x][y]=='x'||x>=15||y>=15)
{ for( ; a[x][y]=='o'||a[x][y]=='x'; )
{ cout<<"已有子请重下";
cout<<"请输入x子下的位置:";
cin>>x>>y;continue; }
for ( ; x>=15||y>=15||x; )
{ cout<<"输入错误请重输"<<","; //判断输入棋子位置是否正确
cout<<"请输入x子下的位置:";
cin>>x>>y;continue ;}
a[x][y]='x';break; }
else
{ a[x][y]='x'; break; } }
qipan(a);//再一次输出棋盘
if(Bsheng(a))//判断x子是否已经获胜
{ cout<<"x子获胜"<<endl; break; }
if(he(a))//判断是否平局
{ cout<<"平局"<<endl; break; } }
return 0; }
int Hsheng(char a[][15])
{ int i,j;//判断横着的5个是否都相等
for(i=0;i<15;i++)
for(j=0;j<15;j++)
if(a[i][j]=='o'&&a[i][j+1]=='o'&&a[i][j+2]=='o'&&a[i][j+3]=='o'&&a[i][j+4]=='o')
return 1;
for(j=0;j<15;j++)//判断竖着的5个是否都相等
for(i=0;i<15;i++)
if(a[i][j]=='o'&&a[i+1][j]=='o'&&a[i+2][j]=='o'&&a[i+3][j]=='o'&&a[i+4][j]=='o')
return 1;
for(i=0;i<15;i++)//判断左斜5个
for(j=0;j<15;j++)
if(a[i][j]=='o'&&a[i+1][j+1]=='o'&&a[i+2][j+2]=='o'&&a[i+3][j+3]=='o'&&a[i+4][j+4]=='o')
return 1;
for(i=0;i<15;i++)//右斜5个
for(j=14;j>3;j--)
if(a[i][j]=='H'&&a[i+1][j-1]=='o'&&a[i+2][j-2]=='o'&&a[i+3][j-3]=='o'&&a[i+4][j-4]=='o')
return 1;
return 0; }
int Bsheng(char a[][15])//同o,只是改字符
{ int i,j;
for(i=0;i<15;i++)
for(j=0;j<15;j++)
if(a[i][j]=='x'&&a[i][j+1]=='x'&&a[i][j+2]=='x'&&a[i][j+3]=='x'&&a[i][j+4]=='x')
return 1;
for(j=0;j<15;j++)
for(i=0;i<15;i++)
if(a[i][j]=='x'&&a[i+1][j]=='x'&&a[i+2][j]=='x'&&a[i+3][j]=='x'&&a[i+4][j]=='x')
return 1;
for(i=0;i<15;i++)
for(j=0;j<15;j++)
if(a[i][j]=='x'&&a[i+1][j+1]=='x'&&a[i+2][j+2]=='x'&&a[i+3][j+3]=='x'&&a[i+4][j+4]=='x')
return 1;
for(i=0;i<15;i++)
for(j=14;j>3;j--)
if(a[i][j]=='x'&&a[i+1][j-1]=='x'&&a[i+2][j-2]=='x'&&a[i+3][j-3]=='x'&&a[i+4][j-4]=='x')
return 1;
return 0; }
int he(char a[][15])
{ for(int i=0;i<15;i++)
for(int j=0;j<15;j++)
{ if(a[i][j]==' ')//当棋盘全部子都不是' '时才能return 1,即棋盘已下满
return 0;
}
return 1;
}
希望能帮到你!!
2. 经典五子棋的C++程序设计
#include<iostream>
#include<stdlib.h>
usingnamespacestd;
classfivegame
{charm,n;
inth,l;
charz;
charlist[20][20];
public:
intkk;
intinit();
intenterchar(charq);
intprint();
intpk();
intifwin();
boolison;
booltest();
charlist1[5];
intpuout();
};
intfivegame::puout()
{cout<<"这是个五字棋游戏"<<endl;
cout<<"制作--elva6401--"<<endl;
cout<<"(注:行列都要用大写字母)"<<endl;
return0;
}
boolfivegame::test()
{
inti;
for(i=0;i<=4;i++)
{if(list1[i]!=z)
returnfalse;}
returntrue;
}
intfivegame::init()
{inti,j,m=0;
for(i=0;i<=9;i++)cout<<i<<"";
for(i=65;i<=75;i++)cout<<static_cast<char>(i)<<"";
cout<<0<<endl;
for(j=0;j<=8;j++)
{m=m+1;cout<<m<<"";
for(i=0;i<=19;i++)
{list[j][i]='';cout<<list[j][i]<<"";}
cout<<m<<endl;}
m=64;
for(j=9;j<=19;j++)
{m=m+1;cout<<static_cast<char>(m)<<"";
for(i=0;i<=19;i++)
{list[j][i]='';cout<<list[j][i]<<"";}
cout<<static_cast<char>(m)<<endl;}
for(i=0;i<=9;i++)cout<<i<<"";
for(i=65;i<=75;i++)cout<<static_cast<char>(i)<<"";
cout<<0<<endl;
return0;
}
intfivegame::enterchar(charq)
{chara,b;
cout<<"现在轮到"<<q<<"下."<<endl;
cout<<"请输入要下的行号和列号."<<endl;
cin>>a>>b;
z=q;m=a;n=b;
return0;
}
intfivegame::print()
{if(static_cast<int>(m)>60)h=static_cast<int>(m)-56;
elseh=static_cast<int>(m)-49;
if(static_cast<int>(n)>60)l=static_cast<int>(n)-56;
elsel=static_cast<int>(n)-49;
inti,j,m=0;
if(list[h][l]!='')
{kk=0;
for(i=0;i<=9;i++)cout<<i<<"";
for(i=65;i<=75;i++)cout<<static_cast<char>(i)<<"";
cout<<0<<endl;
for(j=0;j<=8;j++)
{m=m+1;cout<<m<<"";
for(i=0;i<=19;i++)
cout<<list[j][i]<<"";
cout<<m<<endl;}
m=64;
for(j=9;j<=19;j++)
{m=m+1;cout<<static_cast<char>(m)<<"";
for(i=0;i<=19;i++)
cout<<list[j][i]<<"";
cout<<static_cast<char>(m)<<endl;}
for(i=0;i<=9;i++)cout<<i<<"";
for(i=65;i<=75;i++)cout<<static_cast<char>(i)<<"";
cout<<0<<endl;
return0;}
else
list[h][l]=z;
for(i=0;i<=9;i++)cout<<i<<"";
for(i=65;i<=75;i++)cout<<static_cast<char>(i)<<"";
cout<<0<<endl;
for(j=0;j<=8;j++)
{m=m+1;cout<<m<<"";
for(i=0;i<=19;i++)
cout<<list[j][i]<<"";
cout<<m<<endl;}
m=64;
for(j=9;j<=19;j++)
{m=m+1;cout<<static_cast<char>(m)<<"";
for(i=0;i<=19;i++)
cout<<list[j][i]<<"";
cout<<static_cast<char>(m)<<endl;}
for(i=0;i<=9;i++)cout<<i<<"";
for(i=65;i<=75;i++)cout<<static_cast<char>(i)<<"";
cout<<0<<endl;
return0;
}
intfivegame::ifwin()
{inti,j,q=0,k=0;
for(i=0;i<=19;i++)
{q=0,k=0;
while(q<=15)
{for(j=q;j<=q+4;j++)
list1[j-k]=list[i][j];
if(fivegame::test())
{ison=true;returntrue;}
else
q++;k++;}
}
for(i=0;i<=19;i++)
{q=0,k=0;
while(q<=15)
{for(j=q;j<=q+4;j++)
list1[j-k]=list[j][i];
if(fivegame::test())
{ison=true;returntrue;}
else
q++;k++;}
}
for(i=0;i<=15;i++)
{q=0,k=0;
while(q<=15)
{
for(j=q;j<=q+4;j++)
list1[j-k]=list[i+j-k][j];
if(fivegame::test())
{ison=true;returntrue;}
else
q++;k++;}
}
for(i=18;i>=4;i--)
{q=0,k=0;
while(q<=15)
{
for(j=q;j<=q+4;j++)
list1[j-k]=list[i-j+k][19-j];
if(fivegame::test())
{ison=true;returntrue;}
else
q++;k++;}
}
for(i=0;i<=15;i++)
{q=0,k=0;
while(q<=15)
{
for(j=q;j<=q+4;j++)
list1[j-k]=list[i+j-k][19-j];
if(fivegame::test())
{ison=true;returntrue;}
else
q++;k++;}
}
for(i=18;i>=4;i--)
{q=0,k=0;
while(q<=15)
{
for(j=q;j<=q+4;j++)
list1[j-k]=list[i-j+k][19-j];
if(fivegame::test())
{ison=true;returntrue;}
else
q++;k++;}
}
for(i=18;i>=4;i--)
{q=0,k=0;
while(q<=15)
{
for(j=q;j<=q+4;j++)
list1[j-k]=list[i-j+k][j];
if(fivegame::test())
{ison=true;returntrue;}
else
q++;k++;}
}
return0;
}
intfivegame::pk()
{cout<<m<<""<<n<<""<<z<<endl;
cout<<static_cast<int>(m)<<static_cast<int>(n)<<endl;
return0;}
intmain()
{
intabc;
chary='a';
fivegamegame;
game.puout();
game.ison=false;
game.init();
while(game.ison==false)
{
game.kk=1;
game.enterchar(y);
system("cls");
game.puout();
game.print();
game.ifwin();
if(game.kk==1)
{
if(y=='a')y='b';
elsey='a';
}
}
if(y=='a')y='b';
elsey='a';
cout<<y<<"赢了!"<<endl;
cin>>abc;
return0;
}
3. C语言五子棋程序设计 谢谢!!
现在在变成语来言越变越快自,底层程序都可以用可视化的界面来完成了,就不要再固守c语言了,当然如果初学的话还是研究完c语言把,现在多用java和vs,高深多一点的是erlang,平时研究的同时多接触点高级的东西,即便弄不懂也对自己有用处的。
4. 五子棋c程序设计
#include<stdio.h>
#define N 10
void welcome();
void initqipan();
void showqi(int i);
void save(int p);
void panan(int p);
void heqi();
void over();
int zouqihang();
int zouqilie();
/******************结构体*****************/
struct zuobiao
{
int x[N];
int y[N];
}wei[N];
/******************主函数*****************/
void main()
{
int p=0;
welcome();
initqipan();
for(p=1;p<=N;p++)
{
wei[p].x[p]=zouqihang();
wei[p].y[p]=zouqilie();
save(p);
showqi(p);
panan(p);
}
if(p==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],b[N];
FILE *fp;
fp=fopen("wuzi_list","rb");
for(i=1;i<=N;i++)
{
fread(&wei[i],sizeof(struct zuobiao),1,fp);
a[i]=wei[i].x[i];
b[i]=wei[i].y[i];
}
for(m=1;m<p;m++)
{
while(wei[p].x[p]==a[m]&&wei[p].y[p]==b[m])
{
printf("错误!\n");
wei[p].x[p]=zouqihang();
wei[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==wei[k].x[k]&&j==wei[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("错误!\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("错误!\n");
printf("请输入要走棋子所在列数!\n");
printf("y=");
scanf("%d",&y);
}
return y;
}
/******************文件保存*****************/
void save(int i)
{
FILE *fp;
fp=fopen("wuzi_list","wb");
fwrite(&wei[i],sizeof(struct zuobiao),1,fp);
}
/****************判断输赢*******************/
void panan(int p)
{
int i,j,k[8]={1,1,1,1,1,1,1,1,};
int a[N],b[N];
FILE *fp;
fp=fopen("wuzi_list","rb");
for(i=1;i<=p;i++)
{
fread(&wei[i],sizeof(struct zuobiao),1,fp);
a[i]=wei[i].x[i];
b[i]=wei[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");
}
/****************游戏结束*******************/
void over()
{
printf("游戏结束!!!\n");
}
/****************游戏开始*******************/
void welcome()
{
printf("欢迎使用!!!\n");
}
这个是10x10的,你改一下了就行 别忘了给分哦
5. 求一个五子棋程序设计实验报告
我给你一个c++五子棋的程序mian.cpp#include <cstdio>
#include <string>
#include <cstdlib>
#include <ctime>
#include <Windows.h>
#include "pl.h"
using namespace std;pl game;
pl game2;void srandput(int &x,int &y) {
srand(time(NULL));
do {
x = rand() % 20;
y = rand() % 20;
} while (!game.isok(x,y));
}void scanfput(int &x,int &y) {
do {
scanf("%d %d",&x,&y);
} while (!game.isok(x,y));
}int main() {
int x,y;
char who = com;
x = y = -1;
do {
if (who == com) who = me;
else who = com;
if (who == me) {
game.getxy(x,y);
printf("Com put chess in (%d,%d)\n",x,y);
game.printmap();
if (game.isend(x,y,com)) {
who = com;
break;
} game.sendxy(x,y);
printf("I put chess in (%d,%d)\n",x,y);
game.printmap();
if (game.isend(x,y,me)) break;
//system("pause");
}
else {
//srandput(x,y);
scanfput(x,y);
//game2.getxy(x,y);
//game2.sendxy(x,y);
}
} while (true);
if (who == me) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),dwMe);
puts("You Win, Computer Lose.");
}
else {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),dwCom);
puts("Computer Win, You Lose.");
}
printf("Use %d Steps\n",game.getstep());
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),dwWhite);
} pi.hconst DWORD dwWhite = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
const DWORD dwMe = FOREGROUND_GREEN;
const DWORD dwCom = FOREGROUND_RED;
//■□○●
char rec1[] = {-95,-10,0};
char rec2[] = {-95,-11,0};
char cir1[] = {-95,-16,0};
char cir2[] = {-95,-15,0};
//////////////////////////////////////////////////////////////////////////
//class pl
//////////////////////////////////////////////////////////////////////////
const int NMAX = 20;
const int MAX = 1200;
const char blank = '0';
const char me = '1';
const char com = '2';class pl {
public:
void sendxy(int &,int &);
void getxy(int,int);
void initscore();
void refreshscore(char,int,int);
void calscore(char);
void solve(int &,int &);
void printmap();
bool isok(int,int);
bool isend(int,int,char);
int getstep();
pl();
private:
int usestep;
int wincount;
char chess[NMAX][NMAX];
int win[2][MAX];
//ps,pt -> me
//cs,ct -> com
int ps[NMAX][NMAX],
cs[NMAX][NMAX];
bool pt[NMAX][NMAX][MAX],
ct[NMAX][NMAX][MAX];
};pl::pl() {
memset(chess,blank,sizeof(chess));
memset(pt,false,sizeof(pt));
memset(ct,false,sizeof(ct));
memset(win,0,sizeof(win));
wincount = 0;
usestep = 0;
initscore();
}void pl::printmap() {
int i,j; for (i=0;i<NMAX;i++) {
printf("\t\t\t%d\t",i);
for (j=0;j<NMAX;j++) {
if (chess[i][j] == me) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),dwMe);
printf("%s",cir2);
}
else if (chess[i][j] == com) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),dwCom);
printf("%s",cir2);
}
else printf("%s",rec2);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),dwWhite);
}
putchar('\n');
}
printf("\n\t\t\t\t");
for (i=0;i<NMAX;i++) printf("%2d",i);
putchar('\n');
}void pl::getxy(int x,int y) {
if (x==-1 && y==-1) return;
refreshscore(com,x,y);
}bool pl::isok(int x,int y) {
return (chess[x][y] == blank);
}bool pl::isend(int x,int y,char who) {
int i,j;
int l,r,u,d,c1,c2,c3,c4;
if (x==-1 && y==-1) return false;
l = r = u = d = 0;
c1 = c2 = c3 = c4 = 0;
for (i=1;i<5 && x+i < NMAX;i++) {
if (who == chess[x+i][y]) u ++;
else break;
}
for (i=1;i<5 && x-i >= 0;i++) {
if (who == chess[x-i][y]) d ++;
else break;
}
for (i=1;i<5 && y+i < NMAX;i++) {
if (who == chess[x][y+i]) r ++;
else break;
}
for (i=1;i<5 && y-i >= 0;i++) {
if (who == chess[x][y-i]) l ++;
else break;
}
for (i=1;i<5 && x+i < NMAX && y+i < NMAX;i++) {
if (who == chess[x+i][y+i]) c1 ++;
else break;
}
for (i=1;i<5 && x+i < NMAX && y-i >= 0;i++) {
if (who == chess[x+i][y-i]) c2 ++;
else break;
}
for (i=1;i<5 && x-i >= 0 && y-i >= 0;i++) {
if (who == chess[x-i][y-i]) c3 ++;
else break;
}
for (i=1;i<5 && x-i >= 0 && y+i < NMAX;i++) {
if (who == chess[x-i][y+i]) c4 ++;
else break;
}
return ( (u+1+d)>=5 || (l+1+r)>=5 || (c1+1+c3)>=5 || (c2+1+c4)>=5 );
}void pl::sendxy(int &x, int &y) {
solve(x,y);
usestep ++;
}//枚举赢的局面
void pl::initscore() {
int i,j,k;
//竖
for (i=0;i<NMAX;i++) {
for (j=0;j<NMAX-4;j++) {
for (k=0;k<5;k++) pt[j+k][i][wincount] = ct[j+k][i][wincount] = true;
wincount ++;
}
}
//横
for (i=0;i<NMAX;i++) {
for (j=0;j<NMAX-4;j++) {
for (k=0;k<5;k++) pt[i][j+k][wincount] = ct[i][j+k][wincount] = true;
wincount ++;
}
}
//斜1
for (i=0;i<NMAX-4;i++) {
for (j=0;j<NMAX-4;j++) {
for (k=0;k<5;k++) pt[j+k][i+k][wincount] = ct[j+k][i+k][wincount] = true;
wincount ++;
}
}
//斜2
for (i=0;i<NMAX-4;i++) {
for (j=NMAX-1;j>=4;j--) {
for (k=0;k<5;k++) pt[j-k][i+k][wincount] = ct[j-k][i+k][wincount] = true;
wincount ++;
}
}
}//计算全局位置的分值
void pl::calscore(char who) {
bool (*table)[NMAX][MAX];
int (*score)[NMAX];
int iwho;
if (who == me) {
table = pt;
score = ps;
iwho = 1;
}
else {
table = ct;
score = cs;
iwho = 0;
}
srand(time(NULL));
int i,j,k;
for (i=0;i<NMAX;i++) {
for (j=0;j<NMAX;j++) {
score[i][j] = 0;
if (chess[i][j] == blank) {
for (k=0;k<wincount;k++) {
if (!table[i][j][k]) continue;
//分值的大小影响棋子位置的选择
srand(rand());
switch (win[iwho][k]) {
case 1:
score[i][j] += 1;
break;
case 2:
score[i][j] += 10;
break;
case 3:
score[i][j] += 100;
break;
case 4:
score[i][j] += 1000;
}
}
}
}
}
}void pl::solve(int &x, int &y) {
calscore(me);
calscore(com);
int i,j;
int me_score,com_score;
int me_x,me_y,com_x,com_y;
me_score = com_score = -1;
//选取我方或对方得分最大值
for (i=0;i<NMAX;i++) {
for (j=0;j<NMAX;j++) {
if (chess[i][j] == blank) {
if (me_score < ps[i][j]) {
me_score = ps[i][j];
me_x = i;
me_y = j;
}
if (com_score < cs[i][j]) {
com_score = cs[i][j];
com_x = i;
com_y = j;
}
}
}
}
if (me_score > com_score) {
x = me_x;
y = me_y;
}
else {
x = com_x;
y = com_y;
}
refreshscore(me,x,y);
}//更新分数
void pl::refreshscore(char who,int x,int y) {
bool (*table)[NMAX][MAX];
bool (*antitable)[NMAX][MAX];
int iwho;
if (who == me) {
table = pt;
antitable = ct;
iwho = 1;
}
else {
table = ct;
antitable = pt;
iwho = 0;
}
chess[x][y] = who;
for (int i=0;i<wincount;i++) {
//一方位置能胜利次数
if (table[x][y][i] && win[iwho][i] < INT_MAX) win[iwho][i] ++;
if (antitable[x][y][i]) {
//另一方无法放置
antitable[x][y][i] = false;
win[1-iwho][i] = INT_MAX;
}
}
}int pl::getstep() {
return usestep;
}
6. 五子棋游戏程序设计(VB)
五子棋的构想 有句话叫“当局者迷,旁观者清。”,但这句话在由AI所控制的计算机玩家上是不成立的,因为计算机必须知道有那些获胜方式,并计算出每下一步棋到棋盘上任一格子的获胜几率,也就是说,一个完整的五子棋的AI构想必须:
1、能够知道所有的获胜组合; 2、建立和使用获胜表; 3、设定获胜的分数; 4、使电脑具有攻击和防守的能力; 一、求五子棋的获胜组合 在一场五子棋的游戏中,计算机必须要知道有那些的获胜组合,因此我们必须求得获胜组合的总数。我们假定当前的棋盘为10*10。 (1)计算水平方向的获胜组合数,每一列的获胜组合是:6,共10列,所以水平方向的获胜组合数为:6*10=60 (2)计算垂直方向的获胜组合总数,每一行的获胜组合是:6,共10行,则垂直方向的获胜组合数为:6*10=60 (3)计算正对角线方向的获胜组合总数,正对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36 (4)计算反对角线方向的获胜组合总数,反对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36 ,这样所有的获胜组合数为:60+60+36+36=192 二、建立和使用获胜表 我们已经计算出了一个10*10的五子棋盘会有192种获胜方式,这样我们可以利用数组建立获胜表,获胜表的主要作用是:1,判断当前的获胜方式是否有效;2,判断当前的获胜方式中到底有多少子落入该获胜组合中。详细的使用您将在后面的程序中可以看出。 三,分数的设定 在游戏中为了让计算机能够决定下一步最佳的走法,必须先计算出计算机下到棋盘上任一空格的分数,而其中最高分数便是计算机下一步的最佳走法。 原理:我们判定当前讨论的空格与当前讨论的点有几种获胜的方式,有几种该空格就加几分。这种原理初听起来似乎是无法入手,没关系,当您了解我们后面的程序后您就会明白这种决策原理了。 这种决策有一些缺陷,因为如果只根据这个模型设计,就有可能出现电脑或玩家有三个子连成一线的时候,计算机却判断不出,它认为其他某些空格是当前的获胜的最佳位置而不去攻击或防守。没关系我们完全可以通过一个加强算法来改变当前的分值情况,也就是说当电脑或玩家有三个子或四个子连成一线时,我们通过加强算法将当前与三个子或四个子有关的空格的分值提高,从而可以弥补这一缺憾。 四、攻击与防守 以上的方式,事实上计算机只是计算出了最佳的攻击位置,为了防守我们还应计算当前玩家的最佳的攻击位置。这样有什么用呢?道理很简单,如果玩家最佳攻击位置的分数大于计算机最佳攻击位置上的分数,那么计算机就将下一步的棋子摆在玩家的最佳攻击位上以阻止玩家的进攻,否则计算机便将棋子下在自己的最佳攻击位置上进行攻击。 事实上,这个AI构想是很强大的如果你不是很厉害的五子棋高手的话,可能很快会被计算机打败。我在联众上可是中级棋手啊,跟这种构想打的时候胜率也不是很高。 使用vb.net编写五子棋 一、编写前的准备: 1、用计算机的思想描述整个下棋的过程 考虑步骤: (1)为了简便我们可以先让电脑先走第一步棋,电脑每走一步就会封掉许多玩家的获胜可能情况。 (2)当玩家走棋的时候我们首先应该考虑玩家走棋的合法性。 (3)如果合法,那么玩家也会封掉许多电脑的获胜的可能情况。 (4)电脑的思考路径:首先判断当前玩家和电脑的所有获胜组合是否需要进行加强赋值,
是进行加强赋值,否则进行普通的赋值。 (5)比较当前玩家和电脑谁的分值最大。将分值最大的点作为电脑的下一步走法。 2、利用vb.net窗体和图形工具建立五子棋的棋盘界面 (1)添加一个picturebox控件 作用:使用picturebox控件绘制棋子和棋盘 (2)添加一个label控件 作用:显示当前的获胜标志,也就是当某一方获胜或和棋时显示此标签。 (3)添加一个mainmenu控件 作用:控制游戏的开始或结束 (4)添加一个mediaplay组件 作用:使程序可以播放音乐。 3、设置整体框价 我们采取10*10的棋盘,为主要的平台。利用数组定义整个棋盘桌面,利用数组定义获胜组合以及获胜标志等。 二,声明全局数组和变量 定义虚拟桌面: Dim table(9, 9) As Integer 定义当前玩家桌面空格的分数: Dim pscore(9, 9) As Integer 定义当前电脑桌面空格的分数: Dim cscore(9, 9) As Integer 定义玩家的获胜组合: Dim pwin(9, 9, 191) As Boolean 定义电脑的获胜组合: Dim cwin(9, 9, 191) As Boolean 定义玩家的获胜组合标志: Dim pflag(191) As Boolean 定义电脑的获胜组合标志:
Dim cflag(191) As Boolean 定义游戏有效标志: Dim theplayflag As Boolean 三、初始化游戏 '*****************************************************************************
'** 模块名称: initplayenvironment
'**
'** 描述: 此函数主要功能如下:
'** 1. 设置背景音乐。
'** 2. 设置游戏状态有效。
'** 3. 初始化游戏状态标签。
'** 4. 直接指定电脑的第一步走法。
'** 5. 初始化基本得分桌面。
'** 6. 电脑和玩家获胜标志初始化。
'** 7. 初始化所有获胜组合。
'** 8. 重新设定玩家的获胜标志。
'**
'*****************************************************************************
Sub initplayenvironment()
player.FileName = ".\music\zhyu01.mid"
player.Play()
theplayflag = True
'游戏有效
Label1.Visible = False
'游戏状态标签不显示
PictureBox1.Refresh()
'清空picturebox1的内容
yuandian(130, 130)
'调用绘图函数绘制当前电脑先走的位置
Dim i, j, m, n As Integer
For i = 0 To 9
For j = 0 To 9
table(i, j) = 0
Next
Next
'桌面初始化
For i = 0 To 191
pflag(i) = True
cflag(i) = True
Next
'获胜标志初始化
table(4, 4) = 1
'由于我们设定电脑先手,并下了4,4位所以将其值设为1
''' ******** 初始化获胜组合 ********
n = 0
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i, n) = True
cwin(j + m, i, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(i, j + m, n) = True
cwin(i, j + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i + m, n) = True
cwin(j + m, i + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 9 To 4 Step -1
For m = 0 To 4
pwin(j - m, i + m, n) = True
cwin(j - m, i + m, n) = True
Next
n = n + 1
Next
Next
''' ******** 初始化获胜组合结束 ********
For i = 0 To 191
If pwin(4, 4, i) = True Then
pflag(i) = False
End If
Next
'由于电脑已下了4,4位所以我们需要重新设定玩家的获胜标志
End Sub
四,处理鼠标事件 '*****************************************************************************
'** 模块名称: themousedown
'**
'** 描述: 此函数主要实行以下功能:
'** 1. 判定当前游戏标志是否有效。
'** 2. 将实际坐标转化成虚拟坐标。
'** 3. 绘制玩家的棋子。
'** 4. 执行检查获胜函数。
'** 5. 执行电脑算法函数。
'**
'*****************************************************************************
Sub themousedown(ByVal x As Integer, ByVal y As Integer)
If theplayflag = False Then
Exit Sub
End If
'检查游戏状态是否有效
Dim i, j As Integer
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
For i = 0 To 9
For j = 0 To 9
If table(zhx, zhy) > 0 Then
Exit Sub
End If
Next
Next
'检查当前鼠标点击的格子是否有效
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
mycolor = Color.White
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
'绘制玩家的棋子
table(zhx, zhy) = 2
For i = 0 To 191
If cwin(zhx, zhy, i) = True Then
cflag(i) = False
End If
Next
'重设电脑的获胜标志
checkwin()
'检查当前玩家是否获胜
diannao()
'调用电脑算法
End Sub 五、获胜检查算法。 '*****************************************************************************
'** 模块名称: checkwin
'**
'** 描述: 此模块执行以下功能:
'** 1. 检查是否和棋。
'** 2. 检查电脑是否获胜。
'** 3. 检查玩家是否获胜。
'**
'*****************************************************************************
Sub checkwin()
Dim i, j, k, m, n As Integer
Dim ca As Integer
Dim pa As Integer
Dim cnormal As Integer = 0
For i = 0 To 191
If cflag(i) = False Then
cnormal = cnormal + 1
End If
Next
If cnormal = 190 Then
Label1.Visible = True
Label1.Text = "和棋,请重新开始!"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
'设定和棋规则
For i = 0 To 191
If cflag(i) = True Then
ca = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
ca = ca + 1
End If
End If
Next
Next
If ca = 5 Then
Label1.Visible = True
Label1.Text = "电脑获胜,请重新开始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'检查电脑是否获胜
For i = 0 To 191
If pflag(i) = True Then
pa = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pa = pa + 1
End If
End If
Next
Next
If pa = 5 Then
Label1.Visible = True
Label1.Text = "玩家获胜,请重新开始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'检查玩家是否获胜
End Sub 六、电脑算法 '*****************************************************************************
'** 模块名称: diannao
'**
'** 描述: 此程序主要执行以下功能:
'** 1. 初始化赋值系统。
'** 2. 赋值加强算法。
'** 3. 计算电脑和玩家的最佳攻击位。
'** 4. 比较电脑和玩家的最佳攻击位并决定电脑的最佳策略。
'** 5. 执行检查获胜函数。
'**
'***************************************************************************** Sub diannao()
Dim i, j, k, m, n As Integer
Dim dc As Integer
Dim cab As Integer
Dim pab As Integer
For i = 0 To 9
For j = 0 To 9
pscore(i, j) = 0
cscore(i, j) = 0
Next
Next
'初始化赋值数组
''' ******** 电脑加强算法 ********
For i = 0 To 191
If cflag(i) = True Then
cab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
cab = cab + 1
End If
End If
Next
Next
Select Case cab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
cscore(m, n) = cscore(m, n) + 5
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
For i = 0 To 191
If pflag(i) = True Then
pab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pab = pab + 1
End If
End If
Next
Next
Select Case pab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
pscore(m, n) = pscore(m, n) + 30
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
''' ******** 电脑加强算法结束 ******** ' ******** 赋值系统 ********
For i = 0 To 191
If cflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If cwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 1 Then
If cwin(m, n, i) = True Then
cscore(j, k) = cscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
For i = 0 To 191
If pflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If pwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 2 Then
If pwin(m, n, i) = True Then
pscore(j, k) = pscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
''' ******** 赋值系统结束 ********
''' ******** 分值比较算法 ********
Dim a, b, c, d As Integer
Dim cs As Integer = 0
Dim ps As Integer = 0
For i = 0 To 9
For j = 0 To 9
If cscore(i, j) > cs Then
cs = cscore(i, j)
a = i
b = j
End If
Next
Next
For i = 0 To 9
For j = 0 To 9
If pscore(i, j) > ps Then
ps = pscore(i, j)
c = i
d = j
End If
Next
Next
If cs > ps Then
yuandian(a * 30 + 10, b * 30 + 10)
table(a, b) = 1
For i = 0 To 191
If pwin(a, b, i) = True Then
pflag(i) = False
End If
Next
Else
yuandian(c * 30 + 10, d * 30 + 10)
table(c, d) = 1
For i = 0 To 191
If pwin(c, d, i) = True Then
pflag(i) = False
End If
Next
End If
''' ******** 分值比较算法结束 ********
checkwin()
End Sub 七、绘制棋子 '*****************************************************************************
'** 模块名称: yuandian
'**
'** 描述: 此函数主要进行电脑棋子的绘制。
'**
'***************************************************************************** Sub yuandian(ByVal x As Integer, ByVal y As Integer)
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
mycolor = Color.Black
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
End Sub
7. 五子棋的程序设计.
// 程序“五子棋第三方版.exe”运行时,把以前下棋的棋谱保存在“棋谱.txt”文件中,
// 然后调用本程序。
// 本程序的作用是:首先读入以前的棋谱,然后调用函数“qxwz()”计算出计算机应该
// 下棋的位置,并保存在c中,然后把应下棋的位置写入文件“当前棋子.txt”
#include <stdio.h>
typedef struct
{
char x;
char y;
} QZ;
QZ qzwz(); //取得应下棋位置,返回值为QZ类型,其中的x,y两个成员代表应下棋位置
char qp[19][19]; //用于保存棋盘上每个点的状态,0--空,1--黑棋,2--白棋
void main()
{
FILE *fp;
int tmp1,tmp2,tmp3;
QZ c;
/* 读入当前棋谱 */
if((fp=fopen("棋谱.txt","r"))==NULL)
{
printf("[棋谱.TXT]文件打开失败!\n");
return;
}
while(!feof(fp))
{
tmp1=tmp2=tmp3=-1;
fscanf(fp,"%d%d%d",&tmp1,&tmp2,&tmp3);
if(tmp3!=-1)
{
qp[tmp1][tmp2]=tmp3;
}
}
fclose(fp);
c=qzwz();
if((fp=fopen("当前棋子.txt","w"))==NULL)
{
printf("[当前棋子.TXT]文件打开失败!\n");
return;
}
fprintf(fp,"%d,%d,%d",c.x,c.y,2); //将应下棋位置传送到文件中
fclose(fp);
}
QZ qzwz()
{
(把这里面的程序补充完整就好了)
} 这个程序要求是:
1。只适用于人先下,机器后下的情况。有了“五子棋第三方版.exe”来制作下棋界面,就只需要编写下棋算法,而不必考虑其它的问题了。
2.当运行“五子棋第三方版.exe”程序时,该程序接受人下棋位置,然后调用“wzq.exe”程序,由“wzq.exe”程序计算出机器的应对并写入到“当前棋子.txt”文件中(结束),机器的应对结果由“五子棋第三方版.exe”负责读入,并等待人下一步的应对。
3.要做的工作就是,完成“wzq.cpp” 中“qxwz()”函数的设计,使之能返回一个比较好的下棋位置。在设计过程中,可以增加全局变量以保存你认为有必要保存的数据,可以增加其它文件,用来保存你认为下次调用还有必要使用的数据,可以增加其它函数以方便下棋位置的计算过程。总之,所给出的“wzq.cpp”程序只是一个框架,在不影响其功能的情况下,可以随意更改。
8. 跪求五子棋的编程和流程图
关键词:五子棋;极大极小值;剪枝;算法改进 近来随着计算机的快速发展,各种棋类游戏被纷纷请进了电脑,使得那些喜爱下棋,又常常苦于没有对手的棋迷们能随时过足棋瘾。而且这类软件个个水平颇高,大有与人脑分庭抗礼之势。其中战胜过国际象棋世界冠军-卡斯帕罗夫的“深蓝”便是最具说服力的代表;其它像围棋的“手淡”、象棋的“将族”等也以其优秀的人工智能深受棋迷喜爱;而我们今天将向大家介绍的是五子棋的算法。 当我们与电脑对战时,您知道这些软件是怎样象人脑一样进行思考的吗?在这里就以此为例和大家一起探讨探讨。 为了使读者对五子棋搜索复杂度有个形象的认识,举一个中国象棋跟五子棋搜索次数的比较(如图)。可以看出同中国象棋相比,五子棋的分支系数大的多,而且胜负条件判断也复杂一些。在极大的分支系数下,搜索程序的最大搜索深度增加1层,耗费的运算时间都将大量增加。因此设计出一个有效的搜索算法是非常重要的。 中国象棋 五子棋 棋子种类 14 2 棋盘大小 9×10 15×15 分支系数 约40 约200 棋子数量 递减 递增 胜负条件 某方将帅丧失 某方五个棋子连成一线 文章的组织如下:首先简单介绍用C语言作图的基本方法(Turbo C 2.0环境)以及主循环控制下棋模块,其次介绍设计这个五子棋程序的数据结构,然后介绍了评分算法以及胜负判断,最后重点讨论实现搜索算法。 1. 基本的C作图方法及主循环控制模块 Turbo C提供了非常丰富的图形函数,所有的图形函数的原型均建立在graphics.h中,在使用图形函数时要确保有显示器图形驱动程序*.BGI,同时将集成开发环境Options/Linker中的Graphics lib选为on,只有这样才能保证正确使用图形函数。 这个程序调用一个EGA、VGA显示器下能独立图形运行的函数。所谓独立图形运行程序,就是在编译和连接时将相应的驱动程序(*.BGI)直接装入到执行程序,从而能在独立的计算机上运行,避免需要重新编译连接才能运行(请查阅参考书1以及源码)。Turbo C进行画点、画线、封闭图形填充以及图形下文本输出只需要调用graphics.h中相关的函数。 主循环控制模块:控制下棋顺序,当轮到某方下子时,负责将程序转到相应的模块中去,主要担当一个调度者的角色。这个五子棋程序是用键盘控制下棋,所以要用到Turbo C中的bios.h。在一个循环块中等待键盘信息,判断键盘所输入的信息是否需要响应,调用相关的代码进行下棋(参考源码中的main函数部分)。 2. 五子棋基本数据结构 为整个棋盘建立一张表格用以记录棋子信息,使用一个15*15的二维数组 chessman[15][15] (15*15是五子棋棋盘的大小),数组的每一个元素对应棋盘上的一个交叉点,用“0”表示空位、“1”代表己方棋子、“2”代表对方棋子。这张表也是今后分析的基础。其次要建立一个结构,主要用于搜索过程中,定义如下: typedef struct five_chess* point; struct five_chess{ int x; int y; int layer; int value; int score; int chess[LENGTH][LENGTH]; int record[LENGTH][LENGTH]; }; x,y表示在某个位置上扩展出来的新节点,layer是表示第几层扩展,用于控制扩展深度。value表示该点上极大极小值,score表示叶子节点的得分,用于推算父辈节点的value,chess这个二维数组表示扩展出来的棋盘信息,record记录在x、y点上扩展过的节点,如果没有扩展record中对应某个值为0。如果record中没有可以扩展的节点,那么该层扩展结束,返回一个特定值。 数组和一个结构构成了程序的基本数据骨架,今后只要再加入一些辅助变量便可以应付自如了。 3. 评分规则以及胜负判断 评估一个棋盘的分数,主要通过扫描整个棋盘,对每个点评分。对某个点上评分从四个方向(角度分别为0、45、90、135的四个方向)分别统计,进而累积该
9. 五子棋软件设计
/*********************************************************************************
加分才能得到更多的回答呀!
游戏说明
1.本五子棋规则遵循一般五子棋游戏规则。
2.'W',',S','A','D'分别对应与光标的上、下、左、右。“Enter”为落子键.且在
游戏当中双方必须分时复用。
3.本代码在Turboc 2.0 SMALL模式下调试通过。
4.如果要单独运行该代码生成的EXE文件,请确保Turboc 2.0系统自带的*.BGI与
该EXE在同一目录下,以便图形系统的正常运行。
*********************************************************************************/
#include <graphics.h>
#include <stdio.h>
#include <dos.h>
/*******************************全程变量****************************************/
#define HORIZON 150
#define VERTICAL 30
#define MAXX 15
#define MAXY 15
int curx=HORIZON,cury=VERTICAL;
char C='';
int AOrB=0;
int state[MAXY][MAXX]; /*state[][]为红白方状态:1为红方,2为白方.*/
/*******************************************************************************/
struct Offset
{
int abs;
int array;
int offset;
int state;
};
struct XYPoint
{
int x;
int y;
};
struct WinPoint
{
struct XYPoint pointXY[5];
char win;
};
char getkey()
{
union REGS regs;
regs.h.ah=0;
return int86(0x16,®s,®s);
}
void DrawRectangle(int color)
{
int tmpcolor=0,i=0;
tmpcolor=getcolor();
setcolor(color);
for(i=0;i<16;i++)
line(20,190+i,100,190+i);
setcolor(tmpcolor);
}
void PutCharADSW(char ch)
{
setcolor(WHITE);
outtextxy(20,50,"W");
outtextxy(20,80,"S");
outtextxy(20,110,"A");
outtextxy(20,140,"D");
setcolor(LIGHTBLUE);
switch(ch)
{
case 'A':
case 'a':
outtextxy(20,110,"A");
break;
case 'D':
case 'd':
outtextxy(20,140,"D");
break;
case 'S':
case 's':
outtextxy(20,80,"S");
break;
case 'W':
case 'w':
outtextxy(20,50,"W");
break;
}
}
void InterFace(void)
{
int i;
char *tp=NULL;
tp="W: up";
outtextxy(20,50,tp);
tp="S: down";
outtextxy(20,80,tp);
tp="A: left";
outtextxy(20,110,tp);
tp="D: Right";
outtextxy(20,140,tp);
tp="Current:";
outtextxy(20,170,tp);
DrawRectangle(WHITE);
for(i=0;i<MAXX;i++)
line(HORIZON,i*30+VERTICAL,HORIZON+420,i*30+VERTICAL);
for(i=0;i<MAXY;i++)
line(HORIZON+i*30,VERTICAL,HORIZON+i*30,420+VERTICAL);
}
void DrawCircle(int x,int y,int radius,int colour)
{
int i;
setcolor(colour);
for(i=0;i<radius;i++)
circle(x,y,i);
}
void DrawLine(int x,int y,int xx,int yy,int col)
{
int tmpcolour=0;
tmpcolour=getcolor();
setcolor(col);
line(x,y,xx,yy);
setcolor(tmpcolour);
}
void SetCursor(int x1,int y1,int col)
{
DrawLine(curx-14+x1,cury-14+y1,curx-4+x1,cury-14+y1,col);
DrawLine(curx+4+x1,cury-14+y1,curx+14+x1,cury-14+y1,col);
DrawLine(curx-14+x1,cury-14+y1,curx-14+x1,cury-4+y1,col);
DrawLine(curx+14+x1,cury-14+y1,curx+14+x1,cury-4+y1,col);
DrawLine(curx-14+x1,cury+14+y1,curx-4+x1,cury+14+y1,col);
DrawLine(curx+4+x1,cury+14+y1,curx+14+x1,cury+14+y1,col);
DrawLine(curx-14+x1,cury+4+y1,curx-14+x1,cury+14+y1,col);
DrawLine(curx+14+x1,cury+4+y1,curx+14+x1,cury+14+y1,col);
}
/*struct Offset
{
int abs; curx,cury
int array; x,y
int offset; x1,y1
int state; 0表示:无空位;1表示:有空位
};*/
/*Test Vertical*/
/*Test x Y Or N Space*/
int TestxYOrNSpace(int y)
{
int i=0,sum=1;
for(i=0;i<MAXY;i++)
{
sum&=(1==state[i][y]||2==state[i][y]);
if(!sum)break;
}
return(sum);
/*sum==0表示该行列没有空位*/
}
/*Go Left*/
struct Offset * TestMoveCursorLeft(int y,struct Offset * pointer)
{
int i=0,sum=1;
for(i=y-1;i>=0;i--)
{
sum=TestxYOrNSpace(i);
if(!sum)break;
}
if(sum)
{/*表示该点左边已没有空位*/
pointer->abs=0;
pointer->array=0;
pointer->offset=0;
pointer->state=0;/*若为0,表示无空位*/
}
else
{
pointer->abs=(30)*(y-i);
pointer->array=y-i;
pointer->offset=(30)*(y-i);
pointer->state=1;/*若为1,表示有空位*/
}
return(pointer);
}
/*Go Right*/
struct Offset * TestMoveCursorRight(int y,struct Offset * pointer)
{
int i=0,sum=1;
for(i=y+1;i<MAXX;i++)
{
sum=TestxYOrNSpace(i);
if(!sum)break;
}
if(sum)
{
pointer->abs=0;
pointer->array=0;
pointer->offset=0;
pointer->state=0;/*若为0,表示无空位*/
}
else
{
pointer->abs=(30)*(i-y);
pointer->array=i-y;
pointer->offset=(30)*(i-y);
pointer->state=1;/*若为1,表示有空位*/
}
return(pointer);
}
/*Test y Y Or N Space*/
int TestyYOrNSpace(int x)
{
int i=0,sum=1;
for(i=0;i<MAXX;i++)
{
sum&=(1==state[x][i]||2==state[x][i]);
if(!sum)break;
}
return(sum);
}
/*Go Up*/
struct Offset * TestMoveCursorUp(int x,struct Offset * pointer)
{
int i=0,sum=1;
for(i=x-1;i>=0;i--)
{
sum=TestyYOrNSpace(i);
if(!sum)break;
}
if(sum)
{
pointer->abs=0;
pointer->array=0;
pointer->offset=0;
pointer->state=0;/*若为0,表示无空位*/
}
else
{
pointer->abs=(30)*(x-i);
pointer->array=x-i;
pointer->offset=(30)*(x-i);
pointer->state=1;/*若为1,表示有空位*/
}
return(pointer);
}
/*Go Down*/
struct Offset * TestMoveCursorDown(int x,struct Offset * pointer)
{
int i=0,sum=1;
for(i=x+1;i<MAXY;i++)
{
sum=TestyYOrNSpace(i);
if(!sum)break;
}
if(sum)
{
pointer->abs=0;
pointer->array=0;
pointer->offset=0;
pointer->state=0;/*若为0,表示无空位*/
}
else
{
pointer->abs=(30)*(i-x);
pointer->array=i-x;
pointer->offset=(30)*(i-x);
pointer->state=1;/*若为1,表示有空位*/
}
return(pointer);
}
void ClearPoint(struct Offset * pointer)
{
pointer->abs=0;
pointer->array=0;
pointer->offset=0;
pointer->state=0;
}
void Delay(int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<32767;j++);
}
/*Move Cursor*/
void MoveCursor(struct XYPoint *PointXY)
{
int x1=0,y1=0,lop=1,x=0,y=0; /*x1,y1为光标在各方向的偏移量*/
struct Offset InfoOffset,*point=NULL;
point=&InfoOffset;
ClearPoint(point);
x=(curx-HORIZON)/30; /*(x,y)为STATE[][]数组坐标*/
y=(cury-VERTICAL)/30;
while(lop)
{
C=getkey();
switch(C)
{
case 'A':
case 'a':
PutCharADSW(C);
if(curx>HORIZON)
{
point=TestMoveCursorLeft(x,point);
if(point->state)
{
curx-=point->abs;
x-=point->array;
x1+=point->offset;
ClearPoint(point);
}
}
break;
case 'D':
case 'd':
PutCharADSW(C);
if(curx<420+HORIZON)
{
point=TestMoveCursorRight(x,point);
if(point->state)
{
curx+=point->abs;
x+=point->array;
x1-=point->offset;
ClearPoint(point);
}
}
break;
case 'W':
case 'w':
PutCharADSW(C);
if(cury>VERTICAL)
{
point=TestMoveCursorUp(y,point);
if(point->state)
{
cury-=point->abs;
y-=point->array;
y1+=point->offset;
ClearPoint(point);
}
}
break;
case 'S':
case 's':
PutCharADSW(C);
if(cury<VERTICAL+420)
{
point=TestMoveCursorDown(y,point);
if(point->state)
{
cury+=point->abs;
y+=point->array;
y1-=point->offset;
ClearPoint(point);
}
}
break;
case 13 : /*落子:AOrB==0 RED;AOrB==1 WHITE*/
if(!(state[y][x]&0x3))
{
if(1==AOrB)
{
state[y][x]|=0x1;
DrawCircle(curx,cury,15,RED);
AOrB=0;
DrawRectangle(WHITE);
}
else
{
state[y][x]|=0x2;
DrawCircle(curx,cury,15,WHITE);
AOrB=1;
DrawRectangle(RED);
}
lop=0;
PointXY->x=x;
PointXY->y=y;
}
break;
}
SetCursor(x1,y1,getbkcolor()); /*clear old*/
x1=0;
y1=0;
SetCursor(0,0,BLUE);
}
}
/*Example: MoveCircle(60+cou*30,20,'H',30,WHITE);*/
void MoveCircle(int x,int y,char way,int offset,int colour)
{
int tmp=0;
for(tmp=0;tmp<15;tmp++)
DrawCircle(x,y,15,getbkcolor());
DrawLine(x-15,y,x+15,y,WHITE);
DrawLine(x,y,x,y+15,WHITE);
switch(way)
{
case 'h':
case 'H':
DrawCircle(x+offset,y,15,colour);
break;
case 'v':
case 'V':
DrawCircle(x,y+offset,15,colour);
}
}
void DrawRLine(int x,int y)
{
if(x> HORIZON)
DrawLine(x-15,y,x,y,WHITE); /*Left*/
if(x<30*14+HORIZON)
DrawLine(x,y,x+15,y,WHITE); /*Right*/
if(y>VERTICAL)
DrawLine(x,y-15,x,y,WHITE); /*Up*/
if(y<30*14+VERTICAL)
DrawLine(x,y,x,y+15,WHITE); /*Down*/
}
void FlashCircle(struct WinPoint win)
{
int i=0,color=0,count=0,EXIT=0;
/*DrawCircle(curx,cury,15,RED)*/
switch(AOrB)
{
case 0: /*AOrB==0 RED*/
color=RED;
break;
case 1: /*AOrB==1 WHITE*/
color=WHITE;
break;
}
while(1)
{
if(count)
{
DrawCircle(HORIZON+30*win.pointXY[0].x,VERTICAL+30*win.pointXY[0].y,15,getbkcolor());
DrawRLine( HORIZON+30*win.pointXY[0].x,VERTICAL+30*win.pointXY[0].y);
DrawCircle(HORIZON+30*win.pointXY[1].x,VERTICAL+30*win.pointXY[1].y,15,getbkcolor());
DrawRLine( HORIZON+30*win.pointXY[1].x,VERTICAL+30*win.pointXY[1].y);
DrawCircle(HORIZON+30*win.pointXY[2].x,VERTICAL+30*win.pointXY[2].y,15,getbkcolor());
DrawRLine( HORIZON+30*win.pointXY[2].x,VERTICAL+30*win.pointXY[2].y);
DrawCircle(HORIZON+30*win.pointXY[3].x,VERTICAL+30*win.pointXY[3].y,15,getbkcolor());
DrawRLine( HORIZON+30*win.pointXY[3].x,VERTICAL+30*win.pointXY[3].y);
DrawCircle(HORIZON+30*win.pointXY[4].x,VERTICAL+30*win.pointXY[4].y,15,getbkcolor());
DrawRLine( HORIZON+30*win.pointXY[4].x,VERTICAL+30*win.pointXY[4].y);
}
else
{
DrawCircle(HORIZON+30*win.pointXY[0].x,VERTICAL+30*win.pointXY[0].y,15,color);
DrawCircle(HORIZON+30*win.pointXY[1].x,VERTICAL+30*win.pointXY[1].y,15,color);
DrawCircle(HORIZON+30*win.pointXY[2].x,VERTICAL+30*win.pointXY[2].y,15,color);
DrawCircle(HORIZON+30*win.pointXY[3].x,VERTICAL+30*win.pointXY[3].y,15,color);
DrawCircle(HORIZON+30*win.pointXY[4].x,VERTICAL+30*win.pointXY[4].y,15,color);
}
Delay(1000);
if(5==i)
{
i=0;
if(count)
count=0;
else
count=1;
}
i++;
EXIT++;
if(105==EXIT)break;
}
}
void InitializationState(int pointer[MAXY][MAXX])
{
int i,j;
for(i=0;i<MAXY;i++)
for(j=0;j<MAXX;j++)
{
*(*(pointer+i)+j)=0;
}
}
/*Test WIN*/
struct WinPoint TestWIN(int Tmp,struct WinPoint TmpWinPoint,struct XYPoint * PointXY)
{
int i=0,j=0,s=Tmp;
TmpWinPoint.win=0;
for(i=0;i<5;i++)
{
if(PointXY->x+i>=4 && PointXY->x+i <15)
{
for(Tmp=s,j=4;j>=0;j--)/*0度*/
{
TmpWinPoint.pointXY[j].x=PointXY->x+i-j;
TmpWinPoint.pointXY[j].y=PointXY->y;
Tmp&=state[PointXY->y][PointXY->x+i-j];
}
if(Tmp)
{
TmpWinPoint.win=1;
break;
}
}
if(PointXY->x-i>=0 && PointXY->x-i <11 && PointXY->y+i>=4 && PointXY->y+i <15)
{
for(Tmp=s,j=4;j>=0;j--)/*45度*/
{
TmpWinPoint.pointXY[j].x=PointXY->x-i+j;
TmpWinPoint.pointXY[j].y=PointXY->y+i-j;
Tmp&=state[PointXY->y+i-j][PointXY->x-i+j];
/*printf(" %d",state[PointXY->y+i-j][PointXY->x+i+j]);*/
}
if(Tmp)
{
TmpWinPoint.win=1;
break;
}
}
if(PointXY->y+i>=4 && PointXY->y+i <15)
{
for(Tmp=s,j=4;j>=0;j--)/*90度*/
{
TmpWinPoint.pointXY[j].x=PointXY->x;
TmpWinPoint.pointXY[j].y=PointXY->y+i-j;
Tmp&=state[PointXY->y+i-j][PointXY->x];
}
if(Tmp)
{
TmpWinPoint.win=1;
break;
}
}
if(PointXY->x+i>=4 && PointXY->x+i <15 && PointXY->y+i>=4 && PointXY->y+i <15)
{
for(Tmp=s,j=4;j>=0;j--)/*135度*/
{
TmpWinPoint.pointXY[j].x=PointXY->x+i-j;
TmpWinPoint.pointXY[j].y=PointXY->y+i-j;
Tmp&=state[PointXY->y+i-j][PointXY->x+i-j];
}
if(Tmp)
{
TmpWinPoint.win=1;
break;
}
}
}
return(TmpWinPoint);
}
/*Test Win Y or N*/
struct WinPoint Test_Win_YorN(struct XYPoint * PointXY)
{
struct WinPoint TmpWinPoint;
TmpWinPoint.win=0;
switch(AOrB)
{
case 0: /*AOrB==0 RED*/
TmpWinPoint=TestWIN(1,TmpWinPoint,PointXY);
break;
case 1: /*AOrB==1 WHITE*/
TmpWinPoint=TestWIN(2,TmpWinPoint,PointXY);
break;
}
return(TmpWinPoint);
}
main()
{
int driver,mode,NoWiner=1;
struct XYPoint CurrentXY;
struct WinPoint WIN;
START:
driver=DETECT;
mode=0;
detectgraph(&driver,&mode);
initgraph(&driver,&mode,"");
InterFace();
InitializationState(state);
CurrentXY.x=0;
CurrentXY.y=0;
SetCursor(0,0,BLUE);
while(NoWiner)
{
MoveCursor(&CurrentXY);
WIN=Test_Win_YorN(&CurrentXY);
if(WIN.win)break;
}
FlashCircle(WIN);
setcolor(WHITE);
outtextxy(280,215,"CONTINUE ?[Y/N]");
C=getkey();
if('Y'==C ||'y'==C)
{
C='';
goto START;
}
}