C语言实现简易三子棋游戏

前言:

        本文讲述的是如何用C语言实现最基础的三子棋游戏,主要采用的是数组知识。

        若不需要过程详情解释,只需工程代码,我会在最后总结全部展示出来。

一.创建工程:

        分别创造三个项到工程中,分别是

                                                                test.c( 测试三子棋游戏 )

                                                                game.h( 游戏的函数声明 )

                                                                game.c( 游戏函数的实现 )


二.设计和实现代码:

        2.1 设计和实现游戏菜单和选项

                首先,既然是游戏,当然有游戏的开始菜单和选项,这边我们现在test.c文件中实现菜单函数,打印出简易的菜单列表。        

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

                这样我们便有了简易的菜单列表展示,既然有选项,当然也需要给玩家设计能选择选项的功能

int main() {
	int input = 0;//选项
	do
	{
		menu();
		printf("请选择:\n");
		scanf("%d", &input);
		switch (input) {
			case 0:
				printf("退出游戏");
				break;
			case 1:
				game();//之后实现的游戏功能
				break;
			default:
				printf("输入有误,请重新输入:\n");
				break;
		}
	} while (input);
	
	return 0;
}

                这样当玩家选择0时,会退出游戏;选择1时,会开始游戏;若选错,则会重新选择。

        2.2 设计和实现棋盘

                首先我们要设计出棋盘的样子,假设我们的棋盘是“井”字状,那棋盘应该是这样的

                  那么 我们的代码打印出来可以是这样的 

                根据图中所想,来实现代码

                首先在game函数中,初始化一个棋盘数组,然后再调用game.c中的display_board()实现棋盘(已在game.h中包含所需库函数和声明行(row)和列(col))

game() {
	char board[ROW][COL] = { 0 };
	display_board(board,ROW,COL);
}
void display_board(char board[ROW][COL], int row, int col) {
	for (int i = 0; i < row; i++) {
			//打印数据
			printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
			if (i < row - 1)
				printf("---|---|---\n");
	}
}

                接着我们测试运行下函数,看是否实现我们所想的棋盘样子

                 由图可以看出,我们的代码应该在某一部分出现了问题。

                 问题就出再了我们的初始化数组上,因为我们初始化数组时所赋的值是{0},而在打印时,0(\0)打印的时候是不会显示出来的,所以可以从上图看出来,我们在打印数据那行,每一个小格中都缺少了一个字符空间。

                既然问题找到了,我们就开始解决问题。我们设计在game.c中设计一个初始化函数,把数组中每一个空间都赋一个空格。

game() {
	char board[ROW][COL] = { 0 };
	init_board(board, ROW, COL);
	display_board(board,ROW,COL);
}
void init_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++){
		for (int j = 0; j < col; j++){
			board[i][j] = ' ';
		}
	}
}

                接着在测试运行代码:

                这回就可以看到,棋盘是符合我们所需要的。

                既然棋盘已经设计和实现好了,接着便是在棋盘下棋了。

        2.2 玩家下棋

                首先设计玩家下棋的规则,选择棋子落子位置,必须在方框里面,且如果已经被有棋子在里面了,应该提示玩家有棋子,让玩家重新选择,所以:实现玩家下棋函数player_move()

void player_move(char board[ROW][COL], int row, int col) {
	int x = 0;//横坐标
	int y = 0;//纵坐标
	printf("玩家下棋:\n");
	while (1) {
		printf("请输入要下棋的坐标:");
		scanf("%d %d", &x, &y);
		//然后判断坐标的合法性和是否被占用了
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (board[x - 1][y - 1] = ' ') {
				board[x - 1][y - 1] = '*';
				break;
			}
			else {
				printf("该坐标已被占用,请重新选择坐标\n");
			}
		}
		else {
			printf("该坐标不在棋盘范围内,请重新选择坐标\n");
		}
	}
}

                然后测试,假设落子到(1,1)的位置,结果如下图:

         2.3 电脑下棋

                接下来设计电脑下棋,由于电脑是随机下棋的,首先我们得设计一个在棋盘范围内下棋的随机数值,其实还得考虑电脑下棋应该选择更好赢的位置,但这里只是简单的随机下棋,就不过多在设计复杂函数。

                所以接下来实现函数电脑下棋void computer_move()

                在test.c的main函数中已使用srand()来设计随机的随机数值。

void computer_move(char board[ROW][COL], int row, int col) {
	printf("电脑下棋:\n");
	while (1) {
		//实现电脑下棋的坐标
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' '){
			board[x][y] = '#';
			break;
		}
	 }
}

                测试下代码,结果如图:

                

        2.4 判断输赢和平局 

                 首先我们要设计,怎样算赢,怎样算输,怎样算平局。

                赢输:某一方所拥有的棋子,能在横、竖、对角线其中任意一方连接起三个棋子,则算赢,反之则输。

                平局:在棋盘全部位置已经有棋子的情况下,仍未达到输赢条件,则算平局。

                根据上面所设计的规则,实现函数。首先实现函数 is_full(),判断棋盘是否满了。

