基于C语言的回合制闯关游戏

一、流程图

        本项目旨在设计和实现一个闯关游戏系统,用户可以创建多个角色、查看角色属性面板、修改角色信息、删除角色、通过闯关获取属性点、实时更新角色属性、自行分配属性点来提升角色属性数值、在闯关进行时可以自行选择技能来对怪物造成不同的效果,怪物采用随机出招来进行对局。

二、代码展示

1.main.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<stdbool.h>
#include<time.h>

#define ATKA    25
#define ATKB    15
#define SPEEDA  20
#define SPEEDB  10
#define XUETA   150
#define XUETB   200
#define EQUIPA  "匕首"
#define EQUIPB  "铁锤"
//属性点说明:一个属性点等于10点生命值或者5点攻击力,5点速度


//游戏关卡的结构体
typedef struct gamelevel{
    char      monster[10];          //怪物名字
    int       mtiao;                //血条    
    int       mspeed;               //速度
    int       mATK;                 //攻击 
}GameLevel;


//玩家信息结构体声明
typedef struct player{
    char      name[7];              //姓名
    char      sex[2];               //性别
    int       age;                  //年龄
    /*
    阵营
    a速度快,攻击高,血条薄:20,20,100,匕首
    b速度慢,攻击较低,血条厚;10,10,200,铁锤
    */
    char      camp[10];             //阵营
    int       xietiao;              //血条    
    int       speed;                //速度
    int       ATK;                  //攻击
    char      equip[10];            //装备
    int       muscle;               //属性点
    bool      Poss[6];             //通关与否
    struct player* pNextPlayer;     //指向下一个玩家信息的指针
    struct player* pPrevPlayer;     //指向前一个玩家信息的指针
    GameLevel* Ll;                  //当前玩家关卡
}Players;

//菜单显示 menu.c
void showcamp();                        //选择阵营时候的阵营显示
void showSkill();                       //玩家野怪总技能技能展示
void menuMuscle();                      //属性点分配菜单
void menuAmendPlayer();                 //修改玩家部分信息菜单
void menu(Players* list);               //主菜单
void nextLenel(Players** list);         //循环闯关

//用到了定义的关卡结构体数组 About_Level.c
Players* newplayer();                    //创建新玩家函数定义
int numLevel(Players* list);            //关卡判断,是当前角色的第几个关卡了
void PlayGame(Players** list);          //play!!!!
bool stage_clear(Players* list);        //打通关没得?
void showblood(Players* list,int num);  //Play时显示玩家名血条变化

//技能选择 skill.c
int Skill();                            //玩家技能的选择,返回值为技能效果
int Mskill();                           //怪物随机释放技能,返回值为技能效果

//属性点 Muscle.c
void Muscle(Players** list);            //属性点分配主函数
void ideMuscle(Players** list);         //play时判断要不要属性点分配
void Muscle2(Players** pTemp1);         //play时的属性点分配函数

//增删改查 change.c
void travel(Players* list);             //从头到尾遍历链表(查看所有玩家属性)
void Intail(Players** list);            //尾插玩家信息到链表中
void Delplayer(Players** list);         //删除玩家
void amendPlayer(Players** list);        //修改玩家部分信息(名称,年龄,性别)
void currentPlayer(Players** list);     //选择玩家
Players* currentPlayer1(Players* list); //查找玩家位置

2.菜单显示 menu.c

#include"main.h"

//属性点分配菜单
void menuMuscle(){
    printf("*******************玩家属性点分配界面**************************\n");
    printf("1点属性点对应可选操作:   +10点血量上限 or +5点攻击力 or +5点速度\n");
    printf("1--------->加血量上限\n");
    printf("2--------->加攻击力\n");
    printf("3--------->加速度\n");
    printf("4--------->加不起不加了!\n");
    printf("**************************************************************\n");
}

//修改玩家部分信息菜单
void menuAmendPlayer(){
    printf("*******************修改玩家信息界面****************************\n");
    printf("1--------->更改名称\n");
    printf("2--------->更改年龄\n");
    printf("3--------->更改性别\n");
    printf("4--------->不想改了!\n");
    printf("**************************************************************\n");
}

//选择阵营时候的阵营显示
void showcamp(){
    printf("**********************阵营展示***********************************\n");
    printf("阵营a:\n");
    printf("血量:%d\t武器:%s\t攻击:%d\t,速度:%d\t\n",XUETA,EQUIPA,ATKA,SPEEDA);
    printf("阵营b:\n");
    printf("血量:%d\t武器:%s\t攻击:%d\t,速度:%d\t\n",XUETB,EQUIPB,ATKB,SPEEDB);
    printf("****************************************************************\n");
}

