论坛: 编程破解 标题: 刚学c++,在写井字棋遇到困难,代码加了好多的注释了谢谢了268 复制本贴地址    
作者: bailove [bailove]    论坛用户   登录
//编写井字棋游戏:
//编写一个完整的三连棋游戏程序。该类包含一个3X3双下标整型数组,将其作为private数据,/构造函数将空棋盘全部初始化为空。允许两个人玩游戏。第一个人走棋时,将x放在某个格中; 第二个人走棋时,将0放在另一格中,每次放置到空白格。走棋之后,确定是已胜负,还是出现了平局。如果想进一步研究,还可以将程序修改成人机对战游戏,允许游戏者决定他是先走还是后走。
//
//开始:
//  |  |
//---+---+---
//  |  | 
//---+---+---
//  |  |
//
//player x enter move: 2 0
//  |  |
//---+---+---
//  |  | 
//---+---+---
// x |  |
//
//...
//
//  |  | x
//---+---+---
//  | x | 0 
//---+---+---
// x |  | 0
//
//player x赢了,而player 0 输了

//上面是题目

//现在出现的问题是  没有办法正确的判断 输赢  可能是int judge(int x,int y,direction way)这个成员函数出了问题
//但找了一天了 都没有答案  单步执行 也觉的局部数据没错 但执行却乱跳  郁闷到死了  又觉的这样的思路完全可行,

//谁能帮帮小弟  谢谢了

//如果注释不够 我再加  再次谢谢  大哥  老大们

//设计思路  通过递归 探索 从所下棋的棋当前棋子 所有路径 能不能联成3 个一样的(相同的压栈)。其中四角和中间的点 容许8种方式,其他的点容许4种的探索方式
//当遇到边界的时候 向相反的方向搜索 直到所有的棋盘位置都没了  判定平局

#include <iostream>
#include <string>
#include <stack>
using namespace std;

enum chessman{//棋子枚举类型
enmty,
charonechessman,
chartwochessman
};

enum direction{    //方向表示
up,down,leftd,rightd,up_left,right_down,down_left,up_right,error
};

class ticktacktoe{
private:
chessman chessboard[3][3];
public:
stack<chessman> judgestack;
ticktacktoe(){    //通过构造函数初始化棋盘
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++){
chessboard[i][j]=enmty;
}
}

bool playchess(int x,int y,chessman chara){  //下棋
if(chessboard[x][y]==enmty){
chessboard[x][y]=chara;
return true;
}else
return false;
}