int is_full(char board[ROW][COL], int row, int col){
	for (int i = 0; i < row; i++){
		for (int j = 0; j < col; j++){
			if (' ' == board[i][j]){
				return 0;
			}
		}
	}
	return 1;
}

        接着实现函数is_win(),判断是否赢了.

char is_win(char board[ROW][COL], int row, int col){
	//判断横方向是否达到赢的条件
	for (int i = 0; i < row; i++){
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' '){
			return board[i][0];
		}
	}

	//判断竖方向是否达到赢的条件
	for (int i = 0; i < col; i++){
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' '){
			return board[0][i];
		}
	}

	//判断对角线方向是否达到赢的条件
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){
		return board[1][1];
	}

	//判断对角线方向是否达到赢的条件
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){
		return board[1][1];
	}

	//判断平局
	if (is_full(board, row, col) == 1){
		return 'Q';
	}

	//继续
	return 'C';
}

        2.5 设计和完成game()函数运行逻辑

                根据上面所实现的判断输赢平局的代码,我们应设计一个接收值,如果返回的是

                ‘#’ ——电脑赢

                ‘*’ ——玩家赢

                ‘Q’——平局

                ‘C’——再来一局

                接着,应该设计运行逻辑:

                        1.初始化一个二维数组(棋盘)

                        2.打印棋盘

              3-8循环(游玩过程)

                        3.玩家下棋

                        4.打印棋盘

                        5.判断输赢、平局

                        6.电脑下棋

                        7.打印棋盘

                        8.判断输赢、平局

               根据上述逻辑实现代码

game() {
	char ret = 0;
	//数据的存储需要一个3*3的二维数组
	char board[ROW][COL] = { 0 };
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);
	//玩游戏
	while (1){
		player_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;

		computer_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	 }
	if (ret == '*'){
		printf("玩家赢\n");
	}
	else if (ret == '#'){
		printf("电脑赢\n");
	}
	else if (ret == 'Q'){
		printf("平局\n");
	}
	//在最后展示棋盘
	display_board(board, ROW, COL);
}

                这样就可以实现一个入门级的三子棋游戏了


总体代码:

        test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

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

game() {
	char ret = 0;
	//数据的存储需要一个3*3的二维数组
	char board[ROW][COL] = { 0 };
	init_board(board, ROW, COL);
	display_board(board, ROW, COL);
	//玩游戏
	while (1){
		player_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;

		computer_move(board, ROW, COL);
		display_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
			break;
	 }
	if (ret == '*'){
		printf("玩家赢\n");
	}
	else if (ret == '#'){
		printf("电脑赢\n");
	}
	else if (ret == 'Q'){
		printf("平局\n");
	}
	//在最后展示棋盘
	display_board(board, ROW, COL);
}

int main() {
	int input = 0;//选项
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input) {
			case 0:
				printf("退出游戏");
				break;
			case 1:
				game();//之后实现的游戏功能
				break;
			default:
				printf("输入有误,请重新输入:\n");
				break;
		}
	} while (input);
	
	return 0;
}

          game.h:             

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 3
#define COL 3

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

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

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

//判断游戏状态
char is_win(char board[ROW][COL], int row, int col);

        game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

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

void display_board(char board[ROW][COL], int row, int col) {
	for (int i = 0; i < row; i++) {
		//打印数据
		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
		if (i < row - 1)
			printf("---|---|---\n");
	}
}

void player_move(char board[ROW][COL], int row, int col) {
	int x = 0;//横坐标
	int y = 0;//纵坐标
	printf("玩家下棋:\n");
	while (1) {
		printf("请输入要下棋的坐标:");
		scanf("%d %d", &x, &y);
		//然后判断坐标的合法性和是否被占用了
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (board[x - 1][y - 1] = ' ') {
				board[x - 1][y - 1] = '*';
				break;
			}
			else {
				printf("该坐标已被占用,请重新选择坐标\n");
			}
		}
		else {
			printf("该坐标不在棋盘范围内,请重新选择坐标\n");
		}
	}
}

void computer_move(char board[ROW][COL], int row, int col) {
	printf("电脑下棋:\n");
	while (1) {
		//实现电脑下棋的坐标
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' '){
			board[x][y] = '#';
			break;
		}
	 }
}

int is_full(char board[ROW][COL], int row, int col){
	for (int i = 0; i < row; i++){
		for (int j = 0; j < col; j++){
			if (' ' == board[i][j]){
				return 0;
			}
		}
	}
	return 1;
}

char is_win(char board[ROW][COL], int row, int col){
	//判断横方向是否达到赢的条件
	for (int i = 0; i < row; i++){
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' '){
			return board[i][0];
		}
	}

	//判断竖方向是否达到赢的条件
	for (int i = 0; i < col; i++){
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' '){
			return board[0][i];
		}
	}

	//判断对角线方向是否达到赢的条件
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){
		return board[1][1];
	}

	//判断对角线方向是否达到赢的条件
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){
		return board[1][1];
	}

	//判断平局
	if (is_full(board, row, col) == 1){
		return 'Q';
	}

	//继续
	return 'C';
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值