推箱子,带登录,带写入文件,带悔棋,无UI界面,大学c语言课程设计可用

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<Windows.h>
int arr[5][10][10] = // 5张地图
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 4, 3, 0, 0, 0, 0, 3, 4, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 2, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 4, 3, 0, 0, 0, 0, 3, 4, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 4, 3, 0, 0, 0, 0, 3, 4, 1,
1, 0, 0, 3, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 4, 0, 0, 0, 0, 0, 1,
1, 0, 1, 1, 0, 1, 1, 0, 0, 1,
1, 0, 2, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 4, 3, 0, 0, 0, 0, 3, 4, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 4, 3, 0, 0, 0, 0, 0, 4, 1,
1, 0, 0, 0, 0, 0, 0, 3, 1, 1,
1, 0, 1, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 1, 1, 0, 0, 0, 1,
1, 0, 4, 1, 1, 1, 1, 0, 0, 1,
1, 0, 0, 3, 0, 0, 3, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 4, 0, 1,
1, 0, 2, 0, 0, 0, 0, 3, 4, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 4, 3, 0, 0, 0, 0, 3, 4, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 1, 1, 0, 0, 0, 1,
1, 0, 0, 0, 1, 1, 0, 4, 0, 1,
1, 0, 0, 0, 0, 0, 3, 1, 0, 1,
1, 0, 0, 0, 0, 4, 2, 3, 0, 1,
1, 4, 3, 0, 0, 0, 0, 3, 4, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 4, 3, 0, 0, 0, 0, 3, 4, 1,
1, 0, 0, 1, 1, 1, 0, 0, 0, 1,
1, 0, 1, 0, 0, 4, 0, 0, 0, 1,
1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
1, 0, 0, 2, 3, 0, 0, 1, 0, 1,
1, 4, 3, 0, 1, 0, 0, 3, 4, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

};
typedef struct cli
{
char name[100];
char passwd[100];
char id[100];
int step[5];
int lv;
int map[10][10];
}cli_t;
typedef struct node
{
cli_t cli;
struct node* next;
struct node* prev;
}node_t;
cli_t curcli;
node_t* head = nullptr;
//用户用双向带头循环链表来进行管理
void initList()
{
head = (node_t*)malloc(sizeof(node_t));
head->next = head->prev = head;
}
void add_user(cli_t cli)
{
node_t* node = (node_t*)malloc(sizeof(node_t));
node->cli = cli;
//双向带头循环链表头插
node->next = head->next;
node->prev = head;
head->next->prev = node;
head->next = node;
}
bool isEqual(cli_t cli1,cli_t cli2)
{
if (strcmp(cli1.id, cli2.id)==0 && strcmp(cli1.name, cli2.name)==0)
{
return true;
}
return false;
}

void del_user(cli_t cli)
{
node_t* cur = head->next;
while (cur != head)
{
if (isEqual(cur->cli, cli))
{
cur->next->prev = cur->prev;
cur->prev->next = cur->next;
free(cur);
break;
}
cur = cur->next;
}
}
int list_Len()
{
int res = 0;
node_t* cur = head->next;
while (cur != head)
{
res++;
cur = cur->next;
}
return res;
}

void writeFile()
{
add_user(curcli);
FILE* fp = fopen(“D:/pushBox.bin”, “wb+”);
if (fp == NULL)
perror(“fopen”), exit(-1);
node_t* cur = head->next;
while (cur!=head)
{
fwrite(&cur->cli, sizeof(cli_t), 1, fp);
cur = cur->next;
}
fclose(fp);
}
void readFile()
{
FILE* fp = fopen(“D:/pushBox.bin”, “rb+”);
if (fp == NULL)
perror(“fopen”), exit(-1);
initList();
cli_t cli;
while (fread(&cli, sizeof(cli), 1, fp)!=0)
{
add_user(cli);
}
fclose(fp);
}
void InitFile()
{
FILE* fp = fopen(“D:/pushBox.bin”, “ab+”);
fclose(fp);
}
bool isExist(cli_t cli)
{
node_t* cur=head->next;
while (cur != head)
{
if (isEqual(cur->cli, cli))
{
return true;
}
cur = cur->next;
}
return false;
}