//玩家野怪总技能技能展示
void showSkill(){
    printf("玩家技能表:\n1--->额外对敌方造成5点伤害\n2--->额外对敌方造成10点伤害\n3--->对敌方造成1点伤害,并使其陷入混乱状态(致使对方不能出招)\n4--->恢复自身10点血量\n");
    printf("怪物技能表:\n1--->额外对敌方造成10点伤害\n2--->额外对敌方造成15点伤害\n3--->对敌方造成1点伤害,并使其陷入混乱状态(致使对方不能出招)\n4--->恢复自身20点血量\n");
}

//主菜单
void menu(Players* list){
    system("clear");
    printf("------欢迎游玩回合制打怪游戏!----------\n");
    printf("1---->创建新玩家!\n");
    printf("2---->打开角色属性面板!\n");
    printf("3---->开始游戏!\n");
    printf("4---->删除玩家!\n");
    printf("5---->属性点分配!\n");
    printf("6---->修改玩家部分信息!\n");
    printf("7---->退出游戏!\n");
    printf("--------------------------------------\n");
    int num1;
    while(1){
        char s[1000];
        printf("请输入你想要执行的内容的数字:");
        scanf("%s",s);
        if(1 == strlen(s) && 0 < s[0]-'0' && 7 >= s[0]-'0'){
            num1 = s[0]-'0';
            break;
        }else{
            printf("能不能好好选选项啊!重新输入去!\n");
            sleep(1);
            continue;
        }
    }
    switch(num1){
        case 1: Intail(&list);          break;//新建玩家
        case 2: travel(list);           break;//查看玩家信息
        case 3: currentPlayer(&list);   break;//开始游戏
        case 4: Delplayer(&list);       break;//删除玩家
        case 5: Muscle(&list);          break;//属性点分配
        case 6: amendPlayer(&list);     break;//修改玩家部分信息
        case 7:  
            system("clear");
            exit(-1);   
            break;
    }
    sleep(2);
    menu(list);
}

//循环闯关
void nextLenel(Players** list){
    int i;
    printf("是否继续挑战?(1/0):");
    scanf("%d",&i);
    if(i){
        PlayGame(list);
    }else{
        printf("那就出去吧!\n");
        sleep(2);
        return;
    }
}

3.用到了定义的关卡结构体数组内容 About_Level.c

#include"main.h"

//游戏关卡固定模式
GameLevel Level[6]={
    {"aaa",100,10,10},
    {"bbb",150,15,10},
    {"ccc",200,20,10},
    {"ddd",250,30,20},
    {"eee",300,50,20},
    {"fff",500,100,30}
};

