yo!这里是三子棋

目录

前言

模块介绍

测试模块

1.测试文件

功能实现模块

1.头文件

2.函数实现文件

 完整测试

 后记


前言

       三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是三子棋在很多时候会出现和棋的局面。---百度百科

       在三子棋小游戏的编写过程中,可以用到数组,循环等c语言基础知识,是练习c语言基础的推荐之一,下面就让我们一步一步实现它吧!

模块介绍

  • 测试模块

1.测试文件

       在整个编写开始前,建议可以先写好测试文件,写完一个功能函数测试一个函数,保证思路的顺利展开,否则,若一下全写完再测试,如果出现问题,就不清楚错从何处来,会影响到自己的思路。

       主函数使用了一个do while循环以及嵌套一个switch语句,可以保证游戏可以在ta的选择下一直进行。

 代码(test.c):

#define _CRT_SECURE_NO_WARNINGS
#include "game_szq.h"

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));   //rand函数的辅助
                                       //在猜数字游戏中有详细介绍,这里不再赘述
	do
	{
		menu();    //菜单
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();    //博弈
			break;
		case 0:
			printf("退出成功\n");
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (input);

	return 0;
}
  • 功能实现模块

1.头文件

       在测试文件中可以看到,主函数主要包括菜单,博弈,而三子棋主要核心在于博弈,主要有初始化棋盘、打印棋盘、玩家下棋、电脑下棋以及判断输赢等功能模块。

代码(game.h):

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

#define ROW 3   //行数
#define COL 3   //列数

//菜单
void menu();
//游戏具体实现
void game();
//初始化棋盘
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 PCMove(char board[ROW][COL], int row, int col);
//判断输赢
char is_win(char board[ROW][COL], int row, int col);

2.函数实现文件

1)菜单

      菜单的制作依旧很简单,是读者展示自己个性的地方,可以根据自己对游戏的理解装点菜单界面,让ta可以对游戏的功能一目了然。

代码: 

void menu()
{
	printf("*********三子棋************\n");
	printf("*********1.start***********\n");
	printf("*********0.exit************\n");
	printf("***************************\n");
}

测试:

2)初始化棋盘

        棋盘在程序中就是一个二维数组,为在.exe文件表现成一个棋盘模样(如图),将二维数组的所有元素初始化为 空格 。

代码: 

void InitBoard(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

3)打印棋盘

       打印棋盘是三子棋小游戏中的难点之一,可以细细打敲,在.exe文件中,可以将棋盘分解为如左图的格式,其中半格代表空格,方格代表字符,竖线、横线则是棋盘网格线,而棋盘的一行占.exe文件中的两行,如右图的①②两行。

                

代码: 

void PrintBoard(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);   //打印上图的①
			if (j < col - 1)    //防止出现右边框
				printf("|");    //因为最右边不需要竖线,所以加上if语句进行特殊处理
		}
		printf("\n");

		if (i < row - 1)   //防止出现下边框,最下边不需要横线
		{
			for (j = 0; j < col; j++)
			{
				printf("---");   //打印上图的②
				if (j < col - 1)     //防止出现右边框
					printf("|");
			}
			printf("\n");
		}
	}
	printf("\n");
}

 测试:

注意:笔者在前面的头文件中对棋盘的行列作了预处理设置,即#define ROW 3   #define COL 3,此时,若将3改成5,则棋盘变成了5X5,如左图,若改为10,则变成10X10,如右图,所以读者可以任意更改棋盘的格式成为n子棋(但游戏规则没有发生变化,依旧是三子棋的规则hahaha)。

    

4)玩家下棋

       当轮到玩家下棋时,玩家根据三子棋的规则去放置己方棋子(*),使用if语句对所选择坐标做出限制,选择不当时作出提示,让玩家重新选择,此时,也需要一个循环去实现重复选择坐标的效果,当选择合法坐标时跳出循环。

代码: 

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入棋盘坐标:\n");
		scanf("%d %d", &i, &j);
		if (i >= 1 && i <= row && j >= 1 && j <= col&&board[i - 1][j - 1]==' ')
        //限制棋盘坐标的选择,包括坐标合法以及此坐标为空(为空格符)
		{
			board[i - 1][j - 1] = '*';
			break;
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}

 测试:

