教你用C语言实现三子棋

 更新时间:2021年11月11日 10:41:54   作者:钓月亮  
这篇文章主要为大家详细介绍了C语言实现简单三子棋程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

三子棋

三子棋的规则是:在3x3的棋盘里,双方轮流下子(以X和O表示),先将3个子连成一条线(横竖斜都可以)的一方获胜

下面是三子棋C语言实现的几个问题:

1.要想实现三子棋,我们需要一个棋盘,然后就是棋盘的内容。

2.下棋的时候需要判断是否该位置合法。

3.玩家和电脑的下棋逻辑不同,玩家需要手动输入,电脑是自己下棋

4.每下一步棋都需要判断游戏是否结束(哪方胜利、平局还是继续下棋)。

设计方式:

需要创建三个文件:一个头文件,两个源文件,头文件里面放的是函数的声明以及一系列预处理命令,命名为game.h

两个源文件,一个里面放的是主函数(游戏大体的运行顺序),命名为work.c,一个里面放的是游戏内容的实现逻辑(放大部分执行函数),命名为game.c

work.c的设置

首先是进入游戏,为了确保游戏可以重复玩,我们可以以循环的方式实现

//work.c里面的内容
#include"gmae.h"//这样的话,在game.h里面包含的文件,在work.c里面也能使用
int main()
{
	int option = 0;//在主函数里面设计循环,可以保证每次游戏结束后可以选择继续游戏或者退出游戏
	do 
	{
		Menu();
		scanf("%d", &option);
		switch (option)
		{
		case 1:
			game();//如果选择开始游戏,就会进入到game()函数,
                /*我们需要定义game函数来存放游戏的实现顺序*/
			break;
		case 0:
			printf("已退出");
			break;
		default :
			printf("错误选择,请重新输入");
		}
	} while (option);
	return 0;
}
//work.c里面的内容
void Menu()//定义菜单函数,配合主函数里面的循环,可以实现每次游戏结束会跳到这个界面
{
	printf("*****************\n");
	printf("***  1.play  ****\n");
	printf("***  0.exit  ****\n");
	printf("*****************\n");
	printf("请选择");
}

然后就是游戏进行的顺序需要在game函数里面实现

//work.c里面的内容
void game()
{
	srand((unsigned int)time(NULL));//使用随机数,便于后面电脑下棋时是随机出棋
	char board[ROW][COL] = { 0 };//创建一个二维数组,用来实现棋盘的内容
	printf("游戏开始:\n");
	init_board(board,ROW,COL);//初始化棋盘
	print_board(board, ROW, COL);//打印棋盘
	while (1)
	{
		char ret = '0';
		player_move(board, ROW, COL);//玩家下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断是否结束
		if (ret == '*')
		{
			printf("玩家胜利\n");
			break;
		}
		computer_move(board, ROW, COL);//电脑下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断是否结束
		if (ret == '#')//
		{
			printf("电脑胜利\n");
			break;
		}//判断电脑胜利
		if (ret == 'Q')//判断平局
		{
			printf("平局\n");
			break;
		}//判断平局
	}
}
//work.c里面的内容
void game()
{
	srand((unsigned int)time(NULL));//使用随机数,便于后面电脑下棋时是随机出棋
	char board[ROW][COL] = { 0 };//创建一个二维数组,用来实现棋盘的内容
	printf("游戏开始:\n");
	init_board(board,ROW,COL);//初始化棋盘
	print_board(board, ROW, COL);//打印棋盘
	while (1)
	{
		char ret = '0';
		player_move(board, ROW, COL);//玩家下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断是否结束
		if (ret == '*')
		{
			printf("玩家胜利\n");
			break;
		}
		computer_move(board, ROW, COL);//电脑下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断是否结束
		if (ret == '#')//
		{
			printf("电脑胜利\n");
			break;
		}//判断电脑胜利
		if (ret == 'Q')//判断平局
		{
			printf("平局\n");
			break;
		}//判断平局
	}
}

下面是对这几点问题的解决方法:

game.h的内容设置

