C语言实现简易三子棋

本文介绍了如何从零开始编写一个简单的三子棋游戏程序,包括游戏逻辑、玩家与电脑的交互以及游戏状态的判断。通过多文件编程实现,玩家先手,电脑后手,电脑的落子位置为随机。虽然电脑策略简单,但足以提供基本的游戏体验,适合初学者进行编程实践。
摘要由CSDN通过智能技术生成

前言

在学习完数组相关的一些知识后,我们就可以来动手写属于自己的游戏程序了!这样学习起来感觉是不是充满了斗志呢?并且这可能是你游戏创作生涯的重要一步。

简单介绍

下面所实现的三子棋游戏程序完成了玩家先手,电脑后手的下棋步骤;
在开始菜单栏里,我们通过输入1或者0来选择开始游戏或退出游戏;
当然,这里实现的三子棋程序缺点多多,其中最致命的是电脑无法来进行有效的防御或进攻,这里电脑所下位置是在所剩空格处随机下棋(随机也是一种美),哈哈^ - ^
当然,实现哪些功能我们完全可以手写出来(即可以通过玩家所下棋位置进行当前最好的下棋位置的判断),我在这里必须膜拜一下阿尔法狗了~
我们在玩三子棋的时候可以发现,两个会下三子棋的人最终结果都是平局,所以这个程序还是有优点的,可以体验三子棋经常胜利的感觉!
当然,也希望各位大佬在评论区提出自己的见解和看法。

思路

在这里,我是应用多文件编程进行了三子棋程序的编写。
创建了game源文件,game头文件,test源文件。
不了解的可以了解多文件编程的优点。

一、编写主要框架

那我们先编写主函数完成主要框架的搭建吧

int main()
{
	int input = 2;
	do {                          //这里用do...while循环
		menu();                   //菜单栏0
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();               //三子棋游戏
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
		system("cls");
	} while (input-2);             //直接用到真值判断是否继续游戏
	return 0;
}

开始菜单

void menu()
{
	printf("********  三子棋  ********\n");
	printf("1.开始游戏       2.退出游戏\n");
	printf("**************************\n");
}

二、初始化并打印棋盘

开始时我们先用define定义三子棋棋盘的行和列,这样会让接下来程序的编写更加轻松,也便于理解。

#define ROW 3
#define COL 3

接下来定义一个二维数组

char board[ROW][COL];

我们还要初始化三子棋棋盘的内容,因为在你不初始化数组时会发生意想不到的后果 > - <

void InitBoard(char board[ROW][COL], int row, int col)
{  //Init 初始化英文缩写
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

接下来我们需要打印出我们的棋盘

void PrintBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//打印分割列
		printf("|");
		int j = 0;
		for (j = 0; j < col; j++)
			printf(" %c |", board[i][j]);
		printf("\n");
		//打印分割行
		printf("---");
		for (j = 0; j < col; j++)
			printf("---");
		printf("\n");
	}
}

三、玩家下棋

接下来,我们让玩家下棋,函数实现如下:

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("请下棋:>\n");
	while (1)                  //这里用一个while循环让玩家下对为止
	{
		printf("请输入一个坐标,例:1 1>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= row)
		{
			if (board[x - 1][y - 1] != ' ')//当所下位置为空时,才能键入
				printf("坐标被占用,请重新输入!\n");
			else
			{
				board[x - 1][y - 1] = '*';
				break;
			}
		}
		else
			printf("坐标非法,请重新输入!\n");//可能玩家会输入100 100,这当然也不行
	}
}

四、电脑下棋

这里用到了一个随机数生成的函数,我们利用时间戳的唯一性来生成随机数。

srand((unsigned int)time(NULL));  //该行需要添加至合适位置,实现下面代码随机数的生成
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:>");
	while (1)
	{
		int x = rand() % row;//这里用到了生成随机数的功能
		int y = rand() % col;//可以查查相关的资料,还可以看它
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
		printf("%d %d\n",x,y);
	}
}

五、判断回合阶段

