欢迎光临
我们一直在努力

C语言实现:影院票务管理系统(铠甲怪兽管理系统)(详细解析+效果展示)C语言实现:影院票务管理系统(铠甲怪兽管理系统)(详细解析+效果展示)

C语言实现:影院票务管理系统(铠甲怪兽管理系统)(详细解析+效果展示)C语言实现:影院票务管理系统(铠甲怪兽管理系统)(详细解析+效果展示)

  • 效果展示

目录

  • 项目背景
  • 概念对照表
  • 系统功能分析
    • 用户功能
    • 管理员功能
  • 源码展示
    • entity.h
    • dal.h
    • bll.h
    • ui.h
    • dal.c
    • bll.c
    • ui.c
    • main.c
  • 总结

效果展示

影院票务管理系统(铠甲怪兽管理系统)

项目背景

这个项目是一个用 C 编写的台程序,原本是要求写一个影院票务管理系统,但是主播魔改了一下,改成了铠甲打怪项目:


概念对照表

光影铠甲概念影院票务概念说明
铠甲 (movie) 电影 每个铠甲就是一部电影,有名称、类型、属性、授权价格(票价)、状态
怪兽 (monster) 座位 封印状态表示座位是否被占用
场景 (MonsterScene) 影厅 不同场景对应不同影厅
用户 (user) 观众/管理员 普通用户是观众,管理员是影院管理者
授权/购票 (order) 购票记录 用户购买铠甲授权 → 购票记录
出战 (battle) 入场观影 铠甲出战怪兽 → 观众入场观影
座位矩阵 (showSeatMatrix) 座位布局 可视化显示座位状态
属性克制 (attr) 电影类型/座位策略 不同铠甲属性可克制怪兽 → 可类比座位策略或优惠策略
密码/登录 (login) 用户验证 登录验证身份
注册 (reg) 会员注册 新用户注册
数据持久化 (save/load) 数据库 保存用户/电影/座位/订单信息

系统功能分析

