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