C语言三子棋简易实现

目录

一 .基本思路

二 .正文

2.1    生成目录

               2.1.1  test.c

2.2    初始化棋盘

               2.2.1  test.c

               2.2.2  game.c

               2.2.3  game.h

2.3    打印棋盘

               2.3.1  test.c

               2.3.2  game.c

               2.3.3  game.h

2.4    玩家下棋

               2.4.1  test.c

               2.4.2  game.c

               2.4.3  game.h

2.5    电脑下棋

               2.5.1  test.c

               2.5.2  game.c

               2.5.3  game.h

2.6    判断局面

               2.6.1  test.c

               2.6.2  game.c

               2.6.3  game.h

三 .游戏整个代码

3.1     test.c     文件

3.2     game.c  文件

3.3     game.h  文件


一 .基本思路

先总览下三子棋实现的整个样板吧

 在开始写代码之前,要先对整个代码进行归纳,我们可以将整个代码分为三大部分:第一:用test.c文件来进行游戏的测试逻辑。第二:用game.c文件来进行游戏的实现逻辑。第三:用game.h文件来进行游戏实现函数的声明。在下列正文中,我们将会不断运用到这三个文件

二 .正文

2.1    生成目录

从三子棋的样板可以看出,前面四行是整个游戏的菜单项,会给出player提示1.play或者2.exit选项

如图:

               2.1.1  test.c

在test.c文件中,我们需要完成这样的代码从而实现目录的打印

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

void test()
{
	int input = 0;
	srand((unsigned int)time NULL);
	do
	{
		menu();
		printf("请选择");
		scanf("%d", &input);
		//当用户输入相对应的数字时,我们可以使用switch语句来更好的接收信息
		switch (input)
		{
		case 1:
		//当用户输入1时,开始游戏
		//game();此时此刻就需要调用game()函数来实现整个游戏的过程,此过程下文会讲到
			break;
		case 0:
		//当用户输入0时,则退出游戏	
			printf("退出游戏\n");
			break;
		default:
		//当输入其他信息时,则返回错误
			printf("选择错误\n");
			break;
		}
	}while (input);//为了使游戏循环出现,我们使用 do while循环语句
}
int main()
{
	test();
	return 0;
}

 可能有人会注意到,第一行并没有之前熟悉的#include<stdio.h>头文件,而是#include"game.h",这里就需要重点说明下,为了使我们的代码块看起来更加清晰,可以将所有的需要定义的头文件函数统一放到game.h文件中,以后需要用到时只需引用下总头文件即可

如图所示:

2.2    初始化棋盘

从这个简易三子棋模板我们可以看出,这里面一共是3*3块格子,想实现这样我们可以通过创建二维数组来实现,即char board[ROW][COL] = { 0 };这里ROW代表行数,COL代表列数。每一块格子里面都是空格,想要实现空格就是我们此步骤的核心目的,即初始化棋盘的每一块格子都是空的,从而方便玩家下棋

               2.2.1  test.c

在test.c文件中,我们需要实现这样的代码

#include"game.h"
//引用头文件

void game()
{
    //创建二维数组
	char board[ROW][COL] = { 0 };
    //用InitBoard来初始化二维数组
	InitBoard(board,ROW,COL);
  
}

               2.2.2  game.c

在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] = ' ';
		}
	}
}


//通过创建变量i,j以及使用循环语句对每一块格子初始化为空格

               2.2.3  game.h

在初始化数组之前,需要对InitBoard函数进行声明,需要在game.h文件完成,并且为了后续能够自由的实现多子棋的玩法,并非仅仅是三子棋,则需要在game.h文件中定义行数ROW列数COL的大小,省的以后还需要手动多次修改行数列数

如图:

2.3    打印棋盘

正常的棋盘显示如下图所示:

               2.3.1  test.c

在初始化棋盘后,我们需要打印出棋盘来看看初始化后的样子。在test.c文件中就需要完成以下代码:

#include"game.h"
//引用头文件

void game()
{
    //创建二维数组
	char board[ROW][COL] = { 0 };


    //用InitBoard函数来初始化二维数组
	InitBoard(board,ROW,COL);


    //用DisplayBoard函数来实现对棋盘的打印
    DisplayBoard(board, ROW, COL);
  
}

               2.3.2  game.c

如何才能实现棋盘的打印呢,需要思考这样一个问题,在上述棋盘样例中,我们不难发现,棋盘被分成了9块格子,每块格子的分割都有个规律,可将其分为两大类。1:数据行,由    |来实现,可以采用循环语句来打印数据类内容。2:分割行,由---|来实现,也可使用循环语句来打印分割行的内容。

在此文件需要完成的代码:

#include"game.h"
void DisplayBoard(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("|");
		}

		printf("\n");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

               2.3.3  game.h

想要实现game.c对棋盘格式的打印,则现需要在game.h中声明此函数

如图:

2.4    玩家下棋

玩家下棋用‘*’表示

如图所示内容:

               2.4.1  test.c

#include"game.h"

