C語言項目-後宮選妃系統-第三天-終結

因爲疫情只能在家看網課,學了幾天C語言之後,就打算找個項目來,今天是做這個項目的第三天,想要看之前的內容可以到我同一個專欄去找

項目:後宮選妃系統

六大模塊:

1.下旨選妃 -完成
    輸入一名新妃子的名字,新增加一位新的妃子,然後其他妃子的寵愛度減 10 點
2.翻牌寵幸-完成
    輸入一名妃子的名字,翻牌寵幸其,增加其寵愛度10點,減少其他妃子寵愛度10點
3.打入冷宮-完成
    輸入一名妃子的名字,刪除一位妃子,然後其他所有的妃子寵愛度加 10 點,若無此人則顯示虛驚一場
4.朕的愛妃呢-完成
    查找妃子,輸入妃子的姓名並顯示基本信息,被選中的妃子寵幸度加 10 點.其他妃子寵愛度減10點
5.巡視後宮-完成
    巡視後宮,顯示所有在宮妃子信息
6.遊戲規則判定-完成
	1.若有三名妃子寵愛度處於50以下則發生暴動,遊戲結束
    2.若有人寵愛度達到100,鎮壓後宮,遊戲結束

第三天,今天基本把合格項目做完了,爲什麼說是基本,因爲還是有一些小問題需要處理,好了,廢話少說,今天遇到的坑和留下的問題都會放在下面的,完整代碼在最後

1.遊戲規則判定

其實這個判定模塊總共只寫了10分鐘,非常快,下面是代碼,兩個函數,一個函數判定一條規則,然後將返回值進行與運算,傳給最開始的while循環條件

//判定函數,失敗返回0,否則1
//不放完整代碼.需要最後看
int judege_1(concu *ptca, int *num);
int judege_2(concu *ptca, int *num);


int c, d; //控制,循環控制界面
while (d)//d是循環條件
{....
	switch{}
	d = judege_1(p, num) && judege_2(p, num);//!!!關鍵
	if (d == 0)
	{
	     printf("後宮暴動,遊戲失敗!");
	     printf("輸入任意鍵以退出.....\n");
	     scanf("%d", &c);
	 }
 }

2.選妃時進行甄別,防止姓名重複

之前做的時候沒有考慮到重複添加的問題,知道我自己無意間連續選了兩個同名的"妃",才發現這個問題,我的方法是在選妃以及寵愛度增減的之前再加一層判斷,如果發現同名,就直接退出這個函數,雖然有點繁瑣,但是也沒得辦法
下面是實現代碼

 for (int i = 0; i < n + 1; i++)
    {
        if (strcmp(p->name, ch) == 0)//P是一個數組指針 數組存儲的是結構體
        {
            printf("皇上,%s已經在宮中了呢!\n", ch);
            return 0;//直接用return退出函數
        }
        p++;
    }
    
//判斷是否在宮中
concu *p = ptca;
int a_count = 0; //不同名妃子計數器
for (int i = 0; i < n; i++)
{
   // printf("%s --- %s\n", p->name, a_name);
   if (strcmp(p->name, a_name) != 0)
     {
         a_count++;
      }
   // printf("%d\n", a_count);
   p++;
}
if (a_count == n)
  {
      printf(" %s 還不在宮中呢...\n", a_name);
      return 0;
  }

其實上面都是今天上午就做好的,但是一直有點煩惱,因爲在解決問題的過程中發現如果要去修改的話要對之前的代碼大動干戈在這個項目裏還好我變量名用的統一,因此只是改了一下每個子函數的返回類型和添加了一個判斷,可是自己感覺還是不滿意,這個項目算上註釋總共420行,不大也不小,但是邏輯還算簡單,由此可見在進行中大型項目之前進行構思,僞代碼實現多重要!!不要像我這樣一頭撲上來就寫代碼,也算是吃了教訓了,繼續加油!奧利給!