//play!!!!
void PlayGame(Players** pTemp1){
    system("clear");
    //防呆
    if(NULL == pTemp1) return;
    if(NULL == *pTemp1){
        printf("角色都么得,还玩个锤子哦!\n");
        return;
    }
    Players* pTemp = *pTemp1;//选择玩家
    int n = numLevel(pTemp);//获取当前关卡
    printf("————————————————————————第%d关初始值————————————————————————————————\n",n);
    showblood(pTemp,n);//玩家野怪血量实时显示
    showSkill();//玩家野怪技能展示
    int  round = 1;//回合数
    int  monsterblood = ((pTemp->Ll)+(n-1))->mtiao;
    int  playerblood  = pTemp->xietiao; 
    while(1){
        if( pTemp->speed >=  ((pTemp->Ll)+(n-1))->mspeed ){//玩家先攻击,角色和野怪的速度作比较,判断谁先出招
            if(0 < pTemp->xietiao && 0 < ((pTemp->Ll)+(n-1))->mtiao){//血量比较
                printf("————————————————————————第%d关,第%d回合!————————————————————————————————\n",n,round++);
                /*---------------------------------当前回合-玩家先手攻击----------------------------------------------------------------*/
                int Damage = Skill();//获取玩家技能的特性(输入1,2,对应额外造成5,10点伤害;输入3,对应888是1点伤害和混乱技能:敌方下一回合不能出招;输入4,对应999回复技能:自身恢复10点血)
                if(5 == Damage || 10 == Damage){//这就是要造成伤害给野怪
                    ((pTemp->Ll)+(n-1))->mtiao -= Damage + pTemp->ATK;//怪物被攻击 掉血(+上了玩家技能的伤害)
                    sleep(1);
                    showblood(pTemp,n);
                }
                else if(888 == Damage){//怪物本回合不能出招,用结束这一次循环方式来直接进入下一回合
                    printf("野怪进入混乱状态并受到1点伤害!\n");
                    ((pTemp->Ll)+(n-1))->mtiao -= 1;
                    showblood(pTemp,n);
                    sleep(2);
                    continue;
                }
                else if(999 == Damage){//玩家自身回血10点
                    pTemp->xietiao += 10;
                    sleep(1);
                    showblood(pTemp,n);
                }
                /*---------------------------------当前关卡-玩家先手攻击结束------------------------------------------------------------------*/
                
                /*---------------------------------当前关卡-轮到了怪物攻击----------------------------------------------------------------*/
                loop1://怪物随机技能抽取到了888;使得玩家进入混乱状态,玩家下一回合不能出招;跳到的这里直接略过玩家攻击
                if(0 < ((pTemp->Ll)+(n-1))->mtiao){//当前回合 被攻击后 怪物血量大于0 
                    //就该怪物进行技能抽取
                    int mDamage = Mskill();//获取怪物技能的特性(随机数的0,1对应额外造成10,15点伤害;888是一点伤害和混乱技能:敌方下一回合不能出招;999回复技能:自身恢复20点血)
                    if(mDamage < 30){
                        pTemp->xietiao -= mDamage + (pTemp->Ll+(n-1))->mATK/*(mDamage + (((pTemp->Ll)+(n-1))->mATK))*/;//玩家被攻击 掉血(+上了怪物技能的伤害)
                        sleep(1);
                        showblood(pTemp,n);
                    }else if(888 == mDamage){
                        printf("玩家进入混乱状态并受到1点伤害!\n");
                        pTemp->xietiao -= 1;
                        showblood(pTemp,n);
                        sleep(2);
                        printf("————————————————————————第%d关,第%d回合!————————————————————————————————\n",n,round++);
                        goto loop1;//跳转实现怪物继续攻击
                    }else if(999 == mDamage){
                        ((pTemp->Ll)+(n-1))->mtiao += 20;
                        sleep(1);
                        showblood(pTemp,n);
                    }
                }
                /*---------------------------------当前关卡-玩家先手,怪物攻击结束-------------------------------------------------------------------*/    
                
            }   
        }else{//怪物先攻击
            if(0 < pTemp->xietiao && 0 < ((pTemp->Ll)+(n-1))->mtiao){//血量比较
                printf("————————————————————————第%d关,第%d回合!————————————————————————————————\n",n,round++);
                
                /*---------------------------------当前关卡-怪物先手攻击----------------------------------------------------------------*/
                int mDamage = Mskill();//获取怪物技能的特性(5or10是伤害;888是混乱技能:敌方下一回合不能出招;999回复技能:自身恢复10点血)
                if(mDamage < 30){
                    pTemp->xietiao -= mDamage + ((pTemp->Ll)+(n-1))->mATK;//玩家被攻击 掉血(+上了怪物技能的伤害)
                    sleep(1);
                    showblood(pTemp,n);
                }
                if(999 == mDamage){
                    ((pTemp->Ll)+(n-1))->mtiao += 20;
                    sleep(1);
                    showblood(pTemp,n);
                }
                if(888 == mDamage){
                    printf("玩家进入混乱状态并受到1点伤害!\n");
                    pTemp->xietiao -= 1;
                    showblood(pTemp,n);
                    sleep(2);
                    continue;
                } //因为是怪物先攻击,所以是结束这一次循环就好
                /*---------------------------------当前关卡-怪物先手攻击结束----------------------------------------------------------------*/

                /*---------------------------------当前关卡-轮到玩家攻击----------------------------------------------------------------*/
                loop2://玩家随机技能抽取到了888;使得怪物进入混乱状态,怪物下一回合不能出招;跳到的这里直接略过怪物攻击
                if(0 < pTemp->xietiao){//当前回合 被攻击后 玩家血量大于0 
                    int Damage = Skill();//获取玩家技能的特性(5or10是伤害;888是混乱技能:敌方下一回合不能出招;999回复技能:自身恢复10点血)
                    if(5== Damage || 10 == Damage){//这就是要造成伤害给野怪
                        ((pTemp->Ll)+(n-1))->mtiao -= Damage + pTemp->ATK;//怪物被攻击 掉血(+上了玩家技能的伤害)
                        sleep(1);
                        showblood(pTemp,n);
                    }else if(888 == Damage){//怪物下回合不能出招
                        printf("野怪进入混乱状态并受到1点伤害!\n");
                        pTemp->xietiao -= 1;
                        showblood(pTemp,n);
                        sleep(2);
                        printf("————————————————————————第%d关,第%d回合!————————————————————————————————\n",n,round++);
                        goto loop2;//跳转实现怪物继续攻击
                    }else if(999 == Damage){//玩家自身回血10点
                        pTemp->xietiao += 10;
                        sleep(1);
                        showblood(pTemp,n);
                    }
                }
                /*---------------------------------当前关卡-怪物先手,玩家攻击结束----------------------------------------------------------------*/
            }//end of if(0 < pTemp->xietiao && 0 < ((pTemp->Ll)+(n-1))->mtiao){//血量比较 
        }//end of else{//怪物先攻击
        //判断过关与否
        if( 0 >= pTemp->xietiao){//玩家被攻击后 血量小于0{
            printf("这么弱的啊!第%d关都过不了!\n",n);
            pTemp->xietiao = playerblood;
            break;
        }else if(0 >= ((pTemp->Ll)+(n-1))->mtiao){//当前回合 被攻击后 怪物血量小于0 
            //通过本关标记
            pTemp->Poss[n-1] = true;
            //是否全部打通关
            bool isf = stage_clear(pTemp);
            if(isf){//ture就是全部打通关了
                printf("恭喜你全部通过啦!牛的雅痞啊!\n");
                return;
            }
            printf("恭喜你通过第%d关!并获得%d点属性点!\n",n,n);//1,2,3,4,5
            //玩家血条复原
            pTemp->xietiao = playerblood;
            //属性点增加
            pTemp->muscle += n;
            //判断要不要现在就分配属性点
            ideMuscle(pTemp1);
            sleep(2);
            break;
        }
    }//end of while(1){
    //恢复血条
    ((pTemp->Ll)+(n-1))->mtiao = monsterblood;
    nextLenel(pTemp1);
}

