一篇文章教你学会如何编写三字棋代码

本文介绍了运用C语言代码实现三子棋程序的编写。先说明了基本流程,包括安装Visual Studio 2022等编译器、创建新项目及文件。接着讲解思路,如菜单界面、棋盘初始化、玩家和电脑下棋、判断输赢等函数的编写。最后给出了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题描述及文章声明

1. 问题描述

通过运用c语言代码实现三子棋程序的编写

2. 文章声明

如果您想系统学会如何编写三子棋程序,请先认真理解思路讲解中的整体思路分析,而后按照每个步骤认真学习,相信您会有所收获。
如果您只是想复制代码,直接跳到代码实现步骤即可。

二、基本流程

1. 在电脑安装Visual Studio 2022等编译器

可于b站查找按照流程

2. 创建一个新项目

(1). 在新建的项目中创建三个文件(如图所示)

test.c文件用于编写程序运行代码
game.c文件用于定义函数
game.h文件用于函数声明

在新建的项目中创建三个文件

三、思路讲解

1. 编写代码时的整体思路分析

当你产生对一件事的想法时,你需要先基本捋清思路,而后在实行的时候不断进行优化,编写三子棋代码也是如此。
首先我们需要明白三子棋代码的整体框架。

  1. 当用户进行游戏时,首先需要有个选择窗口让用户进行选择,因此我们首先需要进行菜单界面的编写。
  2. 而当用户进入游戏时,我们需要给用户展现出一个棋盘,因此第二步便是进行棋盘的初始化代码编写。
  3. 当用户看到棋盘之后,便会开始进行游戏,因此我们需要先编写一个玩家下棋的函数,并在函数中对用户行为进行提醒。
  4. 我们都知道三子棋是回合制游戏,因此当用户下完棋之后,便需要电脑进行下棋,因此需要编写一个电脑下棋函数。而为了使电脑下棋具有随机性,我们运用<stdlib.h>库中的srand函数和rand函数以及<time.h>中的tiime函数,来随机生成数字。
  5. 当每一方下完棋后,需要进行判断输赢,因此我们需要编写一个判断输赢函数。而三子棋存在输、赢、平局三种可能,而平局则是在填满棋盘时双方都没取得胜利,因此编写一个判断是否填满棋盘函数来进行判断。

2. 代码的具体分布编写

(1). 菜单函数的设置

下面展示一些 菜单设置代码片
菜单函数设置—— 在game.c文件下


#include <stdio.h>

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

int main()
{
	int input = 0;//变量初始化
	do
	{
		menu();//设置菜单函数
		printf("请选择:>");//提醒用户进行选择
		scanf("%d",&input);//获取用户输入
		switch(input)
		{
			case 1:
				printf("三子棋\n");
				break;
			case 0:
				printf("退出游戏\n");
			default:
				printf("选择错误,请重新选择");
		}
	}while(input);//当input为非0时进入循环
	return 0;
}

(2). 设置游戏函数

下面展示一些 游戏设置代码片
游戏函数设置——在test.c文件下进行函数调用

//思路分析
void game()
{
	//1.创建board数组 创建棋盘
	//三子棋则为3*3棋盘
	char board[3][3] = { 0 };//因为需要用空格代表棋盘,因此用char二维数组
	char board[ROW][COL] = { 0 };//为了设棋盘可以更方便改变,我们将方括号中改成符号常数
	//上述两行代码选取其中一行即可,本文以第二行代码为例
	
	//2.初始化棋盘的函数
	InitBoard();
	//3.打印棋盘函数
	DisplayBoard();
	//4.玩家下棋
	PlayerMove();
	DisplayBoard();//下完棋后需重新打印棋盘
	//5.电脑下棋
	ComputerMove();
	DisplayBoard();//下完棋后需重新打印棋盘
	//6.判断输赢
	IsWin();
}

(3). 棋盘初始化

初始化棋盘函数设置——在game.h文件下先定义Initboard()函数


#pragma once

#define ROW 3	//设置符号变量
#define COL 3	//设置符号变量

void InitBoard(char board[ROW][COL], int row, int col);//进行函数声明

