C语言实现简易n子棋超详细手把手

C语言实现简易n子棋超详细手把手,第1张

由于n子棋代码较复杂,编辑时可当成三子棋理解。我们还需要分成三个文件来写。请耐心看完,保证你能学会。定义test.c为源文件,用于编写游戏的主体,定义game.c为源文件,用于编写程序用到的函数,定义game.h为头文件,用于使用的函数的声明。

在这里添加这些文件。

再看一下棋盘吧,方便后面理解。

接着上一串代码,这个就是游戏的主体,其他需要写的基本都是函数

int main()
{
	srand((unsigned int)time(NULL));
	int put=0;
	do
	{
		menu();
		printf("\n");
		printf("请选择\n");
		scanf("%d", &put);
		switch (put)
		{
		case 1:
			 game();
			break;
		case 0:
				printf("退出游戏");
				break;
		default:
				printf("请重新输入");
				break;
		}
	} while (put);
	getchar();
	getchar();
	return 0;
}

代码第一行有关时间戳,需要和后面用到的rand()一起用,具体请自行查阅,或者先记住就行。

下面我们需要写一个为玩家提供选择功能的代码,首先我们写一个打印选项菜单的函数

menu()

void menu()
{
	printf("******1 play,0 quit*****");
}

需要写在主函数上面。

剩下的主干照着写就行了,自己写代码时会发现,这种do~while形的循环适合这个菜单判断。

而那个game函数就是我们要啃的硬骨头。

下面是test.c文件的剩余部分

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
	printf("******1 play,0 quit*****");
}
void game()
{
	char board[row][col] = { 0 };
	initboard(board, row, col);
	displayboard(board, row, col);
	while (1)
	{
		playmove(board, row, col);
		displayboard(board, row, col);
		if (isfull(board, row, col)!='q')
		{
			computer(board, row, col);
			displayboard(board, row, col);
		}
		char ret;
		ret = iswin(board, row, col);
		if (ret == '*')
		{
			printf("玩家赢\n");
			break;
		}
		if (ret == '#')
		{
			printf("电脑赢\n");
			break;
		}
		if (ret == 'q')
		{
			printf("平局\n");
			break;
		}
	}
}

由于函数声明都在game.h中,所以直接引用game.h就行了。但要注意game.h里是然后引头文件的。

menu菜单函数上面有写过.

接着写的是game函数的主体,首先定义一个字符数组,玩家和电脑通过输入字符,在这个数组里面下棋,至于这个row,col是在game.h里面定义的,要玩几子棋,就改变define后面的数就可以了,但这个简易n子棋程序,这俩个数要一样。

#pragma once是什么请自行查找。简单说就是下边的代码只包含一次。

 接着是初始化数组的函数,要把每个数组元素赋值为空格,方便下一步打印棋盘。

 接着在game.h中声明函数,在game.c中定义函数,这里注意一下game.c文件的开头怎么写,从第二行开始看,第一行懂的都懂,不知道的可以先不管。

注意形参实参的变化。

接着会到test.c文件,是一个打印棋盘的函数,下面需要和上面初始化棋盘的函数一样,先在game.h中声明这个函数,然后在game.c中编写打印棋盘的函数displayboard()。

 

 这是game.h中全部代码,下面会有可复制的代码段。

下面需编写打印棋盘的函数

void displayboard(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		for (int k = 0;k < co;k++)
		{
			if (k < co - 1)
			{
				printf(" %c |", board[i][k]);
			}
			else if (k == co - 1)
			{
				printf("%c", board[i][k]);
				printf("\n");
			}
		}if (i < ro - 1)
		{
			for (int i = 0;i < col;i++)
			printf("--- ");
			printf("\n");
		}
	}
}

下面进入编写下棋的代码,需要一个while(1)循环,进入循环后首先需要写一个玩家下棋的函数,声明同上,在game.c定义编写函数代码如下。因为玩家不知道数组减一的情况,所以-1需编写出来。注意两个重新输入的不同情况。