//打通关没得?
bool stage_clear(Players* list){
    int num = 0;
    for(int i=0;i<6;i++){//6个关卡,循环6次
        //每过一个关卡,pass为ture,num++
        if(list->Poss[num]) num++;
    }
    //6个关卡全部pass就可以判定打通关
    if(6 == num)return true;
    return false;
}

//关卡判断,是当前角色的第几个关卡了
int numLevel(Players* list){
    if(NULL == list){
        printf("角色都么得,还玩个锤子哦!\n");
        return -9999;
    }
    int numLl = 1;//当前关卡,是关卡下标+1
    Players* pTemp = list;
    while(pTemp->Poss[numLl-1])numLl++;
    return numLl;
}

//Play时显示玩家名血条变化
void showblood(Players* list,int num){
    if(NULL == list){
        printf("角色都么得,还玩个锤子哦!\n");
        return;
    }
    Players* pTemp = list;
    printf("玩家姓名:%s\t血量:%3d  速度:%d  攻击:%d\n",
        pTemp->name,pTemp->xietiao,pTemp->speed,pTemp->ATK);
    printf("当前野怪:%s\t血量:%3d  速度:%d  攻击:%d\n",
        ((pTemp->Ll)+(num-1))->monster,((pTemp->Ll)+(num-1))->mtiao,((pTemp->Ll)+(num-1))->mspeed,((pTemp->Ll)+(num-1))->mATK);
}