初始化棋盘函数设置—— 在game.c文件下

#include "game.h"	//需要导入game.h文件,才能进行函数定义

void InitBoard(char board[ROW][COL], int row, int col) 
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';//将数组中的所有元素替换成空格表示
		}
	}
}

(4). 打印棋盘函数

打印棋盘函数设置—— 在game.c文件下

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)
		{
			int j = 0;
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");//打印---以隔开上下棋盘
				}
			}
			printf("\n");
		}
}		

运行效果展示:

在这里插入图片描述

(5). 玩家下棋

玩家下棋函数设置—— 在game.h文件下进行声明

//总代码
#pragma once

#define ROW 3
#define COL 3

#include <stdio.h>

//初始化棋盘
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);

玩家下棋函数设置—— 在game.c文件下进行定义

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	printf("玩家下棋:>\n");

	//很显然下面的代码需要重复运行,因此我们用while循环
	while(1)
	{
		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;//玩家合法下棋后需要结束循环进行电脑下棋
			}
			else
			{
				printf("坐标被占用,请选择其他位置\n");
			}	}
		else
		{
			printf("坐标非法,请重新输入\n"); 
		}
	}
}

玩家下棋函数设置—— 在test.c文件下进行使用

//game函数中到目前为止的总代码
void game()
{
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	//玩家下棋
	PlayerMove(board, ROW, COL);
	//每次下完棋需要重新打印棋盘
	DisplayBoard(board, ROW, COL);
}

(6). 电脑下棋

电脑下棋函数设置—— 在game.h文件下进行声明

#pragma once

#define ROW 3
#define COL 3

#include <stdio.h>
#include <stdlib.h>	//调用rand、srand函数
#include <time.h>	//调用time函数

//初始化棋盘
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);

电脑下棋函数设置—— 在game.c文件下进行定义

void ComputerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	printf("电脑下棋:>\n");
	while (1)
	{
		//rand()随机生成一个数
		x = rand() % row;  	//%row  当row为3时生成0~2的数
		y = rand() % col;	//%col  当col为3时生成0~2的数
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

电脑下棋函数设置—— 在test.c文件下进行使用

//game函数中到目前为止的总代码
void game()
{
	char board[ROW][COL] = { 0 };
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);

	//因为需要重复玩家输入和电脑输入,因此将他们加入循环
	while (1)
	{
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);

		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
	}
}

(7). 判断输赢

判断输赢函数设置—— 在game.h文件下进行声明

//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'

//判断是否取得胜利
char IsWin(char board[ROW][COL],int row ,int col );
//判断棋盘是否填满
int IsFull(char board[ROW][COL], int row, int col);

判断输赢函数设置—— 在game.c文件下进行定义

int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	//循环遍历数组,当数组元素全部不为空格时,返回1。否则返回0。
	for (i = 0; i < row; i++)
	{
		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;
	int j = 0;
	int flag = 0;
	for (i = 0; i < row; i++)
	{
		flag = 1;
		for (j = 0; j < col - 1; j++)//0~2
		{
			if (board[i][j] != board[i][j+1]) //判断是否相等
			{
				flag = 0;
			}
		}
		if (flag == 1 && board[i][j] != ' ')	//当一行的字符全相等且不为空时
		{
			return board[i][j];	//返回赢的一方的字符
		}
	}
	//列
	for (j = 0; j < col; j++)
	{
		flag = 1;
		for (i = 0; i < row - 1; i++)
		{
			if (board[i][j] != board[i + 1][j])//判断是否相等
			{
				flag = 0;
			}
		}
		if (flag == 1 && board[i][j] != ' ')//当一列的字符全相等且不为空时
		{
			return board[i][j];//返回赢的一方的字符
		}
	}
	//斜对角
	//左对角线
	for (i = 0; i < row - 1; i++)
	{
		flag = 1;
		if (board[i][i] != board[i + 1][i + 1]) //左对角线三个坐标分别为(0,0)(1,1)(2,2)
		{
			flag = 0;
		}
	}
	if (flag == 1 && board[i][i] != ' ')//当对角线的字符全相等且不为空时
	{
		return board[i][i];//返回赢的一方的字符
	}
	//右对角线
	for (i = 0; i < col - 1; i++)
	{
		flag = 1;
		if (board[i][col - 1 - i] != board[i + 1][col - 2 - i])//右对角线三个坐标分别为(0,2)(1,1)(2,0)
		{
			flag = 0;
		}
	}
	if (flag == 1 && board[i][col - 1 - i] != ' ')//当对角线的字符全相等且不为空时
	{
		return board[i][col - 1 - i];//返回赢的一方的字符
	}
	
	//判断棋盘是否填满
	if (IsFull(board, ROW, COL) == 1)
	{
		return 'Q';
	}
	return 'C';
}