/*
後宮選妃系統
六大模塊:
    1.下旨選妃 -完成
        輸入一名新妃子的名字,新增加一位新的妃子,然後其他妃子的寵愛度減 10 點
    2.翻牌寵幸-完成
        輸入一名妃子的名字,翻牌寵幸其,增加其寵愛度10點,減少其他妃子寵愛度10點
    3.打入冷宮-完成
        輸入一名妃子的名字,刪除一位妃子,然後其他所有的妃子寵愛度加 10 點,若無此人則顯示虛驚一場
    4.朕的愛妃呢-完成
        查找妃子,輸入妃子的姓名並顯示基本信息,被選中的妃子寵幸度加 10 點.其他妃子寵愛度減10點
    5.巡視後宮-完成
        巡視後宮,顯示所有在宮妃子信息
    6.遊戲規則判定-未
妃子等級制(始皇制):
    一後
    三夫人
    九嬪
    二十七世婦
    八十一御女
遊戲規則:1.若有三名妃子寵愛度處於50以下則發生暴動,遊戲結束
        2.若有人寵愛度達到100,鎮壓後宮,遊戲結束
        3.每名妃子默認寵愛度70點
*/

#include <stdio.h>
#include <string.h>

typedef struct concubine
{
    char name[10];  //名字,最多十個字符
    int level;      //後宮等級
    int likability; //寵愛度
} concu;

//函數聲明
int addOne(concu *ptca, int *num);
int chooseOne(concu *ptca, int *num);
int forsakeOne(concu *ptca, int *num);
int findOne(concu *ptca, int *num);
void seeAll(concu *ptca, int *num);
int judege_1(concu *ptca, int *num);
int judege_2(concu *ptca, int *num);

//   遊戲規則判斷計數器1   冷宮總人數
int count = 0, leave = 0; //初始化總比不初始化好

int main(void)
{
    //存儲conu的(X可變長)數組
    concu concus[31];
    int n = 0, *num = &n; //存儲後宮妃子總數,使用指針方便更改!數字指針定義時需要&取地址
    concu *p;

    //後宮初始化,默認有三位妃子
    concu c1 = {"劉解憂", 1, 70};
    concu c2 = {"孫尚香", 1, 70};
    concu c3 = {"魚幼薇", 1, 70};
    concus[0] = c1;
    concus[1] = c2;
    concus[2] = c3;
    *num = 3;

    //選妃系統界面控制

    int c, d; //控制,循環控制界面
    while (d)
    {
        p = concus; //初始化指針
        printf("-------後宮選妃系統-------\n\
            四大模塊:\n\
                1.下旨選妃\n\
                2.翻牌寵幸\n\
                3.打入冷宮\n\
                4.朕的愛妃呢\n\
                5.後宮巡視\n\
                6.退出選妃系統\n\
            請輸入序號選擇功能:\n");

        scanf("%d", &c);
        switch (c)
        {
        case 1:
            // printf("1\n");
            addOne(p, num); //函數1
            printf("輸入任意鍵以繼續.....\n");
            scanf("%d", &c);
            break;
        case 2:
            // printf("2");
            chooseOne(p, num); //函數2
            printf("輸入任意鍵以繼續.....\n");
            scanf("%d", &c);
            break;
        case 3:
            // printf("3");
            forsakeOne(p, num); //函數3
            printf("輸入任意鍵以繼續.....\n");
            scanf("%d", &c);
            break;
        case 4:
            // printf("4");
            findOne(p, num); //函數4
            printf("輸入任意鍵以繼續.....\n");
            scanf("%d", &c);
            break;
        case 5:
            // printf("5");
            seeAll(p, num); //函數5
            printf("輸入任意鍵以繼續.....\n");
            scanf("%d", &c);
            break;
        case 6:
            printf("退出成功...\n");
            c = 0;
            break;
        default:
            printf("小主,查無此功能啊!\n");
            printf("輸入任意鍵以繼續.....\n");
            scanf("%d", &c);
            break;
        }

        d = judege_1(p, num) && judege_2(p, num);
        if (d == 0)
        {
            printf("後宮暴動,遊戲失敗!");
            printf("輸入任意鍵以退出.....\n");
            scanf("%d", &c);
        }
    }
}

