三子棋,五子棋(一个代码全部搞定,支持双人,人机对战)

   

  可以通过修改ROW和COL后面的值来改变棋盘的大小,如图中ROW和COL后面的值为3表示棋盘的大小为3行3列,通过修改CHESS后面的值来改变游戏方式,如CHESS后面的值为3表示游戏方式是三子棋。

  在输入时,PVP表示双人对战,PVE表示人机对战

  PVE模式的电脑没有智商,所以可玩性不大

  此程序比较麻烦的地方集中于win_game()函数,该函数用于判断是否有玩家或者电脑获胜。

程序采用分文件方式编写,代码如下:

text.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void vext()
{
	int n=0;
	int n1 = 0;
	do
	{
		Menu();
		scanf("%d", &n);
		switch (n)
		{
		case 1:
			srand((unsigned int)time(NULL));
			
			do
			{
				Menu1();
				scanf("%d", &n1);
				switch (n1)
				{
				case 0:
					printf("欢迎下次游玩\n");
					break;
				case 1:
					GamePVP();
					break;
				case 2:
					GamePVE();
					break;
				default:
					printf("输入有误,请重新输入\n");
					break;
				}
			} while (n1);
			break;
		case 0:
			printf("欢迎下次游玩\n");
			break;
		default:
			printf("输入有误,请重新输入\n");
			break;
		}
		system("pause");
		system("cls");
	} while (n);

}


int main()
{
	vext();
	return 0;
}

函数功能头文件game.h

#pragma once
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include<time.h>
#define	ROW 3      //行
#define COL 3      //列
#define CHESS 3      //下棋类型(如三子棋)

//菜单
void Menu();

//次菜单
void Menu1();

//进行人机游戏
void GamePVE();

//进行双人游戏
void GamePVP();

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

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

//玩家1操作
void player_operate1(char arr[ROW][COL], int row, int col);

//玩家2操作
void player_operate2(char arr[ROW][COL], int row, int col);

//电脑操作
void computer_operate(char arr[ROW][COL], int row, int col);

//判断胜利(电脑胜利返回#,玩家胜利返回*)
char win_game(char arr[ROW][COL], int row, int col,int chess);

//判断平局(平局返回false,没有平局返回true)
bool dogfall_game(char arr[ROW][COL], int row, int col);

函数功能源文件game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"


void Menu()
{
	printf("**************************\n");
	printf("********** 1.game ********\n");
	printf("********** 0.exit ********\n");
	printf("**************************\n");
}

void Menu1()
{
	printf("**************************\n");
	printf("********** 1.PVP *********\n");
	printf("********** 2.PVE *********\n");
	printf("********** 0.exit ********\n");
	printf("**************************\n");
}

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

void print_board(char arr[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ",arr[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1)
		{
			for (int j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

void player_operate1(char arr[ROW][COL], int row, int col)
{
	printf("玩家1输入\n");
	while (true)
	{
		printf("请输入要下棋的坐标 (如1 3)\n");
		int m = 0, n = 0;
		scanf("%d %d", &m, &n);
		if (m >= 1 && n >=1 && m <= row && n <=col&&arr[m-1][n-1]==' ')
		{
			arr[m - 1][n - 1] = '*';
			break;
		}
		else
		{
			printf("输入失败\n");
		}
	}
}

void player_operate2(char arr[ROW][COL], int row, int col)
{
	printf("玩家2输入\n");
	while (true)
	{
		printf("请输入要下棋的坐标 (如1 3)\n");
		int m = 0, n = 0;
		scanf("%d %d", &m, &n);
		if (m >= 1 && n >= 1 && m <= row && n <= col && arr[m - 1][n - 1] == ' ')
		{
			arr[m - 1][n - 1] = '#';
			break;
		}
		else
		{
			printf("输入失败\n");
		}
	}
}

void computer_operate(char arr[ROW][COL], int row, int col)
{
	printf("电脑输入\n");
	while (true)
	{
		int m = rand() % row;
		int n = rand() % col;
		if (arr[m][n] == ' ')
		{
			arr[m][n] = '#';
			break;
		}
	}
}


char win_game(char arr[ROW][COL], int row, int col,int chess)
{
	int count;
	//判断行是否获胜
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j<=col-chess;j++)      //比col-chess下标大的位置已经凑不出chess个格子
		{
			count = 1;
			if (arr[i][j] == ' ')
			{
				continue;
			}
			for (int k = j + 1; k <=j+chess-1; k++)
			{
				if (arr[i][j] == arr[i][k])
				{
					count++;
				}
			}
			if (count == chess)
			{
				return arr[i][j];
			}
			
		}
	}

	//判断列是否获胜
	for (int j = 0; j < col; j++)
	{
		for (int i = 0; i <= row - chess; i++)
		{
			count = 1;
			if (arr[i][j] == ' ')
			{
				continue;
			}
			for (int k = i + 1; k <= i + chess - 1; k++)
			{

				if (arr[i][j] == arr[k][j])
				{
					count++;
				}
			}
			if (count == chess)
			{
				return arr[i][j];
			}
		}
	}

	//判断单调递减的斜边是否获胜
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j <= col; j++)
		{
			if (i + chess <= row && j + chess <= col)      //当以arr[i][j]为起点判断发现无法构成chess个数据的单调递减的斜边
			{                                            //j之后的列数肯定都不能构成,i之后的行数不一定
				if (arr[i][j] == ' ')
				{
					continue;
				}
				else
				{
					count = 1;
					for (int k = 1; k < chess; k++)
					{
						if (arr[i][j] == arr[i + k][j + k])
						{
							count++;
						}
					}
					if (count == chess)
					{
						return arr[i][j];
					}
				}
			}
			else
			{
				break;
			}
		}
	}

	//判断单调递增的斜边是否获胜
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j <= col; j++)
		{
			if (i - chess <= row && j + chess <= col)
			{
				if (arr[i][j] == ' ')
				{
					continue;
				}
				else
				{
					count = 1;
					for (int k = 1; k < chess; k++)
					{
						if (arr[i][j] == arr[i -k][j + k])
						{
							count++;
						}
					}
					if (count == chess)
					{
						return arr[i][j];
					}
				}
			}
			else
			{
				continue;
			}
		}
	}

}

