栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言实现五子棋人人对战

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言实现五子棋人人对战

利用简单的c语言基础实现最简单的功能,界面比较丑陋主要是刚学完c的一个小实践,未使用MFC所以界面没有很好看 ,主要目的加强对c语言的理解与运用,同时增加自己的代码量。

首先要学一些头文件可以看我的博客前面的文章

要用到到的头文件stdio.h stdlib.h windows.h time.h conio.h

思路就是

1.画个棋盘,使用数组来代替初始化出*

2.使用循环使双方轮流下棋,使用数组存放棋子的位置

3.判断是否有一方获胜

首先打印棋盘

#include
#include
#include
#include
 
char qipan[16][16];
//函数声明
void initQipan();//将*存入16*16的二维数组中
void printQipan();//将二维数组打印出来
 
void initQipan()
{
 int i,j;
 for(i = 0;i < 16 ;i++)
 for(j = 0;j <16 ;j++)
 qipan[i][j] = '*';
}
 
void printQipan()
{
 int i,j;
 for(i = 0;i < 16 ;i++)
 {
 for(j = 0;j <16 ;j++)
 printf("%c",qipan[i][j]);
 printf("n");
 } 
}
 
int main()
{
 initQipan();
 printQipan(); 
}

打印出来效果图

这里面我发现一个算是c语言的小陷阱

void printQipan()
{
 int i,j;
 for(i = 0;i < 16 ;i++)
 {
 for(j = 0;j <16 ;j++)
 printf("%c",qipan[i][j]);
 printf("n");
 } 
}

这段代码中内层for循环后跟着两个语句但是按正常想法应该两条语句都应随着内层循环而循环也就是打出来的应该是这样

打印出来这样的代码是

int i,j;
 for(i = 0;i < 16 ;i++)
 {
 for(j = 0;j <16 ;j++)
 {
 printf("%c",qipan[i][j]);
 printf("n");
 }
 
 
 }

但是显然他们的效果不等价

这样其实是因为如果内层没有写出{}就会默认将第一条指令给内层,其余所有指令给外层

可以看下面的代码

int i,j;
 for(i = 0;i < 16 ;i++)
 {
 for(j = 0;j <16 ;j++) 
 printf("%c",qipan[i][j]);
 printf(",");
 printf("n"); 
 }
 
}

这样很显然得出结论

在这样结构的双重for循环中

for()
{
 for()
 语句1
 语句2
 语句3
 ...
}

只有第一条语句属于内存循环,写成这样更加明了一些

for()
{
 for()
 语句1
 语句2
 语句3
 ...
}

下面实现双方轮流下棋


#include
#include
#include
#include

char qipan[16][16];
int x,y;

void initQipan();//将*存入16*16的二维数组中
void printQipan();//将二维数组打印出来
void starGame();//开始游戏

void initQipan()
{
 int i,j;
 for(i = 0;i < 16 ;i++)
 for(j = 0;j <16 ;j++)
 qipan[i][j] = '*';
}
void printQipan()
{
 int i,j;
 for(i = 0;i < 16 ;i++)
 {
 for(j = 0;j <16 ;j++) 
 printf("%c",qipan[i][j]);
 printf("n");
 }
 
}
void starGame()
{
 initQipan(); 
 printQipan();
 while(1)
 {
 printf("请白方落子,按下行与列的坐标:");
 scanf("%d%d",&x,&y);
 qipan[x][y]='W';
 system("cls");
 printQipan();
 printf("请黑方落子,按下行与列的坐标:");
 scanf("%d%d",&x,&y);
 qipan[x][y]='B';
 system("cls");
 printQipan();
 }
 
}

int main()
{
 starGame();
}

现在可以实现双方轮流下棋,接下来就是要实现系统去判定是否有人获胜


#include
#include
#include
#include

char qipan[16][16];
int x,y;

void initQipan();//将*存入16*16的二维数组中
void printQipan();//将二维数组打印出来
void starGame();//开始游戏
int panduan(int x,int y);//判断是否有人获胜
void win(int winner);//有人获胜后显示那方胜利

void initQipan()
{
 int i,j;
 for(i = 0;i < 16 ;i++)
 for(j = 0;j <16 ;j++)
 qipan[i][j] = '*';
}
void printQipan()
{
 int i,j;
 for(i = 0;i < 16 ;i++)
 {
 for(j = 0;j <16 ;j++) 
 printf("%c",qipan[i][j]);
 printf("n");
 }
 
}
void starGame()
{
 int temp;
 initQipan(); 
 printQipan();
 while(1)
 {
 printf("请白方落子,按下行与列的坐标:");
 scanf("%d%d",&x,&y);
 qipan[x][y]='W';
 system("cls");
 printQipan();
 temp = panduan(x,y);
 if(temp==1)
 {
 printf("白方获胜");
 system("pause");
 }
 printf("请黑方落子,按下行与列的坐标:");
 scanf("%d%d",&x,&y);
 qipan[x][y]='B';
 system("cls");
 printQipan();
 temp = panduan(x,y);
 if(temp==2)
 {
 printf("黑方获胜");
 system("pause");
 } 
 } 
}
int panduan(int x,int y)
{
 char temp;//保存棋子的颜色
 int winner;//1代表白方,2代表黑方
 int i;//距离落子位置水平方向的差
 int j;//距离落子位置竖直方向的差
 int count;//记下有多少个连续的棋子
 count = 1;
 i = 1;
 j = 1;
 winner = 0;
 temp = qipan[x][y]; 
 /
int main()
{
 starGame();
 return 0;
}

此时有一个问题就是程序会卡死如图

在写程序时出现这种错误可能的原因是:

①除以零

②数组越界:int a[3]; a[10000000]=10;

③指针越界:int * p; p=(int *)malloc(5 * sizeof(int)); *(p+1000000)=10;

④使用已经释放的空间:int * p; p=(int *)malloc(5 * sizeof(int));free(p); *p=10;

⑤数组开得太大,超出了栈的范围,造成栈溢出:int a[100000000]

ok发现问题是在如图位置没有初始化这几个变量现在已经将上面的代码修正了

下面来看最后优化完的代码


#include
#include
#include
#include

#define N 16 //可以更改棋盘大小

char qipan[N][N];//全局变量,整个文件的都可以用
int x,y;//代表的是棋盘(数组)下标为x的行 和 下标为y列的一个交点

void initQipan();//棋盘的初始化
void printQipan();//打印棋盘
void Pos(int x, int y);//设置光标位置
void startGame();//游戏开始
int panduan(int x,int y);//判断是否有人连成五子
int showWhoWin();//输出谁赢了
void whitePlay();//白方下子
void blackPlay();//黑方下子
void printShuzi();//打印数字模板
 
 

void Pos(int x, int y)//设置光标位置,从哪里开始输出
{
 COORD pos;//表示一个字符在控制台屏幕上的坐标,左上角(0,0)
 HANDLE hOutput;
 pos.X = x;
 pos.Y = y;
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//返回标准的输入、输出或错误的设备的句柄,也就是获得输入、输出/错误的屏幕缓冲区的句柄
 SetConsoleCursorPosition(hOutput, pos);
}
 
void printShuzi()
{
 int i;
 Pos(2,0);
 for(i=0;i=0&&x=0&&y=0&&x=0&&y=0&&x=0&&y=0&&x=0&&y=0&&x=0&&y=0&&x=0&&y=0&&x=0&&y=0&&x=0&&y

下面测试一下功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/61059.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号