C语言实现三子棋代码

码前须知

 三子棋即为井字棋,在任意行、列、斜线上完成三个图案相同则为胜

(该三子棋的电脑方为随机下棋,并不能实现智能分析棋局)

码前准备

       test.c 文件 用来存放菜单函数、游戏函数、主函数

game.c文件 用来存放游戏实现的核心函数(棋盘初始化、棋盘打印、玩家下棋、电脑下棋、判断输赢)

game.h文件 用于包含头文件、相关宏定义、各函数的声明

主函数

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();                     //打印菜单
		printf("请选择 :>  ");
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			printf("三子棋\n");
			game();                     //游戏函数
			printf("还玩吗?\n");                          
			printf("请选择 :> 1:返回主页面 0:退出\n");
			scanf("%d", &input);
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("\n");
			printf("\n");
			printf("不想玩就选 0 ( - - )。。\n");             //  ✧(≖ ◡ ≖✿) 
			printf("\n"); 
			printf("\n");
			break;
		}
	} while (input);             //通过输入的数字,判断是否继续以上语句
	return 0;
}

srand((unsigned int)time(NULL));

 传入空指针进而生成时间戳,然后强制转换为整型,来设置随机数起点。该语句作用于随后的Computermove函数中的rand函数来生成随机数

x = rand() % row;
y = rand() % col;     //电脑下棋函数中生成随机坐标

函数模块

1.菜单函数 

void menu()
{
	printf("*******************************\n");
	printf("*********1.play 0.exit*********\n");
	printf("*******************************\n");

 生成菜单界面用于为开始或结束提供选择

2.游戏函数 

void game()
{
	char ret = 0;                                  
	char board[ROW][COL] = { 0 };                   //生成一个二维数组作为棋盘的载体
	//初始化棋盘的函数
	InitBoard(board, ROW, COL);
	//打印棋盘函数
	DispalyBoard(board, ROW, COL);
    //下棋
	while (1)
	{
		Playmove(board, ROW, COL);
		ret = Iswin(board,ROW,COL);            //判断输赢函数
		if (ret !='c')
		{
			break;
		}
		DispalyBoard(board, ROW, COL);

		Comeputermove(board, ROW, COL);
		ret = Iswin(board, ROW, COL);
		if (ret !='c')
		{
			break;
		}
		DispalyBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if(ret == '#')
	{
		printf("电脑赢\n");
		printf("你个辣鸡,即将执行关机程序,如果输入:我是猪,则取消关机\n");
		subject_shutdown();
	}
	else 
	{
		printf("平局\n");
	}
	DispalyBoard(board, ROW, COL);
}

1.棋盘初始化

在game.h 中,首先宏定义棋盘行与列都为三

#define ROW 3
#define COL 3

 棋盘初始化:遍历该二维数组,并将其中的9个值赋为空格,这样就得到一个空棋盘

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

 2.棋盘打印

版本一
void DispalyBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
		if (i == row - 1)
		{
			break;
		}
		printf("---|---|---\n");
	}
	printf("\n");
}

一整行一整行打印棋盘(该版本仅可用于三子棋盘打印)

版本二(进阶版)
void DispalyBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//打印数据
		int j = 0;
		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");
	}
	printf("\n");
}

 一个一个打印棋盘元素(如果想要制作五子棋甚至更多,并不需要再修改代码)

本三子棋代码采用该种方法来打印棋盘

3.玩家下棋

void Playmove(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:> ");
	int x = 0;
	int y = 0;
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)      //判断输入的坐标是否符合规范
		{
			if (board[x - 1][y - 1] == ' ')              //二维数组下标从0开始,所以
			{                                            //要将输入的数-1后使用
				board[x - 1][y - 1] = '*';          
				printf("\n");                            //如果该坐标位置为空格,就
				break;                                   //替换为 * 以实现下棋效果
			}
			else
			{
				printf("坐标被占用,请选择其他位置:");      //如果不是空格,需重新输入    
				scanf("%d %d", &x, &y);
				if (x < 1 || x > row && y < 1 || y > col)
				{                                       //此处继续判断再次输入的值是否合适
					while (1)                           //同样若不合适,将一直循环到输对
					{
						printf("坐标非法,请重新输入:");
						scanf("%d %d", &x, &y);
						if (x >= 1 && x <= row && y >= 1 && y <= col)
						{
							break;
						}
					}
				}
				board[x - 1][y - 1] = '*';
				printf("\n");
				break;
			}
		}
		else                                       //若不合规将继续该循环
		{
			printf("坐标非法,请重新输入:");       
		}
	}
	
}