//1.下旨選妃-輸入一名新妃子的名字,新增加一位新的妃子,然後其他妃子的寵愛度減 10 點
int addOne(concu *ptca, int *num)
{
    //根據輸入初始化一位妃子的信息
    char ch[10];
    int lev;
    printf("請輸入妃子姓名,等級(1-5)(空號間隔):\n");
    scanf("%s %d", ch, &lev);
    concu c;
    strcpy(c.name, ch);
    c.level = lev;
    c.likability = 70;
    int n = *num; //臨時數量控制器,操縱循環
    //使用遍歷完成下旨選妃中的操作
    concu *p = ptca;
    for (int i = 0; i < n + 1; i++)
    {
        if (strcmp(p->name, ch) == 0)
        {
            printf("皇上,%s已經在宮中了呢!\n", ch);
            return 0;
        }
        p++;
    }
    for (int i = 0; i < n + 1; i++)
    {

        if (i < *num)
        {
            ptca->likability -= 10;
            ptca++;
        }
        else
        {
            *ptca = c;
            *num += 1; //總數加一
            printf("恭喜選妃成功;妃子信息:姓名:%s,等級:%d,寵愛度:%d\n", ptca->name, ptca->level, ptca->likability);
            // printf("當前後宮總人數:%d\n", *num);
        }
    }
}

//2.翻牌寵幸-輸入一名妃子的名字,翻牌寵幸其,增加其寵愛度10點,減少其他妃子寵愛度10點
int chooseOne(concu *ptca, int *num)
{
    int n = *num; //臨時變量,控制循環
    char a_name[10];

    //準備翻牌
    printf("皇上,可以翻牌了呢,輸入想翻牌的妃子名字即可:\n");
    scanf("%s", a_name);
    // gets(name);
    // printf("1");
    // int i = 0;
    printf("當前即將被翻牌的妃子名稱是 %s ...\n", a_name);

    //判斷是否在宮中
    concu *p = ptca;
    int a_count = 0; //不同名妃子計數器
    for (int i = 0; i < n; i++)
    {
        // printf("%s --- %s\n", p->name, a_name);
        if (strcmp(p->name, a_name) != 0)
        {
            a_count++;
        }
        // printf("%d\n", a_count);
        p++;
    }
    if (a_count == n)
    {
        printf(" %s 還不在宮中呢...\n", a_name);
        return 0;
    }

    printf("\n");
    for (int i = 0; i < n; i++)
    {
        if ((strcmp(a_name, (ptca->name)) == 0)) //判斷名字是否相等,相等返回0
        {
            ptca->likability += 10;
            printf(" %s 翻牌成功!\n", ptca->name);
        }
        else
        {
            ptca->likability -= 10;
            printf("後宮徒生嫉妒, %s 寵愛度減少10點!\n", ptca->name);
        }
        ptca++; //指針指向下一個結構體
    }
};

//3.打入冷宮-輸入一名妃子的名字,刪除一位妃子,然後其他所有的妃子寵愛度加 10 點,若無此人則顯示虛驚一場
int forsakeOne(concu *ptca, int *num)
{
    int n = *num; //臨時變量,控制循環
    char a_name[10];
    concu c;
    strcpy(c.name, "0");
    c.level = 0;
    c.likability = 0;

    //準備翻牌
    printf("皇上,您要拋棄哪位妃子呢,輸入妃子名字即可:\n");
    scanf("%s", a_name);
    // gets(name);
    // printf("1");
    int i = 0;
    printf("當前即將被即將被打入冷宮的妃子名稱是 %s ...", a_name);

    //判斷是否在宮中
    concu *p = ptca;
    int a_count = 0; //不同名妃子計數器
    for (int i = 0; i < n; i++)
    {
        // printf("%s --- %s\n", p->name, a_name);
        if (strcmp(p->name, a_name) != 0)
        {
            a_count++;
        }
        // printf("%d\n", a_count);
        p++;
    }
    if (a_count == n)
    {
        printf(" %s 還不在宮中呢...\n", a_name);
        return 0;
    }

    printf("\n");
    for (int i = 0; i < n; i++)
    {

        if ((strcmp(a_name, (ptca->name)) == 0)) //判斷名字是否相等,相等返回0
        {
            *ptca = c;
        }
        else
        {
            ptca->likability += 10;
            printf("因 %s 被打入冷宮, %s寵愛度增加10點!\n", a_name, ptca->name);
        }

        ptca++; //指針指向下一個結構體
    }
};