//创建新玩家函数定义
Players* newplayer(){
    //开内存
    Players* pNew = (Players*)malloc(sizeof(Players));
    if(NULL==pNew){//防呆
        printf("新玩家内存开辟失败!!!\n");
        return NULL;
    }

    //数据赋值
    while(1){
        printf("请输入角色名称(长度不能超过7):");
        scanf("%s",pNew->name);
        if(7 >= strlen(pNew->name) && 0 < strlen(pNew->name))break;
        printf("输入不合规则!\n");
        continue;
    }
    while(1){
        printf("请选择玩家人物性别(男/女):");
        scanf("%s",pNew->sex);
        if( 0 == strcmp(pNew->sex,"男") || 0 == strcmp(pNew->sex,"女") )break;
        printf("输入不合规则!\n");
        continue;
    }
    while(1){
        char a[100];
        printf("请输入玩家人物年龄(0,100):");
        scanf("%s",a);
        if(2 == strlen(a) && 0 < a[0]-'0' && 10 > a[0]-'0' &&
            10 > a[1]-'0' && 0 <= a[1]-'0'){
            pNew->age = 10*(a[0]-'0')+ (a[1]-'0');
            break;
        }else if(1 == strlen(a) && 0 < a[0]-'0' && 10 > a[0]-'0' ){
            pNew->age = a[0]-'0';
            break;
        }else{
            printf("输入不合规则!\n");
            // printf("%ld,%s,%c,%c",strlen(a),a,a[0],a[1]);
            continue;
        }
    }
    //选择阵营时候的阵营显示
    showcamp();
    while(1){
        printf("请选择玩家人物所属阵营(a/b):");
        scanf("%s",pNew->camp);
        if(0 == strcmp(pNew->camp,"a") || 0 == strcmp(pNew->camp,"b"))break;
        printf("输入不合规则!\n");
        continue;    
    }   
    pNew->muscle = 0;        //属性点
    pNew->pNextPlayer = NULL;//后一个节点为空
    pNew->pPrevPlayer = NULL;//前一个节点为空
    for(int i=0;i<6;i++){    //通关与否
        pNew->Poss[i] = false;
    }
    pNew->Ll=Level;//指向关卡结构体

    //通过阵营判断其血量和武器还有速度
    if(0 == strcmp((pNew->camp),"a")){//a阵营
        pNew->ATK=ATKA;
        pNew->speed=SPEEDA;
        pNew->xietiao=XUETA;
        strcpy(pNew->equip,EQUIPA);
    }
    else if(0 == strcmp((pNew->camp),"b")){//b阵营
        pNew->ATK=ATKB;
        pNew->speed=SPEEDB;
        pNew->xietiao=XUETB;
        strcpy(pNew->equip,EQUIPB);
    }
    return pNew;
}

4.玩家以及怪物技能选择 skill.c

#include"main.h"
//技能的选择,返回值是技能伤害
int Skill(){
    int skill;//技能编号
    int hurt;//技能效果
    while(1){
        printf("请选择技能!\n");
        char s[100];
        scanf("%s",s);
        if(1 == strlen(s) && 0 < s[0]-'0' && 4 >= s[0]-'0'){
            skill = s[0]-'0';
            break;
        }else{
            printf("能不能好好选选项啊!重新输入去!\n");
            sleep(1);
            continue;
        }
    }
    switch(skill){
        case 1:hurt = 5;break;
        case 2:hurt = 10;break;
        case 3:hurt = 888;break;//混乱技能,让对方下一回合不能出招
        case 4:hurt = 999;break;//回血技能,回血10
    }
    return hurt;
}

//怪物随机释放技能
int Mskill(){
    int mskill;//技能编号
    int mhurt;//技能效果
    srand((unsigned)time(NULL));
    mskill = rand()%4 + 1;//随机数固定在1-4这四个数来随机技能输出
    switch (mskill){
        case 1:mhurt = 10;printf("野怪使用了1技能,对你额外造成了10点伤害\n");break;
        case 2:mhurt = 15;printf("野怪使用了2技能,对你额外造成了15点伤害\n");break;
        case 3:mhurt = 888;printf("野怪使用了3技能\n");break;//混乱技能,让对方本一回合不能出招
        case 4:mhurt = 999;printf("野怪使用了4技能,恢复了20点血\n");break;//回血技能,回血20
    }
    return mhurt;
}

5.属性点 Muscle.c

#include"main.h"

//play时判断要不要属性点分配
void ideMuscle(Players** pTemp1){
    int nMuscle;//1就现在开始分配,2就结束这个函数
    while(1){//防止给我输入了一堆数字一堆字符
        char s[100];
        printf("是否要现在分配属性点?(1/0)\n");
        scanf("%s",s);
        if(1 == strlen(s) && 0 <= s[0]-'0' && 2 >= s[0]-'0'){
            nMuscle = s[0]-'0';
            break;
        }else{
            printf("能不能好好选选项啊!重新输入去!\n");
            sleep(1);
            continue;
        }
    }
    if(1 == nMuscle)
        Muscle2(pTemp1);/*调用属性点分配主函数*/
    return;
}

