三子棋-C语言-进阶

局部最终效果

3*3

6*6

(由于不会屏幕录制,就截了一小部分图

下面按照编程步骤给出此游戏实现过程

(分三个源文件,两个.cpp一个.h,一个cpp用于测试游戏,一个cpp用于函数实现,一个.h用于函数声明以及符号定义及头文件声明)

游戏初始部分,进入游戏之前的部分

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

void test()
{
	srand((unsigned int)time(NULL));
	int ret = 0;
	do
	{
		menu();
		printf("请输入你的选项:\n");
		scanf("%d", &ret);
		switch (ret)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出成功\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (ret);
}
int main()
{
	test();
	return 0;
}

注意此do-while结构的使用以及switch语句

game()函数的实现(三子棋游戏的过程)

#include"三子棋.h"

void game()
{
	char ret;
	char chess[ROW][COL];
	Init_chess(chess, ROW, COL);  //初始化棋盘,使棋盘全都为空格
	Print_chess(chess, ROW, COL); //打印棋盘
	while (1)
	{
		Gamer_move(chess, ROW, COL);  //玩家移动
		Print_chess(chess, ROW, COL);  
		ret = Is_win(chess, ROW, COL);  //判断输赢
		if (ret != 'C')
			break;
		Computer_move(chess, ROW, COL);  //电脑移动
		Print_chess(chess, ROW, COL); 
		ret = Is_win(chess, ROW, COL);  
		if (ret != 'C')
			break;
	}
	if (ret == '#')
		printf("游戏结束,玩家赢\n");
	else if (ret == '*')
		printf("游戏结束,电脑赢\n");
	else if (ret == 'P')
		printf("游戏结束,平局\n");
}

这是游戏过程的实现,包括初始化棋盘,打印棋盘,玩家移动,电脑移动,判断输赢...

里面的每个功能都封装成函数,使程序模块化

三子棋.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;

#define ROW 3
#define COL 3
// 初始化棋盘
void Init_chess(char arr[ROW][COL], int row, int col);
// 打印棋盘
void Print_chess(char arr[ROW][COL], int row, int col);
// 玩家下棋
void Gamer_move(char arr[ROW][COL], int row, int col);
// 判断输赢
char Is_win(char arr[ROW][COL], int row, int col);
// 电脑下棋
void Computer_move(char arr[ROW][COL], int row, int col);

注意里面的ROW,COL的定义,目的是使这个棋盘的大小不固定,而是由ROW,COL指定,以实现一改全改,这样棋盘的大小可以随意指定,否则若以后想改变棋盘大小,就会出现很多地方的数字需要更改,很麻烦。

Init_chess()

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

print_chess()

void Print_chess(char chess[ROW][COL], int row, int col)
{

	// row 行 col 列
	for (int i = 0; i < row; i++)
	{
		// 每一次循环 打印一组
		// 先打印   |   |   
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", chess[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");
	}
}

注意里面打印时用的是row,col这样的变量,不是3这样的常量

Gamer_move() 以及 Computer_move()

void Gamer_move(char chess[ROW][COL], int row, int col)
{
	while (1)
	{
		printf("请输入你选择的坐标\n");
		int x = 0, y = 0;
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
		{
			if (chess[x - 1][y - 1] == ' ')
			{
				chess[x - 1][y - 1] = '#';
				break;
			}
			else
				printf("该位置已被占用,请重新选择\n");
		}
		else
		{
			printf("输入错误,请重新输入\n");
		}
	}
}

void Computer_move(char chess[ROW][COL], int row, int col)
{
	printf("电脑下棋:>\n");
	while (1)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (chess[x-1][y-1] == ' ')
		{
			chess[x-1][y-1] = '*';
			break;
		}
	}
}

Is-win()  旧版

char Is_win(char chess[ROW][COL], int row, int col)
{
	//人# 机器* 平局P 继续 C
	// 先判断是否有人赢 横三行
	for (int i = 0; i < 3; i++)
	{
		if (chess[i][0] == chess[i][1] && chess[i][1] == chess[i][2] && chess[i][1] != ' ')
			return chess[i][1];
	}
	if (chess[0][0] == chess[1][1] && chess[1][1] == chess[2][2] && chess[1][1] != ' ')
		return chess[1][1];
	if (chess[2][0] == chess[1][1] && chess[0][2] == chess[1][1] && chess[1][1] != ' ')
		return chess[1][1];
	for (int i = 0; i < 3; i++)
	{
		if (chess[0][i] == chess[1][i] && chess[1][i] == chess[2][i] && chess[1][i] != ' ')
			return chess[1][i];
	}
	char c = Is_continue(chess, row, col);
	return c;
}

上方Is_win() 不够好,这个函数只限于3*3棋盘的判断,如果是其他的就不适用了,所以下方给出了升级版

Is_win()  新版

char Is_win(char chess[ROW][COL], int row, int col)
{
	//人# 机器* 平局P 继续 C
	// 先判断是否有人赢 横
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col - 2; j++)
		{
			if (chess[i][j] == chess[i][j + 1] && chess[i][j + 1] == chess[i][j + 2] && chess[i][j + 1] != ' ')
				return chess[i][j + 1];
		}
	}
	//竖
	for (int i = 0; i < col; i++)
	{
		for (int j = 0; j < row - 2; j++)
		{
			if (chess[j][i] == chess[j + 1][i] && chess[j + 1][i] == chess[j + 2][i] && chess[j + 1][i] != ' ')
				return chess[j + 1][i];
		}
	}
	//右下
	for (int i = 0; i < row - 2; i++)
	{
		for (int j = 0; j < col - 2; j++)
		{
			if (chess[i][j] == chess[i + 1][j + 1] && chess[i + 1][j + 1] == chess[i + 2][j + 2] && chess[i + 1][j + 1] != ' ')
				return chess[i][j];
		}
	}
	//左下
	for (int i = row - 1; i >= 2; i--)
	{
		for (int j = col - 1; j >= 2; j--)
		{
			if (chess[i][j] == chess[i + 1][j - 1] && chess[i + 1][j - 1] == chess[i + 2][j - 2] && chess[i][j] != ' ')
				return chess[i][j];
		}
	}
	char c = Is_continue(chess, row, col);
	return c;
}

此函数适用于所有row与col,

解析:

如图所示,如果是6*6的棋盘,若想判断输赢,也是横三个,竖三个,斜着三个

这样的话,判断时就必须有限制条件了,因为如果是对于1 5这个坐标,往右判断三个就会出现数组越界的情况,所以。

只有红线所及的区域,可以进行向下或者向右的判断,也就是6*6的棋盘,只有4*4的区域可以进行延申判断。

这个是斜着的,6*6的棋盘,左上4*4进行右下方判断,右上4*4进行左下方判断。这样,也就有了上方的新版Is_win() 

 Is_continue()   (辅助Is_win函数的实现)

char Is_continue(char chess[ROW][COL], int  row, int col)
{
	int flag = 0;
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (chess[i][j] == ' ')
				flag = 1;  //有一个是空格,所以表示没满继续
		}
	}
	if (flag)
		return 'C';
	else
		return 'P';
}

------------------------------------------------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值