C语言实现三子棋,回顾童年!

这篇博客详细介绍了如何创建一个简单的三子棋游戏。首先,通过初始化和打印棋盘来开始,接着阐述了棋盘的初始化和打印方法。然后,讲解了玩家和电脑如何轮流下棋,包括边界检查和落子逻辑。此外,还实现了输赢判断的逻辑,包括横向、纵向以及对角线的连子判断。最后,展示了完整的代码结构,包括主函数和各功能函数的实现。
摘要由CSDN通过智能技术生成

1.整体思路

(1)棋盘的样式

       这就是棋盘进行初始化以及初始打印后的成果,我们要围绕这个图进行分析与讨论。

(2)棋盘的初始化

       可以看到,三子棋的棋盘是三行三列,这不难想到我们应该要用到一个二维数组去初始化 ,当棋盘是空的时候我们可以将数组元素设置为空格这就可以推断出我们应该用一个char类型的二维数组去存储九宫格的元素。我们初始化的部分就是标为1的地方,我只是为了方便我把它标为1,其实初始化的为空格

     初始化代码:

#define ROW 3 //行的宏定义,方便代码的维护

#define COL 3 //列的宏定义,方便代码的维护


void Initboard(char board[ROW][COL], int m, int n);//初始化的定义


//初始化的实现
void Initboard(char board[ROW][COL], int m, int n)
{
	int i = 0;
	for (i = 0; i < m; i++)
	{
		int j = 0;
		for (j = 0; j < n; j++)
		{
			board[i][j] = ' ';
		}
	}
}

3.棋盘的打印

   要如何打印这个棋盘呢?其实非常简单,只用两个循环就能做到。直接上代码:

void Displayboard(char board[ROW][COL], int m, int n);//生成棋盘



