李兆霆
(李兆霆)
1
大家好,我是一位萌新,我自己制作了五子棋的代码,其中,玩法是先输入棋盘大小,再来输入要下的坐标位置,0代表没有棋子,1代表是黑子,2代表是白子,祝大家玩的愉快,也请大佬们尽情提出修改意见
#include<iostream>
using namespace std;
int a[1005][1005];
int main(){
int n,x,y;
int cnt=1;
cin>>n;
while(cin>>x>>y)
{
if(x<1||y<1||x>n||y>n||a[x][y]!=0)
{
cout<<"犯规,对方胜";
return 0;
}
if(cnt%2==1)
a[x][y]=1;
else
a[x][y]=2;
cnt++;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==a[i][j+1]&&a[i][j+1]==a[i][j+2]&&a[i][j+2]==a[i][j+3]&&a[i][j+3]==a[i][j+4]&&a[i][j+4]==1)
{
cout<<"黑方胜,对弈结束";
return 0;
}
else if(a[i][j]==a[i][j+1]&&a[i][j+1]==a[i][j+2]&&a[i][j+2]==a[i][j+3]&&a[i][j+3]==a[i][j+4]&&a[i][j+4]==2)
{
cout<<"白方胜,对弈结束";
return 0;
}
if(a[i][j]==a[i+1][j]&&a[i+1][j]==a[i+2][j]&&a[i+2][j]==a[i+3][j]&&a[i+3][j]==a[i+4][j]&&a[i+4][j]==1)
{
cout<<"黑方胜,对弈结束";
return 0;
}
else if(a[i][j]==a[i+1][j]&&a[i+1][j]==a[i+2][j]&&a[i+2][j]==a[i+3][j]&&a[i+3][j]==a[i+4][j]&&a[i+4][j]==2)
{
cout<<"白方胜,对弈结束";
return 0;
}
if(a[i][j]==a[i+1][j+1]&&a[i+1][j+1]==a[i+2][j+2]&&a[i+2][j+2]==a[i+3][j+3]&&a[i+3][j+3]==a[i+4][j+4]&&a[i+4][j+4]==1)
{
cout<<"黑方胜,对弈结束";
return 0;
}
else if(a[i][j]==a[i+1][j+1]&&a[i+1][j+1]==a[i+2][j+2]&&a[i+2][j+2]==a[i+3][j+3]&&a[i+3][j+3]==a[i+4][j+4]&&a[i+4][j+4]==2)
{
cout<<"白方胜,对弈结束";
return 0;
}
}
}
}
return 0;
}
2 个赞
2345安全卫士
(蛋小黄(蒟蒻))
2
可以先将棋盘写出来,然后标号,不然你下哪里都不知道
2 个赞
黄炜
(黄炜)
3
我发现你少写了一种五子的情况,
而且数组越界了,
下面是我的一些改进并注释了
游戏:
输入前可以告诉玩家输入什么,规定一下棋盘范围,n不能<5,也不能太大;
输出棋盘的时候,在外面额外输出行数和列数,好让玩家知道怎么填参数;
优化一下输出,让玩家看的懂;
判断和棋的情况;
优化和简化一下代码。
建议:
数组越界虽然在dev c++里不会报错,
但尽量避免,越界后的野值是不可控的。
#include<iostream>
using namespace std;
int a[1005][1005];//建议把变量丢最前面,防止未定义就使用的情况
int n,x,y;//根据情况丢,不是全丢
int len(int num)//定义函数,这个非常的有用,可以做去重、化简、递归等。int是返回类型; len是函数名,可以与变量重名,不过函数最大的使用特征就是“函数名()”;()是调用函数和传入参数的象征;int num是传入参数的类型和名称,可以有多个(或没有)参数,可以与全局变量重名,不过使用时调用的是局部的,建议尽量不重名
{//这个函数是用来获取正数的长度
int cnt=0;//记录长度
while(num)//截取成0就是没了
{
num/=10;//将个位截去
cnt++;//记录长度
}
return cnt;//返回记录的长度
}
string string_num(int num)//这个函数是用来将正数转成string类型
{
string str="";//记录字符串
while(num)//截取成0就是没了
{
str=char(num%10+'0')+str;//num%10是取个位;+'0'是要转成char类型,int是连接不了string的;+在string类型里是指字符串string(或字符char)连接字符串string(或字符char)。str=char(num%10+'0')+str是指将num的个位连接到str前面
num/=10;//将个位截去
}//理解不了“取个位连接在前面又将个位截去”没关系,现在知道怎么用就行,以后会连接的
return str;//返回记录的字符串
}
string printf_string(int strlen,int num)//这个函数是用来将num补位(左对齐)
{
string str="";//记录要补位的字符串
for(int i=1;i<=strlen-len(num);i++)//strlen-len(num)是补位的位数,循环得到补位的字符串
str+=" ";//+=在是string类型里是将=后面的字符串string(或字符char)连接到变量后面。
return string_num(num)+str;//返回补位后的num(左对齐)
}
void print_map(){//void是没有任何返回值的意思,是不能用return的
string str="";//为了更快的输出,可以定义string类型的变量将你要输出的内容先存起来,然后再输出
for(int i=0;i<=n;i++)//注意!i的初始值变了!为下面输出行数和列数做准备
{
for(int j=0;j<=n;j++)//注意!j的初始值变了!为下面输出行数和列数做准备
{
if(i>=1&&j>=1)//在输出棋盘的范围内
{
if(a[i][j]==1)
str+="○";//黑方棋子
else if(a[i][j]==2)
str+="●";//白方棋子
else
str+="╋ ";//格子
}
else//在输出辅助信息的范围内
{
if(i!=0||j!=0)//左上角不输出数
{
if(i==0)//要输出的是列数
str+=printf_string(2,j);//调用函数
else//要输出的是行数
str+=printf_string(2,i);//同上
}
else//左上角输出两个空格
str+=" ";//连接两个空格
}
}
str+="\n";//"\n"(或'\n')是换行符
}
cout<<str;//输出
}
int main(){
bool cnt=false;//只有黑白两种状态,用bool就行
cout<<"请输入棋盘大小:";//输入前缀
do
{
cin>>n;
if(n<5||n>50)//不合法的范围
cout<<"不合法!"; //告诉玩家不合法
}
while(n<5||n>50);//一直到合法为止
print_map();//不管有没有返回值,都是可以单独使用的
while(1)
{
cout<<"请输入第几行第几列:";//输入前缀
if(!(cin>>x>>y))break;//输入ctrl+z时退出
if(x<1||y<1||x>n||y>n||a[x][y]!=0)
{
cout<<"犯规,对方胜";
return 0;
}
a[x][y]=cnt+1;//化简
print_map();//输出棋盘
bool pd=true;//定义判断变量
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
pd=(pd&&(a[i][j]>0));//只要有一个位置上是空的,那么还没和棋;如果下到最后一步了刚好黑/白方五子了,因为是检测到五子直接结束,所以不会判断和棋了,否则和棋
//原代码数组会越界,而且很长,甚至我还发现了写少了一种情况,所以进行了优化
for(int k=-1;k<=1;k++)//i的偏移量
{
for(int l=-1;l<=1;l++)//j的偏移量
{
if(k!=0||l!=0)//不含不动
{
bool wzpd=true;//判断五子
for(int m=0;wzpd&&m<5;m++)//循环五次,没五子提前退出
{
if(i+m*k<1||i+m*k<1>n||j+m*l<1||j+m*l>n)//越界就不可能五子
wzpd=false;//不可能五子
else//没越界
wzpd=(a[i+m*k][j+m*l]==cnt+1);//看这五个位置是否是一个子
}
if(wzpd)//判断五子
{
if(cnt==0)//黑方胜
cout<<"黑方胜,对弈结束";//输出
else//白方胜
cout<<"白方胜,对弈结束";//输出
return 0;//结束
}
}
}
}
}
}
cnt=!cnt;//取反
if(pd)//判断是否全是棋子并没有五子
{
cout<<"和棋,对弈结束";//输出
return 0;//结束
}
}
return 0;
}
一些数据给测试大家
//黑方胜
//竖线
10
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
//横线
10
1 1
2 1
1 2
2 2
1 3
2 3
1 4
2 4
1 5
//斜线1
10
1 1
1 2
2 2
2 3
3 3
3 4
4 4
4 5
5 5
//斜线2
10
5 1
5 2
4 2
4 3
3 3
3 4
2 4
2 5
1 5
//白方胜
//竖线
10
10 10
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
//横线
10
10 10
1 1
2 1
1 2
2 2
1 3
2 3
1 4
2 4
1 5
//斜线1
10
10 10
1 1
1 2
2 2
2 3
3 3
3 4
4 4
4 5
5 5
//斜线2
10
10 10
5 1
5 2
4 2
4 3
3 3
3 4
2 4
2 5
1 5
//和棋
5
1 1
1 2
1 3
1 4
1 5
5 1
5 2
5 3
5 4
5 5
2 1
2 2
2 3
2 4
2 5
4 1
4 2
4 3
4 4
4 5
3 1
3 2
3 3
3 4
3 5