#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define COL 3//设置了行与列的值,可以更改
#include<stdio.h>
#include<time.h>//用来实现时间戳
//下面是游戏实现逻辑所需的函数声明。
void init_board(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
void print_board(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);

game.c的设置

1.棋盘的内容

我们通过创建一个二维数组来作为棋子,通过输入坐标的方式来进行下棋的步骤

创建数组:

char board[ROW][COL] ;这里括号里面的值我们用提前处理过的ROW与COL来表示,
    通过预处理命令,我们后期可以很方便的更改ROW与COL的值来改变棋盘的大小

2.棋盘以及棋盘的初始化

棋盘是3x3形式,所以我们可以通过循环的方式打印一个棋盘,下面是棋盘的格式

 0 | 0 | 0  
---|---|---
 0 | 0 | 0
---|---|---
 0 | 0 | 0 //而这个表里面的0就是我们的下的棋子占有的位置
 /*而这个棋盘的设计是有明显的规律的:
     第一行: 空格%c空格
	第二行:---|循环3遍,但是最后遍不打印“|”
     然后这样的两行在循环中多次打印,就出现了这样的三子棋表格
     注意:最后一行不用再打印“---”

这里我们定义init_board()函数来初始化棋盘(即让数组的所有元素的值都为空格)

void init_board(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] = ' ';//把所有元素赋值为' '
		}
	}
}

3.打印棋盘

void print_board(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++)
		{
			printf(" %c ", board[i][j]);
			if (j != col - 1)
			{
				printf("|");//最后一列不打印'|'
			}
		}
		//每次进行上一个循环时,i的值在变化,打印的是不同的值
		printf("\n");
		if (i != row - 1)//最后一行不打印字符
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j != col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
	printf("\n");
}

4.下棋步骤 玩家下棋

void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:\n");
	int x = 0;
	int y = 0;
	int i = 0;
	int j = 0;
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col & y >= 1)
		{
			if (board[x-1][y-1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
	}
}

电脑下棋

void computer_move(char board[ROW][COL], int row, int col)
{
	char x = 0;
	char y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

5.判断是否胜利

char is_full(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;//用是否还有空格判断平局
		} 
	}
}
char is_win(char board[ROW][COL], int row, int col)//这里是判断横竖斜三种方式是否出现胜利
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = 0; i < row; i++)
	{
		if ((board[i][0] == board[i][1])&&(board[i][1]==board[i][2])&&board[i][1]!=' ');
		{
			return board[i][0];
		}
	}
	for (i = 0; i < row; i++)
	{
			if ((board[0][i] == board[1][i])&&(board[2][i]==board[1][i]) && board[1][i] != ' ')
			{
				return board[0][i];
			}
	}
	if ((board[0][0] == board[1][1]) &&( board[1][1] == board[2][2]) && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if ((board[0][2] == board[1][1] )&& (board[1][1] == board[2][0]) && board[1][1] != ' ')
	{
		return board[1][1];
	}
//一旦出现胜利,就返回胜利一方的棋子字符
	if (is_full(board,ROW,COL))
	{
		return 'Q';//平局返回'Q'
	}
	else
		return 'C';//什么情况都没有就继续游戏
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • C语言中大小端问题实例探索解决方法

    C语言中大小端问题实例探索解决方法

    这篇文章主要介绍了C语言中大小端问题实例,总的来说这并不是一道难题,那为什么要拿出这道题介绍?拿出这道题真正想要传达的是解题的思路,以及不断优化探寻最优解的过程。希望通过这道题能给你带来一种解题优化的思路
    2023-02-02
  • C语言中 type *(0)的具体使用

    C语言中 type *(0)的具体使用

    表达式 type * (0) 在 C/C++ 编程中是一个常见的技巧,通常用于内核编程和一些系统编程场景中,本文主要介绍了C语言中 type *(0)的具体使用,感兴趣的可以了解一下
    2024-08-08
  • 深入了解C++中常用的三个智能指针

    深入了解C++中常用的三个智能指针

    C++是一门强大的编程语言,但是在内存管理方面却存在着一些问题。手动管理内存不仅费时费力,而且容易出错。因此,C++中引入了智能指针这一概念,以更好地管理内存,下面就来详细讲讲C++中常用的三个智能指针吧
    2023-05-05
  • c语言中形参与实参的关系解读

    c语言中形参与实参的关系解读

    这篇文章主要介绍了c语言中形参与实参的关系,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • C语言深入分析整形数据存储

    C语言深入分析整形数据存储

    C语言中,我们经常使用数据类型,那么整形数据在内存中如何存储?存储方式是什么?如果你对这些内容不太了解的话,相信看完这篇博客后,你会对整形数据的存储有一个新的认识。话不多说,我们进入正题
    2022-08-08
  • Visual Studio新建类从默认internal改为public

    Visual Studio新建类从默认internal改为public

    本文将介绍如何将Visual Studio中的internal修饰符更改为public,以实现更广泛的访问和重用,需要的朋友们下面随着小编来一起学习学习吧
    2023-09-09
  • C/C++ 获取Windows系统的位数32位或64位的实现代码

    C/C++ 获取Windows系统的位数32位或64位的实现代码

    这篇文章主要介绍了C/C++ 获取Windows系统的位数32位或64位的实现代码的相关资料,希望通过本文能帮助到大家,让大家实现这样的功能,需要的朋友可以参考下
    2017-10-10
  • C++使用动态内存分配的原因解说

    C++使用动态内存分配的原因解说

    这篇文章主要介绍了C++使用动态内存分配的原因解说,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • c++算法进阶删除有序链表中的重复元素

    c++算法进阶删除有序链表中的重复元素

    这篇文章主要为大家介绍了c++算法进阶删除有序链表中的重复元素示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 用C语言实现三子棋小游戏

    用C语言实现三子棋小游戏

    这篇文章主要为大家详细介绍了用C语言实现三子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06

最新评论