5)电脑下棋

       当电脑下棋时,电脑会根据剩下棋格随机放入棋子(#)(由于笔者能力有限,同时其作为c语言基础的练习,无法去实现智能下棋,有能力的可以尝试做一下),此时也就利用到了rand函数(别忘了在主函数中加上srand函数以及头文件哦,这个知识点在猜数字游戏中讲过)。同时,与玩家下棋一样,也要利用循环做出 坐标非法就重新选择坐标 的效果。

代码: 

void PCMove(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	printf("电脑下棋\n");
	while (1)
	{
		i = rand() % row;   //随机行坐标
		j = rand() % col;   //随机列坐标
		if (board[i][j] == ' ')   //限制坐标为空(为空格符)
		{
			board[i][j] = '#';
			break;
		}
	}
}

 测试:

6)判断输赢

       判断输赢也是三子棋游戏的难点之一,因为需要考虑游戏结果的多种情况,包括①三行、三竖、两斜成线均为赢,②没人赢但棋格满了为平局,③没人赢且棋格没满则继续,具体看代码注释。

代码: 

char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;

    //判断行
    for (i = 0; i < row; i++)  //循环判断每一行
	{
		for (j = 1; j < col; j++)  //判断玩家有无成行
		{
			if (board[i][j] != board[i][0] || board[i][0] != '*')
				break;
		} //从此循环出来有两种情况 ①break出来,即出现if语句中的情况 
          //②j==col,即未出现if语句的情况,即if语句的反命题,
          //即在第某行中,每一个棋盘的棋子均与第一个棋子相同且棋子为*,即玩家成行
		if (j==col)  //此if语句就是判断是否为②的情况
			return '*';
		for (j = 1; j < col; j++)  //判断电脑是否成行,情况与玩家一致
		{
			if (board[i][j] != board[i][0] || board[i][0] != '#')
				break;
		}
		if (j==col)
			return '#';
	}

	//判断列
	for (j = 0; j < col; j++)   //循环判断每一列,与判断每一行情况一致
	{
		for (i = 1; i < row; i++)
		{
			if (board[i][j] != board[0][j] || board[0][j] != '*')
				break;
		}
		if (i == row)
			return '*';
		for (i = 1; i < row; i++)
		{
			if (board[i][j] != board[0][j] || board[0][j] != '#')
				break;
		}
		if (i == row)
			return '#';
	}

	//判断正对角线
	for (i = 1; i < row; i++)   //仔细理解判断行的情况,理解之后,判断正副对角线就不难理解了
	{
		if (board[0][0] == ' ' || board[i][i] != board[0][0])
			break;
	}
	if (i==row)
		return board[0][0];

	//判断副对角线
	for (i = 1; i < row; i++)
	{
		if (board[0][row - 1] == ' ' || board[i][row - i - 1] != board[0][row - 1])
			break;
	}
	if (i == row)
		return board[0][row - 1];

    //当没人赢且有空格符时则继续
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 'c';   //继续
		}
	}
    //当没人赢且没有空格符时则判为平局
	return 'q';   //平局
}

 测试:

7)博弈

        在玩家与电脑下棋之前,需要将棋盘初始化,之后利用循环进行玩家与电脑的博弈,当某方下完棋之后立马判断是否有人胜利,有人胜利时就退出循环公布结果,否则就继续下棋。

代码: 

void game()
{
	char tmp = 0;
	//设置棋盘
	char board[ROW][COL] = {0};
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//打印
	PrintBoard(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		tmp = is_win(board, ROW, COL);
		if (tmp != 'c')
			break;
		//电脑下棋
		PCMove(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		tmp = is_win(board, ROW, COL);
		if (tmp != 'c')
			break;
	}
	printf("游戏结束,结果:\n");
	if (tmp == '*')
		printf("玩家获胜\n");
	else if (tmp=='#')
		printf("电脑获胜\n");
	else
		printf("平局\n");
}

测试:

 完整测试

 后记

       以上就是三子棋小游戏的实现,在设计过程中,有些部分可能做的不是很好,有错误或者需要改进的可以写在评论区,我会学习的,一起进步!有老铁想要源码可以三连加关注私信我或者写在评论区哦,谢谢。

猜你喜欢

转载自blog.csdn.net/phangx/article/details/130297964
今日推荐