void game()
{
	//数据存储到一个字符的二维数组中,玩家下棋是‘*’ 电脑下棋是‘#’
	char board[ROW][COL] = { 0 };//数组的初始化理想值为空格
	InitBoard(board, ROW, COL);  //对数组进行初始化函数为空格
	DisplayBoard(board, ROW, COL);  //打印三子棋模板
	while (1)                  //进行游戏
	{
		player_move(board, ROW, COL);   //玩家先玩
		DisplayBoard(board, ROW, COL); //每输入一组数组,相应的三子棋模板也要显示出来
		
	}

               2.4.2  game.c

实现玩家下棋这个函数的整个过程,则需要完成下列代码:

#include"ghame.h"
//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:>");
	int x = 0;
	int y = 0;
	scanf("%d %d", &x, &y);
	while (1)
	{
		if (x > 0 && x <= row && y > 0 & y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该位置已被占用,请重新输入\n");
				break;
			}
		}
		else
		{
			printf("非法输入,请重新输入\n");
			break;
		}
	}
}

               2.4.3  game.h

在定义函数player_move之前,需要在game.h中声明此函数。

如图:

2.5    电脑下棋

当玩家下完棋时,电脑下,原理与玩家差不多。

实现后如图所示:

               2.5.1  test.c

想实现上图所示的内容,需要在test.c中写出下列代码

void game()
{
	//数据存储到一个字符的二维数组中,玩家下棋是‘*’ 电脑下棋是‘#’
	char board[ROW][COL] = { 0 };//数组的初始化理想值为空格
	InitBoard(board, ROW, COL);  //对数组进行初始化函数为空格
	DisplayBoard(board, ROW, COL);  //打印三子棋模板
	while (1)                  //进行游戏
	{
		player_move(board, ROW, COL);   //玩家先玩
		DisplayBoard(board, ROW, COL); //每输入一组数组,相应的三子棋模板也要显示出来
		computer_move(board, ROW, COL);  //电脑再玩
		DisplayBoard(board, ROW, COL);
		
}

               2.5.2  game.c

与玩家下棋方式不同的是,由于玩家下棋是凭借主观臆断,而电脑则需要随机下一个位置,就需要我们用到srand((unsigned int)time NULL);从而确保电脑下的是个随机值

则在game.c需要完成这样的代码:

//电脑下棋用‘#’
void computer_move(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;
		}
	}
}

在test.c需要完成这样的代码

void test()
{
	int input = 0;
	srand((unsigned int)time NULL);     //确保电脑下的位置是个随机数
}

               2.5.3  game.h

相应的定义头文件也是少不了的:

2.6    判断局面

当玩家和电脑下到一定程度时,则需要判断胜负或平局

如图:

判断输赢的字符:
//玩家赢 - '*'
//电脑赢 - '#'
//平均 --- 'Q'
//继续 --- 'C'

               2.6.1  test.c

char ret = 0;   //全局变量定义ret
void game()
{
	//数据存储到一个字符的二维数组中,玩家下棋是‘*’ 电脑下棋是‘#’
	char board[ROW][COL] = { 0 };//数组的初始化理想值为空格
	InitBoard(board, ROW, COL);  //对数组进行初始化函数为空格
	DisplayBoard(board, ROW, COL);  //打印三子棋模板
	while (1)                  //进行游戏
	{
		player_move(board, ROW, COL);   //玩家先玩
		DisplayBoard(board, ROW, COL); //每输入一组数组,相应的三子棋模板也要显示出来
		ret = is_win(board, ROW, COL);  //开始判断胜利条件
		if (ret != 'C')
		{
			break;
		}
		computer_move(board, ROW, COL);  //电脑再玩
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);

		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
}

               2.6.2  game.c

int 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;
			}
		}
	}
	return 1;
}


char is_win(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][1] != ' ')
		{
			return board[i][1];

		}
	}

	//判断胜利条件---三列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}

	}

	//判断胜利条件---对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
	{
		return board[0][0];

	}


	if (board[2][0] == board[1][1] & board[1][1] == board[0][2] && board[2][0] != ' ')
	{
		return board[2][0];

	}

	//判断平局
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
	//继续
	else
		return 'C';

}

               2.6.3  game.h

三 .游戏整个代码

3.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");
}

int ret = 0;
void game()
{
	char board[ROW][COL] = { 0 };
	InitBoard(board,ROW,COL);
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);

		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
}

void test()
{
	int input = 0;
	srand((unsigned int)time NULL);
	do
	{
		menu();
		printf("请选择");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
		game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	}while (input);
}
int main()
{
	test();
	return 0;
}

3.2     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;
	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("|");
		}

		printf("\n");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

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


void computer_move(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 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;
			}
		}
	}
	return 1;
}


char is_win(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][1] != ' ')
		{
			return board[i][1];

		}
	}
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
			
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
	{
		return board[0][0];

	}
		
	
	if (board[2][0] == board[1][1] & board[1][1] == board[0][2] && board[2][0] != ' ')
	{
		return board[2][0];

	}


	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
	else
		return 'C';
	
}

3.3     game.h  文件

#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
void InitBoard(char board[ROW][COL], int row, int col);
void DisplayBoard(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);
char is_win(char board[ROW][COL], int row, int col);

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三分苦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值