void playchessboard(){  //显示当前棋盘情况
char onechessman='x';
char twochessman='0';
char enmtychessman=' ';
char chess[3][3];
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++){
if (chessboard[i][j]==charonechessman)
chess[i][j]=onechessman;
if(chessboard[i][j]==chartwochessman)
chess[i][j]=twochessman;
if(chessboard[i][j]==enmty)
chess[i][j]=enmtychessman;
}
cout<<" "<<chess[0][0]<<" | "<<chess[0][1]<<" | "<<chess[0][2]<<" "<<endl;
cout<<"---+---+---"<<endl;
cout<<" "<<chess[1][0]<<" | "<<chess[1][1]<<" | "<<chess[1][2]<<" "<<endl;
cout<<"---+---+---"<<endl;
cout<<" "<<chess[2][0]<<" | "<<chess[2][1]<<" | "<<chess[2][2]<<" "<<endl;
}
//判定从该点各个方向出发是否发现相同的棋子,发现相同的向前出发一步,不相同的报错
direction judge_direction(int& x,int& y,direction way){
if(way==up){
if(x-1<0)
return down;
if(chessboard[x][y]!=chessboard[x-1][y])
return error;
else {
x=x-1;
return up;

}
}
if(way==down){
if(x+1>2)
return up;
if(chessboard[x][y]!=chessboard[x+1][y])
return error;
else {
x=x+1;
return down;

}
}
if(way==leftd){
if(y-1<0)
return rightd;
if(chessboard[x][y]!=chessboard[x][y-1])
return error;
else {
y=y-1;
return leftd;

}
}
if(way==rightd){
if(y+1>0)
return leftd;
if(chessboard[x][y]!=chessboard[x][y+1])
return error;
else {
y=y+1;
return rightd;

}
}

if(way==up_left){
if(y-1<0||x-1<0)
return right_down;
if(chessboard[x][y]!=chessboard[x-1][y-1])
return error;
else {
y=y-1;x=x-1;
return up_left;

}
}
if(way==right_down){
if(y+1>2||x+1>2)
return up_left;
if(chessboard[x][y]!=chessboard[x+1][y+1])
return error;
else {
y=y+1;x=x+1;
return right_down;

}
}

if(way==down_left){
if(y-1<0||x+1>2)
return up_right;
if(chessboard[x][y]!=chessboard[x+1][y-1])
return error;
else {
y=y-1;x=x+1;
return down_left;

}
}
if(way==up_right){
if(y+1<0||x-1>2)
return down_left;
if(chessboard[x][y]!=chessboard[x-1][y+1])
return error;
else {
y=y+1;x=x-1;
return up_right;

}
}
}
//通过递归 探索 从当前棋子所有路径可能路径能不能联成3 个一样的。其中四角加中间的点 容许8种方式,其他的点容许4种的探索方式
//当遇到边界的时候 向相反的方向搜索
int judge(int x,int y,direction way){

int tempx=x,tempy=y;
int sameness=0;//用来表示从当前点出发了多少步
int i;
if(!judgestack.empty()){
for(i=0;i<judgestack.size();i++)
judgestack.pop ();
}
if(x+y==2||x==y){
judgestack.push(chessboard[x][y]);
do{

if(judge_direction(tempx,tempy,way)==way){
judgestack.push(chessboard[tempx][tempy]);
if(judgestack.size() ==3){
cout<<"你赢了";
return 1;
}
sameness++;
continue;
}
if(judge_direction(tempx,tempy,way)==(direction)(way+1)){  //判断是否向相反的方向走了,下面分两个处理,如果已经走了一步直接判断另一个方向位置是否相同而连成3个,
                                                      //如果没有走,就把另一个方向代入,通过递归 把栈清空 再进行走方向
tempx=x;
tempy=y;
way=(direction)(way+1);
if(judge_direction(tempx,tempy,way)==way&&sameness>0){
judgestack.push(chessboard[tempx][tempy]);
if(judgestack.size() ==3){
cout<<"你赢了";
return 1;
}
sameness++;
}else
judge(x,y,way);


}
if(judge_direction(tempx,tempy,way)==error){
sameness=0;
if(way<8){
if(way%2)
way=(direction)(way+1);
else
way=(direction)(way+2);
if(way==error)
return 0;

judge(x,y,way);
}

}
}while(sameness);

}else {
sameness=0;
judgestack.push(chessboard[x][y]);
do{

if(judge_direction(tempx,tempy,way)==way){
judgestack.push(chessboard[tempx][tempy]);
if(judgestack.size() ==3){
cout<<"你赢了";
return 1;
}
sameness++;
continue;
}
if(judge_direction(tempx,tempy,way)==(direction)(way+1)){
tempx=x;
tempy=y;
way=(direction)(way+1);
sameness=0;
if(judge_direction(tempx,tempy,way)==way&&sameness>0){
judgestack.push(chessboard[tempx][tempy]);
if(judgestack.size() ==3){
cout<<"你赢了";
return 1;
}
sameness++;
}else {
judge(x,y,way);
}

}
if(judge_direction(tempx,tempy,way)==error){
if(way!=4){
if(way%2)
way=(direction)(way+1);
else
way=(direction)(way+2);
if(way==error)
return 0;
judge(x,y,way);
}

}
}while(sameness);
}

}


};

void main(){
ticktacktoe aticktacktoe;
chessman chessman1=charonechessman,chessman2=chartwochessman;
direction way=up;
int x,y;
int times=0;
cout<<"开始:"<<endl;
aticktacktoe.playchessboard ();
do{
cout<<"第一个玩家下棋:";
cin>>x>>y;
aticktacktoe.playchess(x,y,chessman1);
aticktacktoe.playchessboard ();
if(aticktacktoe.judgestack.size() ==3){
cout<<"第一个玩家状态:鹰";

break;
}

times++;


cout<<"第二个玩家下棋:";
cin>>x>>y;
aticktacktoe.playchess(x,y,chessman2);
aticktacktoe.playchessboard ();
if(aticktacktoe.judgestack.size ()==3){
cout<<"第二个玩家状态:赢";

break;
}
times++;

cout<<aticktacktoe.judge (x,y,way);//自己想看 还回了什么值 没有特殊的涵义
}while(aticktacktoe.judge(x,y,way)==0||times<=8);
if(times>=8)
cout<<"平局";
}




地主 发表时间: 05-08-06 10:06

回复: 286 [unique]   版主   登录
判断时为什么不直接对chessboard[3][3];判断呢?

for (int i=0;i<3;i++)
{
    if (chessboard[i][0]==chessboard[i][1]==chessboard[i][2])
        //有赢返回。
    if (chessboard[0][i]==chessboard[1][i]==chessboard[2][i])
        //有赢返回。
}
if (chessboard[0][0]==chessboard[1][1]==chessboard[2][2])
        //有赢返回。
if (chessboard[0][2]==chessboard[1][1]==chessboard[2][0])
        //有赢返回。

//返回无赢。



B1层 发表时间: 05-08-08 10:25

回复: bailove [bailove]   论坛用户   登录
因为 我想把这想法  扩展到  五子棋的情况  和迷宫问题

B2层 发表时间: 05-08-08 22:25

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号