现在需要进行回合阶段的判断,即 玩家胜、电脑胜、平局或者游戏继续的判断。
胜利的判断方法:查找是否有三个连续非空的 *#
平局的判断方法:棋盘下满无胜出者
继续的判断方法:除去两者之外的情况则继续

char CheckWin(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][1] == board[i][2]&&board[i][0]!=' ')
		{
			return board[i][0];
		}
	}
	//三列的判断
	for (i = 0; i < row; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
	{
		return board[1][1];
	}
	//平局
	if (IsFull(board,row,col) == 1)//这里又调用IsFull函数
	{
		return 'E';
	}
	return 'C';
}

判断棋盘是否下满

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;
}

六、game()函数

完成了game()函数的各个功能,就可以整合在一起了

void game()
{
	//数据的存储是二维数组
	char board[ROW][COL];
	//初始化棋盘-初始化为空格
	InitBoard(board, ROW, COL);
	DisplayBoard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C')
			break;
		DisplayBoard(board, ROW, COL);
		//电脑下棋
		ComputerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C')
			break;
		DisplayBoard(board, ROW, COL);
	}
	if (ret == '*')
		printf("玩家赢!\n");
	else if (ret == '#')
		printf("电脑赢!\n");
	else if (ret == 'E')
		printf("平局\n");
}

最终代码

game.h
#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 PrintBoard(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 CheckWin(char board[ROW][COL], int row, int col);

//电脑赢了  #  利用所用字符代表
//玩家赢了  *  
//平局     E  --even
//继续     C  --continue
game.c
#include "game.h"

void InitBoard(char board[ROW][COL], int row, int col)
{  //Init 初始化英文缩写
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}
void PrintBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	printf(" --- --- ---\n");
	for (i = 0; i < row; i++)
	{
		//打印分割列
		printf("|");
		int j = 0;
		for (j = 0; j < col; j++)
			printf(" %c |", board[i][j]);
		printf("\n");
		//打印分割行
		for (j = 0; j < col; j++)
			printf(" ---");
		printf("\n");
	}
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("请下棋:>\n");
	while (1)                  //这里用一个while循环让玩家下对为止
	{
		printf("请输入一个坐标,例:1 1>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= row)
		{
			if (board[x - 1][y - 1] != ' ')//当所下位置为空时,才能键入
				printf("坐标被占用,请重新输入!\n");
			else
			{
				board[x - 1][y - 1] = '*';
				break;
			}
		}
		else
			printf("坐标非法,请重新输入!\n");//可能玩家会输入100 100,这当然也不行
	}
}
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:>\n");
	while (1)
	{
		int x = rand() % row;//这里用到了生成随机数的功能
		int 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 CheckWin(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][1] == board[i][2] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}
	//三列的判断
	for (i = 0; i < row; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
	{
		return board[0][2];
	}
	//平局
	if (IsFull(board, row, col) == 1)//这里又调用IsFull函数
	{
		return 'E';
	}
	return 'C';
}
test.c
#include"game.h"

void menu()
{
	printf("********  三子棋  ********\n");
	printf("1.开始游戏       2.退出游戏\n");
	printf("**************************\n");
}
void game()
{
	//数据的存储是二维数组
	char board[ROW][COL];
	//初始化棋盘-初始化为空格
	InitBoard(board, ROW, COL);
	PrintBoard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C')
			break;
		PrintBoard(board, ROW, COL);
		//电脑下棋
		ComputerMove(board, ROW, COL);
		ret = CheckWin(board, ROW, COL);
		if (ret != 'C')
			break;
		PrintBoard(board, ROW, COL);
	}
	if (ret == '*')
		printf("玩家赢!\n");
	else if (ret == '#')
		printf("电脑赢!\n");
	else if (ret == 'E')
		printf("平局\n");
}
int main()
{
	int input = 2;
	do {                          //这里用do...while循环
		menu();                   //菜单栏0
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();               //三子棋游戏
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
		system("cls");
	} while (input-2);             //直接用到真值判断是否继续游戏
	return 0;
}

实现效果图

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

结束语

我们在编程学习中可以将一些简单的或者简化的游戏写出来,在为自己创造乐趣的同时也可以带来自身的进步,使coding不再乏味。也让自己在成长中体会别样的品味。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值