#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;
}
978

被折叠的 条评论
为什么被折叠?



