/*二维数组知识点:二维数组中列数必须给出,行数可以由编译器来数。
每行一个{},用逗号分隔。
如果省略,表示补零。
三子棋练习二维数组遍历:
读入一个3*3的矩阵,矩阵中的数字为1表示该位置上有一个x为0表示有一个o
程序判断矩阵中是否有获胜的一方,输出表示获胜方的字符,或无人获胜
*/
- 定好数组大小3*3,定好初始值,result=1,0,-1分别表示1获胜0获胜和无人获胜,默认result=-1
- 检查行列是否有赢家:
- for循环遍历数组且在无人获胜的情况下才做此循环,若有人获胜不就不用检查了吗,要严谨是这个道理
- 内部在用j做一次遍历,可以形成一个下标不变另一个走一圈的a[i][j]这就是再检查行,反过来让a[j][i]就是在检查列,两种检查都是,如count1==3就把result=1;表示1获胜,
- 循环内部要将count置位0,否则第二次循环会累加第一次循环的count值达不到单行单列的计数要求。
- 做行列计数时要使用不同的count,否则行列的count会叠加,造成结果不准确
- 不管是行还是列只要对1的计数到了size就将result置位1,0也一样
- 检查左对角线:
- for循环同一个i,a[i][i]可以遍历00 11 22,若计数为3则改result的值
- 注意for循环中加上result==-1的条件来确定是否前面的行列检查已经出现了赢家,若已经出现了赢家则不必检查对角线了
- 检查右对角线:
- 检查对角线的时候不必像检查行列的时候一样把count放在循环内部,因为仅仅只有一重循环,如果是双重循环会做n的平方次,一重循环只做n次
- 02 11 20用a[i][size-i-1]来表示
#include <stdio.h>
int main(){
int a[3][3]={{0,0,0},
{1,1,0},
{1,0,1}};
int count0=0,count1=0;//行计数
int count00=0,count11=0;//列计数
int flag=0;//若已经连线成功则不进行后面的判断
/*判断行列是否连线*/
for(int i=0;i<3;i++){
int count0=0,count1=0;//每次只检查单行单列,所以当i的值变化就要清零
int count00=0,count11=0;
for(int j=0;j<3;j++){
if(a[i][j]==0){
count0++;
}else count1++;
if(a[j][i]==0){
count00++;
}else count11++;
}
if(count0==3||count00==3) {
printf("行列上0获胜");
flag=1;
} else if(count11==3||count1==3) {
printf("行列1获胜") ;
flag=1;
}
}
count0=0,count1=0; //对角线
count00=0,count11=0; //反对角线
/*判断对角线*/
if(flag!=1){
for(int i=0;i<3;i++){
if(a[i][i]==0) count0++;
else if(a[i][i]==1) count1++ ;
if(a[i][3-i-1]==0) count00++;//反对角线20 11 02
else if(a[i][3-i-1]==1) count11++;
}
if(count0==3) {
printf("对角线上0获胜");
} else if(count1==3) {
printf("对角线上1获胜") ;
}else if(count00==3) {
printf("反对角线上0获胜");
} else if(count11==3) {
printf("反对角线上1获胜") ;
}
}
}
flag保证若行列上有连线成功则不检查对角线