速解 三子棋

目录

1.设计思路

2.主函数的创建

3.游戏主体函数

4.输出棋盘

5.判断输赢

6.玩家落子

7.电脑落子

8.总结


1.设计思路

      我们可以先想一下三子棋的样子,三行三列,所以自然而然的我们就可以想到用一个二维数组来解决。

      然后就是两个部分,玩家落子和电脑落子。玩家落子:创建两个变量一个横轴,一个纵轴,然后输入要落子的坐标就好了。电脑落子:和玩家差不多,但是电脑落子需要两个随机变量,需要用到rand函数以及和它配套的srand函数还要一个时间戳time()

      最后,我们写一个判断输赢的函数就大功告成啦!

2.主函数的创建

     对于主函数在这样的程序中会很简单,我们大多都是在这调用其他的函数。

 这里写个do while循环保证我们可以一直玩,然后我们在这调用了两个函数,一个是菜单menu,一个就是我们游戏的主体菜单game。至于srand((unsigned int)time(NULL));这行代码,这是srand()函数利用时间戳time()rand()函数创建了真正的随机值,这个在电脑落子部分会体现。至于菜单的设计,就看各位喜欢怎样就怎样设计啦!

3.游戏主体函数

话不多说先看代码

 这里面调用到了很多函数有show_board()(输出棋盘)win()(判断输赢)p_move(玩家落子)c_move(电脑落子),我还用了一个清屏的系统命令system("cls"),这个可以不用写,我主要是想让玩家有更好的体验感init()(初始化)

4.输出棋盘

 输出棋盘我们不能简单地用for循环写,我们还要保证棋盘的美观,所以要适当的加一些横竖

 就像这玩意。好,我们展示代码

 我们这里用了有个if的限制条件,这个是为了让我们的棋盘美观如果不加就会这样让我们的棋盘下面多一横或是右边多一横,当然你要是就喜欢这样就当我没说。我们随带讲一下init()这函数,它的话就只是让数组的值都变成空格,也同样是为了棋盘的美观因为如果不输入空格,就会这样它的值不占一个空间,就会让棋盘很丑。

5.判断输赢

代码如下

void win(char board[ROW][COL], int row, int col)
{

	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == '*')
				return '*';
			if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '*')
				return '*';
			if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == '#')
				return '#';
			if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '#')
				return '#';

		}
	}
	if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == '*')
		return '*';
	if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == '*')
		return '*';
	if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == '#')
		return '#';
	if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == '#')
		return '#';
	int ret = is_full(board, ROW, COL);
	if (1 == ret)
		return 'Q';
	return 'c';
}

代码有点长,但其实就是利用for循环去找三个一样的棋子然后就可以判断输赢啦!如果棋盘都排满了还是没有输赢就平局啦!这里用到一个判断棋盘是否满的函数is_full(),函数如下

int is_full(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (' ' == board[i][j])
				return 0;
		}
	}
	return 1;
}

6.玩家落子

代码如下

void p_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
				printf("这里被占,请重新输入!\n");
		}
		else
			printf("输入错误,请重新输入!\n");
	}
}

玩家落子其实就是利用你输入的坐标把棋子赋值给数组中,当然我们这里坐标要减一,因为数组下标是从0开始的,而我们下棋是从一开始。然后加一些限制输入坐标的条件就可以了。

7.电脑落子

代码如下

void c_move(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;
		}

	}
}

电脑落子这里就更精简了,但是我们这里用到了rand函数,这个函数是用来生成随机值的,但是光靠他自己是不行的,还要用到前面讲的srand()函数和time()时间戳,至于怎么用这就不多讲述了毕竟我们是讲三子棋,若是各位看客想了解那就关注博主,我会出一篇博客哦!

8.总结

好了,三子棋的所有部分基本都差不多了,只要将他们整合一下就可以了,博主的话,将他们分了三个部分,源.c、test.hgame.c.

下面就是这三个文件的代码了

//源.c
#include"test.h"
void menu()
{
	printf("*****************************\n");
	printf("***********  1.play   *******\n");
	printf("***********  0.exit   *******\n");
	printf("*****************************\n");

}
void game()
{
	char ret;
	char board[ROW][COL] = { 0 };
	init(board, ROW, COL);
	show_board(board, ROW, COL);
	while (1)
	{

		p_move(board, ROW, COL);
		system("cls");
		show_board(board, ROW, COL);
		ret = win(board, ROW, COL);
		if (ret != 'c')
			break;
		c_move(board, ROW, COL);
		show_board(board, ROW, COL);
		ret = win(board, ROW, COL);
		if (ret != 'c')
			break;
	}
	if (ret == '*')
	{
		system("cls");
		printf("恭喜你,获胜!\n");
		show_board(board, ROW, COL);

	}
	else if (ret == '#')
	{
		system("cls");
		printf("很遗憾,你输了!\n");
		show_board(board, ROW, COL);

	}

	else if (ret == 'Q')
	{
		system("cls");
		printf("平局!\n");
		show_board(board, ROW, COL);
	}


}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入!\n");
		}

	} while (input);

	return 0;
}
//game.c
#include"test.h"
void show_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}printf("\n");
		if (i < row - 1)
		{
			for (int j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}printf("\n");
		}
	}
}
void init(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
		for (int j = 0; j < col; j++)
			board[i][j] = ' ';
}
void p_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
				printf("这里被占,请重新输入!\n");
		}
		else
			printf("输入错误,请重新输入!\n");
	}
}
void c_move(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 is_full(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (' ' == board[i][j])
				return 0;
		}
	}
	return 1;
}
void win(char board[ROW][COL], int row, int col)
{

	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == '*')
				return '*';
			if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '*')
				return '*';
			if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == '#')
				return '#';
			if (board[0][j] == board[1][j] && board[0][j] == board[2][j] && board[0][j] == '#')
				return '#';

		}
	}
	if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == '*')
		return '*';
	if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == '*')
		return '*';
	if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == '#')
		return '#';
	if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == '#')
		return '#';
	int ret = is_full(board, ROW, COL);
	if (1 == ret)
		return 'Q';
	return 'c';
}
//test.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define ROW 3
#define COL 3

void show_board(char board[ROW][COL], int row, int col);
void init(char board[ROW][COL], int row, int col);
void p_move(char board[ROW][COL], int row, int col);
void c_move(char board[ROW][COL], int row, int col);
char win(char board[ROW][COL], int row, int col);

好了,希望多多点赞,多多评论,还有点点关注哦!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值