【C语言】项目-三子棋

C语言项目

三子棋

实现思想

  大家都玩过五子棋,也对五子棋的游戏规则不陌生,今天我们就仿照五子棋做一个三子棋,以函数模块为进行封装逐步实现,并且实现一个万能算法,可以达到n*n的棋盘上玩n子棋(前提是屏幕够大)。
  实现具体思想很简单,先做出菜单,然后根据玩家选择执行不同的内容函数,如果选择游戏则开始三子棋的游戏主体函数,执行完成之后重新执行菜单,知道玩家选择退出游戏!
  三子棋的主体游戏思想也很简单,用一个数组表示棋盘,每一个回合开始前先打印棋盘,随后让玩家进行坐标选择要落子的地方,此时注意 要判断玩家输入是否合法,玩家输入后将棋盘上的数据进行更改,并判断是否已经分出胜负,未结束的话是由电脑随机选择坐标进行落子(在这里我们暂时先进行简单的设计,让电脑随机落子),电脑落子完成后也要判断是否游戏已经结束,未结束的话重新打印棋盘即可完成一个循环。在游戏中我们应该考虑到游戏有三中胜负情况,分别是:玩家胜、电脑胜和平局。

实现代码

/*!
 * \文件名 源.cpp
 * \日期 2018/11/10 13:35
 *
 * \作者 Misaki
 * 联系方式  1761607418@qq.com
 *
 * 文件描述: 三子棋
 *
*/
#define _CRT_SECURE_NO_WARNINGS
#define ROW 5//棋盘行
#define COL 5//棋盘列
#define WIN 5//获胜条件
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
char g_board[ROW][COL];
/*
将棋盘进行初始化
*/
void initBoard()
{
	for (int row = 0; row < ROW; row++)
	{
		for (int col = 0; col < COL; col++)
		{
			g_board[row][col] = ' ';//空位置用' '表示
		}
	}
}
/*
打印菜单
*/
int menu()
{
	system("cls");
	int choose = 0;
	printf("1、开始游戏\n");
	printf("2、游戏说明\n");
	printf("3、退出\n");
	printf("请选择:");
	scanf("%d", &choose);
	return choose;
}
/*
打印棋盘
*/
void printBoard()
{
	system("cls");
	for (int col = 0; col < COL; col++)
	{
		printf(" _____");
	}
	printf(" \n");
	for (int row = 0; row < ROW; row++)
	{
		printf("|");
		for (int col = 0; col < COL; col++)
		{
			printf("%6c", '|');
		}
		printf("\n|");
		for (int col = 0; col < COL; col++)
		{
			printf("  %c  |", g_board[row][col]);
		}
		printf("\n|");
		for (int col = 0; col < COL; col++)
		{
			printf("_____|");
		}
		printf("\n");
	}
	printf("\n");
}
/*
玩家回合
*/
void playerMove(int* row, int* col)
{
	printf("玩家回合:\n");
	int rowt = 0, colt = 0, result;
	while (1)
	{
		printf("请输入坐标:(格式:y x)");
		if (result = scanf("%d%d", &rowt, &colt) != 2)
		{
			printf("你输的是坐标么?重来\n");
			rewind(stdin);
			continue;
		}
		if (rowt < 0 || rowt >= ROW || colt < 0 || colt >= COL)
		{
			printf("输入坐标不合法,请重新输入!\n");
			rewind(stdin);
			continue;
		}
		if (g_board[rowt][colt] != ' ')
		{
			printf("这个位置已经有子了!\n");
			rewind(stdin);
			continue;
		}
		g_board[rowt][colt] = 'x';
		//将值返回出去
		*row = rowt;
		*col = colt;
		break;
	}
}
void computerMove(int* row, int* col)
{
	int rowt = 0;
	int colt = 0;
	while (1)
	{
		rowt = rand() % (ROW);
		colt = rand() % (COL);
		if (g_board[rowt][colt] == ' ')
		{
			break;
		}
	}
	g_board[rowt][colt] = 'o';
	//将值返回出去
	*row = rowt;
	*col = colt;
}
/*
判断是否平局
*/
int isdraw()
{
	int num = 0;
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (g_board[i][j] == ' ')
			{
				num++;
			}
		}
	}
	if (num == 0)//平局了,棋盘满了
	{
		return 1;
	}
	else//还能打
	{
		return 0;
	}
}
/*
判断是否三子相连
参数:当前下子位置
返回值:谁获得胜利
*/
char judge(int row, int col)
{
	int num =1;//计数相连棋子个数
	int i = 1;//判断周围第i个棋子是否相同
	//从左到右的判断
	for (i = 1; i < WIN; i++)
	{
		if ((col + i) > (COL - 1) || g_board[row][col] != g_board[row][col + i])
		{
			break;
		}
		num++;
	}
	//从右到左的判断
	for (i = 1; i < WIN; i++)
	{
		if ((col - i) < 0 || g_board[row][col] != g_board[row][col - i])
		{
			break;
		}
		num++;
	}
	if (num >= WIN)
	{
		return g_board[row][col];
	}
	num = 1;
	//从上到下的判断
	for (i = 1; i < WIN; i++)
	{
		if ((row + i) > (ROW - 1) || g_board[row][col] != g_board[row + i][col])
		{
			break;
		}
		num++;
	}
	//从下到上的判断
	for (i = 1; i < WIN; i++)
	{
		if ((row - i) < 0 || g_board[row][col] != g_board[row - i][col])
		{
			break;
		}
		num++;
	}
	if (num >= WIN)
	{
		return g_board[row][col];
	}
	num = 1;
	//从左上到右下的判断
	for (i = 1; i < WIN; i++)
	{
		if ((row + i) > (ROW - 1) || (col + i) > (COL - 1) || g_board[row][col] != g_board[row + i][col + i])
		{
			break;
		}
		num++;
	}
	//从右下到左上的判断
	for (i = 1; i < WIN; i++)
	{
		if ((row - i) < 0 || (col - i) < 0 || g_board[row][col] != g_board[row - i][col - i])
		{
			break;
		}
		num++;
	}
	if (num >= WIN)
	{
		return g_board[row][col];
	}
	num = 1;
	//从右上到左下的判断
	for (i = 1; i < WIN; i++)
	{
		if ((row + i) > (ROW - 1) || (col - i) < 0 || g_board[row][col] != g_board[row + i][col - i])
		{
			break;
		}
		num++;
	}
	//从左下到右上的判断
	for (i = 1; i < WIN; i++)
	{
		if ((row - i) < 0 || (col + i) > (COL - 1) || g_board[row][col] != g_board[row - i][col + i])
		{
			break;
		}
		num++;
	}
	if (num >= WIN)
	{
		return g_board[row][col];
	}
	if (isdraw())//平局了
	{
		return 'd';
	}
	else
	{
		return ' ';
	}
}
/*
游戏是否结束
*/
int isOver(int row, int col)
{
	char c = judge(row, col);
	if (c == ' ')
	{
		return 0;
	}
	if (c == 'x')
	{
		printf("恭喜你赢了!\n");
		system("pause");
		return 1;
	}
	if (c == 'o')
	{
		printf("不走运,你输了!\n");
		system("pause");
		return 1;
	}
	else
	{
		printf("平局!\n");
		system("pause");
		return 1;
	}
}
/*
游戏主体
*/
void mainGame()
{
	int row = 0;
	int col = 0;
	//初始化棋盘
	initBoard();
	//打印棋盘
	printBoard();
	//循环控制游戏进程
	while (1)
	{
		//玩家开始下
		playerMove(&row, &col);
		//打印棋盘
		printBoard();
		//判定是否游戏结束
		if (isOver(row, col))
		{
			break;
		}
		//电脑下
		computerMove(&row, &col);
		//打印棋盘
		printBoard();
		printf("计算机回合↑\n");
		//判定是否游戏结束
		if (isOver(row, col))
		{
			break;
		}
	}
}
void gameExplain()
{
	system("cls");
	printf("五子棋你会玩,三子棋你不会玩?\n");
	printf("什么你五子棋都不会玩,你不会百度,搜狗,goole啊!\n");
	system("pause");
}
int main()
{
	srand(time(NULL));
	while (1)
	{
		int choose = menu();
		if (choose == 1)
		{
			mainGame();
			continue;
		}
		if (choose == 2)
		{
			gameExplain();
			continue;
		}
		if (choose == 3)
		{
			break;
		}
		else
		{
			printf("别瞎比选!\n");
			rewind(stdin);
			system("pause");
			continue;
		}
	}
	printBoard();
	return 0;
}

  在这里值得一提的是我用来判断是否获胜的算法,算法可总结为以落子为中心,向横纵正斜和反斜四个方向分别计数,以达到统计是否已经连子获胜的目的。
  欢迎来我的博客闲逛:https://misakifx.github.io/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值