//4.朕的愛妃呢-查找妃子,輸入妃子的姓名並顯示基本信息,被選中的妃子寵幸度加 10 點.其他妃子寵愛度減10點
int findOne(concu *ptca, int *num)
{
    int n = *num; //臨時變量,控制循環
    char a_name[10];
    printf("皇上您要查找哪一位妃子呢,輸入名字即可:\n");
    scanf("%s", a_name);
    printf("當前要查找的妃子是%s....\n", a_name);

   //判斷是否在宮中
    concu *p = ptca;
    int a_count = 0; //不同名妃子計數器
    for (int i = 0; i < n; i++)
    {
        // printf("%s --- %s\n", p->name, a_name);
        if (strcmp(p->name, a_name) != 0)
        {
            a_count++;
        }
        // printf("%d\n", a_count);
        p++;
    }
    if (a_count == n)
    {
        printf(" %s 還不在宮中呢...\n", a_name);
        return 0;
    }

    //在遍歷中尋找符合要求的妃子並打印信息
    for (int i = 0; i < n; i++)
    {

        if ((strcmp(a_name, (ptca->name)) == 0))
        {
            printf("姓名\t等級\t寵愛度\t\n");
            printf("%s\t", ptca->name);
            //打印等級,並用中文替代
            switch (ptca->level)
            {
            case 1:
                printf("御女\t");
                break;
            case 2:
                printf("世婦\t");
                break;
            case 3:
                printf("嬪\t");
                break;
            case 4:
                printf("夫人\t");
                break;
            case 5:
                printf("後\t");
                break;
            default:
                printf("0\t");
                break;
            }
            //打印寵愛度
            printf("%d\n", ptca->likability);
        }
        ptca++;
    }
};

//5.巡視後宮,打印所有妃子信息,跳過被打入冷宮的妃子信息
void seeAll(concu *ptca, int *num)
{
    int n = *num; //臨時變量控制循環
    printf("-----------------------------------------\n");
    printf("姓名\t等級\t寵愛度\t\n");
    for (int i = 0; i < n; i++)
    {
        if (ptca->level != 0)
        {
            //打印姓名
            printf("%s\t", ptca->name);
            //打印等級,並用中文替代
            switch (ptca->level)
            {
            case 1:
                printf("御女\t");
                break;
            case 2:
                printf("世婦\t");
                break;
            case 3:
                printf("嬪\t");
                break;
            case 4:
                printf("夫人\t");
                break;
            case 5:
                printf("後\t");
                break;
            default:
                printf("0");
                break;
            }
            //打印寵愛度
            printf("%d\n", ptca->likability);
        }
        ptca++;
    }
};

//6.1.若有三名妃子寵愛度處於50以下則發生暴動,遊戲結束
int judege_1(concu *ptca, int *num)
{
    int n = *num; //臨時變量,控制循環
    count = 0;    //計數器清0

    //循環  計數器
    for (int i = 0; i < n; i++)
    {
        if (ptca->likability < 50)
        {
            count++;
        }
    }

    //判斷
    if (count >= 3)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

//6.2.若有人寵愛度達到100,鎮壓後宮,遊戲結束
int judege_2(concu *ptca, int *num)
{
    int n = *num; //臨時變量,控制循環

    //循環  計數器
    for (int i = 0; i < n; i++)
    {
        if (ptca->likability >= 100)
        {
            return 0;
        }
    }
    return 1;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章