萌新的第一个小游戏之五子棋

#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; 
}
1 个赞

希望得到大佬们的指点

2 个赞

游戏:
输入前可以告诉玩家输入什么,规定一下棋盘范围,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
1 个赞

你少写了一种五子的情况
而且数组越界了