原本要求是做一个影院管理系统,但是主播觉得那样写太无聊了,就魔改了一下;
增添函数
void addMovie() {
clearScreen();
movie* newmovie = (movie*)malloc(sizeof(movie));
if (newmovie == NULL)
{
printf("分配内存失败\n");
getchar(); getchar();
clearScreen();
return;
}
int maxid = 0;
movie* p = movieList;
while (p != NULL)
{
if (p->id > maxid) maxid = p->id;
p = p->next;
}
newmovie->id = maxid + 1;
printf("添加铠甲,请输入新铠甲的名字\n");
char name[50];
scanf("%s", name);
strcpy(newmovie->title, name);
printf("添加铠甲,请输入新铠甲的授权能量值\n");
float money;
scanf("%f", &money);
newmovie->price = money;
printf("请输入铠甲类型(全能型/爆发型/速度型/防御型):");
scanf("%s", newmovie->type);
printf("请输入铠甲属性(1=火属性 2=水属性 3=雷属性 4=土属性 5=风属性):");
int attr;
scanf("%d", &attr);
newmovie->attr = (MonsterAttr)(attr - 1);
newmovie->status = ARMOR_IDLE;
newmovie->next = movieList;
movieList = newmovie;
printf("铠甲添加成功\n");
save_to_file();
printf("按任意键继续。。。。。\n");
getchar(); getchar();
clearScreen();
}
效果展示
核心思路就是创建新的链表节点,然后头插法插入;
删除函数
void deleteMovie() {
clearScreen();
int id;
printf("请输入要销毁的铠甲id\n");
scanf("%d", &id);
movie* cur = movieList;
movie* pre = NULL;
while (cur != NULL)
{
if (cur->id == id)
{
if (pre == NULL)
{
movieList = movieList->next;
}
else
{
pre->next = cur->next;
}
save_to_file();
printf("铠甲销毁成功,按任意键继续。。。。。\n");
getchar(); getchar();
clearScreen();
return;
}
pre = cur;
cur = cur->next;
}
printf("未找到id为%d的铠甲\n", id);
printf("按任意键继续\n");
getchar(); getchar();
clearScreen();
}
效果展示
核心思路是链表的删除,遍历到这个节点的时候,让这个节点的上一个直接指向这个节点的下一个,跳过这个;
修改函数
void updateMovie() {
clearScreen();
printf("===== 可修复的铠甲列表 =====\n");
movie* p = movieList;
int hasRepairable = 0;
printf("铠甲ID\t名称\t\t当前状态\n");
while (p != NULL) {
if (p->status != ARMOR_IDLE) {
hasRepairable = 1;
printf("%d\t%s\t\t%s\n",
p->id,
p->title,
p->status == ARMOR_IN_BATTLE ? "战斗中" :
(p->status == ARMOR_REPAIRING ? "维修中" : "破损"));
}
p = p->next;
}
if (!hasRepairable) {
printf("暂无需要修复的铠甲(所有铠甲均为闲置状态)\n");
printf("按任意键继续...\n");
getchar(); getchar();
clearScreen();
return;
}
int id;
printf("\n请输入要调校的铠甲ID: ");
scanf("%d", &id);
p = movieList;
while (p != NULL)
{
if (p->id == id)
{
printf("当前铠甲名: %s\n", p->title);
printf("当前授权能量: %.2f\n", p->price);
printf("当前铠甲类型: %s\n", p->type);
printf("当前铠甲属性: %s\n",
p->attr == ATTR_FIRE ? "火属性" :
(p->attr == ATTR_WATER ? "水属性" :
(p->attr == ATTR_THUNDER ? "雷属性" :
(p->attr == ATTR_EARTH ? "土属性" : "风属性"))));
printf("当前铠甲状态: %s\n",
p->status == ARMOR_IDLE ? "闲置" :
(p->status == ARMOR_IN_BATTLE ? "战斗中" :
(p->status == ARMOR_REPAIRING ? "维修中" : "破损")));
printf("请输入新铠甲名: ");
scanf("%s", p->title);
printf("请输入新授权能量: ");
scanf("%f", &p->price);
printf("请输入新铠甲类型: ");
scanf("%s", p->type);
printf("请输入新铠甲属性(1-5): ");
int attr;
scanf("%d", &attr);
p->attr = (MonsterAttr)(attr - 1);
printf("请输入新铠甲状态(1=闲置 2=战斗中 3=维修中 4=破损): ");
int status;
scanf("%d", &status);
p->status = (ArmorStatus)(status - 1);
printf("铠甲调校成功!\n");
save_to_file();
printf("按任意键继续...");
getchar(); getchar();
clearScreen();
return;
}
p = p->next;
}
printf("未找到ID为%d的铠甲\n", id);
printf("按任意键继续...\n");
getchar(); getchar();
clearScreen();
}
效果展示
铠甲由破损状态到闲置状态;
核心思路是先遍历一遍链表,把所有破损状态的铠甲和战斗中的铠甲找出来;
然后再次遍历链表,输入要改变状态的id,遍历时找到id对应的节点,然后直接进行修改链表节点;
查看所有召唤人函数
void view_all_armor() {
clearScreen();
user* p = head;
if (p == NULL)
{
printf("暂无召唤人\n");
printf("按任意键继续。。。。\n");
getchar(); getchar();
clearScreen();
return;
}
printf("召唤人ID\t召唤人名称\t身份\n");
while (p != NULL)
{
printf("%d\t%s\t%s\n",
p->id,
p->name,
p->isAdmin == 1 ? "管理员" : "普通用户");
p = p->next;
}
printf("按任意键继续。。。。。\n");
getchar(); getchar();
clearScreen();
}
效果展示:
核心思路是遍历用户结构体;
浏览怪兽信息函数
void browseMonster() {
clearScreen();
monster* p = monsterList;
if (p == NULL)
{
printf("暂无怪兽\n");
printf("按任意键继续。。。。\n");
getchar(); getchar();
clearScreen();
return;
}
printf("怪兽ID\t怪兽名称\t等级\t属性\t危险等级\t封印状态\t出没地点\n");
while (p != NULL)
{
printf("%d\t%s\t%d\t%s\t%d\t%s\t%s\n",
p->id,
p->name,
p->level,
p->attr == ATTR_FIRE ? "火属性" :
(p->attr == ATTR_WATER ? "水属性" :
(p->attr == ATTR_THUNDER ? "雷属性" :
(p->attr == ATTR_EARTH ? "土属性" : "风属性"))),
p->danger,
p->isDefeated ? "已封印" : "未封印",
sceneToString(p->scene));
p = p->next;
}
printf("按任意键继续。。。。。\n");
getchar(); getchar();
clearScreen();
}
效果展示:
核心思路是遍历怪兽结构体链表
新增怪兽函数
void addMonster() {
clearScreen();
monster* newMonster = (monster*)malloc(sizeof(monster));
if (newMonster == NULL) {
printf("内存分配失败!无法新增怪兽\n");
getchar(); getchar();
clearScreen();
return;
}
int maxId = 0;
monster* p = monsterList;
while (p != NULL) {
if (p->id > maxId) maxId = p->id;
p = p->next;
}
newMonster->id = maxId + 1;
printf("\n===== 新增怪兽(新增座位)=====\n");
printf("请输入怪兽名称:");
scanf("%s", newMonster->name);
printf("请输入怪兽等级:");
scanf("%d", &newMonster->level);
printf("请输入怪兽属性(1=火 2=水 3=雷 4=土 5=风):");
int attr;
scanf("%d", &attr);
newMonster->attr = (MonsterAttr)(attr - 1);
printf("请输入怪兽危险等级(1-10):");
scanf("%d", &newMonster->danger);
printf("请输入怪兽封印状态(0=未封印 1=已封印):");
scanf("%d", &newMonster->isDefeated);
printf("请选择怪兽出没地点(场次):\n");
printf("1: 铠一-城市市区\n2: 铠一-郊外山林\n3: 铠一-沿海区域\n");
printf("4: 铠一-远古遗迹\n5: 铠二-希望市\n6: 铠二-阿瑞斯星球\n7: 铠二-其他区域\n");
int scene;
scanf("%d", &scene);
newMonster->scene = (MonsterScene)(scene - 1);
newMonster->next = NULL;
if (monsterList == NULL) {
monsterList = newMonster;
}
else {
p = monsterList;
while (p->next != NULL) p = p->next;
p->next = newMonster;
}
printf("怪兽新增成功!ID:%d\n", newMonster->id);
save_to_file();
printf("按任意键返回...\n");
getchar(); getchar();
clearScreen();
}
效果展示
新建链表节点,然后插入,记得保存进入文件;
修改怪兽封印状态函数
void updateMonsterStatus() {
clearScreen();
printf("\n===== 修改怪兽封印状态(修改座位)=====\n");
printf("请输入要修改的怪兽ID:");
int id;
scanf("%d", &id);
monster* p = monsterList;
while (p != NULL) {
if (p->id == id) {
printf("当前怪兽:%s | 封印状态:%s\n",
p->name, p->isDefeated ? "已封印" : "未封印");
printf("请输入新的封印状态(0=未封印 1=已封印):");
scanf("%d", &p->isDefeated);
printf("怪兽封印状态修改成功!\n");
save_to_file();
getchar(); getchar();
clearScreen();
return;
}
p = p->next;
}
printf("未找到ID为%d的怪兽!\n", id);
getchar(); getchar();
clearScreen();
}
效果展示
遍历链表找到对应的id,对里面元素进行修改;
搜索怪兽(场景搜索)
void searchMonsterByScene() {
int s;
printf("\n===== 选择出没地点(电影场次)=====\n");
printf("1: 铠一-城市市区\n2: 铠一-郊外山林\n3: 铠一-沿海区域\n");
printf("4: 铠一-远古遗迹\n5: 铠二-希望市\n6: 铠二-阿瑞斯星球\n7: 铠二-其他区域\n");
printf("请选择:");
scanf("%d", &s);
MonsterScene target;
switch (s) {
case 1: target = SCENE_KAI1_CITY; break;
case 2: target = SCENE_KAI1_MOUNTAIN; break;
case 3: target = SCENE_KAI1_OCEAN; break;
case 4: target = SCENE_KAI1_ANCIENT; break;
case 5: target = SCENE_KAI2_HOPE_CITY; break;
case 6: target = SCENE_KAI2_ARES; break;
case 7: target = SCENE_KAI2_OTHER; break;
default: printf("输入错误!\n"); getchar(); getchar(); return;
}
printf("\n===== 地点「%s」的怪兽 =====\n", sceneToString(target));
printf("ID\t名称\t\t等级\t属性\t\t是否封印\n");
printf("------------------------------------------------------------\n");
monster* p = monsterList;
int found = 0;
while (p) {
if (p->scene == target) {
found = 1;
printf("%d\t%-15s\t%d\t%s\t%s\n",
p->id,
p->name,
p->level,
attrToString(p->attr),
p->isDefeated ? "已封印" : "可封印");
}
p = p->next;
}
if (!found) printf("该地点暂无怪兽\n");
printf("按回车返回...\n");
getchar(); getchar();
}
效果展示
选择场景,遍历链表,如果某个节点的场景元素和选择的场景一样就输出这个节点(怪兽)的所有信息;
剩余的函数在下一篇更新;