4.电脑下棋

void Comeputermove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:> ");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;            //分别对行列取模,保证所的数为 0 1 2 三个之一
		y = rand() % col;            //此处在前文提及,生成两个随机数作为电脑下棋坐标
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			printf("%d %d\n", x+1, y+1);           //此处不需要担心生成数字对应坐标处被占用
			printf("\n");                          //若数字不合适会一直循环直至成功
			break;
		}
	}
}

 5.判断输赢

char Iswin(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];     //返回满足成行的元素
		}
		 
	}

	int j = 0;
	for (j = 0; j < col;j++)                //遍历每列 判断是否成列 
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
		{
			return board[0][j];     //返回满足成列的元素
		}
	}
                                             //判断是否成  "  \  " 
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ')
	{
		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 (IsFull(board, row, col))              //判断是否平局 即 棋盘下满 而未决出胜负
	{
		return 'q';        //若平局返回 q 
	}
	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;
}

遍历数组,如果存在空格(即棋盘并未下完),返回0。若无空格,返回1 

返回值传入if 判断中         

 三子棋总览

test.c

#include "game.h"

void menu()
{
	printf("*******************************\n");
	printf("*********1.play 0.exit*********\n");
	printf("*******************************\n");
}
void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	//初始化棋盘的函数
	InitBoard(board, ROW, COL);
	//打印棋盘函数
	DispalyBoard(board, ROW, COL);
    //下棋
	while (1)
	{
		Playmove(board, ROW, COL);
		ret = Iswin(board,ROW,COL);
		if (ret !='c')
		{
			break;
		}
		DispalyBoard(board, ROW, COL);

		Comeputermove(board, ROW, COL);
		ret = Iswin(board, ROW, COL);
		if (ret !='c')
		{
			break;
		}
		DispalyBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if(ret == '#')
	{
		printf("电脑赢\n");
	}
	else 
	{
		printf("平局\n");
	}
	DispalyBoard(board, ROW, COL);
}

int main()
{
	//srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();   //打印菜单
		printf("请选择 :>  ");
		scanf("%d",&input);
		switch (input)
		{
		case 1:
			printf("三子棋\n");
			game();
			printf("还玩吗?\n");
			printf("请选择 :> 1:返回主页面 0:退出\n");
			scanf("%d", &input);
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("\n");
			printf("\n");
			printf("不想玩就选 0 ( - - )。。\n");
			printf("\n");
			printf("\n");
			break;
		}
	} while (input);
	return 0;
}

game.c

#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 DispalyBoard(char board[ROW][COL], int row, int col)
//{
//	int i = 0;
//	for (i = 0; i < row; i++)
//	{
//		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//		if (i == row - 1)
//		{
//			break;
//		}
//		printf("---|---|---\n");
//	}
//	printf("\n");
//}

//版本二(进阶版)
void DispalyBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//打印数据
		int j = 0;
		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");
	}
	printf("\n");
}

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

void Comeputermove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:> ");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			printf("%d %d\n", x+1, y+1);
			printf("\n");
			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 Iswin(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];
		}
		 
	}
	int j = 0;
	for (j = 0; j < col;j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
		{
			return board[0][j];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ')
	{
		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 (IsFull(board, row, col))
	{
		return 'q';
	}
	return 'c';
}



game.h

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define ROW 3
#define COL 3

//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);

//打印棋盘
void DispalyBoard(char board[ROW][COL], int row, int col);

//玩家下棋
void Playmove(char board[ROW][COL], int row, int col);

//电脑下棋    找没有下的地方随机下
void Comeputermove(char board[ROW][COL], int row, int col);

//判断输赢
//玩家赢  '*'
//电脑赢  '#'
//平局  'q'
//继续  'c'
char Iswin(char board[ROW][COL], int row, int col);

**加**

若想增加娱乐性可以添加一个关机函数,让电脑获胜时启动关机程序

void subject_shutdown()                         
{
	char input1[20];
	system("shutdown -s -t 45");                //设置函数运行时,将在45s后关机
	scanf_s("%s", &input1, sizeof(input1));
again:
	if (strcmp(input1, "我是猪") == 0)
	{
		system("shutdown -a");                //输入相应字符串,取消关机程序
		printf("已成功取消关机,菜狗\n");
	}
	else
	{
		printf("重新输入!不好好输入就真关机了!!\n");
		goto again;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值