void Displayboard(char board[ROW][COL], int m, int n)
{
	int i = 0;
	for (i = 0; i < m; i++)
	{
		int j = 0;
		for (j = 0; j < n; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < n - 1)
				printf("|");
		}
		printf("\n");
		if (i < m - 1)
		{
			for (j = 0; j < n; j++)
			{
				printf("---");
				if (j < n - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

4.玩家下棋

        因为作者水平有限不能做到用鼠标点来下棋,所以只能用坐标的形式去进行下棋。一共三行三列,所以进行的就是1 1,1 2,1 3,2 1……的形式来进行下棋。如果超出范围就会提示超出边界,如果玩家下的地方已经落子也会提示该区域已经有了棋子。

       玩家的下的棋子我设置为    *   让棋盘更加真实。上代码

void PlayerMove(char board[ROW][COL], int m, int n);//声明



//实现
void PlayerMove(char board[ROW][COL], int m, int n)
{
	printf("It is time for you to play chess!\n");
	while (1)
	{
		printf("Please enter the coordinates!\n");
		int x, y;
		scanf("%d%d", &x, &y);//输入坐标
		if (x > m || y > n)//判断是否超过边界
		{
			printf("Beyond the boundary,please re-enter!--->");;
		}
		if (board[x - 1][y - 1] != ' ')//判断下棋点是否为空
		{
			printf("\n");
			printf("This grid is already in use, please re-enter!--->");
		}
		else
		{
			board[x - 1][y - 1] = '*';
			break;
		}
	}
}

5.电脑下棋

       电脑下棋的坐标是随机生成的,我们使用的是定义一个x坐标,一个y坐标,然后使用rand()函数进行生成随机数。然后用时间戳然随机生成的数更加随机。即在主函数前定义一下该函数的使用srand((unsigned)time(NULL));

rand和srand函数的头文件是#include<stdlib.h>

time函数的头文件是#include<time.h>      上代码:

void ComputerMove(char board[ROW][COL], int m, int n);//声明


void ComputerMove(char board[ROW][COL], int m, int n)
{
	printf("This computer play!\n");
	int x, y;
	while (1)
	{
		x = rand() % m;
		y = rand() % n;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

6.输赢的判断

1.输赢判断的标准

(1).玩家赢我们返回一个 *

(2).电脑赢我们返回一个 #

(3)平局我们返回一个 Q

(4)游戏继续我们就返回一个 C

在主函数上的代码为:

void game()
{
	char board[ROW][COL];//棋盘
	//初始化棋盘
	Initboard(board, ROW, COL);
	Displayboard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
		PlayerMove(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		ComputerMove(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
		printf("player win!!\n");
	else if (ret == '#')
		printf("computet win!\n");
	else
		printf("Tie game\n");
}

那么如何去实现这个赢的逻辑呢?我们可以分为如下几点进行判断:

(1).横向三个连子赢

(2).纵向三个连字赢

(3).向下对角线赢

(4).向上对角线赢

char IsWin(char board[ROW][COL], int m, int n);//声明


char IsWin(char board[ROW][COL], int m, int n)
{
	//1.判断输赢
	//(1).横向赢
	int i, j;
	for (i = 0; i < m; i++)
	{
		int count1 = 0;
		int count2 = 0;
		for (j = 0; j < n; j++)
		{
			if (board[i][j] == '*')
				count1++;
			if (board[i][j] == '#')
				count2++;
		}
		if (count1 == n)
			return '*';
		if (count2 == n)
			return '#';
	}
	//(2).竖向赢
	for (i = 0; i < n; i++)
	{
		int count1 = 0;
		int count2 = 0;
		for (j = 0; j < m; j++)
		{
			if (board[j][i] == '*')
				count1++;
			if (board[j][i] == '#')
				count2++;
		}
		if (count1 == m)
			return '*';
		if (count2 == m)
			return '#';
	}
	//(3).下对角线赢
	int x = 0, y = 0;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{

			if (i == j && board[i][j] == '*')
				x++;
			if (i == j && board[i][j] == '#')
				y++;
		}
	}
	if (x == 3)
		return '*';
	if (y == 3)
		return '#';
	//(4).上对角线赢
	j = n - 1;
	int countone = 0;
	int counttwo = 0;
	for (i = 0; i < m; i++)
	{
		if (board[i][j] == '*')
			countone++;
		if (board[i][j] == '#')
			counttwo++;
		if (countone == m)
			return '*';
		if (counttwo == m)
			return '*';
		j--;
	}

	//2.判断平局
	int count = m * n;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
			if (board[i][j] == ' ')
				count--;
	}
	if (count == 9)
	{
		return 'Q';
	}
	//3.游戏继续
	return 'C';
}

7.完整代码

1.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
	printf("****************************************\n");
	printf("*************   1.play   ***************\n");
	printf("*************   0.exit   ***************\n");
	printf("****************************************\n");
}
void game()
{
	char board[ROW][COL];//棋盘
	//初始化棋盘
	Initboard(board, ROW, COL);
	Displayboard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
		PlayerMove(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		ComputerMove(board, ROW, COL);
		Displayboard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
		printf("player win!!\n");
	else if (ret == '#')
		printf("computet win!\n");
	else
		printf("Tie game\n");
}
int main()
{
	int input;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("please select:>");
		scanf("%d", &input);
		switch (input)
		{
		case 0:
			printf("exit successful!\n");
			break;
		case 1:
			game();
			break;
		default:
			printf("Select error! Please select again\n");
			break;
		}
	} while (input);
	return 0;
}

2.game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Initboard(char board[ROW][COL], int m, int n)
{
	int i = 0;
	for (i = 0; i < m; i++)
	{
		int j = 0;
		for (j = 0; j < n; j++)
		{
			board[i][j] = ' ';
		}
	}
}
void Displayboard(char board[ROW][COL], int m, int n)
{
	int i = 0;
	for (i = 0; i < m; i++)
	{
		int j = 0;
		for (j = 0; j < n; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < n - 1)
				printf("|");
		}
		printf("\n");
		if (i < m - 1)
		{
			for (j = 0; j < n; j++)
			{
				printf("---");
				if (j < n - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}
void PlayerMove(char board[ROW][COL], int m, int n)
{
	printf("It is time for you to play chess!\n");
	while (1)
	{
		printf("Please enter the coordinates!\n");
		int x, y;
		scanf("%d%d", &x, &y);
		if (x > m || y > n)
		{
			printf("Beyond the boundary,please re-enter!--->");;
		}
		if (board[x - 1][y - 1] != ' ')
		{
			printf("\n");
			printf("This grid is already in use, please re-enter!--->");
		}
		else
		{
			board[x - 1][y - 1] = '*';
			break;
		}
	}
}
void ComputerMove(char board[ROW][COL], int m, int n)
{
	printf("This computer play!\n");
	int x, y;
	while (1)
	{
		x = rand() % m;
		y = rand() % n;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}
//玩家赢返回   '*'
//电脑赢返回   '#'
//平局返回     'Q'
//游戏继续     'C'
char IsWin(char board[ROW][COL], int m, int n)
{
	//1.判断输赢
	//(1).横向赢
	int i, j;
	for (i = 0; i < m; i++)
	{
		int count1 = 0;
		int count2 = 0;
		for (j = 0; j < n; j++)
		{
			if (board[i][j] == '*')
				count1++;
			if (board[i][j] == '#')
				count2++;
		}
		if (count1 == n)
			return '*';
		if (count2 == n)
			return '#';
	}
	//(2).竖向赢
	for (i = 0; i < n; i++)
	{
		int count1 = 0;
		int count2 = 0;
		for (j = 0; j < m; j++)
		{
			if (board[j][i] == '*')
				count1++;
			if (board[j][i] == '#')
				count2++;
		}
		if (count1 == m)
			return '*';
		if (count2 == m)
			return '#';
	}
	//(3).下对角线赢
	int x = 0, y = 0;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
		{

			if (i == j && board[i][j] == '*')
				x++;
			if (i == j && board[i][j] == '#')
				y++;
		}
	}
	if (x == 3)
		return '*';
	if (y == 3)
		return '#';
	//(4).上对角线赢
	j = n - 1;
	int countone = 0;
	int counttwo = 0;
	for (i = 0; i < m; i++)
	{
		if (board[i][j] == '*')
			countone++;
		if (board[i][j] == '#')
			counttwo++;
		if (countone == m)
			return '*';
		if (counttwo == m)
			return '*';
		j--;
	}

	//2.判断平局
	int count = m * n;
	for (i = 0; i < m; i++)
	{
		for (j = 0; j < n; j++)
			if (board[i][j] == ' ')
				count--;
	}
	if (count == 9)
	{
		return 'Q';
	}
	//3.游戏继续
	return 'C';
}

3.game.h

#pragma once

#define ROW 3
#define COL 3
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
//棋盘的初始化
void Initboard(char board[ROW][COL], int m, int n);
//棋盘的打印生成
void Displayboard(char board[ROW][COL], int m, int n);
//玩家走
void PlayerMove(char board[ROW][COL], int m, int n);
//电脑走
void ComputerMove(char board[ROW][COL], int m, int n);
//判断输赢以及是否继续
char IsWin(char board[ROW][COL], int m, int n);

 

8.演示效果

 

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值