C语言数组—经典“三子棋”小游戏

目录

数组

三子棋

代码实现:打印菜单

代码实现:打印棋盘

代码实现: 人机出棋

代码实现:判断输赢

整体代码:三子棋


在实现我们的“三子棋”小游戏之前,先让我们简单的学习一下数组吧

数组

数组:是一组相同类型元素的集合 

数组有一维数组和二维数组

数组的创建:

注:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数
组的概念,数组的大小可以使用变量指定,但是数组不能初始化。

数组初始化:

 数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。

数组的使用:

1. 数组是使用下标来访问的,下标是从0开始。
2. 数组的大小可以通过计算得到。

数组名是什么呢?

数组名是数组首元素的地址

但是有2个例外:

1. sizeof(数组名),这里的数组名是表示整个数组,计算的是整个数组的大小,单位是字节

2. &数组名,这里的数组名是表示整个数组,&数组名取出的是数组的地址

数组在内存中的存储:

数组在内存中的存储是由低地址到高地址连续存放的

二维数组可以看成由n个一维数组来存放的,所以二维数组在内存的存储也是连续存放的

在简单的认识了数组后,就让我们开始本文的正题,开发一个三子棋的小游戏吧

三子棋

预想的效果:

一个简单的人机对战三子棋的游戏,玩家靠输入坐标来控制下子的位置。

大体思路:

1.一个游戏菜单,开始和退出

2.打印一个3*3的棋盘

3.玩家下子

4.电脑下子

5.判断输赢

6.清屏,重新一局

现在让我们按步骤一步步来实现,一个项目分节完成

为了使主函数不过于复杂,我们采用模块化编程

第一步:打印一个简单的游戏菜单

1.输出一个简易菜单,可以通过1/0来进行选择,输入1开始,0退出,非1,0提示 输入错误,并可以多次的进行游戏,输入错误可以重新输入。

代码实现:打印菜单

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

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

void test()
{
	int a = 0;
	Checkers_menu();
	do
	{
		printf("请选择:");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game(); break;
		case 0:
			printf("退出游戏\n"); break;
		default :
			printf("输入错误\n"); break;
		}

	} while (a);
}

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

 第二步:简易的菜单打印出来后,我们就需要封装一个game函数来实现我们玩游戏的过程。

当我们选择1后,就要开始玩游戏了。游戏开始首先我们需要将棋盘打印出来,先看看我们预期的棋盘效果

 一个简单的井字棋盘,我们会发现这就是一个由3行3列的二维数组来实现的。在打印棋盘之前我们先将棋盘进行初始化,之后在进行打印

代码我们采用的模块化编程,我们将游戏的这部分单独封装在一个game函数中

代码实现:打印棋盘

//初始化棋盘
void Checkers_Init(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++)
		{
			board[i][j] = ' ';
		}
	}

}

//打印棋盘
void Checkers_print(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");
		}
	}
}

 第三步:棋盘打印出来后,我们就要来进行玩家和电脑的下子了

玩家的下子其实就是通过二维数组的下标来控制,电脑的下子我们采用的是随机值来确定下子动作。当我们输入的坐标被占用时提示非法占用。这里我们一样通过两个函数来实现

代码实现: 人机出棋

//玩家下下棋
void Checkers_player(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while (1)
	{
		printf("请玩家出棋:");
		scanf("%d %d", &i, &j);
		if (i > 0 && i <= row && j>0 && j <= col)
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
			{
				printf("非法占用\n");
			}
		}
		else
			printf("非法超出范围\n");

	}
}

//电脑下棋
void Checkers_computer(char board[ROW][COL], int row, int col)
{
	printf("电脑出棋:\n");
	if (is_full(board, row, col) == 0)
	{
		while (1)
		{
			int i = rand() % row;
			int j = rand() % col;
			if (board[i][j] == ' ')
			{
				board[i][j] = '#';
				break;
			}
		}
	}
}

第四步:一个游戏最主要结局就是一个判断输赢

我们通过一个函数来判断是谁赢了,定义返回值:玩家赢返回*,电脑赢返回#,平局返回Q,继续返回C。要认定平局我们也要一个函数来判断是不是满棋。

代码实现:判断输赢

int is_full(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 is_win(char board[ROW][COL], int row, int col)
{
//判断行
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
		{
			return board[i][0];
		}
	}
//判断列
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j])
		{
			return board[0][j];
		}
	}
//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
	{
		return board[1][1];
	}
//判断平局
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
	else
		return 'C';
}

 每个部分的函数我们就封装完成了,在game函数里进行调整

整体代码:三子棋

#define _CRT_SECURE_NO_WARNINGS 1

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

//初始化棋盘
void Checkers_Init(char board[ROW][COL], int row, int col);
//打印棋盘
void Checkers_print(char board[ROW][COL], int row, int col);
//玩家下棋
void Checkers_player(char board[ROW][COL], int row, int col);
//电脑下棋
void Checkers_computer(char board[ROW][COL], int row, int col);
//判断谁赢
char is_win(char board[ROW][COL], int row, int col);

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


void game()
{
	char board[ROW][COL];
	char ret = 0;
	Checkers_Init(board, ROW, COL);
	Checkers_print(board, ROW, COL);
	while (1)
	{
		Checkers_player(board, ROW, COL);
		Checkers_print(board, ROW, COL);
		Checkers_computer(board, ROW, COL);
		Checkers_print(board, ROW, COL);
		ret=is_win(board,ROW,COL);
		if (ret == '*')
		{
			printf("玩家赢了\n");
			break;
		}
		else if (ret == '#')
		{
			printf("电脑赢了\n");
			break;
		}
		else if(ret=='Q')
		{
			printf("平局\n");
				break;
		}
	}
}

void test()
{
	int a = 0;
	srand((unsigned int )time(NULL));
	do
	{
		Checkers_menu();
		printf("请选择:");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game(); break;
		case 0:
			printf("退出游戏\n"); break;
		default:
			printf("输入错误\n"); break;
		}
	} while (a);
}

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

//初始化棋盘
void Checkers_Init(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++)
		{
			board[i][j] = ' ';
		}
	}

}

//打印棋盘
void Checkers_print(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");
		}
	}
}
//玩家下下棋
void Checkers_player(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while (1)
	{
		printf("请玩家出棋:");
		scanf("%d %d", &i, &j);
		if (i > 0 && i <= row && j > 0 && j <= col)
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
			{
				printf("非法占用\n");
			}
		}
		else
			printf("非法超出范围\n");

	}
}

//电脑下棋
void Checkers_computer(char board[ROW][COL], int row, int col)
{
	printf("电脑出棋:\n");
	if (is_full(board, row, col) == 0)
	{
		while (1)
		{
			int i = rand() % row;
			int j = rand() % col;
			if (board[i][j] == ' ')
			{
				board[i][j] = '#';
				break;
			}
		}
	}
}

//判断是否满盘
int is_full(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 is_win(char board[ROW][COL], int row, int col)
{
	//判断行
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
		{
			return board[i][0];
		}
	}
	//判断列
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j])
		{
			return board[0][j];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
	{
		return board[1][1];
	}
	//判断平局
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
	else
		return 'C';
}

三子棋部分没有整理思路,希望过段时间的我自己能看懂。哈哈哈哈

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值