bool isExist2(cli_t cli)
{
node_t* cur=head->next;
while (cur!=head)
{
if (strcmp(cur->cli.id, cli.id) == 0 && strcmp(cur->cli.passwd, cli.passwd) == 0)
{
curcli = cur->cli;
del_user(cur->cli);
return true;
}
cur = cur->next;
}
return false;
}

int lv = 0;
int step = 0;
int map[10][10] = { 0 };
int HuiQ[1000][10][10] = { 0 };
int hIdx = 0;
void InitEnvp()
{
lv = curcli.lv;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = curcli.map[i][j];
}
}
step = 0;
memset(HuiQ, 0x00, sizeof(HuiQ));
hIdx = 0;
}
void EndGame()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
curcli.map[i][j] = map[i][j];
}
}
curcli.lv = lv;
memset(HuiQ, 0x00, sizeof(HuiQ));
hIdx = 0;
step = 0;
}
void writeInHuiQ()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
HuiQ[hIdx][i][j] = map[i][j];
}
}
++hIdx;
}
void ReadInHuiQ()
{
if (hIdx == 0)
return;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = HuiQ[hIdx-1][i][j];
}
}
–hIdx;
}
void DrawMap()//将地图打印出来
{
int i, j;
//winshu();//调用输赢的函数
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++)
{
switch (map[i][j])
{
case 0:
printf(" “); //空白的地方
break;
case 1:
printf(“■”); //墙
break;
case 2:
printf(“♀”); //人
break;
case 3:
printf(“☆”); //箱子
break;
case 4:
printf(“◎”); //终点地方
break;
case 6:
printf(“♂”);//人加终点位置
break;
case 7:
printf(“★”);//箱子加终点位置
break;
}
}
printf(”\n");
}
}
int move()//推箱子主架构
{
int count, caw = 0;//行和列
int i, j, tui;
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++)
{
if (map[i][j] == 2 || map[i][j] == 6)
{
count = i;//i行
caw = j;//j列
}
}
}
tui = getch();
if (tui == ‘q’)
{
return -1;
}
if (tui == ‘r’)
{
return 1;
}
writeInHuiQ();
switch (tui)//小键盘上72下80左75右77
{
case ‘W’😕/上
case 72:
//人的前面是空地; 空地0墙1人2箱子3目的地4人加目的地6箱子加目的地7
//人的前面是终点位置;
//人的前面是箱子
//箱子的前面是空地;
//箱子的前面是终点位置。
if (map[count - 1][caw] == 0 || map[count - 1][caw] == 4)//人的上一行是空地或目的地
{
map[count][caw] -= 2;//原位置人走了
map[count - 1][caw] += 2;//新地方人来了
}
else if (map[count - 1][caw] == 3 || map[count - 1][caw] == 7)//人的上一行是箱子或箱子加目的地
{
if (map[count - 2][caw] == 0 || map[count - 2][caw] == 4)//箱子的前面是空地或目的地
{
map[count][caw] -= 2;//i行人走了
map[count - 1][caw] -= 1;//i-1行箱子走了人来了-3+2
map[count - 2][caw] += 3;//i-2行箱子来了
}
}
break;

case 'S'://下 
case 80://键值 
	if (map[count + 1][caw] == 0 || map[count + 1][caw] == 4)//人的下一行是箱子或箱子加目的地 
	{
		map[count][caw] -= 2;
		map[count + 1][caw] += 2;
	}

	else if (map[count + 2][caw] == 0 || map[count + 2][caw] == 4)
	{
		if (map[count + 1][caw] == 3 || map[count + 1][caw] == 7)
		{
			map[count][caw] -= 2;
			map[count + 1][caw] -= 1;
			map[count + 2][caw] += 3;
		}
	}
	break;
case 'A'://左 
case 75:
	if (map[count][caw - 1] == 0 || map[count][caw - 1] == 4)//人的左面是空地或目的地 
	{
		map[count][caw] -= 2;//原位置人走了 
		map[count][caw - 1] += 2;//新地方人来了
	}

	else if (map[count][caw - 2] == 0 || map[count][caw - 2] == 4)//人的左面的左面是空地或目的地 
	{
		if (map[count][caw - 1] == 3 || map[count][caw - 1] == 7)//人的左面是箱子或箱子加目的地 
		{
			map[count][caw] -= 2;//j列人走了 
			map[count][caw - 1] -= 1;//j-1列箱子走了人来了-3+2 
			map[count][caw - 2] += 3;//j-2列箱子来了 
		}
	}
	break;
case 'D'://右 
case 77:
	if (map[count][caw + 1] == 0 || map[count][caw + 1] == 4)
	{
		map[count][caw] -= 2;
		map[count][caw + 1] += 2;
	}

	else if (map[count][caw + 2] == 0 || map[count][caw + 2] == 4)
	{
		if (map[count][caw + 1] == 3 || map[count][caw + 1] == 7)
		{
			map[count][caw] -= 2;
			map[count][caw + 1] -= 1;
			map[count][caw + 2] += 3;
		}
	}
	break;

}
return 0;

}
int win()
{
int number = 0;//假设所有的箱子都进入了目的地,地图上就没有了箱子,number用来表示站在空地上的箱子的数量
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (map[i][j] == 3)//说明空地上还有箱子
number++;
}
}
if (number == 0)
return 1;
return 0;
}
void UpDateStep()
{
curcli.step[lv] = curcli.step[lv] > step/2 ? curcli.step[lv] : step/2;
step = 0;
}
void Play()
{
InitEnvp();
while (1)
{
DrawMap();
int ret = win();
if (ret == 1)
{
UpDateStep();
memset(HuiQ, 0x00, sizeof(HuiQ));
hIdx = 0;
if (lv == 4)
{
lv = 0;
int a = 0;
while (1)
{
printf(“你已经通过所有的管卡,是否确认重新开始\n”);
printf(“1.重新开始\n”);
printf(“2.退出\n”);
printf(“输入你的选择: “);
scanf(”%d”, &a);
if (a == 1 || a == 2)
{
break;
}
}
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = arr[0][i][j];
}
}
if (a == 2)
{
EndGame();
return;
}
}
else
{
lv++;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = arr[lv][i][j];
}
}

		}
	}
	ret=move();
	if (ret == -1)
	{
		int c = 0;
		while (1)
		{
			printf("1.确认推出\n");
			printf("2.取消\n");
			printf("输入你的选择: ");
			scanf("%d", &c);
			if (c == 1 || c==2)
			{
				break;
			}
		}
		if (c == 1)
		{
			EndGame();
			return;
		}
	}
	else if (ret == 1)
	{
		ReadInHuiQ();
	}
	else
	{
		step++;
	}
	system("cls");
}

}
void showGame()
{
printf("-----------------游戏说明------------------\n");
printf(" ♀–>自己 \n");
printf(" ☆ -->箱子 \n");
printf(" ◎–>箱子目的地 \n");
printf(" 按 ↑可使人向前移动 \n");
printf(" 按 ↓可使人向前移动 \n");
printf(" 按 ←可使人向左移动 \n");
printf(" 按 →可使人向前移动 \n");
printf(" 按q键可以直接离开当前游戏 \n");
printf(" 按r两次(注意!!)键可以悔棋,一局游戏中,您拥有三次悔棋的机会\n");
printf(" 按键一次只可移动一步,箱子只可推,不可反拉 \n");
printf(" 退出游戏时一定要按保存并退出选项,不然信息将不予以保存 \n");
printf("-----------------游戏说明------------------\n");
Sleep(5000);
}
int meau()//菜单
{
int choice = 0;
printf(“推箱子小游戏\n");
printf(" \n");
printf(" [#-#] ┏ ┓ \n");
printf(" 。I 。 -> 推 \n");
printf(" ! ! ┗ ┛ \n");
printf(" \n");
printf(" 1.开始游戏 \n");
printf(" 2.打印用户的信息 \n");
printf(" 3.修改用户的信息 \n");
printf(" 4.显示所有用户信息及排名 \n");
printf(" 5.保存信息并且退出文件 \n");
printf("
**********************************************\n”);
printf(" \n");
printf(" \n");
printf(" 请通过序号进行选择\n");
scanf("%d", &choice);
getchar();
return choice;
}
void modify_user()
{
cli_t cli;
printf(“用户名: “);
scanf(”%s”, cli.name);
printf(“id: “);
scanf(”%s”, cli.id);
printf(“密码: “);
scanf(”%s”, cli.passwd);
strcpy(curcli.id, cli.id);
strcpy(curcli.name, cli.name);
strcpy(curcli.passwd, cli.passwd);
printf(“修改完成\n”);
Sleep(3000);
system(“cls”);
return;
}
typedef struct Info
{
int step;
char name[100];
char id[100];
}info_t;
void swap(info_t* i1, info*_t i2)
{
info_t i;
i = i1;
i1 = i2;
i2 = i;
}
void Sort(info_t
info, int len,int l)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (info[j].step > info[j + 1].step)
{
swap(&info[j], &info[j + 1]);
}
}
}
printf("%d 关: \n", l+1);
int idx = 0;
for (int i = 0; i < len; i++)
{
if (info[i].step != 0)
{
printf("[%d]: ",idx);
printf(“step: %d”, info[i].step);
printf("name: %s ", info[i].name);
printf(“id: %s “, info[i].id);
++idx;
printf(”\n”);
}
}
}
void PrintInfo()
{
int len = list_Len();
info_t
info = (info_t
)malloc(sizeof(info_t)
(len+1));

for (int i = 0; i < 5; i++)
{
	int idx = 0;
	node_t* cur = head->next;
	while (cur!=head)
	{
		strcpy(info[idx].id, cur->cli.id);
		strcpy(info[idx].name, cur->cli.name);
		info[idx].step = cur->cli.step[i];
		++idx;
		cur = cur->next;
	}
	strcpy(info[idx].id, curcli.id);
	strcpy(info[idx].name, curcli.name);
	info[idx].step = curcli.step[i];
	++idx;
	Sort(info, len + 1,i);
}

}
void Game()
{
while (1)
{
int choice = meau();
if (choice == 1)
{
system(“cls”);
Play();
system(“cls”);
}
else if (choice == 2)
{
system(“cls”);
printf(" name: %s\n", curcli.name);
printf(" id: %s\n", curcli.id);
for (int i = 0; i < 5; i++)
{
printf(" 第%d关所用的步数:%d \n", i+1,curcli.step[i]);
}
Sleep(3000);
system(“cls”);
}
else if (choice == 3)
{
system(“cls”);
modify_user();
system(“cls”);
}
else if (choice == 4)
{
system(“cls”);
PrintInfo();
Sleep(3000);
system(“cls”);
}
else if (choice == 5)
{
system(“cls”);
printf(“请等待\n”);
writeFile();
system(“cls”);
return;
}
}
}
void load()
{
readFile();
cli_t cli;
int a = 0;
int flag = 0;
while (1)
{
printf(“1.新用户\n”);
printf(“2.老用户\n”);
printf(“输入你的选择: “);
scanf(”%d”, &a);
if (a == 1)
{
printf(“用户名: “);
scanf(”%s”, cli.name);
printf(“id: “);
scanf(”%s”, cli.id);
printf(“密码: “);
scanf(”%s”, cli.passwd);
if (isExist(cli))
{
printf(“用户名/id重复\n”);
Sleep(2000);
system(“cls”);
}
else
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cli.map[i][j] = arr[0][i][j];
}
}
cli.lv = 0;
for (int i = 0; i < 5; i++)
{
cli.step[i] = 0;
}
curcli = cli;
printf(“账户创建成功\n”);
system(“cls”);
break;
}
}
else if (a == 2)
{
printf(“id: “);
scanf(”%s”, cli.id);
printf(“密码: “);
scanf(”%s”, cli.passwd);
if (!isExist2(cli))
{
printf(“用户不存在\n”);
Sleep(2000);
system(“cls”);
}
else
{
printf(“登录成功\n”);
system(“cls”);
break;
}
}
else
{
printf(“输入有误\n”);
}
}
Game();
}
void Go()
{
showGame();
InitFile();
load();
}
int main()
{
Go();
system(“pause”);
return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值