bool dogfall_game(char arr[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j <= col; j++)
		{
			if (arr[i][j] == ' ')
			{
				return true;
			}
		}
	}
	return false;
}

void GamePVE()
{
	char arr[ROW][COL];

	initboard(arr, ROW, COL);
	print_board(arr, ROW, COL);

	while (true)
	{
		player_operate1(arr, ROW, COL);
		print_board(arr, ROW, COL);
		if ('*' == win_game(arr, ROW, COL, CHESS))
		{
			printf("恭喜玩家!\n");
			break;
		}
		if (false == dogfall_game(arr, ROW, COL))
		{
			printf("平局喽!\n");
			break;
		}

		system("cls");

		computer_operate(arr, ROW, COL);
		print_board(arr, ROW, COL);
		if ('#' == win_game(arr, ROW, COL,CHESS))
		{
			printf("恭喜电脑!\n");
			break;
		}
		if (false == dogfall_game(arr, ROW, COL))
		{
			printf("平局喽!\n");
			break;
		}
	}
}

void GamePVP()
{
	char arr[ROW][COL];

	initboard(arr, ROW, COL);
	print_board(arr, ROW, COL);


	while (true)
	{
		player_operate1(arr, ROW, COL);
		print_board(arr, ROW, COL);
		if ('*' == win_game(arr, ROW, COL, CHESS))
		{
			printf("恭喜玩家1!\n");
			break;
		}
		if (false == dogfall_game(arr, ROW, COL))
		{
			printf("平局喽!\n");
			break;
		}

		player_operate2(arr, ROW, COL);
		print_board(arr, ROW, COL);
		if ('#' == win_game(arr, ROW, COL, CHESS))
		{
			printf("恭喜玩家2!\n");
			break;
		}
		if (false == dogfall_game(arr, ROW, COL))
		{
			printf("平局喽!\n");
			break;
		}

	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这里给出一个简单的 MFC 五子棋复盘功能代码示例,供参考: 在 MFC 对话框应用程序中,设计一个棋盘控件(IDC_BOARD)和若干个按钮,用于选择和播放复盘记录。在对话框类的头文件中定义如下变量和函数: ``` // 用于保存棋盘状态的二维数组 int board[15][15]; // 用于保存复盘记录的 vector,每个元素表示一步落子信息 vector<tuple<int, int, int>> replayRecord; // 当前复盘到的步数 int replayStep; // 初始化棋盘状态和复盘记录 void InitBoard(); // 根据复盘记录还原棋盘状态 void ReplayStep(int step); ``` 在对话框类的源文件中,实现如下函数: ``` void CMyDlg::InitBoard() { memset(board, 0, sizeof(board)); replayRecord.clear(); replayStep = 0; Invalidate(); // 重绘棋盘 } void CMyDlg::ReplayStep(int step) { if (step < 0 || step >= replayRecord.size()) return; auto [x, y, player] = replayRecord[step]; board[x][y] = player; replayStep = step; Invalidate(); // 重绘棋盘 } void CMyDlg::OnBnClickedBtnOpen() { // 使用 CFileDialog 打开棋谱文件并读取复盘记录 ... InitBoard(); ReplayStep(0); } void CMyDlg::OnBnClickedBtnPrev() { ReplayStep(replayStep - 1); } void CMyDlg::OnBnClickedBtnNext() { ReplayStep(replayStep + 1); } void CMyDlg::OnPaint() { CPaintDC dc(this); // 绘制棋盘和棋子 ... } ``` 其中,OnBnClickedBtnOpen() 函数用于打开棋谱文件并读取复盘记录;OnBnClickedBtnPrev() 和 OnBnClickedBtnNext() 函数用于控制复盘进度;OnPaint() 函数用于绘制棋盘和棋子。 需要注意的是,上述代码仅为示例,具体实现方式会因应用场景而异。在实际开发中,还需要考虑异常处理、保存棋谱文件等功能的实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小林想被监督学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值