//游戏中的属性点分配函数
void Muscle2(Players** pTemp1){
    if(NULL == pTemp1) return;
    if(NULL == *pTemp1){
        printf("角色都么得,还玩个锤子哦!\n");
        return;
    }
    Players* pCur = *pTemp1;
    system("clear");
    travel(pCur);
    menuMuscle();
    int nMscle;//菜单选项选择
    int numMs;//分配几个属性点
    while(1){//防止给我输入了一堆数字一堆字符
        char s[100];
        printf("请输入选项:");
        scanf("%s",s);
        if(1 == strlen(s) && 0 < s[0]-'0' && 4 >= s[0]-'0'){
            nMscle = s[0]-'0';
            break;
        }else{
            printf("能不能好好选选项啊!重新输入去!\n");
            sleep(1);
            continue;
        }
    }
    char s[100];
    if(1 == nMscle){
        while(1){//防止给我输入了一堆数字一堆字符
            printf("请输入分配给血量多少属性点:");
            scanf("%s",s);
            if(1 == strlen(s) && 0 <= s[0]-'0' && pCur->muscle >= s[0]-'0'){//不能分配超过我属性点的值啊
                numMs = s[0]-'0';
                break;
            }else{
                printf("能不能好好选选项啊!重新输入去!\n");
                sleep(1);
                continue;
            }
        }
        pCur->xietiao += numMs*10;//血量+ 10*所分配的属性点个数
    }else if(2 == nMscle){
        while(1){//防止给我输入了一堆数字一堆字符
            printf("请输入分配给攻击力多少属性点:");
            scanf("%s",s);
            if(1 == strlen(s) && 0 <= s[0]-'0' && pCur->muscle >= s[0]-'0'){
                numMs = s[0]-'0';
                break;
            }else{
                printf("能不能好好选选项啊!重新输入去!\n");
                sleep(1);
                continue;
            }
        }
        pCur->ATK += numMs*5;//攻击力+ 5*所分配的属性点个数
    }else if(3 == nMscle){
        while(1){//防止给我输入了一堆数字一堆字符
            printf("请输入分配给速度多少属性点:");
            scanf("%s",s);
            if(1 == strlen(s) && 0 <= s[0]-'0' && pCur->muscle >= s[0]-'0'){
                numMs = s[0]-'0';
                break;
            }else{
                printf("能不能好好选选项啊!重新输入去!\n");
                sleep(1);
                continue;
            }
        }
        pCur->speed  += numMs*5;//速度+ 5*所分配的属性点个数
    }else return;
    pCur->muscle -= numMs;//属性点减少
    printf("分配成功!\n");
    // travel(pCur);
    sleep(1);
    Muscle2(pTemp1); 
}

//属性点分配主函数
void Muscle(Players** list){
    if(NULL == list) return;
    if(NULL == *list){
        system("clear");
        printf("角色都么得,还分配个啥!\n");
        return;
    }
    Players* pCur = currentPlayer1(*list);//选择要给哪个玩家分配属性点
    if(NULL == pCur){
        printf("属性点分配,玩家选择出错,请重新来过!\n");
        sleep(2);
        Muscle(list);
        return;
    }
    system("clear");
    travel(*list);
    menuMuscle();
    int nMscle;//菜单选项选择
    int numMs;//分配几个属性点
    while(1){//防止给我输入了一堆数字一堆字符
        char s[100];
        printf("请输入选项:");
        scanf("%s",s);
        if(1 == strlen(s) && 0 < s[0]-'0' && 4 >= s[0]-'0'){
            nMscle = s[0]-'0';
            break;
        }else{
            printf("能不能好好选选项啊!重新输入去!\n");
            sleep(1);
            continue;
        }
    }
    char s[100];
    if(1 == nMscle){
        while(1){//防止给我输入了一堆数字一堆字符
            printf("请输入分配给血量多少属性点:");
            scanf("%s",s);
            if(1 == strlen(s) && 0 <= s[0]-'0' && pCur->muscle >= s[0]-'0'){//不能分配超过我属性点的值啊
                numMs = s[0]-'0';
                break;
            }else{
                printf("能不能好好选选项啊!重新输入去!\n");
                sleep(1);
                continue;
            }
        }
        pCur->xietiao += numMs*10;//血量+ 10*所分配的属性点个数
    }else if(2 == nMscle){
        while(1){//防止给我输入了一堆数字一堆字符
            printf("请输入分配给攻击力多少属性点:");
            scanf("%s",s);
            if(1 == strlen(s) && 0 <= s[0]-'0' && pCur->muscle >= s[0]-'0'){
                numMs = s[0]-'0';
                break;
            }else{
                printf("能不能好好选选项啊!重新输入去!\n");
                sleep(1);
                continue;
            }
        }
        pCur->ATK += numMs*5;//攻击力+ 5*所分配的属性点个数
    }else if(3 == nMscle){
        while(1){//防止给我输入了一堆数字一堆字符
            printf("请输入分配给速度多少属性点:");
            scanf("%s",s);
            if(1 == strlen(s) && 0 <= s[0]-'0' && pCur->muscle >= s[0]-'0'){
                numMs = s[0]-'0';
                break;
            }else{
                printf("能不能好好选选项啊!重新输入去!\n");
                sleep(1);
                continue;
            }
        }
        pCur->speed  += numMs*5;//速度+ 5*所分配的属性点个数
    }else return;
    pCur->muscle -= numMs;//属性点减少
    printf("分配成功!\n");
    travel(*list);
    sleep(2);
    Muscle(list); 
}

