C语言之三子棋的实现【超详细讲解】

目录

一、实现三子棋的简要思路

二、代码的具体实现步骤

 三、完整代码

1、sanziqi.h部分

2、sanziqi.c部分

 3、test.c部分



一、实现三子棋的简要思路

1、首先三子棋要进行游戏或退出需要一个简易选择的菜单

2、菜单创建好以后,实现switch ,case语句,进行游戏或退出的选择

3、在switch语句中若选择游戏,则进行游戏部分的代码

4、在游戏部分先初始化3行3列的二维数组,分别把数组中的每个元素都初始化为空格,这样方便后续玩家和电脑下棋时可以将空格替换

5、打印棋盘,每次玩家或电脑下棋结束后都打印一次棋盘,方便观察下棋后双方棋子的位置

6、分别实现玩家和电脑下棋的具体步骤

玩家下棋:玩家输入一个坐标,例如1 1,但是数组中1 1元素的坐标为0 0,所以需要将玩家所输入的坐标减一,即为玩家实际在数组中所下的位置

电脑下棋:电脑下棋需要用到rand(头文件:stdlib.h)和time(头文件:time.h),结合起来就可以使电脑随机下棋

7、实现完玩家和电脑下棋的代码后,在玩家和电脑下棋后还需实现判断是否游戏结束的代码,判断有四种情况,分别是玩家赢,电脑赢,平局,继续下棋

8、在游戏结束后,继续打印选择的菜单,由玩家决定是否继续进行游戏


 在开始编写之前,请注意一点,我们平时实现一些小程序的时候,都是进行分模块编写的,例如三子棋的实现会用到sanziqi.h,sanziqi.c,test.c这三部分来分别实现具体的要求,并不是所有代码都是写在test.c这个板块的,请大家注意,在以后工作或是编写代码时,都会用到这种方法


二、代码的具体实现步骤

1、创建如下所示的三个部分

2、在sanziqi.h中引用头文件,test.c和sanziqi.c中只需引用sanziqi.h即可



 

3、在test.c中创建main函数及test函数的switch case语句

4、创建简易选择菜单

5、由于是3行3列,所以可以使用宏定义,方便后续更改

 

6、test.c中game函数的实现 (先完成框架,再具体实现

7、在sanziqi.c中具体实现game函数中的要求(在sanziqi.h中声明,在sanziqi.c中实现),下面第一个图片即为声明,第二个图片为函数的实现

(1)、初始化函数的实现 


 (2)、打印棋盘


 (3)、玩家下棋


(4)、电脑下棋

 在test函数中添加:



(5)、判断输赢函数




 三、完整代码

1、sanziqi.h部分

#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define ROW 3//行
#define COL 3//列



//初始化函数
void Initboard(char board[ROW][COL], int row, int col);

//打印棋盘
void Displayboard(char board[ROW][COL], int row, int col);

//玩家下棋
void Playermove(char board[ROW][COL], int row, int col);

//电脑下棋
void Computermove(char board[ROW][COL], int row, int col);

//判断输赢
char Iswin(char board[ROW][COL], int row, int col);

2、sanziqi.c部分

#include "sanziqi.h"



//初始化函数,数组元素都初始化为空格
void Initboard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

//打印棋盘
void Displayboard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		//打印数字行
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
			{
				printf("|");//在一行最后一个不打印|,更美观
			}
		}
		printf("\n");
		//打印分隔行
		if (i < row - 1)//在最后一行不打印分隔行
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");//在一行最后一个不打印|,更美观
				}
			}
			printf("\n");
		}
	}
}


//玩家下棋
void Playermove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入想要下棋的坐标:");
		scanf("%d %d", &x, &y);
		printf("玩家下棋:\n");
		if (x >= 1 && x <= 3 && y >= 1 && y <= 3 && board[x - 1][y - 1] == ' ')
		{
			board[x - 1][y - 1] = '*';
			break;
		}
		else
		{
			printf("输入坐标错误,请重新输入!\n");
		}
	}
}



//电脑下棋
void Computermove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	while (1)
	{
		x = rand() % row;//rand()函数会随机生成0~32767之间的数字
		y = rand() % col;//rand()%row和col即随机生成0~2,满足二维数组坐标要求
		if (board[x][y] == ' ')
		{
			printf("电脑下棋:\n");
			board[x][y] = '#';
			break;
		}
	}
}


//判断是否平局
//下满棋盘返回1,未下满则返回0
int Isfull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}


//判断输赢
char Iswin(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//判断三行中每一行是否相同
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}

	//判断三列中每一列是否相同
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}

	//判断第一条对角线是否相同
	if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ')
	{
		return board[0][0];
	}

	//判断第二条对角线是否相同
	if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != ' ')
	{
		return board[0][2];
	}

	//判断是否平局
	if (Isfull(board, ROW, COL) == 1)//由于Isfull函数,不是功能型函数
		                             //只需要在sanziqi.c中实现即可
	{
		return 'P';
	}

	//若都不满足上方条件语句,则表示继续游戏
	return 'A';
}

 3、test.c部分

#include "sanziqi.h"


void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	Initboard(board, ROW, COL);//初始化函数

	Displayboard(board, ROW, COL);//打印棋盘
	while (1)
	{
		Playermove(board, ROW, COL);//玩家下棋
		Displayboard(board, ROW, COL);//打印棋盘
		ret = Iswin(board, ROW, COL);//判断输赢,并用ret接受
		if (ret != 'A')
		{
			break;//这里的ret为判断输赢函数的返回值,A是自己设定的
			      //在判断输赢函数中,返回A则继续下棋,返回P则平局
			      //返回 # 则电脑赢,返回 * 则玩家赢
			      //不返回A说明游戏结束,则在下方判断具体结果
		}

		Computermove(board, ROW, COL);//电脑下棋
		Displayboard(board, ROW, COL);//打印棋盘
		ret = Iswin(board, ROW, COL);//判断输赢,并用ret接受
		if (ret != 'A')
		{
			break;
		}
	}

	if (ret == 'P')
	{
		printf("平局!\n");
	}

	if (ret == '*')
	{
		printf("玩家赢!\n");
	 }

	if (ret == '#')
	{
		printf("电脑赢!\n");
	}
}


void menu()
{
	printf("******************************\n");
	printf("********   1. play   *********\n");
	printf("********   0. exit   *********\n");
	printf("******************************\n");
}

void test()
{
	int input = 0;
	do
	{
		menu();//菜单
		srand((unsigned int)time(NULL));
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出三子棋程序!\n");
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
	} while (input);
}

int main()
{
	test();
	return 0;
}


C语言实现三子棋到此便告一段落啦,下篇博客再见♪(^∇^*)

猜你喜欢

转载自blog.csdn.net/m0_64411530/article/details/125569110