​
void playmove(char board[row][col], int ro, int co)
{
	while (1)
	{
		printf("请输入");
		scanf("%d %d", &ro, &co);
		if (ro-1 >= 0 && ro-1 < row && co-1 >= 0 && co-1 < col)
		{
			if (board[ro-1][co-1] == ' ')
			{
				board[ro-1][co-1] = '*';
				break;
			}
			else {
				printf("输入错误,重新输入");
			}
		}
		else {
			printf("输入错误,重新输入");
		}
	}
}

​

接着回到test.c写入一个打印棋盘的函数,这回不用再次定义。然后if判断中的函数在这里用到,也在后面定义判断输赢的函数中用到。用来判断棋盘是否输入满了,并用来判断是否平局,此处为前一种情况。声明方法同上,下面是函数代码。

char isfull(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		for (int k = 0;k < co;k++)
		{
			if (board[i][k] == ' ')
			{
				
				return 'c';
			}
		}
	}
	
	return 'q';
}

用return ‘q’,是因为test.c里判断平局时要用到,return ‘c’可以用任意字母。

if语句里第一个是电脑下棋的函数,声明方法同上,定义代码如下。

void computer(char board[row][col], int ro, int co)
{
	while (1)
	{
		int x = rand() % ro;
		int y = rand() % co;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

这里面用到了rand()函数,具体请自行查阅,和上面主函数说到的时间戳都要写,就是能够随机生成一个数,而为了生成的数在数组范围里,需要%上ro或co(请看代码)。回到test.c下面同样是一个打印棋盘的函数,因为电脑输入完的棋盘需要打印出来。出if语句,就到判断棋盘状况的地方了。首先定义一个字符变量ret,用来接收iswin函数的值,iswin函数用来判断棋盘状态,并返回一个值。需要和isfull函数一起看。

char isfull(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		for (int k = 0;k < co;k++)
		{
			if (board[i][k] == ' ')
			{
				
				return 'c';
			}
		}
	}
	
	return 'q';
}
char iswin(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		int count = 0;
		for (int k = 0;k < co-1;k++)
		{
			if (board[i][k] == board[i][k + 1])
			{
				count++;
			}
		}
		if (board[i][0] != ' ')
		{
			count++;
		}
		if (count == ro)
		{
			return board[i][0];
		}
	}
	
	for (int i = 0;i < co;i++)
	{
		int count = 0;
		for (int k = 0;k < ro - 1;k++)
		{
			if (board[k][i] == board[k+1][i])
			{
				count++;
			}
		}
		if (board[0][i] != ' ')
		{
			count++;
		}
		if (count == co)
		{
			return board[0][i];
		}
	}
	int count = 0;
	for (int i = 0;i < co-1;i++)
	{
		if (board[i][i] == board[i + 1][i + 1])
		{
			count ++ ;
		}
		if (count == ro - 1 && board[0][0] != ' ')
		{
			return board[0][0];
		}
	}
	count = 0;
	for (int i = 0;i < co - 1;i++)
	{
		if (board[ro-i-1][i] == board[ro-i-2][i + 1])
		{
			count++;
		}
		if (count == ro - 1 && board[ro-1][0] != ' ')
		{
			return board[ro-1][0];
		}
	}
	char k;
	k=isfull(board, row, col);
	return k;
}

  iswin函数用来判断输赢状态,返回值给ret,如果没有满足一方赢的条件,就让主函数继续执行下棋的语句(和主函数一起看)。iswin如何判断是否满足赢的条件?因为是简易n子棋,所以棋盘是n*n的,简单说就是如果哪一行或哪一列,或左右对脚线是一个字符相同,那么就是这一方赢棋。为了实现n子棋,我们需用到for循环,循环里面用count计数,在上面四种条件下,两个相邻的元素如果相等,这count++,如果这里面元素都不是空格,则count再加1,如果赢,满足条件,那么count的值正好等于n。函数代码在上面,应该能分析明白。因为iswin函数用来判断棋盘状态,所以需要和isfull函数连在一起看,并且iswin函数在最后调用了isfull函数。因为棋盘状态都需要iswin函数传一个值给ret(联系test.c一起看).

  现在硬骨头基本啃完,回到test.c文件(下面有).如果ret为'*',那么打印玩家赢,并结束本次while(1)循环,重新进入do~while循环语句,重新进行判断。剩下代码你应该能分析明白,下面分别吧text.c,game.h,game.c文件完整版重新复制到下面。

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
	printf("******1 play,0 quit*****");
}
void game()
{
	char board[row][col] = { 0 };
	initboard(board, row, col);
	displayboard(board, row, col);
	while (1)
	{
		playmove(board, row, col);
		displayboard(board, row, col);
		if (isfull(board, row, col)!='q')
		{
			computer(board, row, col);
			displayboard(board, row, col);
		}
		char ret;
		ret = iswin(board, row, col);
		if (ret == '*')
		{
			printf("玩家赢\n");
			break;
		}
		if (ret == '#')
		{
			printf("电脑赢\n");
			break;
		}
		if (ret == 'q')
		{
			printf("平局\n");
			break;
		}
	}
}
int main()
{
	srand((unsigned int)time(NULL));
	int put = 0;
	do
	{
		menu();
		printf("\n");
		printf("请选择\n");
		scanf("%d", &put);
		switch (put)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("请重新输入");
			break;
		}
	} while (put);
	getchar();
	getchar();
	return 0;
}
#pragma once
#include
#include
#include
#define row 3
#define col 3
void initboard(char board[row][col], int ro, int co);
void displayboard(char board[row][col], int ro, int co);
	void playmove(char board[row][col], int ro, int co);
	void computer(char board[row][col], int ro, int co);
	char iswin(char board[row][col], int ro, int co);
	char isfull(char board[row][col], int ro, int co);

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void initboard(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		for (int k = 0;k < co;k++)
		{
			board[i][k] = ' ';
		}
	}
}
void displayboard(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		for (int k = 0;k < co;k++)
		{
			if (k < co - 1)
			{
				printf(" %c |", board[i][k]);
			}
			else if (k == co - 1)
			{
				printf("%c", board[i][k]);
				printf("\n");
			}
		}if (i < ro - 1)
		{
			for (int i = 0;i < col;i++)
			printf("--- ");
			printf("\n");
		}
	}
}
void playmove(char board[row][col], int ro, int co)
{
	while (1)
	{
		printf("请输入");
		scanf("%d %d", &ro, &co);
		if (ro-1 >= 0 && ro-1 < row && co-1 >= 0 && co-1 < col)
		{
			if (board[ro-1][co-1] == ' ')
			{
				board[ro-1][co-1] = '*';
				break;
			}
			else {
				printf("输入错误,重新输入");
			}
		}
		else {
			printf("输入错误,重新输入");
		}
	}
}
void computer(char board[row][col], int ro, int co)
{
	while (1)
	{
		int x = rand() % ro;
		int y = rand() % co;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}
char isfull(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		for (int k = 0;k < co;k++)
		{
			if (board[i][k] == ' ')
			{
				
				return 'c';
			}
		}
	}
	
	return 'q';
}
char iswin(char board[row][col], int ro, int co)
{
	for (int i = 0;i < ro;i++)
	{
		int count = 0;
		for (int k = 0;k < co-1;k++)
		{
			if (board[i][k] == board[i][k + 1])
			{
				count++;
			}
		}
		if (board[i][0] != ' ')
		{
			count++;
		}
		if (count == ro)
		{
			return board[i][0];
		}
	}
	
	for (int i = 0;i < co;i++)
	{
		int count = 0;
		for (int k = 0;k < ro - 1;k++)
		{
			if (board[k][i] == board[k+1][i])
			{
				count++;
			}
		}
		if (board[0][i] != ' ')
		{
			count++;
		}
		if (count == co)
		{
			return board[0][i];
		}
	}
	int count = 0;
	for (int i = 0;i < co-1;i++)
	{
		if (board[i][i] == board[i + 1][i + 1])
		{
			count ++ ;
		}
		if (count == ro - 1 && board[0][0] != ' ')
		{
			return board[0][0];
		}
	}
	count = 0;
	for (int i = 0;i < co - 1;i++)
	{
		if (board[ro-i-1][i] == board[ro-i-2][i + 1])
		{
			count++;
		}
		if (count == ro - 1 && board[ro-1][0] != ' ')
		{
			return board[ro-1][0];
		}
	}
	char k;
	k=isfull(board, row, col);
	return k;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/872625.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存