判断输赢函数设置—— 在test.c文件下进行使用

//game函数中到目前为止的总代码
void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);

	while (1)
	{
		PlayerMove(board, ROW, COL);
		//玩家下完棋后,判断双方输赢,并将IsWin返回值用ret储存
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')	//当返回值不为'C'时,说明有人胜出或双方平局
		{
			break;
		}
		DisplayBoard(board, ROW, COL);


		ComputerMove(board, ROW, COL);
		//电脑下完棋后,判断双方输赢,并将IsWin返回值用ret储存
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')	//当返回值不为'C'时,说明有人胜出或双方平局
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
	}
	
	//当循环结束时,ret中只可能存在'*','#'两种结果
	//判断本局游戏的最终结果
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if(ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
	DisplayBoard(board, ROW, COL);
}

(8). 结果演示

此演示中我们仅以玩家赢的结果作为展示

在这里插入图片描述

四、代码实现

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 ret = 0;
	char board[ROW][COL] = { 0 };
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);

	while (1)
	{
		PlayerMove(board, ROW, COL);

		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);


		ComputerMove(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if(ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
	DisplayBoard(board, ROW, COL);
}

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;//变量初始化
	do
	{
		menu();//设置菜单函数
		printf("请选择:>");//提醒用户进行选择
		scanf("%d", &input);//获取用户输入
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
		default:
			printf("选择错误,请重新选择");
		}
	} while (input);//当input为非0时进入循环
	return 0;
}

game.c总代码展示

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitBoard(char board[ROW][COL], int row, int col) 
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		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)
		{
			int j = 0;
			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;

	printf("玩家下棋:>\n");

	while (1)
	{
		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标被占用,请选择其他位置\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	printf("电脑下棋:>\n");
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}
int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		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;
	int j = 0;
	int flag = 0;
	for (i = 0; i < row; i++)
	{
		flag = 1;
		for (j = 0; j < col - 1; j++)
		{
			if (board[i][j] != board[i][j+1])
			{
				flag = 0;
			}
		}
		if (flag == 1 && board[i][j] != ' ')
		{
			return board[i][j];
		}
	}
	//列
	for (j = 0; j < col; j++)
	{
		flag = 1;
		for (i = 0; i < row - 1; i++)
		{
			if (board[i][j] != board[i + 1][j])
			{
				flag = 0;
			}
		}
		if (flag == 1 && board[i][j] != ' ')
		{
			return board[i][j];
		}
	}
	//斜对角
	for (i = 0; i < row - 1; i++)
	{
		flag = 1;
		if (board[i][i] != board[i + 1][i + 1])
		{
			flag = 0;
		}
	}
	if (flag == 1 && board[i][i] != ' ')
	{
		return board[i][i];
	}
	for (i = 0; i < col - 1; i++)
	{
		flag = 1;
		if (board[i][col - 1 - i] != board[i + 1][col - 2 - i])
		{
			flag = 0;
		}
	}
	if (flag == 1 && board[i][col - 1 - i] != ' ')
	{
		return board[i][col - 1 - i];
	}
	if (IsFull(board, ROW, COL) == 1)
	{
		return 'Q';
	}
	return 'C';
}

game.h总代码展示

#pragma once

#define ROW 3
#define COL 3

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

//初始化棋盘
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);

//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL],int row ,int col );

//判断棋盘是否填满
int IsFull(char board[ROW][COL], int row, int col);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值