栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【控制台五子棋游戏】这学期的编程大作业有救了!(建议收藏)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【控制台五子棋游戏】这学期的编程大作业有救了!(建议收藏)

五子棋游戏
  • 1、Chess.h 头文件
  • 2、Chess.c源文件
  • 3、game.c测试文件

本篇博客提供一份五子棋游戏的代码,也不多,三百多行,比较适合想要练习的新手以及应付作业的童鞋!
由于现在是期初,大家记得收藏码住哦!!!

1、Chess.h 头文件

首先,Chess.h头文件中进行相关函数的声明:

#pragma once
#include 
#include 
#include 
#define ROW        15    //棋盘行数
#define COL        15    //棋盘列数
#define WINNUM    5     //赢棋标准
enum//菜单项
{
	Over,
	PvP,
};

void Menu();//打印菜单
void GamePVP();
void InitBoard(int board[ROW][COL], int row, int col);//初始化棋盘
void PrintBoard(int board[ROW][COL], int row, int col);//打印棋盘
bool GameOver(int board[ROW][COL], int row, int col);//判断输赢
bool CheckRow(int board[ROW][COL], int row, int col, int winnum);//判断行是否有五个连续
bool CheckCol(int board[ROW][COL], int row, int col, int winnum);//判断列是否有五个连续
bool CheckLSlash(int board[ROW][COL], int row, int col, int winnum);//判断''方向是否有五个连续
bool CheckRSlash(int board[ROW][COL], int row, int col, int winnum);//判断'/'方向是否有五个连续
int ChessRetract(int board[ROW][COL], int x1, int y1, int x2, int y2,int* ChessNum,int* Retract);//悔棋
2、Chess.c源文件