6.增删改查 change.c

#include"main.h"

//选择玩家
void currentPlayer(Players** list){
    system("clear");
    if(NULL == list) return;
    if(NULL == *list){
        printf("角色都么得,还玩个锤子哦!\n");
        return;
    }
    travel(*list);
    Players* pCurrent = *list;
    char currentname[1000];
scanfPlayerName://符合了规矩,但是没有这个玩家的重新输入
    while(1){
        printf("请输入角色名称(-9退出):");
        scanf("%s",currentname);//获取所要游玩的玩家名
        if(0 < strlen(currentname) && 7 >= strlen(currentname) )break;//名字符合规矩了
        printf("哪里有这么个玩家真的是!\n");
        sleep(2);
        continue;
    }
    while( strcmp((pCurrent->name),currentname) ){//遍历寻找对应玩家信息
        if(0 == strcmp(currentname,"-9"))return;//退出不玩了
        if(NULL == pCurrent->pNextPlayer){//符合了规矩,但是没有这个玩家
            printf("角色名称输入错误!请重新输入!\n");
            goto scanfPlayerName;
        }
        pCurrent = pCurrent->pNextPlayer;//找到相同玩家名字的指针
    }
    PlayGame(&pCurrent); 
}

//修改玩家部分信息
void amendPlayer(Players** list){
    system("clear");
    if(NULL == list)return;
    if(NULL == *list){
        printf("角色都么得,改不了!\n");
        return ;
    }
    Players* ptemp = currentPlayer1(*list);//获得修改的玩家指针
    while(1){
        travel(ptemp);
        menuAmendPlayer();
        int n;//选项
        char s[100];//选项判断符合规矩与否
        while(1){
            scanf("%s",s);
            if(1 == strlen(s) && s[0]-'0'> 0 && s[0]-'0'< 5){
                n = s[0]-'0';
                break;
            }
            printf("输入不合规则!\n");
            continue;
        }
        switch(n){
        case 1://修改名字
            while(1){
                printf("请输入更改后角色名称(长度不能超过7):");
                scanf("%s",ptemp->name);
                if(7 >= strlen(ptemp->name) && 0 < strlen(ptemp->name)){
                    // printf("修改成功!\n");
                    // travel(ptemp);
                    // sleep(2);
                    break;
                }
                printf("输入不合规则!\n");
                continue;
            }break;
        case 2://修改年龄
            while(1){
                char a[100];
                printf("请更改玩家人物年龄(0,100):");
                scanf("%s",a);
                if(2 == strlen(a) && 0 < a[0]-'0' && 10 > a[0]-'0' &&
                    10 > a[1]-'0' && 0 <= a[1]-'0'){
                    ptemp->age = 10*(a[0]-'0')+ (a[1]-'0');
                    break;
                }else if(1 == strlen(a) && 0 < a[0]-'0' && 10 > a[0]-'0' ){
                    ptemp->age = a[0]-'0';
                    break;
                }else{
                    printf("输入不合规则!\n");
                    continue;
                }
            }break;
        case 3://修改性别
            while(1){
                printf("请更改玩家人物性别(男/女):");
                scanf("%s",ptemp->sex);
                if( 0 == strcmp(ptemp->sex,"男") || 0 == strcmp(ptemp->sex,"女") )break;
                printf("输入不合规则!\n");
                continue;
            }break;
        case 4://退出
            return;
        }
        travel(ptemp);
        printf("修改成功!\n");
        sleep(2);
    }
}