用户功能

  • 注册与登录

    • 注册成为预备铠甲勇士(会员)
    • 登录后可访问系统功能
  • 浏览与搜索铠甲(电影)

    • 查看所有铠甲信息
    • 按名称、类型、属性搜索
  • 授权/购票

    • 选择铠甲(电影)
    • 选择授权时长(电影时长)
    • 选择座位(怪兽)和场次(影厅)
  • 查看订单

    • 可召唤铠甲(闲置铠甲/未出战)
    • 所有授权记录显示
  • 退票与密码修改

    • 退未出战订单
    • 修改用户登录密码
  • 铠甲出战(观影)

    • 铠甲属性克制怪兽(座位)
    • 战斗胜利 → 封印怪兽(占座成功)
    • 战斗失败 → 铠甲破损(座位被占/失败)

  • 管理员功能

  • 铠甲管理(电影管理)

    • 浏览、添加、删除、修改铠甲
  • 场景座位矩阵管理(影厅管理)

    • 设置矩阵行列数
    • 查看场景座位布局
    • 修改怪兽封印状态(座位占用情况)
  • 系统管理

    • 查看所有用户
    • 修改管理员密码
    • 初始化怪兽列表(座位数据重置)

  • 源码展示

    entity.h

    #ifndef ENTITY_H
    #define ENTITY_H
    #include <time.h>
    typedef enum {
    ARMOR_IDLE,
    ARMOR_IN_BATTLE,
    ARMOR_REPAIRING,
    ARMOR_DAMAGED
    } ArmorStatus;

    typedef enum {
    ATTR_FIRE,
    ATTR_WATER,
    ATTR_THUNDER,
    ATTR_EARTH,
    ATTR_WIND
    } MonsterAttr;

    typedef enum {
    SCENE_KAI1_CITY,
    SCENE_KAI1_MOUNTAIN,
    SCENE_KAI1_OCEAN,
    SCENE_KAI1_ANCIENT,
    SCENE_KAI2_HOPE_CITY,
    SCENE_KAI2_ARES,
    SCENE_KAI2_OTHER
    } MonsterScene;

    typedef struct user {
    int id;
    char name[50];
    char password[50];
    int isAdmin;
    struct user* next;
    } user;

    typedef struct movie {
    int id;
    char title[50];
    float price;
    char type[50];
    ArmorStatus status;
    MonsterAttr attr;
    struct movie* next;
    } movie;

    typedef struct monster {
    int id;
    char name[50];
    int level;
    MonsterAttr attr;
    int danger;
    int isDefeated;
    MonsterScene scene;
    struct monster* next;
    } monster;

    typedef struct battleTask {
    int id;
    int userId;
    int armorId;
    int monsterId;
    int status;
    float matchScore;
    struct battleTask* next;
    } battleTask;

    typedef struct {
    int row;
    int col;
    } SceneMatrixConfig;

    typedef struct order {
    int id;
    int userId;
    int movieId;
    char movieName[50];
    int quantity;
    float totalPrice;
    int monsterId;
    int battleResult;
    MonsterScene scene;
    time_t timestamp;
    struct order* next;
    } order;

    #endif

    dal.h

    #ifndef DAL_H
    #define DAL_H
    #include "entity.h"
    extern SceneMatrixConfig sceneMatrixConfig[7];
    extern user* adminUser;
    extern user* head;
    extern user* currentUser;
    extern movie* movieList;
    extern monster* monsterList;
    extern battleTask* battleTaskList;
    extern order* orderList;
    void save_to_file();
    void load_from_file();
    void addUser(user* newUser);
    user* findUserById(int id);
    user* findUserByName(const char* name);
    void addMovie();
    movie* findMovieById(int id);
    void deleteMovie();
    monster* findMonsterById(int id);
    void addMonster();
    void addOrder(order* newOrder);
    order* findOrderById(int id);
    #endif

    bll.h

    #ifndef BLL_H
    #define BLL_H
    #include "entity.h"
    #include "dal.h"
    void login();
    void reg();
    void changePassword();
    void browseMovies();
    void searchMovie();
    void updateMovie();
    void buyTicket();
    void myOrders();
    void refundTicket();
    void view_all_armor();
    void updateMonsterStatus();
    void initMonsterList();
    void browseMonster();
    void searchMonsterByScene();
    void battleMonster();
    void showMonsterDynamicMatrix(monster* monsterListArr[], int monsterCount, MonsterScene targetScene);
    void adminSetSceneMatrix();
    void inputPassword(char* password, int maxLen);
    const char* attrToString(MonsterAttr attr);
    const char* sceneToString(MonsterScene scene);
    void showSeatMatrix(MonsterScene scene);
    void clearScreen();
    #endif

    ui.h

    #ifndef UI_H
    #define UI_H
    #include "entity.h"
    #include "bll.h"
    void usermenu();
    void adminmenu();
    void formatTimestamp(time_t timestamp, char* outBuf, int bufSize);
    #endif

    dal.c

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <time.h>
    #include "entity.h"
    #include "dal.h"
    #include"ui.h"
    #include "bll.h"
    SceneMatrixConfig sceneMatrixConfig[7] = {
    {4,4}, {4,4}, {4,4}, {4,4},
    {4,4}, {4,4}, {4,4}
    };
    user* adminUser = NULL;
    user* head = NULL;
    movie* movieList = NULL;
    user* currentUser = NULL;
    order* orderList = NULL;
    monster* monsterList = NULL;
    void save_to_file() {
    FILE* fp = fopen("wj.txt", "w");
    if (!fp) {
    printf("文件打开失败\\n");
    return;
    }
    user* p = head;
    while (p) {
    fprintf(fp, "USER %d %s %s %d\\n", p->id, p->name, p->password, p->isAdmin);
    p = p->next;
    }
    movie* m = movieList;
    while (m) {
    fprintf(fp, "ARMOR %d %s %.2f %s %d %d\\n",
    m->id, m->title, m->price, m->type, m->attr, m->status);
    m = m->next;
    }
    order* o = orderList;
    while (o) {
    fprintf(fp, "ORDER %d %d %d \\"%s\\" %d %.2f %d %d %ld\\n",
    o->id, o->userId, o->movieId, o->movieName,
    o->quantity, o->totalPrice, o->monsterId,
    o->battleResult, o->timestamp);
    o = o->next;
    }
    monster* ms = monsterList;
    while (ms) {
    fprintf(fp, "MONSTER %d %s %d %d %d %d %d\\n",
    ms->id, ms->name, ms->level, ms->attr, ms->danger, ms->isDefeated, ms->scene);
    ms = ms->next;
    }
    fclose(fp);
    printf("数据保存成功(用户+铠甲+订单+怪兽)!\\n");
    }
    void load_from_file() {
    user* p1 = head; while (p1) { user* next = p1->next; free(p1); p1 = next; } head = NULL;
    movie* p2 = movieList; while (p2) { movie* next = p2->next; free(p2); p2 = next; } movieList = NULL;
    order* p3 = orderList; while (p3) { order* next = p3->next; free(p3); p3 = next; } orderList = NULL;
    monster* p4 = monsterList; while (p4) { monster* next = p4->next; free(p4); p4 = next; } monsterList = NULL;
    FILE* fp = fopen("wj.txt", "r");
    if (!fp) { initMonsterList(); return; }
    char type[20]; int id, isAdmin, userId, movieId, quantity, armorAttr, armorStatus, monsterId, battleResult;
    int monsterLevel, monsterAttrVal, monsterDanger, isDefeated, scene;
    char name[50], password[50], title[50], movieName[100], armorType[50], monsterName[50];
    float price, totalPrice; long timestamp;
    char line[256];
    while (fscanf(fp, "%19s", type) != EOF) {
    fgets(line, sizeof(line), fp);
    if (strcmp(type, "USER") == 0) {
    if (sscanf(line, "%d %49s %49s %d", &id, name, password, &isAdmin) == 4) {
    user* u = (user*)malloc(sizeof(user));
    u->id = id; strcpy(u->name, name); strcpy(u->password, password); u->isAdmin = isAdmin;
    u->next = head; head = u;
    }
    }
    else if (strcmp(type, "ARMOR") == 0) {
    if (sscanf(line, "%d %49s %f %49s %d %d", &id, title, &price, armorType, &armorAttr, &armorStatus) == 6) {
    movie* m = (movie*)malloc(sizeof(movie));
    m->id = id; strcpy(m->title, title); strcpy(m->type, armorType); m->price = price;
    m->attr = (MonsterAttr)armorAttr; m->status = (ArmorStatus)armorStatus;
    m->next = movieList; movieList = m;
    }
    }
    else if (strcmp(type, "ORDER") == 0) {
    order* o = (order*)malloc(sizeof(order));
    if (sscanf(line, "%d %d %d \\"%49[^\\"]\\" %d %f %d %d %ld",
    &id, &userId, &movieId, o->movieName, &quantity, &totalPrice, &monsterId, &battleResult, &timestamp) == 9) {
    o->id = id; o->userId = userId; o->movieId = movieId;
    o->quantity = quantity; o->totalPrice = totalPrice; o->monsterId = monsterId;
    o->battleResult = battleResult; o->timestamp = (time_t)timestamp;
    o->next = orderList; orderList = o;
    }
    else free(o);
    }
    else if (strcmp(type, "MONSTER") == 0) {
    if (sscanf(line, "%d %49s %d %d %d %d %d", &id, monsterName, &monsterLevel, &monsterAttrVal, &monsterDanger, &isDefeated, &scene) == 7) {
    monster* m = (monster*)malloc(sizeof(monster));
    m->id = id; strcpy(m->name, monsterName); m->level = monsterLevel; m->attr = (MonsterAttr)monsterAttrVal;
    m->danger = monsterDanger; m->isDefeated = isDefeated; m->scene = (MonsterScene)scene;
    m->next = monsterList; monsterList = m;
    }
    }
    }
    fclose(fp);
    if (!monsterList) initMonsterList();
    printf("铠甲数据加载成功(用户/铠甲/订单/怪兽)\\n");
    }
    const char* attrToString(MonsterAttr attr) {
    switch (attr) {
    case ATTR_EARTH: return "土属性";
    case ATTR_WIND: return "风属性";
    case ATTR_WATER: return "水属性";
    case ATTR_FIRE: return "火属性";
    case ATTR_THUNDER:return "雷属性";
    default: return "未知属性";
    }
    }
    const char* sceneToString(MonsterScene scene) {
    switch (scene) {
    case SCENE_KAI1_CITY: return "铠一-城市市区";
    case SCENE_KAI1_MOUNTAIN: return "铠一-郊外山林";
    case SCENE_KAI1_OCEAN: return "铠一-沿海区域";
    case SCENE_KAI1_ANCIENT: return "铠一-远古遗迹";
    case SCENE_KAI2_HOPE_CITY:return "铠二-希望市";
    case SCENE_KAI2_ARES: return "铠二-阿瑞斯星球";
    case SCENE_KAI2_OTHER: return "铠二-其他区域";
    default: return "未知场景";
    }
    }
    void initMonsterList() {
    monster* temp = monsterList;
    while (temp != NULL) {
    monster* next = temp->next;
    free(temp);
    temp = next;
    }
    monsterList = NULL;
    const struct {
    int id;
    const char* name;
    int level;
    MonsterAttr attr;
    int danger;
    int isDefeated;
    MonsterScene scene;
    } monsterData[] = {
    {101, "恶参兽", 1, ATTR_EARTH, 2, 0, SCENE_KAI1_CITY},
    {102, "刺木兽", 1, ATTR_EARTH, 2, 0, SCENE_KAI1_CITY},
    {103, "蚱蜢兽", 1, ATTR_WIND, 3, 0, SCENE_KAI1_CITY},
    {104, "魔马兽", 2, ATTR_WIND, 4, 0, SCENE_KAI1_CITY},
    {105, "岩石兽", 2, ATTR_EARTH, 4, 0, SCENE_KAI1_CITY},
    {106, "鳄鱼兽", 3, ATTR_WATER, 5, 0, SCENE_KAI1_CITY},
    {107, "魔牛兽", 3, ATTR_EARTH, 5, 0, SCENE_KAI1_CITY},
    {108, "蚂蚁兽", 2, ATTR_EARTH, 4, 0, SCENE_KAI1_CITY},
    {109, "杏木兽", 3, ATTR_EARTH, 5, 0, SCENE_KAI1_CITY},
    {110, "百合兽", 3, ATTR_EARTH, 5, 0, SCENE_KAI1_CITY},
    {111, "脓液兽", 4, ATTR_EARTH, 6, 0, SCENE_KAI1_CITY},
    {112, "恶狼兽", 5, ATTR_WIND, 7, 0, SCENE_KAI1_CITY},
    {121, "苍蝇兽", 4, ATTR_WIND, 6, 0, SCENE_KAI1_MOUNTAIN},
    {122, "蜘蛛兽", 4, ATTR_EARTH, 6, 0, SCENE_KAI1_MOUNTAIN},
    {123, "恶蚊兽", 4, ATTR_WIND, 6, 0, SCENE_KAI1_MOUNTAIN},
    {124, "蝎子兽", 5, ATTR_EARTH, 7, 0, SCENE_KAI1_MOUNTAIN},
    {125, "蝴蝶兽", 5, ATTR_WIND, 7, 0, SCENE_KAI1_MOUNTAIN},
    {126, "螳螂兽", 5, ATTR_WIND, 7, 0, SCENE_KAI1_MOUNTAIN},
    {127, "蜈蚣兽", 6, ATTR_EARTH, 8, 0, SCENE_KAI1_MOUNTAIN},
    {128, "天牛兽", 6, ATTR_WIND, 8, 0, SCENE_KAI1_MOUNTAIN},
    {129, "地鼠兽", 5, ATTR_EARTH, 7, 0, SCENE_KAI1_MOUNTAIN},
    {130, "魔蝉兽", 6, ATTR_WIND, 8, 0, SCENE_KAI1_MOUNTAIN},
    {131, "刀疤兽", 4, ATTR_EARTH, 6, 0, SCENE_KAI1_MOUNTAIN},
    {132, "毒蛾兽", 4, ATTR_WIND, 6, 0, SCENE_KAI1_MOUNTAIN},
    {141, "贝壳兽", 5, ATTR_WATER, 7, 0, SCENE_KAI1_OCEAN},
    {142, "乌贼兽", 6, ATTR_WATER, 8, 0, SCENE_KAI1_OCEAN},
    {143, "螃蟹兽", 7, ATTR_WATER, 9, 0, SCENE_KAI1_OCEAN},
    {144, "龙虾兽", 7, ATTR_WATER, 9, 0, SCENE_KAI1_OCEAN},
    {145, "章鱼兽", 7, ATTR_WATER, 9, 0, SCENE_KAI1_OCEAN},
    {146, "鲨鱼兽", 8, ATTR_WATER, 9, 0, SCENE_KAI1_OCEAN},
    {147, "水母兽", 7, ATTR_WATER, 9, 0, SCENE_KAI1_OCEAN},
    {148, "海星兽", 6, ATTR_WATER, 8, 0, SCENE_KAI1_OCEAN},
    {149, "水草兽", 5, ATTR_WATER, 7, 0, SCENE_KAI1_OCEAN},
    {150, "飞蛾兽", 6, ATTR_WIND, 8, 0, SCENE_KAI1_OCEAN},
    {151, "海马兽", 6, ATTR_WATER, 8, 0, SCENE_KAI1_OCEAN},
    {152, "海螺兽", 6, ATTR_WATER, 8, 0, SCENE_KAI1_OCEAN},
    {161, "穷奇", 8, ATTR_EARTH, 9, 0, SCENE_KAI1_ANCIENT},
    {162, "饕餮", 8, ATTR_FIRE, 9, 0, SCENE_KAI1_ANCIENT},
    {163, "混沌", 8, ATTR_WIND, 9, 0, SCENE_KAI1_ANCIENT},
    {164, "梼杌", 8, ATTR_THUNDER,9, 0, SCENE_KAI1_ANCIENT},
    {165, "恶火护法", 7, ATTR_FIRE, 9, 0, SCENE_KAI1_ANCIENT},
    {166, "恶水护法", 7, ATTR_WATER, 9, 0, SCENE_KAI1_ANCIENT},
    {167, "恶金护法", 7, ATTR_THUNDER,9, 0, SCENE_KAI1_ANCIENT},
    {168, "恶木护法", 7, ATTR_WIND, 9, 0, SCENE_KAI1_ANCIENT},
    {169, "恶土护法", 7, ATTR_EARTH, 9, 0, SCENE_KAI1_ANCIENT},
    {170, "黑魔兽", 9, ATTR_THUNDER,10,0, SCENE_KAI1_ANCIENT},
    {171, "魔一", 8, ATTR_EARTH, 9, 0, SCENE_KAI1_ANCIENT},
    {172, "魔二", 8, ATTR_FIRE, 9, 0, SCENE_KAI1_ANCIENT},
    {201, "巴约比", 5, ATTR_WIND, 6, 0, SCENE_KAI2_HOPE_CITY},
    {202, "巴萨帝", 5, ATTR_FIRE, 6, 0, SCENE_KAI2_HOPE_CITY},
    {203, "库彼修", 5, ATTR_EARTH, 6, 0, SCENE_KAI2_HOPE_CITY},
    {204, "沙古拉", 6, ATTR_EARTH, 7, 0, SCENE_KAI2_HOPE_CITY},
    {205, "沙鲁克", 6, ATTR_EARTH, 7, 0, SCENE_KAI2_HOPE_CITY},
    {206, "沙尔曼", 6, ATTR_EARTH, 7, 0, SCENE_KAI2_HOPE_CITY},
    {207, "巴克特", 6, ATTR_WATER, 7, 0, SCENE_KAI2_HOPE_CITY},
    {208, "巴库鲁", 6, ATTR_WIND, 7, 0, SCENE_KAI2_HOPE_CITY},
    {209, "库克", 7, ATTR_FIRE, 8, 0, SCENE_KAI2_HOPE_CITY},
    {210, "巴尔格姆", 7, ATTR_THUNDER,8, 0, SCENE_KAI2_HOPE_CITY},
    {211, "巴纳雷斯", 7, ATTR_WIND, 8, 0, SCENE_KAI2_HOPE_CITY},
    {212, "库拉", 8, ATTR_WATER, 9, 0, SCENE_KAI2_HOPE_CITY},
    {221, "路法", 10,ATTR_THUNDER,10,0, SCENE_KAI2_ARES},
    {222, "安迷修", 9, ATTR_FIRE, 9, 0, SCENE_KAI2_ARES},
    {223, "乔奢费", 9, ATTR_WIND, 9, 0, SCENE_KAI2_ARES},
    {224, "库忿斯", 9, ATTR_EARTH, 9, 0, SCENE_KAI2_ARES},
    {225, "沙宾", 8, ATTR_EARTH, 8, 0, SCENE_KAI2_ARES},
    {226, "吉拉", 7, ATTR_THUNDER,8, 0, SCENE_KAI2_ARES},
    {227, "库列斯克", 7, ATTR_FIRE, 8, 0, SCENE_KAI2_ARES},
    {228, "巴尔格姆", 7, ATTR_WIND, 8, 0, SCENE_KAI2_ARES},
    {229, "巴纳雷斯", 7, ATTR_WATER, 8, 0, SCENE_KAI2_ARES},
    {230, "库克", 7, ATTR_EARTH, 8, 0, SCENE_KAI2_ARES},
    {231, "沙鲁克", 6, ATTR_FIRE, 7, 0, SCENE_KAI2_ARES},
    {232, "巴库鲁", 6, ATTR_WIND, 7, 0, SCENE_KAI2_ARES},
    {241, "灰冥分队杂兵",4, ATTR_FIRE, 5, 0, SCENE_KAI2_OTHER},
    {242, "赤冥分队杂兵",4, ATTR_EARTH, 5, 0, SCENE_KAI2_OTHER},
    {243, "蓝冥分队杂兵",4, ATTR_WIND, 5, 0, SCENE_KAI2_OTHER},
    {244, "紫冥分队杂兵",4, ATTR_WATER, 5, 0, SCENE_KAI2_OTHER},
    {245, "沙古拉", 6, ATTR_EARTH, 7, 0, SCENE_KAI2_OTHER},
    {246, "巴克特", 6, ATTR_WATER, 7, 0, SCENE_KAI2_OTHER},
    {247, "巴萨帝", 6, ATTR_FIRE, 7, 0, SCENE_KAI2_OTHER},
    {248, "巴约比", 6, ATTR_WIND, 7, 0, SCENE_KAI2_OTHER},
    {249, "库彼修", 7, ATTR_EARTH, 8, 0, SCENE_KAI2_OTHER},
    {250, "库拉", 8, ATTR_WATER, 9, 0, SCENE_KAI2_OTHER},
    {251, "安迷修", 9, ATTR_FIRE, 9, 0, SCENE_KAI2_OTHER},
    {252, "修罗铠甲(受控)",10,ATTR_THUNDER,10,0,SCENE_KAI2_OTHER}
    };
    int monsterCount = sizeof(monsterData) / sizeof(monsterData[0]);
    monster* tail = NULL;
    for (int i = 0; i < monsterCount; i++) {
    monster* newMonster = (monster*)malloc(sizeof(monster));
    if (!newMonster) {
    printf("内存分配失败!\\n");
    return;
    }
    newMonster->id = monsterData[i].id;
    strcpy(newMonster->name, monsterData[i].name);
    newMonster->level = monsterData[i].level;
    newMonster->attr = monsterData[i].attr;
    newMonster->danger = monsterData[i].danger;
    newMonster->isDefeated = monsterData[i].isDefeated;
    newMonster->scene = monsterData[i].scene;
    newMonster->next = NULL;
    if (!monsterList) {
    monsterList = newMonster;
    tail = newMonster;
    }
    else {
    tail->next = newMonster;
    tail = newMonster;
    }
    }
    printf(" 怪兽列表初始化完成!共加载 %d 只原版怪兽\\n", monsterCount);
    }

    bll.c

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <time.h>
    #include "entity.h"
    #include "dal.h"
    #include"ui.h"
    #include "bll.h"
    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("添加铠甲,请输入新铠甲的名字:");
    char name[50] = { 0 };
    scanf("%s", name);
    movie* checkMovie = movieList;
    int nameExists = 0;
    while (checkMovie != NULL) {
    if (strcmp(checkMovie->title, name) == 0) {
    nameExists = 1;
    break;
    }
    checkMovie = checkMovie->next;
    }
    if (nameExists) {
    printf("\\n错误:名称为「%s」的铠甲已存在,无法重复添加!\\n", name);
    free(newmovie);
    newmovie = NULL;
    getchar(); getchar();
    clearScreen();
    return;
    }
    strcpy(newmovie->title, name);
    printf("添加铠甲,请输入新铠甲的授权能量值:");
    float money;
    scanf("%f", &money);
    newmovie->price = money;
    printf("请输入铠甲类型(全能型/爆发型/速度型/防御型):");
    scanf("%s", newmovie->type);
    printf("请输入铠甲属性(1=火属性 2=水属性 3=雷属性 4=土属性 5=风属性):");
    int attr;
    scanf("%d", &attr);
    if (attr < 1 || attr > 5) {
    printf("\\n❌ 错误:属性值必须是1-5!添加失败\\n");
    free(newmovie);
    newmovie = NULL;
    getchar(); getchar();
    clearScreen();
    return;
    }
    newmovie->attr = (MonsterAttr)(attr 1);
    newmovie->status = ARMOR_IDLE;
    newmovie->next = movieList;
    movieList = newmovie;
    printf("\\n 铠甲「%s」添加成功!ID:%d\\n", name, newmovie->id);
    save_to_file();
    printf("按任意键继续。。。。。\\n");
    getchar(); getchar();
    clearScreen();
    }
    void myOrders() {
    clearScreen();
    if (currentUser == NULL) {
    printf("请先登录铠甲召唤系统后再查看授权记录!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    char orderTime[64];
    order* userOrder = orderList;
    int availableArmorCount = 0;
    printf("\\n======= 可召唤的闲置铠甲(当前可用)=======\\n");
    while (userOrder != NULL) {
    if (userOrder->userId == currentUser->id) {
    movie* armor = movieList;
    while (armor != NULL) {
    if (armor->id == userOrder->movieId && armor->status == ARMOR_IDLE) {
    availableArmorCount++;
    formatTimestamp(userOrder->timestamp, orderTime, sizeof(orderTime));
    printf("订单ID: %d | 铠甲: %s | 类型: %s | 属性: %s | 时长: %d小时 | 总价: %.2f | 创建时间: %s\\n",
    userOrder->id, armor->title, armor->type, attrToString(armor->attr),
    userOrder->quantity, userOrder->totalPrice, orderTime);
    break;
    }
    armor = armor->next;
    }
    }
    userOrder = userOrder->next;
    }
    if (availableArmorCount == 0) {
    printf("暂无可召唤的闲置铠甲!\\n");
    }
    printf("\\n======= 所有铠甲授权记录(含不可用)=======\\n");
    userOrder = orderList;
    int totalOrderCount = 0;
    while (userOrder != NULL) {
    if (userOrder->userId == currentUser->id) {
    totalOrderCount++;
    formatTimestamp(userOrder->timestamp, orderTime, sizeof(orderTime));
    printf("订单ID: %d | 铠甲: %s | 场次: %s | 时长: %d小时 | 总价: %.2f | 战斗记录: %s | 创建时间: %s\\n",
    userOrder->id, userOrder->movieName, sceneToString(userOrder->scene),
    userOrder->quantity, userOrder->totalPrice,
    userOrder->battleResult == 1 ? "未出战" :
    (userOrder->battleResult == 1 ? "胜利" : "失败"), orderTime);
    }
    userOrder = userOrder->next;
    }
    if (totalOrderCount == 0) {
    printf("你暂无任何铠甲授权记录!\\n");
    }
    printf("\\n按任意键返回菜单…\\n");
    getchar(); getchar();
    clearScreen();
    }
    void buyTicket() {
    clearScreen();
    if (currentUser == NULL) {
    printf("请先登录系统!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    browseMovies();
    int armorId, hourNum, sceneChoice;
    printf("请输入要授权的铠甲ID:");
    scanf("%d", &armorId);
    movie* selectedArmor = movieList;
    while (selectedArmor != NULL) {
    if (selectedArmor->id == armorId) break;
    selectedArmor = selectedArmor->next;
    }
    if (!selectedArmor) {
    printf("未找到该铠甲!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    if (selectedArmor->status == ARMOR_IN_BATTLE || selectedArmor->status == ARMOR_DAMAGED) {
    printf("该铠甲不可授权(战斗中/破损)!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("请选择授权时长(小时):");
    scanf("%d", &hourNum);
    if (hourNum <= 0) {
    printf("授权时长必须大于0!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("请选择出战场次(1-7):\\n");
    printf("1: 铠一-城市市区 2: 铠一-郊外山林 3: 铠一-沿海区域\\n");
    printf("4: 铠一-远古遗迹 5: 铠二-希望市 6: 铠二-阿瑞斯星球 7: 铠二-其他区域\\n");
    scanf("%d", &sceneChoice);
    if (sceneChoice < 1 || sceneChoice > 7) {
    printf("场次选择错误!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    MonsterScene selectedScene = (MonsterScene)(sceneChoice 1);
    order* checkOrder = orderList;
    int hasPurchased = 0;
    while (checkOrder != NULL) {
    if (checkOrder->userId == currentUser->id &&
    checkOrder->movieId == selectedArmor->id &&
    checkOrder->scene == selectedScene &&
    checkOrder->battleResult == 1) {
    hasPurchased = 1;
    break;
    }
    checkOrder = checkOrder->next;
    }
    if (hasPurchased) {
    printf("\\n你已购买过【%s】在【%s】场次的未出战授权,无法重复购买!\\n",
    selectedArmor->title, sceneToString(selectedScene));
    getchar(); getchar();
    clearScreen();
    return;
    }
    int row = sceneMatrixConfig[selectedScene].row;
    int col = sceneMatrixConfig[selectedScene].col;
    monster*** seatMatrix = (monster***)malloc(row * sizeof(monster**));
    if (!seatMatrix) {
    printf("内存分配失败!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    for (int i = 0; i < row; i++) {
    seatMatrix[i] = (monster**)malloc(col * sizeof(monster*));
    if (!seatMatrix[i]) {
    printf("内存分配失败!\\n");
    for (int j = 0; j < i; j++) free(seatMatrix[j]);
    free(seatMatrix);
    getchar(); getchar();
    clearScreen();
    return;
    }
    for (int j = 0; j < col; j++) {
    seatMatrix[i][j] = NULL;
    }
    }
    monster* seat = monsterList;
    int r = 0, c = 0;
    while (seat != NULL && r < row) {
    if (seat->scene == selectedScene) {
    seatMatrix[r][c] = seat;
    c++;
    if (c >= col) {
    c = 0;
    r++;
    }
    }
    seat = seat->next;
    }
    printf("\\n===== %s 座位矩阵(%d×%d)=====\\n", sceneToString(selectedScene), row, col);
    printf(" ");
    for (int c = 0; c < col; c++) {
    printf(" 列%d ", c + 1);
    }
    printf("\\n");
    for (int r = 0; r < row; r++) {
    printf("行%d ", r + 1);
    for (int c = 0; c < col; c++) {
    if (seatMatrix[r][c] == NULL) {
    printf(" [ 空 ] ");
    }
    else {
    char seatChar = seatMatrix[r][c]->isDefeated ? 'X' : 'O';
    printf(" [%c]%2d ", seatChar, seatMatrix[r][c]->id);
    }
    }
    printf("\\n");
    }
    printf("说明:O=可选择 | X=已占用 | 数字=怪兽ID | 空=无怪兽\\n");
    int targetRow, targetCol;
    monster* selectedSeat = NULL;
    while (1) {
    printf("\\n请输入要选择的座位坐标(格式:行号 列号,空格分隔):");
    scanf("%d %d", &targetRow, &targetCol);
    if (targetRow < 1 || targetRow > row || targetCol < 1 || targetCol > col) {
    printf(" 坐标错误!行号范围1-%d,列号范围1-%d,请重新输入!\\n", row, col);
    continue;
    }
    int rIdx = targetRow 1;
    int cIdx = targetCol 1;
    if (seatMatrix[rIdx][cIdx] == NULL) {
    printf(" 该位置无怪兽!请选择有数字的位置!\\n");
    continue;
    }
    if (seatMatrix[rIdx][cIdx]->isDefeated == 1) {
    printf(" 该座位已被占用!请选择标有O的位置!\\n");
    continue;
    }
    selectedSeat = seatMatrix[rIdx][cIdx];
    printf("选择成功!座位:行%d列%d | 怪兽ID:%d | 名称:%s\\n",
    targetRow, targetCol, selectedSeat->id, selectedSeat->name);
    break;
    }
    for (int i = 0; i < row; i++) {
    free(seatMatrix[i]);
    }
    free(seatMatrix);
    seatMatrix = NULL;
    selectedSeat->isDefeated = 1;
    order* newOrder = (order*)malloc(sizeof(order));
    if (!newOrder) {
    printf("内存分配失败!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    int maxOrderId = 0;
    order* o = orderList;
    while (o != NULL) {
    if (o->id > maxOrderId) maxOrderId = o->id;
    o = o->next;
    }
    newOrder->id = maxOrderId + 1;
    newOrder->userId = currentUser->id;
    newOrder->movieId = selectedArmor->id;
    strcpy(newOrder->movieName, selectedArmor->title);
    newOrder->quantity = hourNum;
    newOrder->totalPrice = selectedArmor->price * hourNum;
    newOrder->monsterId = selectedSeat->id;
    newOrder->battleResult = 1;
    newOrder->scene = selectedScene;
    newOrder->timestamp = time(NULL);
    newOrder->next = orderList;
    orderList = newOrder;
    save_to_file();
    char createTime[64];
    formatTimestamp(newOrder->timestamp, createTime, sizeof(createTime));
    printf("\\n==================== 授权成功 ====================\\n");
    printf("├─ 订单ID: %d\\n", newOrder->id);
    printf("├─ 铠甲: %s\\n", newOrder->movieName);
    printf("├─ 场次: %s\\n", sceneToString(newOrder->scene));
    printf("├─ 授权时长: %d小时\\n", newOrder->quantity);
    printf("├─ 总价: %.2f 元\\n", newOrder->totalPrice);
    printf("├─ 选择座位: 行%d列%d(怪兽ID:%d)\\n", targetRow, targetCol, selectedSeat->id);
    printf("└─ 创建时间: %s\\n", createTime);
    printf("==================================================\\n");
    printf("\\n按任意键返回菜单…\\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)
    {
    bool hasOrder = false;
    order* o = orderList;
    while (o != NULL) {
    if (o->movieId == p->id) {
    hasOrder = true;
    break;
    }
    o = o->next;
    }
    if (hasOrder) {
    clearScreen();
    printf("=============================================\\n");
    printf(" 操作失败\\n");
    printf(" 该铠甲已被召唤授权,无法修改状态!\\n");
    printf("=============================================\\n");
    printf("按任意键返回…\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("当前铠甲名: %s\\n", p->title);
    printf("当前铠甲状态: %s\\n",
    p->status == ARMOR_IDLE ? "闲置" :
    (p->status == ARMOR_IN_BATTLE ? "战斗中" :
    (p->status == ARMOR_REPAIRING ? "维修中" : "破损")));
    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();
    }
    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();
    }
    void battleMonster() {
    clearScreen();
    if (currentUser == NULL) {
    printf("请先登录铠甲召唤系统!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    order* userOrder = orderList;
    int hasArmor = 0;
    while (userOrder != NULL) {
    if (userOrder->userId == currentUser->id) {
    hasArmor = 1;
    break;
    }
    userOrder = userOrder->next;
    }
    if (hasArmor == 0) {
    printf("你还没有授权任何铠甲!请先去召唤授权(购票)\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("\\n===== 选择讨伐场次(怪兽出没场景)=====\\n");
    printf("1: 铠一-城市市区\\n2: 铠一-郊外山林\\n3: 铠一-沿海区域\\n");
    printf("4: 铠一-远古遗迹\\n5: 铠二-希望市\\n6: 铠二-阿瑞斯星球\\n7: 铠二-其他区域\\n");
    printf("请选择要讨伐的场次:");
    int sceneChoice;
    scanf("%d", &sceneChoice);
    MonsterScene targetScene;
    switch (sceneChoice) {
    case 1: targetScene = SCENE_KAI1_CITY; break;
    case 2: targetScene = SCENE_KAI1_MOUNTAIN; break;
    case 3: targetScene = SCENE_KAI1_OCEAN; break;
    case 4: targetScene = SCENE_KAI1_ANCIENT; break;
    case 5: targetScene = SCENE_KAI2_HOPE_CITY; break;
    case 6: targetScene = SCENE_KAI2_ARES; break;
    case 7: targetScene = SCENE_KAI2_OTHER; break;
    default:
    clearScreen();
    printf("输入错误!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    clearScreen();
    monster* tempMonster = monsterList;
    int hasUndefeated = 0;
    int monsterCount = 0;
    int monsterIds[100];
    monster* monsterListArr[100];

    printf("\\n===== %s 场次可讨伐的怪兽(未封印)=====\\n", sceneToString(targetScene));
    while (tempMonster != NULL) {
    if (tempMonster->isDefeated == 0 && tempMonster->scene == targetScene) {
    hasUndefeated = 1;
    monsterCount++;
    monsterIds[monsterCount 1] = tempMonster->id;
    monsterListArr[monsterCount 1] = tempMonster;
    }
    tempMonster = tempMonster->next;
    }
    if (hasUndefeated) {
    showMonsterDynamicMatrix(monsterListArr, monsterCount, targetScene);
    }

    if (hasUndefeated == 0) {
    printf("该场次暂无未封印的怪兽!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    int monsterChoice;
    printf("请选择要讨伐的怪兽序号(1-%d):", monsterCount);
    scanf("%d", &monsterChoice);
    if (monsterChoice < 1 || monsterChoice > monsterCount) {
    clearScreen();
    printf("输入错误!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    monster* targetMonster = monsterListArr[monsterChoice 1];
    clearScreen();
    printf("\\n===== 选择出战铠甲 =====\\n");
    userOrder = orderList;
    int armorCount = 0;
    movie* armorList[100];
    while (userOrder != NULL) {
    if (userOrder->userId == currentUser->id) {
    movie* p = movieList;
    while (p != NULL) {
    if (p->id == userOrder->movieId && p->status == ARMOR_IDLE) {
    armorCount++;
    armorList[armorCount 1] = p;
    printf("%d. 铠甲名称:%s | 属性:%s | 授权时长:%d小时\\n",
    armorCount,
    p->title,
    attrToString(p->attr),
    userOrder->quantity);
    break;
    }
    p = p->next;
    }
    }
    userOrder = userOrder->next;
    }
    if (armorCount == 0) {
    printf("你暂无闲置铠甲可出战(已出战/维修中/破损)\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    int armorChoice;
    printf("请选择出战的铠甲序号(1-%d):", armorCount);
    scanf("%d", &armorChoice);
    if (armorChoice < 1 || armorChoice > armorCount) {
    clearScreen();
    printf("输入错误!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    movie* battleArmor = armorList[armorChoice 1];
    clearScreen();
    printf("\\n===== 铠甲出战!缉捕怪兽 =====\\n");
    printf("场次:%s | %s VS %s 战斗开始!\\n",
    sceneToString(targetScene), battleArmor->title, targetMonster->name);

    int battleResult = 0;
    if (
    (battleArmor->attr == ATTR_FIRE && targetMonster->attr == ATTR_WIND) ||
    (battleArmor->attr == ATTR_WIND && targetMonster->attr == ATTR_EARTH) ||
    (battleArmor->attr == ATTR_EARTH && targetMonster->attr == ATTR_WATER) ||
    (battleArmor->attr == ATTR_WATER && targetMonster->attr == ATTR_THUNDER) ||
    (battleArmor->attr == ATTR_THUNDER && targetMonster->attr == ATTR_FIRE)
    ) {
    battleResult = 1;
    printf("【属性克制】%s对%s造成致命伤害!\\n", battleArmor->title, targetMonster->name);
    }
    else if (battleArmor->attr == targetMonster->attr) {
    if (battleArmor->price >= targetMonster->danger * 2) {
    battleResult = 1;
    printf("【同属性对决】%s凭借高授权等级战胜%s!\\n", battleArmor->title, targetMonster->name);
    }
    else {
    battleResult = 0;
    printf("【同属性对决】%s授权等级不足,被%s击败!\\n", battleArmor->title, targetMonster->name);
    }
    }
    else {
    battleResult = 0;
    printf("【属性被克制】%s不敌%s,战斗失败!\\n", battleArmor->title, targetMonster->name);
    }
    if (battleResult == 1) {
    targetMonster->isDefeated = 1;
    battleArmor->status = ARMOR_IDLE;
    printf("战斗胜利!%s已被封印!\\n", targetMonster->name);
    }
    else {
    battleArmor->status = ARMOR_DAMAGED;
    printf("战斗失败!%s破损,需要维修!\\n", battleArmor->title);
    }
    userOrder = orderList;
    while (userOrder != NULL) {
    if (userOrder->userId == currentUser->id && userOrder->movieId == battleArmor->id) {
    userOrder->monsterId = targetMonster->id;
    userOrder->battleResult = battleResult;
    break;
    }
    userOrder = userOrder->next;
    }
    save_to_file();
    printf("\\n战斗结束!按任意键返回菜单…\\n");
    getchar(); getchar();
    clearScreen();
    }
    void showMonsterDynamicMatrix(monster* monsterListArr[], int monsterCount, MonsterScene targetScene) {
    int matrixCol = sceneMatrixConfig[targetScene].col;
    printf("\\n========== %s 可讨伐怪兽图鉴(%d×%d矩阵版)==========\\n",
    sceneToString(targetScene),
    sceneMatrixConfig[targetScene].row,
    matrixCol);
    for (int i = 0; i < monsterCount; i++) {
    monster* m = monsterListArr[i];
    if (i + 1 < 10) {
    printf("[%d] %-12s | %-8s | 危险等级:%d",
    i + 1, m->name, attrToString(m->attr), m->danger);
    }
    else {
    printf("[%d] %-11s | %-8s | 危险等级:%d",
    i + 1, m->name, attrToString(m->attr), m->danger);
    }
    if ((i + 1) % matrixCol == 0) {
    printf("\\n————————————————————\\n");
    }
    else if (i != monsterCount 1) {
    printf(" | ");
    }
    }
    if (monsterCount % matrixCol != 0) {
    printf("\\n");
    }
    printf("===========================================================\\n");
    }
    void adminSetSceneMatrix() {
    clearScreen();
    if (currentUser == NULL || currentUser->isAdmin != 0) {
    printf("无管理员权限!仅系统管理员可修改矩阵尺寸!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("======= 铠甲勇士系统-管理员面板【怪兽矩阵配置】=======\\n");
    printf("1. 设置场景怪兽矩阵尺寸\\n");
    printf("2. 查看所有场景矩阵配置\\n");
    printf("请选择操作:");
    int op;
    scanf("%d", &op);
    if (op == 1) {
    printf("\\n======= 选择要配置的场景 =======\\n");
    printf("1: 铠一-城市市区\\n2: 铠一-郊外山林\\n3: 铠一-沿海区域\\n");
    printf("4: 铠一-远古遗迹\\n5: 铠二-希望市\\n6: 铠二-阿瑞斯星球\\n7: 铠二-其他区域\\n");
    printf("请选择场景:");
    int sceneChoice;
    scanf("%d", &sceneChoice);
    if (sceneChoice < 1 || sceneChoice > 7) {
    printf(" 场景选择错误!请选择1-7之间的场景!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    MonsterScene targetScene = (MonsterScene)(sceneChoice 1);
    printf("请输入该场景怪兽矩阵行数(2-4):");
    int row;
    scanf("%d", &row);
    printf("请输入该场景怪兽矩阵列数(2-4):");
    int col;
    scanf("%d", &col);
    if (row < 2 || row > 4 || col < 2 || col > 4) {
    printf(" 行数/列数必须在2-4之间!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    sceneMatrixConfig[targetScene].row = row;
    sceneMatrixConfig[targetScene].col = col;
    printf("场景「%s」矩阵尺寸已设置为 %d×%d!\\n",
    sceneToString(targetScene), row, col);
    getchar(); getchar();
    clearScreen();
    }
    else if (op == 2) {
    printf("\\n======= 所有场景矩阵配置 =======\\n");
    const char* sceneNames[] = {
    "铠一-城市市区", "铠一-郊外山林", "铠一-沿海区域",
    "铠一-远古遗迹", "铠二-希望市", "铠二-阿瑞斯星球", "铠二-其他区域"
    };
    for (int i = 0; i < 7; i++) {
    printf("%d. %-15s → %d×%d矩阵\\n",
    i + 1, sceneNames[i],
    sceneMatrixConfig[i].row, sceneMatrixConfig[i].col);
    }
    printf("\\n按任意键返回…");
    getchar(); getchar();
    clearScreen();
    }
    else {
    printf(" 输入错误!\\n");
    getchar(); getchar();
    clearScreen();
    }
    }
    void refundTicket() {
    clearScreen();
    if (currentUser == NULL) {
    printf("请先登录系统!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    order* userOrders[100];
    int orderCount = 0;
    order* o = orderList;
    char orderCreateTime[64];
    while (o != NULL) {
    if (o->userId == currentUser->id && o->battleResult == 1) {
    userOrders[orderCount++] = o;
    }
    o = o->next;
    }
    if (orderCount == 0) {
    printf("\\n暂无可退订单(仅未出战的授权订单可退)!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("===== 可退授权订单列表 =====\\n");
    for (int i = 0; i < orderCount; i++) {
    order* cur = userOrders[i];
    formatTimestamp(cur->timestamp, orderCreateTime, sizeof(orderCreateTime));
    printf("[%d] 订单ID: %d | 铠甲: %s | 场次: %s | 金额: %.2f | 创建时间: %s\\n",
    i + 1, cur->id, cur->movieName, sceneToString(cur->scene), cur->totalPrice, orderCreateTime);
    }
    int index;
    printf("\\n请输入要退票的订单序号(1-%d):", orderCount);
    scanf("%d", &index);
    if (index < 1 || index > orderCount) {
    printf("输入无效!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    order* targetOrder = userOrders[index 1];
    o = orderList;
    order* pre = NULL;
    int found = 0;
    while (o != NULL) {
    if (o == targetOrder) {
    found = 1;
    break;
    }
    pre = o;
    o = o->next;
    }
    if (!found) return;
    movie* armor = movieList;
    while (armor != NULL) {
    if (armor->id == targetOrder->movieId) {
    armor->status = ARMOR_IDLE;
    break;
    }
    armor = armor->next;
    }
    monster* seat = monsterList;
    while (seat != NULL) {
    if (seat->id == targetOrder->monsterId && seat->scene == targetOrder->scene) {
    seat->isDefeated = 0;
    break;
    }
    seat = seat->next;
    }
    if (pre == NULL) {
    orderList = o->next;
    }
    else {
    pre->next = o->next;
    }
    time_t now = time(NULL);
    char buf[64];
    strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&now));
    formatTimestamp(targetOrder->timestamp, orderCreateTime, sizeof(orderCreateTime));
    printf("\\n 退票成功!退票时间:%s | 原订单创建时间:%s\\n", buf, orderCreateTime);
    showSeatMatrix(targetOrder->scene);
    free(o);
    o = NULL;
    save_to_file();
    printf("\\n按任意键返回菜单…\\n");
    getchar(); getchar();
    clearScreen();
    }
    void changePassword() {
    clearScreen();
    if (currentUser == NULL) {
    printf("请先登录铠甲召唤系统后再修改密码!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    char oldPwd[50] = { 0 };
    char newPwd[50] = { 0 };
    char confirmPwd[50] = { 0 };
    printf("===== 铠甲召唤密码修改 =====\\n");
    printf("当前召唤人:%s\\n", currentUser->name);
    printf("请输入原召唤密码:");
    inputPassword(oldPwd, sizeof(oldPwd) 1);
    if (strcmp(currentUser->password, oldPwd) != 0) {
    printf("\\n❌ 原密码错误!密码修改失败\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("\\n请输入新召唤密码(6-20位):");
    inputPassword(newPwd, sizeof(newPwd) 1);
    if (strlen(newPwd) < 6 || strlen(newPwd) > 20) {
    printf("\\n 新密码长度必须在6-20位之间!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("\\n请再次输入新召唤密码:");
    inputPassword(confirmPwd, sizeof(confirmPwd) 1);
    if (strcmp(newPwd, confirmPwd) != 0) {
    printf("\\n 两次输入的新密码不一致!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    if (strcmp(newPwd, oldPwd) == 0) {
    printf("\\n 新密码不能与原密码相同!\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    strcpy_s(currentUser->password, sizeof(currentUser->password), newPwd);
    save_to_file();
    printf("\\n 密码修改成功!下次登录请使用新密码\\n");
    printf("\\n按任意键返回菜单…\\n");
    getchar(); getchar();
    clearScreen();
    }

    ui.c

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <time.h>
    #include "entity.h"
    #include "dal.h"
    #include "bll.h"
    #include"ui.h"
    static void browseMonsterByScene(MonsterScene targetScene) {
    clearScreen();
    monster* p = monsterList;
    if (p == NULL) {
    printf("该场景暂无怪兽!\\n");
    printf("按任意键继续…\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }

    printf("===== %s 场景怪兽列表 =====\\n", sceneToString(targetScene));
    printf("怪兽ID\\t怪兽名称\\t等级\\t属性\\t危险等级\\t封印状态\\n");
    printf("————————————————————\\n");
    int found = 0;
    while (p != NULL) {
    if (p->scene == targetScene) {
    found = 1;
    printf("%d\\t%s\\t%d\\t%s\\t%d\\t%s\\n",
    p->id, p->name, p->level,
    attrToString(p->attr), p->danger,
    p->isDefeated ? "已封印(X)" : "未封印(O)");
    }
    p = p->next;
    }

    if (!found) printf("该场景暂无怪兽!\\n");
    printf("\\n按任意键返回矩阵页面…\\n");
    getchar(); getchar();
    clearScreen();
    }

    void adminmenu() {
    int choice;
    do {
    clearScreen();
    printf("\\n====================================\\n");
    printf(" 光影铠甲 – 管理员控制面板\\n");
    printf("====================================\\n");
    printf("【座位状态说明】\\n");
    printf(" O: 怪兽未封印 → 空座(可选择)\\n");
    printf(" X: 怪兽已封印 → 已占座(有人坐)\\n");
    printf(" 空: 无怪兽 → 怪兽逃跑(位置空缺)\\n");
    printf("————————————\\n");
    printf("1. 铠甲管理(新增/删除/修改/浏览)\\n");
    printf("2. 场景座位总控(怪兽/矩阵管理)\\n");
    printf("3. 系统管理(用户/数据/密码)\\n");
    printf("0. 退出登录(铠甲解体)\\n");
    printf("————————————\\n");
    printf("请选择操作: ");
    while (getchar() != '\\n');
    scanf("%d", &choice);
    switch (choice) {
    case 1: {
    clearScreen();
    int armorChoice;
    do {
    clearScreen();
    printf("\\n===== 铠甲管理面板 =====\\n");
    printf("1. 浏览所有铠甲\\n");
    printf("2. 新增铠甲\\n");
    printf("3. 删除铠甲\\n");
    printf("4. 修改铠甲信息\\n");
    printf("0. 返回上一级\\n");
    printf("————————\\n");
    printf("请选择操作: ");
    while (getchar() != '\\n');
    scanf("%d", &armorChoice);

    switch (armorChoice) {
    case 1: browseMovies(); break;
    case 2: addMovie(); break;
    case 3: deleteMovie(); break;
    case 4: updateMovie(); break;
    case 0: clearScreen(); break;
    default:
    clearScreen();
    printf("输入错误!请选择0-4的数字!\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }
    } while (armorChoice != 0);
    break;
    }
    case 2: {
    clearScreen();
    int sceneChoice;
    printf("\\n===== 选择操作场景 =====\\n");
    printf("1: 铠一-城市市区\\n2: 铠一-郊外山林\\n3: 铠一-沿海区域\\n");
    printf("4: 铠一-远古遗迹\\n5: 铠二-希望市\\n6: 铠二-阿瑞斯星球\\n7: 铠二-其他区域\\n");
    printf("————————\\n");
    printf("请选择场景(1-7): ");
    while (getchar() != '\\n');
    scanf("%d", &sceneChoice);

    if (sceneChoice < 1 || sceneChoice > 7) {
    clearScreen();
    printf("场景选择错误!请选择1-7的数字!\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }

    MonsterScene targetScene = (MonsterScene)(sceneChoice 1);
    int seatOp;
    do {
    clearScreen();
    printf("\\n===== 当前场景:%s 座位矩阵 =====\\n", sceneToString(targetScene));
    showSeatMatrix(targetScene);
    printf("\\n【操作提示】O=空座 | X=已占座 | 数字=怪兽ID | 空=无怪兽\\n");
    printf("————————————\\n");
    printf("===== 该场景座位操作 =====\\n");
    printf("1. 查看本场景所有怪兽\\n");
    printf("2. 按坐标修改怪兽封印状态\\n");
    printf("0. 返回上一级\\n");
    printf("————————\\n");
    printf("请选择操作: ");
    while (getchar() != '\\n');
    scanf("%d", &seatOp);

    switch (seatOp) {
    case 1:
    browseMonsterByScene(targetScene);
    break;
    case 2: {
    clearScreen();
    printf("\\n===== %s – 按坐标修改怪兽封印状态 =====\\n", sceneToString(targetScene));
    showSeatMatrix(targetScene);
    int targetRow, targetCol;
    printf("\\n请输入要修改的怪兽坐标(格式:行号 列号):");
    scanf("%d %d", &targetRow, &targetCol);
    int row = sceneMatrixConfig[targetScene].row;
    int col = sceneMatrixConfig[targetScene].col;
    if (targetRow < 1 || targetRow > row || targetCol < 1 || targetCol > col) {
    clearScreen();
    printf("坐标错误!行号范围1-%d,列号范围1-%d!\\n", row, col);
    getchar(); getchar();
    clearScreen();
    break;
    }
    int rIdx = targetRow 1;
    int cIdx = targetCol 1;
    monster*** seatMatrix = (monster***)malloc(row * sizeof(monster**));
    if (!seatMatrix) {
    printf("内存分配失败!\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }
    for (int i = 0; i < row; i++) {
    seatMatrix[i] = (monster**)malloc(col * sizeof(monster*));
    memset(seatMatrix[i], NULL, col * sizeof(monster*));
    }
    monster* seat = monsterList;
    int r = 0, c = 0;
    while (seat != NULL && r < row) {
    if (seat->scene == targetScene) {
    seatMatrix[r][c] = seat;
    c++;
    if (c >= col) { c = 0; r++; }
    }
    seat = seat->next;
    }
    if (seatMatrix[rIdx][cIdx] == NULL) {
    clearScreen();
    printf("该坐标无怪兽(怪兽逃跑)!无法修改状态!\\n");
    for (int i = 0; i < row; i++) free(seatMatrix[i]);
    free(seatMatrix);
    getchar(); getchar();
    clearScreen();
    break;
    }
    monster* targetMonster = seatMatrix[rIdx][cIdx];
    printf("\\n当前选中:行%d列%d | 怪兽ID:%d | 名称:%s\\n",
    targetRow, targetCol, targetMonster->id, targetMonster->name);
    printf("当前状态:%s(%c)\\n",
    targetMonster->isDefeated ? "已封印(已占座)" : "未封印(空座)",
    targetMonster->isDefeated ? 'X' : 'O');

    int statusChoice;
    printf("请选择新状态(0=未封印/O 1=已封印/X):");
    scanf("%d", &statusChoice);
    if (statusChoice != 0 && statusChoice != 1) {
    clearScreen();
    printf("状态选择错误!只能输入0或1!\\n");
    for (int i = 0; i < row; i++) free(seatMatrix[i]);
    free(seatMatrix);
    getchar(); getchar();
    clearScreen();
    break;
    }
    targetMonster->isDefeated = statusChoice;
    save_to_file();
    clearScreen();
    printf("\\n修改成功!\\n");
    printf("怪兽ID:%d | 新状态:%s(%c)\\n",
    targetMonster->id,
    targetMonster->isDefeated ? "已封印(已占座)" : "未封印(空座)",
    targetMonster->isDefeated ? 'X' : 'O');
    for (int i = 0; i < row; i++) free(seatMatrix[i]);
    free(seatMatrix);
    printf("\\n按任意键返回矩阵页面…\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }
    case 4:
    adminSetSceneMatrix();
    break;
    case 0:
    clearScreen();
    break;
    default:
    clearScreen();
    printf("输入错误!请选择0-4的数字!\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }
    } while (seatOp != 0);
    break;
    }
    case 3: {
    clearScreen();
    int sysChoice;
    do {
    clearScreen();
    printf("\\n===== 系统管理面板 =====\\n");
    printf("1. 查看所有召唤人\\n");
    printf("2. 修改管理员密码\\n");
    printf("3. 初始化怪兽列表\\n");
    printf("0. 返回上一级\\n");
    printf("————————\\n");
    printf("请选择操作: ");
    while (getchar() != '\\n');
    scanf("%d", &sysChoice);
    switch (sysChoice) {
    case 1: view_all_armor(); break;
    case 2: changePassword(); break;
    case 3:
    clearScreen();
    initMonsterList();
    printf("\\n按任意键继续…\\n");
    getchar(); getchar();
    clearScreen();
    break;
    case 0: clearScreen(); break;
    default:
    clearScreen();
    printf("输入错误!请选择0-4的数字!\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }
    } while (sysChoice != 0);
    break;
    }
    case 0:
    clearScreen();
    printf("管理员已退出登录!\\n");
    printf("按任意键返回主界面…\\n");
    getchar(); getchar();
    clearScreen();
    break;
    default:
    clearScreen();
    printf("输入错误!请选择0-3的数字选项!\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }
    } while (choice != 0);
    }
    void usermenu() {
    int choice;
    do {
    clearScreen();
    printf("╔════════════════════╗\\n");
    printf("║ 用户菜单 ║\\n");
    printf("╠════════════════════╣\\n");
    printf("║ 1. 浏览铠甲信息 ║\\n");
    printf("║ (浏览电影) ║\\n");
    printf("║ 2. 搜索铠甲 ║\\n");
    printf("║ (搜索电影) ║\\n");
    printf("║ 3. 召唤授权 ║\\n");
    printf("║ (购票) ║\\n");
    printf("║ 4. 可召唤的铠甲 ║\\n");
    printf("║ (我的订单) ║\\n");
    printf("║ 5. 铠甲出战打怪 ║\\n");
    printf("║ (选场次观影) ║\\n");
    printf("║ 6. 退票 ║\\n");
    printf("║ 7. 修改召唤密码 ║\\n");
    printf("║ 0. 铠甲解体 ║\\n");
    printf("║ (退出登录) ║\\n");
    printf("╚════════════════════╝\\n");
    printf("请选择: ");
    while (getchar() != '\\n');
    scanf("%d", &choice);
    switch (choice) {
    case 1: clearScreen(); browseMovies(); break;
    case 2: clearScreen(); searchMovie(); break;
    case 3: clearScreen(); buyTicket(); break;
    case 4: clearScreen(); myOrders(); break;
    case 5: clearScreen(); battleMonster(); break;
    case 6: clearScreen(); refundTicket(); break;
    case 7: clearScreen(); changePassword(); break;
    case 0: clearScreen(); printf("正在退出登录…\\n"); break;
    default:
    clearScreen();
    printf("输入错误!请选择0-7之间的数字\\n");
    printf("按回车键继续…");
    getchar(); getchar();
    }
    } while (choice != 0);
    }
    void browseMovies() {
    clearScreen();
    movie* p = movieList;
    if (p == NULL)
    {
    printf("暂无铠甲\\n");
    printf("按任意键继续。。。。\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    printf("铠甲ID\\t铠甲名称\\t授权价格\\t铠甲类型\\t铠甲属性\\t铠甲状态\\n");
    while (p != NULL)
    {
    printf("%d\\t%s\\t%.2f\\t%s\\t%s\\t%s\\n",
    p->id,
    p->title,
    p->price,
    p->type,
    p->attr == ATTR_FIRE ? "火属性" :
    (p->attr == ATTR_WATER ? "水属性" :
    (p->attr == ATTR_THUNDER ? "雷属性" :
    (p->attr == ATTR_EARTH ? "土属性" : "风属性"))),
    p->status == ARMOR_IDLE ? "闲置" :
    (p->status == ARMOR_IN_BATTLE ? "战斗中" :
    (p->status == ARMOR_REPAIRING ? "维修中" : "破损")));
    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();
    }
    bool isSubsequenceIgnoreCase(const char* str, const char* sub) {
    if (*sub == '\\0') return true;
    while (*str != '\\0') {
    char c1 = (*str >= 'A' && *str <= 'Z') ? (*str + 32) : *str;
    char c2 = (*sub >= 'A' && *sub <= 'Z') ? (*sub + 32) : *sub;
    if (c1 == c2) {
    sub++;
    if (*sub == '\\0') return true;
    }
    str++;
    }
    return false;
    }
    void searchMovie()
    {
    clearScreen();
    int searchType;
    char keyword[50] = { 0 };
    printf("===== 铠甲搜索 =====\\n");
    printf("1. 按铠甲名称搜索(子序列模糊匹配)\\n");
    printf("2. 按铠甲类型搜索(子序列模糊匹配)\\n");
    printf("3. 按铠甲属性搜索(火/水/雷等,精确匹配)\\n");
    printf("请选择搜索方式:");
    while (getchar() != '\\n');
    scanf("%d", &searchType);
    while (getchar() != '\\n');
    printf("请输入搜索关键词:");
    fgets(keyword, sizeof(keyword), stdin);
    keyword[strcspn(keyword, "\\n")] = '\\0';
    if (strlen(keyword) == 0) {
    printf("\\n 搜索关键词不能为空!\\n");
    getchar();
    clearScreen();
    return;
    }
    movie* p = movieList;
    int found = 0;
    printf("\\n===== 铠甲搜索结果 =====\\n");
    printf("铠甲ID\\t名称\\t\\t授权价格\\t类型\\t\\t属性\\t\\t状态\\n");
    printf("———————————————————————-\\n");
    while (p != NULL)
    {
    int match = 0;
    switch (searchType)
    {
    case 1:
    match = isSubsequenceIgnoreCase(p->title, keyword);
    break;
    case 2:
    match = isSubsequenceIgnoreCase(p->type, keyword);
    break;
    case 3:
    if (strcmp(keyword, "火") == 0 || strcmp(keyword, "火属性") == 0)
    match = (p->attr == ATTR_FIRE);
    else if (strcmp(keyword, "水") == 0 || strcmp(keyword, "水属性") == 0)
    match = (p->attr == ATTR_WATER);
    else if (strcmp(keyword, "雷") == 0 || strcmp(keyword, "雷属性") == 0)
    match = (p->attr == ATTR_THUNDER);
    else if (strcmp(keyword, "土") == 0 || strcmp(keyword, "土属性") == 0)
    match = (p->attr == ATTR_EARTH);
    else if (strcmp(keyword, "风") == 0 || strcmp(keyword, "风属性") == 0)
    match = (p->attr == ATTR_WIND);
    break;
    default:
    printf(" 搜索方式错误!请选择1-3\\n");
    getchar();
    clearScreen();
    return;
    }
    if (match)
    {
    found = 1;
    printf("%-6d%-12s%-12.2f%-12s%-12s%-12s\\n",
    p->id,
    p->title,
    p->price,
    p->type,
    attrToString(p->attr),
    p->status == ARMOR_IDLE ? "闲置" :
    (p->status == ARMOR_IN_BATTLE ? "战斗中" :
    (p->status == ARMOR_REPAIRING ? "维修中" : "破损")));
    }
    p = p->next;
    }
    if (found == 0)
    {
    printf("\\n 未找到符合「%s」条件的铠甲\\n", keyword);
    }
    printf("\\n按任意键继续。。。。。\\n");
    getchar();
    clearScreen();
    }
    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 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();
    }
    void login() {
    clearScreen();
    char name[50];
    char password[50];
    int trycount = 0;
    const int maxtry = 5;
    user* p;
    while (trycount < maxtry) {
    printf("\\n=====召唤者身份验证=====\\n");
    printf("请输入召唤人姓名: ");
    scanf("%s", name);
    p = head;
    while (p != NULL) {
    if (strcmp(p->name, name) == 0) {
    break;
    }
    p = p->next;
    }
    if (p == NULL) {
    trycount++;
    printf("「无法合体!」还剩余%d次验证机会\\n", maxtry trycount);
    continue;
    }
    printf("=====请输入召唤密码=====\\n");
    inputPassword(password, 15);
    printf("\\n");
    if (strcmp(p->password, password) == 0) {
    printf("\\n「铠甲合体!」\\n");
    printf("铠甲合体!!!!,召唤人: %s\\n", p->name);
    currentUser = p;
    clearScreen();
    if (p->isAdmin == 0)
    {
    adminmenu();
    }
    else
    {
    usermenu();
    }
    return;
    }
    else {
    trycount++;
    printf("「密码错误,合体失败!」还剩余%d次机会\\n", maxtry trycount);
    }
    }
    printf("\\n「您不是铠甲召唤人!」登录失败!\\n");
    getchar(); getchar();
    clearScreen();
    }
    void reg()
    {
    clearScreen();
    int admin;
    printf("\\n====================================\\n");
    printf(" 预备铠甲勇士认证\\n");
    printf("====================================\\n");
    printf("「没有做不到的事,只有不想做的事。」\\n\\n");
    printf("请选择你的铠甲类型:\\n");
    printf("0. 天赐铠甲(管理员)\\n");
    printf("1. 人造铠甲(普通用户)\\n");
    printf("请输入你的选择: ");
    scanf("%d", &admin);
    char name[50];
    char password[50];
    printf("\\n===== 召唤者注册 =====\\n");
    printf("召唤人姓名: ");
    scanf("%s", name);
    user* p;
    p = head;
    while (p != NULL)
    {
    if (strcmp(p->name, name) == 0)
    {
    printf("「此代号已被其他铠甲勇士使用!」\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    p = p->next;
    }
    user* newuser = (user*)malloc(sizeof(user));
    if (newuser == NULL)
    {
    printf("「能量不足,召唤失败!」\\n");
    getchar(); getchar();
    clearScreen();
    return;
    }
    if (admin == 0)
    {
    newuser->isAdmin = 0;
    printf("天赐铠甲选择了你!\\n");
    }
    else
    {
    newuser->isAdmin = 1;
    printf("人造铠甲,等待你的召唤!\\n");
    }
    int count = 0;
    p = head;
    while (p != NULL)
    {
    count++;
    p = p->next;
    }
    newuser->id = count + 1;
    printf("\\n请设置你的召唤密码: \\n");
    inputPassword(password, 15);
    printf("\\n");
    strcpy(newuser->name, name);
    strcpy(newuser->password, password);
    newuser->next = head;
    head = newuser;
    printf("\\n====================================\\n");
    printf("「铠甲合体!」\\n");
    printf("恭喜你,%s,成为第%d位铠甲勇士!\\n", name, newuser->id);
    printf("「从现在开始你就是铠甲召唤人。」\\n");
    printf("====================================\\n");
    save_to_file();
    printf("\\n是否立即召唤铠甲?\\n");
    printf("1. 立即合体(登录)\\n");
    printf("2. 暂时离开\\n");
    printf("请选择: ");
    int choice;
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:
    clearScreen();
    login();
    break;
    case 2:
    printf("「暂时的离别,是为了更好的重逢。」\\n");
    getchar(); getchar();
    clearScreen();
    break;
    }
    }
    void showSeatMatrix(MonsterScene scene) {
    if (scene < 0 || scene >= 7) {
    printf("错误:无效的场景编号!无法显示座位矩阵\\n");
    return;
    }
    int row = sceneMatrixConfig[scene].row;
    int col = sceneMatrixConfig[scene].col;
    monster*** seatMatrix = (monster***)malloc(row * sizeof(monster**));
    if (!seatMatrix) {
    printf("内存分配失败!\\n");
    return;
    }
    for (int i = 0; i < row; i++) {
    seatMatrix[i] = (monster**)malloc(col * sizeof(monster*));
    if (!seatMatrix[i]) {
    printf("内存分配失败!\\n");
    for (int j = 0; j < i; j++) free(seatMatrix[j]);
    free(seatMatrix);
    return;
    }
    for (int j = 0; j < col; j++) {
    seatMatrix[i][j] = NULL;
    }
    }
    monster* seat = monsterList;
    int r = 0, c = 0;
    while (seat != NULL && r < row) {
    if (seat->scene == scene) {
    seatMatrix[r][c] = seat;
    c++;
    if (c >= col) {
    c = 0;
    r++;
    }
    }
    seat = seat->next;
    }
    printf("\\n===== %s 座位矩阵(%d×%d)=====\\n", sceneToString(scene), row, col);
    printf(" ");
    for (int c = 0; c < col; c++) {
    printf(" 列%d ", c + 1);
    }
    printf("\\n");
    for (int r = 0; r < row; r++) {
    printf("行%d ", r + 1);
    for (int c = 0; c < col; c++) {
    if (seatMatrix[r][c] == NULL) {
    printf(" [ 空 ] ");
    }
    else {
    char seatChar = seatMatrix[r][c]->isDefeated ? 'X' : 'O';
    printf(" [%c]%2d ", seatChar, seatMatrix[r][c]->id);
    }
    }
    printf("\\n");
    }
    printf("说明:O=空座 | X=已占座/已封印 | 数字=怪兽ID | 空=无怪兽\\n");
    for (int i = 0; i < row; i++) {
    free(seatMatrix[i]);
    }
    free(seatMatrix);
    seatMatrix = NULL;
    }

    common.c

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <time.h>
    #include "entity.h"
    #include "dal.h"
    #include"ui.h"
    #include "bll.h"
    void clearScreen() {
    #ifdef _WIN32
    system("cls");
    #else
    system("clear");
    #endif
    }
    void inputPassword(char* password, int maxLen)
    {
    int i = 0;
    char ch;
    while (1)
    {
    ch = _getch();
    if (ch == 13) {
    password[i] = '\\0';
    break;
    }
    else if (ch == 8) {
    if (i > 0) {
    i;
    printf("\\b \\b");
    }
    }
    else if (i < maxLen 1) {
    password[i++] = ch;
    printf("*");
    }
    }
    }
    void formatTimestamp(time_t timestamp, char* outBuf, int bufSize) {
    if (outBuf == NULL || bufSize < 20) {
    strcpy(outBuf, "时间格式错误");
    return;
    }
    struct tm* tinfo = localtime(&timestamp);
    if (tinfo == NULL) {
    strcpy(outBuf, "无效时间");
    return;
    }
    strftime(outBuf, bufSize, "%Y-%m-%d %H:%M:%S", tinfo);
    }

    main.c

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <time.h>
    #include "entity.h"
    #include "dal.h"
    #include "bll.h"
    #include"ui.h"
    int main()
    {
    load_from_file();
    int choice;
    do {
    printf("\\n====================================\\n");
    printf(" 光影铠甲\\n");
    printf("====================================\\n");
    printf("你只能承诺你有把握的事情,不要冲动\\n");
    printf("\\n");
    printf("1. 铠甲召唤(登录)\\n");
    printf("2. 成为预备铠甲勇士(注册)\\n");
    printf("0. 铠甲解体(退出)\\n");
    printf("\\n请选择你的行动: ");
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:
    login();
    break;
    case 2:
    reg();
    break;
    case 0:
    save_to_file();
    printf("\\n====================================\\n");
    printf("「暂时的离别,是为了更好的重逢。」\\n");
    printf("「只要心中有信念,就没有过不去的坎。」\\n");
    printf("——炎龙侠\\n");
    printf("\\n铠甲解体,期待你下次召唤!\\n");
    printf("====================================\\n");
    break;
    default:
    printf("\\n「犹豫就会败北!」请重新选择!\\n");
    }
    } while (choice != 0);
    return 0;
    }

    赞(0)
    未经允许不得转载:171主机测评 » C语言实现:影院票务管理系统(铠甲怪兽管理系统)(详细解析+效果展示)C语言实现:影院票务管理系统(铠甲怪兽管理系统)(详细解析+效果展示)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址