C语言工程实践实现完整的五子棋项目二

五子棋第二章

游戏菜单和玩家信息操作部分


前言

本篇文章为完整工程实践五子棋项目的第二章。
如未看过前面的章节:
五子棋第一章
本篇文章我们将讲解游戏菜单部分和玩家信息操作部分的实现。


一、游戏菜单部分

在上一章我们实现了玩家注册登录功能,当我们登录成功之后,我们就调用game()函数,正式进入游戏内容部分。进入game()函数里面开头又是一个do…while语句嵌套switch语句作为一个游戏菜单。

game()函数

void game(player* p, player* head, int num)
{
	assert(p);
	assert(head);
	int sc = 0;
	do
	{
		enum
		{
			toexit,
			tologin,
			tocoputer,
			towatch,
			torank,
			tomodify,

		};
		printf("-------------------------------------\n");
		printf("----------欢迎来到五子棋游戏---------\n");
		printf("--------------游戏目录---------------\n");
		printf("-------------1.玩家对战--------------\n");
		printf("-------------2.人机对战--------------\n");
		printf("-------------3.查看信息--------------\n");
		printf("-------------4.查看排名--------------\n");
		printf("-------------5.修改信息--------------\n");
		printf("-------------0.退出登录--------------\n");
		printf("-------------------------------------\n");
		scanf("%d", &sc);
		switch (sc)
		{
		case tologin:
		{
			player* q = log_in2(head);
			if (q == NULL)
			{
				break;
			}
			if (q == p)
			{
				printf("重复登录\n");
				break;
			}
			system("cls");
			//gameprocess(p, q);
			break;
		}
		case tocoputer:
			system("cls");
			//coputerprocess(p);
			break;
		case towatch:
			watch(p);
			break;
		case torank:
			rank(head, num);
			break;
		case tomodify:
			modify(p);
			break;
		case toexit:
			system("cls");
			break;
		default:
			printf("输入错误,请重新输入!\n");
		}
	} while (sc);
}

我们在上面的游戏菜单部分预计了需要实现的功能–如玩家对战,人机对战,查看、修改个人信息等功能。这里当我们选择玩家对战功能时,就需要调用二号玩家登录的函数log_in2(player* head)函数并判断是否会发生重复登录等错误。当都正确后,才正式进入游戏具体进程的gameprocess(p, q)函数。这里开始p代表1号玩家(当前登录玩家),q代表2号玩家

log_in2(player* head)函数,进行二号玩家的登录操作。

player* log_in2(player* head)
{
	assert(head);
	printf("请二号玩家登录\n");
	printf("请输入您的账号:\n");
	char a[15] = { 0 };
	char b[15] = { 0 };
	scanf("%s", a);
	printf("请输入您的密码:\n");
	scanf("%s", b);
	player* cur = head->next;
	while (cur != head)
	{
		if (strcmp(cur->account, a) == 0 && strcmp(cur->password, b) == 0)
		{
			return cur;
		}
		cur = cur->next;
	}
	printf("账号或密码错误,返回前页\n");
	return NULL;
}

二、玩家信息操作部分

watch(player* p)函数,传入当前登录玩家信息的指针,通过打印指针指向的具体内容实现玩家信息的查询

void watch(player* p)
{
	assert(p);
	printf("玩家昵称:%s 胜场:%d 负场:%d 平局:%d 得分:%d\n", p->id, p->win, p->lose, p->tie, p->score);
}

modify(player* p)函数,传入当前登录玩家信息的指针,然后进行玩家信息的修改逻辑,这里我只编写了修改密码和昵称的逻辑,如需增加修改内容,可照葫芦画瓢地增加相似的逻辑。

void modify(player* p)
{
	assert(p);
	int n = 0;
	do
	{
		printf("-------------------------------------\n");
		printf("-------------请选择修改内容----------\n");
		printf("---------------1.修改密码------------\n");
		printf("---------------2.修改昵称------------\n");
		printf("---------------0.修改完成------------\n");
		printf("-------------------------------------\n");
		scanf("%d", &n);
		if (n == 1)
		{
			char a[15] = { 0 };
			printf("请输入您之前的密码:");
			scanf("%s", a);
			if (strcmp(p->password, a) == 0)
			{
				printf("请输入您的新密码(15个字符以内):");
				scanf("%s", p->password);
				printf("修改密码成功\n");
				break;
			}
			else
			{
				printf("密码错误,请重新选择!\n");
			}
		}
		else if (n == 2)
		{
			char a[15] = { 0 };
			printf("请输入您的密码:");
			scanf("%s", a);
			if (strcmp(p->password, a) == 0)
			{
				printf("请输入新的昵称(10个字符以内):");
				scanf("%s", p->id);
				printf("修改昵称成功\n");
				break;
			}
			else
			{
				printf("密码错误,请重新选择!\n");
			}
		}
		else if (n == 0)
		{
			break;
		}

		else
		{
			printf("输入错误,请重新选择!\n");
		}

	} while (n);
}

rank(player* head, int num)函数,传入head头结点和当前存储玩家数量num来实现查看玩家排名的功能。需要注意的是,查看排名就需要先进行排序,所以这里我们就涉及到了对链表的内容进行排序。我们这里就调用实现排序方法的sort(player* head, int num)函数

void rank(player* head, int num)
{
	assert(head);
	if (num == 0)
	{
		printf("暂无玩家数据\n");
		return;
	}
	sort(head, num);
	player* p = head->next;
	int i = 0;
	for (i = 0; i < num; i++)
	{
		printf("第%d名: 玩家昵称:%s 胜场:%d 负场:%d 平局:%d 得分:%d\n", i + 1, p->id, p->win, p->lose, p->tie, p->score);
		p = p->next;
	}
}

sort(player* head, int num)函数,实现对链表的内容进行排序的功能。在这里为了降低难度,我们在这里就使用冒泡排序作为排序方法,但是这种排序方法的效率并不高,有能力的可以把这一段换成归并排序,可以提高很多效率。
但如果连冒泡排序的思想都不知道的话,建议先去补一下,这里我也提供一个常规版的对数组进行冒泡排序BubbleSort(int arr[],int sz)函数,对链表进行冒泡排序和对数组进行冒泡排序的思想是完全一样的。
BubbleSort(int arr[],int sz)函数

void BubbleSort(int arr[],int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int b = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = b;
			}
		}
	}
}

sort(player* head, int num)函数

void sort(player* head, int num)
{
	assert(head);
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		player* p = head->next;
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			player* tmp = p->next;
			if (p->score < tmp->score)
			{
				p->next = tmp->next;
				tmp->next->prev = p;
				p->prev->next = tmp;
				tmp->prev = p->prev;
				tmp->next = p;
				p->prev = tmp;
			}
			else
			{
				p = p->next;
			}
		}
	}
}

其实这一段代码最麻烦的地方就是中间的交换两个结点位置的部分,所以如果搞不清楚的话,可以通过画图或者多设几个变量来帮助我们更好地完成这个功能。


总结

本次五子棋项目的第二章就先到这里了,我们在这一章完成了游戏菜单和玩家信息操作部分,实现了游戏菜单和对玩家信息进行修改、查看、排序等功能,到这里玩家信息部分的所有功能应该都算完成了,下一章预计将讲解五子棋游戏内容逻辑的具体实现。

如需源码,可在我的gitee上找到,下面是链接。
五子棋源码

每文推荐

王力宏–天地龙鳞
庄心妍–念
萨吉–玄鸟

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值