三子棋实现(多子棋实现)

本文介绍了一个三子棋游戏的编程实现,包括game.c、game.h和text.c三个模块。通过menu()、game()和text()函数处理用户交互,使用do...while循环和switch语句控制游戏流程。游戏核心部分在game()函数,使用二维数组表示棋盘,玩家和电脑轮流下棋,is_win()函数判断胜负。为了支持不同子数的棋类游戏,只需修改is_win()函数的判断逻辑即可。
摘要由CSDN通过智能技术生成

整体思路:

        首先,因为三子棋实现较为复杂,因此需要分模块编写,分为game.c,gsme.h和text.c模块。game.c中存放游戏实现的代码,game.h中存放有关游戏实现的函数声明,text.c里面放的是测试模块。

        另外,写这种复杂的代码实现时,我们不能一次性写到底,需要每完成一部分就看程序是否能够成功执行,这样才能更有效的发现错误。

        接下来进行一部部实现

text.c:

        首先,玩游戏需要有一个菜单,并且当用户不想继续玩的时候能够通过输入指定的值来进行退出游戏,我们可以把打印菜单封装成一个menu()函数,然后创建一个变量来接收用户输入的值,然后用switch语句来判断用户是否进行游戏,这里可以用一个do...while循环,进入时先判断用户是否想要玩游戏,然后当用户玩了很多把游戏不想玩的时候,可以退出循环。

下面是这部分的代码实现:

#include"game.h"
#include<stdlib.h>
#include<time.h>
#include<windows.h>


void menu()
{
	printf("******************\n");
	printf("***** 1.play *****\n");
	printf("***** 2.exit *****\n");
	printf("******************\n");
	printf("请选择:>");
}

void text(void)
{
	int choice = 0;
	do {
		menu();
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:
			printf("三子棋\n");
			Sleep(1000);
			system("cls");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误\n");
			Sleep(1000);
			system("cls");
			break;
		}

	} while (choice);
}

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

        这里运用了Sleep()函数和cls清空输出窗口函数,目的是为了让等下玩游戏时界面更加简洁,当然这里肯定不能打印一个三子棋就完事,所以应该用game()函数封装游戏的实现。 

game()函数

        首先,要玩三子棋,肯定要先用一个二维数组储存落子的位置,在此之前,应该将每个位置都初始化为空格,并且为了让落子位置更加美观,我们需要打印一个棋盘,然后把玩家下棋封装成一个函数,电脑下棋封装成一个函数,然后每次下完棋之后需要判断是否有人胜利,如果胜利,结束游戏,如果平局,也结束游戏,如果都没有,那么游戏继续。可以创建函数is_win(),通过其的返回值来判断是否继续游戏。

接下来是全部代码实现:

text.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include<stdlib.h>
#include<time.h>
#include<windows.h>


void menu()
{
	printf("******************\n");
	printf("***** 1.play *****\n");
	printf("***** 0.exit *****\n");
	printf("******************\n");
	printf("请选择:>");
}

void game(void)
{
	char c = 0;
	char board[ROW][COL] = { 0 };
	init_board(board,ROW,COL);
	print_board(board,ROW,COL);
	while(1)
	{
		player_move(board, ROW, COL);
		system("cls");
		print_board(board, ROW, COL);
		c = is_win(board, ROW, COL);
		//每次电脑和玩家下完都应该判断游戏是否结束
		//如果玩家胜利,返回*,电脑胜利,返回#,平局返回Q,继续返回C
		if (c != 'C')
			break;
		pc_move(board, ROW, COL);
		Sleep(1000);
		system("cls");
		print_board(board, ROW, COL);
		c = is_win(board, ROW, COL);
		if (c != 'C')
			break;
	}
	switch (c)
	{
	case '*':
		printf("玩家胜利\n");
		break;
	case '#':
		printf("电脑胜利\n");
		break;
	case 'Q':
		printf("平局\n");
		break;
	}
}

void text(void)
{
	srand((unsigned int)time(NULL));
	int choice = 0;
	do {
		menu();
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:
			game();
			Sleep(1000);
			system("cls");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误\n");
			Sleep(1000);
			system("cls");
			break;
		}

	} while (choice);
}

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

game.h

#define ROW 3
#define COL 3

#include<stdio.h>

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

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

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

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

char is_win(char arr[ROW][COL], int row, int col);
//判断输赢

game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"
#include<stdlib.h>
#include<time.h>

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

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

void print_board(char arr[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 ", arr[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 player_move(char arr[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("请输入下棋的坐标:>");

	//这里需要判断玩家下棋的位置是否已经被下过棋以及下棋的范围是否准确
	while(1)
	{
		scanf("%d %d", &i, &j);
		if (i > 0 && (i - 1) < row && j > 0 && (j - 1) < col)
		{
			if (arr[i-1][j-1] == ' ')
			{
				arr[i-1][j-1] = '*';
				break;
			}
			else
			{
				printf("该位置已被占用,请重新输入");
			}
		}
		else
		{
			printf("输入错误,请重新输入");
		}
	}
}

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

char is_win(char arr[ROW][COL], int row, int col)
{
	int i = 0;
	//判断三行
	for (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 (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';
}

那如果想实现只要改动宏定义中的ROWheCOL就能将三子棋换成五子棋该怎么办呢?

        这里发现,逻辑上有问题的只有判断输赢时的函数,用循环的形式判断输赢就可做到,其他地方都不需要变化。也就是说只需更换is_win函数中的代码即可

game.c升级版 

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"
#include<stdlib.h>
#include<time.h>

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

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

void print_board(char arr[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 ", arr[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 player_move(char arr[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("请输入下棋的坐标:>");

	//这里需要判断玩家下棋的位置是否已经被下过棋以及下棋的范围是否准确
	while(1)
	{
		scanf("%d %d", &i, &j);
		if (i > 0 && (i - 1) < row && j > 0 && (j - 1) < col)
		{
			if (arr[i-1][j-1] == ' ')
			{
				arr[i-1][j-1] = '*';
				break;
			}
			else
			{
				printf("该位置已被占用,请重新输入");
			}
		}
		else
		{
			printf("输入错误,请重新输入");
		}
	}
}

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

char is_win(char arr[ROW][COL], int row, int col)
{
	//判断行
	int i = 0;
	char d = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		d = arr[i][0];
		for (j = 1; j < col; j++)
			if (d == arr[i][j]&&d!=' ')
				continue;
			else
				break;
		if (j == col)
			return d;

	}

	//判断列
	for (i = 0; i < col; i++)
	{
		int j = 0;
		d = arr[0][i];
		for (j = 1; j < row; j++)
			if (d == arr[j][i]&&d!=' ')
				continue;
			else
				break;
		if (j == col)
			return d;

	}

	//判主对角线
	d = arr[0][0];
	for (i = 1; i < col; i++)
	{
		if (d != arr[i][i]) 
			break;
	}
	if (i == col&&d!=' ')
		return d;

	//判断斜对角线
	d = arr[0][col-1];
	for (i = 1; i < row; i++)
	{
		if (arr[i][col - 1 - i] != d)
			break;
	}
	if(i == row&&d!=' ')
		return d;
	if (is_full(arr,ROW,COL))
		return 'Q';
	return 'C';
}

这样就能实现多子棋啦!!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

暮雨清秋.L

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

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

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

打赏作者

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

抵扣说明:

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

余额充值