#include<iostream>
#include<cstring>
using namespace std;
class CHESS
{
private:
int Size,Row; //棋盘大小(Size*Size)和连珠数目
int Owin,Xwin,Draws; //棋手获胜局数和平局数
char Board[25][25]; //棋盘
char player_1[20],player_2[20]; //玩家姓名
int x,y,SpotsOnBoard; //记录落子坐标与落子数目
public:
void Gamemode(); //游戏模式 , 选择棋盘大小和连珠数目
void Player(); //存储玩家姓名
void PrintBoard(); //打印棋盘
void PrintInfo(); //打印游戏规则
void PrintStats(); //打印统计的胜负信息
void ChoiceOfChar(char&); //询问用户是否再玩一局
void PromptTurn(); //提示玩家下棋(O 先 X 后)
void IfError(); //判断所下棋子坐标是否有错
int IfJudge(); //判断棋子是否完成连珠
int Result(); //落子后处理
void Setboard(); //重置棋盘、落子坐标和落子数目
};
//3. 各成员函数
void CHESS::Gamemode() //选择棋盘大小和连珠数目
{
do
{
cout<<"请输入棋盘大小 (3~20):";
cin>>Size;
}
while(Size>20||Size<3); //确保输入正确的棋盘大小
do
{
cout<<"请输入连珠数目 (3~5):";
cin>>Row;
}while(Row>5||Row<3); //确保输入正确的连珠数目
Owin=0; //初始化Y胜利数
Xwin=0; //初始化X胜利数
Draws=0; //初始化平局数
}
void CHESS::Player() //存储玩家姓名
{
cout<<"请输入玩家一(player1)姓名 : ";
cin>>player_1;
cout<<endl;
cout<<"请输入玩家二(player2)姓名 : ";
cin>>player_2;
cout<<endl;
}
void CHESS::PrintBoard()
{
int i,j; //分别记录行数、列数
cout<<endl;
cout<<" ";
for(j=0; j<Size; j++) {
if(j<10)
cout<<" "<<j+1; //棋盘的列坐标
else
cout<<" "<<j+1;
}
cout<<endl;
for(i=0; i<Size; i++)
{
cout<<" "<<i+1; //棋盘的行坐标
if(i+1<10) cout<<" ";
for(j=0; j<Size; j++) cout<<Board[i][j]<<" |"; //棋子放置区
cout<<endl;
cout<<" ";
for(j=0; j<Size; j++) cout<<"---|"; //网格边界
cout<<endl;
}
cout<<endl;
}
void CHESS::PrintInfo()
{
cout<<"欢迎来到连珠游戏 "<<endl;
cout<<"本游戏需要两位棋手轮流下棋 "<<endl;
cout<<"当任意一方的棋子连成一条长度为连珠数目的直线,该棋手获胜 "<<endl;
cout<<"棋盘大小为 3~20的整数,连珠数目为 3~5的整数 "<<endl;
cout<<"第一名棋手为 palyer1 ,第二名棋手为 palyer2"<<endl;
cout<<"输入完成请敲击回车键 "<<endl;
cout<<endl;
}
void CHESS::PrintStats()
{
cout<<player_1<<"赢了 "<<Owin<<"次 ,"<<endl;
cout<<player_2<<"赢了 "<<Xwin<<"次 ,"<<endl;
cout<<"总共有 "<<Draws<<"场平局 ."<<endl;
}
void CHESS::ChoiceOfChar(char& choice)
{
cout<<endl;
cout<<"请输入 y 重启对局 "<<endl;
cout<<"否则 , 按任意键退出程序 "<<endl;
cin>>choice;
}
void CHESS::PromptTurn()
{
char turn[20] ;
strcpy(turn,player_1);
if(SpotsOnBoard%2) strcpy(turn,player_2);
else strcpy(turn,player_1); //利用落子个数判断接下来是哪位棋手下棋
cout<<"轮到"<<turn<<"下棋 , 请输入下棋位置 "<<endl;
cout<<"行 列 :";
cin>>x>>y;
SpotsOnBoard++; //落子个数加一,用以判断落子顺序
}
void CHESS::IfError()
{
while (x>Size||x<1||y>Size||y<1||'O'==Board[x-1][y-1]||'X'==Board[x-1][y-1])
{
cout<<"请输入正确的棋子坐标 "<<endl;
cout<<"行 列 :";
cin>>x>>y; //确保输入正确的棋子坐标
}
}
int CHESS::IfJudge()
{
int i,j,k;
for(i=0; i<Size; i++)
{
for(j=0; j<Size-Row+1; j++) //选择一个棋位为判断开始的位置
{
for(k=0; k<Row; k++)
{
if(Board[i][j]!=Board[i][j+k]) break; //只有该方向上的相同棋子数达到连珠数 目才会使计数变量 k==连珠数目
}
if(k==Row&&Board[i][j]!=' ') return 1;//相同棋子数达到连珠数目 &&原棋子不为 空,说明连珠完成,返回 1
}
}//横向连珠判断
for(i=0; i<Size-Row+1; i++)
{
for(j=0; j<Size; j++)
{
for(k=0; k<Row; k++)
{
if(Board[i][j]!=Board[i+k][j]) break;
}
if(k==Row&&Board[i][j]!=' ') return 1;
}
} //纵向连珠判断
for(i=0; i<Size-Row+1; i++)
{
for(j=0; j<Size-Row+1; j++)
{
for(k=0; k<Row; k++)
{
if(Board[i][j]!=Board[i+k][j+k]) break;
}
if(k==Row&&Board[i][j]!=' ') return 1;
}
} //右下方向连珠判断
for(i=Row-1; i<Size; i++)
{
for(j=0; j<Size-Row+1; j++)
{
for(k=0; k<Row; k++){
if(Board[i][j]!=Board[i-k][j+k]) break;
}
if(k==Row&&Board[i][j]!=' ') return 1;
}
} //右上方向连珠判断
return 0; //如果未完成连珠,返回 0
}
int CHESS::Result()
{
IfError(); //先确保落子位置正确
if(SpotsOnBoard%2) Board[x-1][y-1]='O';
else Board[x-1][y-1]='X'; //利用落子数目判断是哪位棋手落子,并 将该位置上放置对应棋子
if(IfJudge()) //判断棋盘上是否连珠完成
{
if(SpotsOnBoard%2)
{
cout<<player_1<<"获胜 !";
Owin++;
}
else
{
cout<<player_2<<"获胜 !"; //根据落子数目可知最后落子的棋手,也 就是获胜者,对应胜场数加一
Xwin++;
}
return 0; //完成获胜判断,返回 0(游戏结束) ,不 再进行之后的平局判断
}
if(SpotsOnBoard==Size*Size) //根据落子数目判断棋盘上是否放满棋子
{
cout<<"平局 !"<<endl;
Draws++; //平局数加一
return 0; //返回 0(此局游戏结束)
}
return 1; //既没有完成连珠,也不是平局,返回 1 (此局游戏继续)
}
void CHESS::Setboard()
{
for(int i=0; i<20; i++)
for(int j=0; j<20; j++)
Board[i][j]=' '; //将棋盘上的棋位变为“空”
x=0;
y=0;
SpotsOnBoard=0; //初始化落子坐标和落子数目
}
//4.主函数
int main()
{
CHESS play;
char choice='y'; //用于判断是否重新游戏,并初始化为 y
play.PrintInfo(); //打印游戏规则
play.Gamemode(); //选择游戏模式(棋盘大小和连珠数目)
play.Player(); //存储玩家姓名
play.Setboard(); //重置棋盘、落子坐标和落子数目
while(choice=='y')
{
do
{
play.PrintBoard(); //打印棋盘
play.PromptTurn(); //棋手落子
}
while(play.Result()); //判断此局游戏是否结束 //一局游戏
play.PrintBoard(); //打印此局游戏最终的棋盘
play.PrintStats(); //打印统计的胜负信息
play.Setboard(); //重置棋盘、落子坐标和落子数目
play.ChoiceOfChar(choice);//询问用户是否再玩一局
}
}