Chess.c文件中进行相关函数的实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include "Chess.h"
void Menu()
	{
	printf(" ------------------------------------- n");
	printf("|<<<<<<<<<<<<<<<<五子棋>>>>>>>>>>>>>>>|n");
	printf("|<<<<<<<<<<<< 选择对战模式 >>>>>>>>>>>|n");
	printf("|<<<<<<<<<<<<    1.PvP    >>>>>>>>>>>|n");
	printf("|<<<<<<<<<<<<  0.退出游戏  >>>>>>>>>>>|n");
	printf("|<<<<<<<<<<<< 当前版本:1.0 >>>>>>>>>>>|n");
	printf(" ------------------------------------- n");
}
void InitBoard(int board[ROW][COL],int row,int col)
{	
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}
void PrintBoard(int board[ROW][COL],int row,int col)
{
	int i, j;
	for (i = 0; i < col; i++)
	{
		if (i == 0)
		{
			printf(" ");
		}
	    printf(" %2d ", i+1);
	}
	putchar('n');
	for (i = 0; i < row; i++)
	{
		printf("%-2d", i + 1);
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j != col - 1)
			{
				putchar('|');
			}
		}
		putchar('n');
		if (i != row - 1)
		{
			for (j = 0; j < col; j++)
			{
				if (j == 0)
				{
					printf("  ");
				}
				printf("---");
				if (j != col - 1)
				{
					putchar('|');
				}
			}
		}
		putchar('n');
	}
}
bool GameOver(int board[ROW][COL], int row, int col)
{
	if (CheckRow(board, row, col, WINNUM))
	{
		return true;
	}
	if (CheckCol(board, row, col, WINNUM))
	{
		return true;
	}
	if (CheckLSlash(board, row, col, WINNUM))
	{
		return true;
	}
	if (CheckRSlash(board, row, col, WINNUM))
	{
		return true;
	}
	return false;
}
int ChessRetract(int board[ROW][COL], int x1, int y1, int x2, int y2, int* ChessNum, int* Retract)
{//x1y1是当前落子方上一次的坐标,x2y2是另一方上一次的坐标
	if ((*ChessNum)>=2)
	{
		if (*Retract > 0)//还有悔棋次数的情况
		{
			board[x1-1][y1-1] = board[x2-1][y2-1] = ' ';
			*ChessNum -= 2;//总落棋数减2
			(*Retract)--;//剩余悔棋数减1
			return 1;
		}
		else//没有悔棋次数
		{
			return 0;
		}
	}
	else
	{
		return -1;//棋盘上的落子数不支持悔棋
	}
}
bool CheckRow(int board[ROW][COL], int row, int col, int winnum)
{
	int i,j,k;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j <= col - winnum; j++)//只需判断1~11【数组0~10】列往后是否有WIN_NUM个连续
		{
			int flag = 1;
			for (k = 0; k < winnum; k++)//判断是否有连续的WIN_NUM个
			{
				if (board[i][j] != board[i][j + k])
				{
					flag = 0;
				}
			}
			if (flag == 1 && board[i][j]!=' ')//有五个 非空格(即棋子) 连续
			{
				return true;
			}
		}
	}
	return false;
}
bool CheckCol(int board[ROW][COL], int row, int col, int winnum)
{
	int i, j, k;
	for (i = 0; i <= row - winnum; i++)//只需判断1~11【数组0~10】行往下是否有WIN_NUM个连续
	{
		for (j = 0; j < col; j++)
		{
			int flag = 1;
			for (k = 0; k < winnum; k++)//判断是否有连续的WIN_NUM个
			{
				if (board[i][j] != board[i + k][j])
				{
					flag = 0;
				}
			}
			if (flag == 1 && board[i][j] != ' ')//有五个 非空格(即棋子) 连续
			{
				return true;
			}
		}
	}
	return false;
}
bool CheckLSlash(int board[ROW][COL], int row, int col, int winnum)
{
	int i, j, k;
	for (i = winnum - 1; i < row; i++)
	{
		for (j = 0; j < col - winnum; j++)
		{
			int flag = 1;
			for (k = 0; k < winnum; k++)
			{
				if (board[i][j] == ' ' || board[i][j] != board[i - k][j + k])
				{
					flag = 0;
					break;
				}
			}
			if (flag)
			{
				return true;
			}
		}
	}
	return false;
}
bool CheckRSlash(int board[ROW][COL], int row, int col, int winnum)
{
	int i, j, k;
	for (i = 0; i < row - winnum; i++)
	{
		for (j = 0; j < col - winnum; j++)
		{
			int flag = 1;
			for (k = 0; k < winnum; k++)
			{
				if (board[i][j] == ' ' || board[i][j] != board[i + k][j + k])
				{
					flag = 0;
					break;
				}
			}
			if (flag)
			{
				return true;
			}
		}
	}
	return false;
}
void GamePVP()
{
	int board[ROW][COL];
	int WhiteRetract = 2;        //白棋剩余悔棋次数
	int BlackRetract = 2;        //黑棋剩余悔棋次数
	int	ChessNum = 0;            //已下的棋子总数
	InitBoard(board, ROW, COL);
	int x=0, y=0;//保存当前落子坐标
	int x_w=0, x_b=0, y_w=0, y_b=0;//保存上一次的落子坐标
	//游戏部分
	while (1)
	{
		//白方落子
		while (1)
		{
			PrintBoard(board, ROW, COL);//打印棋盘
			printf("请白方'*'输入落子坐标(数字+空格+数字<输入0 0可悔棋>)->");
			//清空输入缓冲区
			char clear;
			while ((clear = getchar()) != 'n')
			{
				;
			}
			scanf("%d%d", &x, &y);//读取白子坐标
			if (x == 0 && y == 0)//悔棋
			{
				int ret = ChessRetract(board, x_w, y_w, x_b, y_b, &ChessNum,&WhiteRetract);
				if (ret == -1)
				{
					printf("当前无法悔棋!n");
				}
				else
				{
					printf("白方还剩%d次悔棋机会n", WhiteRetract);
					ChessNum -= 2;
				}
			}
			else
			{
				x_w = x;
				y_w = y;
				if (!(x_w >= 1 && x_w <= 15 && y_w >= 1 && y_w <= 15))//非法坐标
				{
					printf("nnt坐标不合法!(1≤x,y≤15)n");
				}
				else if (board[x_w - 1][y_w - 1] != ' ')
				{
					printf("nnt此处已有棋子,请选择空白处落子!n");
				}
				else
				{
					board[x_w - 1][y_w - 1] = '*';
					ChessNum++;
					break;
				}
			}
		}
		//平局情况
		if (ChessNum == ROW * COL)
		{
			printf("平局!n");
			break;
		}
		PrintBoard(board, ROW, COL);//打印棋盘
		//白方下完后游戏结束,即白方胜的情况
		if (GameOver(board, ROW, COL))
		{
			printf("白方'*'胜!n");
			break;
		}
		system("cls");
		//黑方落子
		while (1)
		{
			PrintBoard(board, ROW, COL);//打印棋盘
			printf("请黑方'#'输入落子坐标(数字+空格+数字<输入0 0可悔棋>)->");
			//清空输入缓冲区
			char clear;
			while ((clear = getchar()) != 'n')
			{
				;
			}
			scanf("%d%d", &x, &y);//读取坐标
			if (x == 0 && y == 0)//悔棋
			{
				int ret = ChessRetract(board, x_b, y_b, x_w, y_w, &ChessNum, &BlackRetract);
				if (ret == -1)
				{
					printf("当前无法悔棋!n");
				}
				else
				{
					printf("黑方还剩%d次悔棋机会n", BlackRetract);
					ChessNum -= 2;
				}
			}
			else
			{
				x_b = x;
				y_b = y;
				if (!(x_b >= 1 && x_b <= 15 && y_b >= 1 && y_b <= 15))//非法坐标
				{
					printf("nnt坐标不合法!(1≤x,y≤15)n");
				}
				else if (board[x_b - 1][y_b - 1] != ' ')
				{
					printf("nnt此处已有棋子,请选择空白处落子!n");
				}
				else
				{
					board[x_b - 1][y_b - 1] = '#';
					ChessNum++;
					break;
				}
			}
		}
		PrintBoard(board, ROW, COL);//打印棋盘
		//白方下完后游戏结束,即白方胜的情况
		if (GameOver(board, ROW, COL))
		{
			printf("黑方'#'胜!n");
			break;
		}
		system("cls");
	}
}
3、game.c测试文件

在game.c中进行主函数的编写和测试

#define _CRT_SECURE_NO_WARNINGS 1
#include "Chess.h"
int main()
{
	int choice;
	do {
		Menu();
		printf("请选择>>");
		scanf("%d", &choice);
		switch (choice)
		{
		default:	
			system("cls");
			printf("请输入菜单中已有选项!n");
			break;
		case PvP:
			system("cls");
			GamePVP();
			break;
		case Over:
			printf("游戏结束|BYE BYE!");
			break;
		}
	} while (choice);
	return 0;
}

源代码已经上传至我的码云上,大家可以点击链接自行下载——
五子棋源代码

//铁子们,如果这篇博客对你有所帮助,留下你们的三连吧!!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/291600.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号