//查找玩家位置
Players* currentPlayer1(Players* list){
    system("clear");
    if(NULL == list){
        printf("角色都么得,还玩个锤子哦!\n");
        return NULL;
    }
    travel(list);
    Players* pCurrent = list;
    char currentname[1000];
scanfNamep:
    while(1){
        printf("请输入角色名称:");
        scanf("%s",currentname);//获取所要游玩的玩家名
        if(0 < strlen(currentname) && 7 >= strlen(currentname) )break;
        printf("哪里有这么个玩家真的是!\n");
        sleep(2);
        continue;
    }
    while( strcmp((pCurrent->name),currentname) ){//遍历寻找对应玩家信息
        if(NULL == pCurrent->pNextPlayer){
            printf("角色名称输入错误!请重新输入!\n");
            goto scanfNamep;
        }
        pCurrent = pCurrent->pNextPlayer;//找到相同玩家名字的指针
    }
    return pCurrent;
}

//从头到尾遍历链表(查看所有玩家属性)
void travel(Players* list){
    system("clear");
    printf("玩家列表:\n");
    if(NULL == list){printf("一个玩家都没有的!\n"); return;}
    while(list){
        //角色属性遍历输出
        printf("玩家姓名:%s\t性别:%s\t年龄:%d\t阵营:%s\t血量:%d\t速度:%d\t攻击:%d\t武器:%s\t属性点:%d\n",
            list->name,list->sex,list->age,list->camp,list->xietiao,list->speed,list->ATK,list->equip,list->muscle);
        //指向下一个节点
        list = list->pNextPlayer;
    }
    printf("\n");   
}

//尾插玩家信息到链表中
void Intail(Players** list){
    system("clear");
    if(NULL == list) return;//防呆

    Players* pNew = newplayer();
    if(NULL == pNew) return;//异常处理

    Players* pTemp = *list;
    if(*list){//非空
        while(pTemp->pNextPlayer) pTemp = pTemp->pNextPlayer;//此时 pTemp非NULL pTemp->pNext为NULL 就是尾节点
        pTemp->pNextPlayer = pNew;//新节点的前一个节点连接上这个尾插的新节点
        pNew->pPrevPlayer  = pTemp;//新节点的前指针指向前一个节点
    }else{
        *list = pNew;//链表为空,新节点就是链表头
    }
}

//删除玩家
void Delplayer(Players** list){
    system("clear");
    //防呆
    if(NULL == list) return;
    if(NULL == *list){
        printf("角色都么得一个,还删个锤子哦!\n");
        return;
    }

    travel(*list);//显示玩家列表

    //找到玩家所在的节点
    Players* pCurrent = *list;
    char delname[7];
    printf("请输入所要删除的角色名称(-9退出):");
    scanf("%s",delname);//获取所要游玩的玩家名
    if(0 == strcmp(delname,"-9"))return;
    while( strcmp((pCurrent->name),delname) ){//遍历寻找对应玩家信息
        if(NULL == pCurrent->pNextPlayer){
            printf("角色名称输入错误!请重新输入!\n");
            sleep(2);
            Delplayer(list);
            return;
        }
        pCurrent = pCurrent->pNextPlayer;//找到相同玩家名字的指针
    }

    //删除
    //只有1个节点
    if(NULL == pCurrent->pNextPlayer){
        //头结点为空就可以
        *list = NULL;
        printf("恭喜你!删除成功!!\n");
        sleep(2);
        return;
    }
    //1.删除的是头结点
    if(NULL == pCurrent->pPrevPlayer){
        //头结点指针后移就可
        *list = pCurrent->pNextPlayer;
        printf("恭喜你!删除成功!!\n");
        sleep(2);
        return;
    }
    //2.删除的是尾结点
    if(NULL == pCurrent->pNextPlayer){
        //2.1前节点的后指针置空
        pCurrent->pPrevPlayer->pNextPlayer = NULL;
        //2.2尾结点的前指针置空
        pCurrent->pPrevPlayer = NULL;
        printf("恭喜你!删除成功!!\n");
        sleep(2);
        return;
    }
    //3.删除的是中间节点
    //3.1前节点的后指针 指向 删除节点的后节点
    pCurrent->pPrevPlayer->pNextPlayer = pCurrent->pNextPlayer;
    //3.2后节点的前指针 指向 删除节点的前节点
    pCurrent->pNextPlayer->pPrevPlayer = pCurrent->pPrevPlayer;
    printf("恭喜你!删除成功!!\n");
    sleep(2);
    return;
}

7.main.c

#include"main.h"
int main(){
    Players* head=NULL;//无头双链表,头先为空
    menu(head);
    return 0;
}

三、结果演示

1.主界面

2.创建玩家选项

3.打开角色属性面板选项

4.开始游戏选项

5.删除玩家选项

6.属性点分配选项

7.修改玩家部分信息选项

8.全部通关展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值