C++語言課程設計之最偉大的puzzle

需求分析
1 . 任務
此次程序設計的任務是要求學生將所學的 C 語言知識運用到具體的課程設計裏面,而這次需要解決的問題就是誰是最偉大 puzzle 這個問題,此次程序要求學生利用數據結構,文件, C 語言等研究出在 1000 次射擊裏面誰是贏家,並且將每次的結果輸出到指定的文件中
2 . 規定
(1). 輸入的形式和輸入值的範圍:輸入的數據類型只有整型和字符型, n 的值只有輸入 1 或 2 ,程序纔會運行得出結果,否則將提示出錯。當提示是否嘗試另一種遊戲方法時,只有輸入 y , Y 或 n , N 程序纔會正常運行,否則將提示出錯。
( 2 ) 輸出形式:當輸入的 n 值爲 1 或 2 時,將會輸出正確的結果,即三個人在一千次遊戲當中各自獲勝的概率,若用戶輸入其它數值,將輸出一語句提示用戶輸入錯誤。在以一種方法進行了遊戲之後,將輸出提示語句,提示用戶是否繼續以另一種遊戲方法再進行一次遊戲,這時若用戶輸入 y 或 Y ,則界面將會提示用戶再一次輸入 n 值,若輸入 n 或 N ,則輸出一語句提示遊戲結束,若輸入其它的字符,則提示輸入錯誤。
( 3 ) 程序所能達到的功能: a. 模擬一次射擊的過程; b. 模擬一次整個遊戲的循環過程; c. 進行一千次遊戲,並將每個遊戲參與者最後獲勝的概率輸出; d. 能將遊戲方法的標誌,即 n 值,以及每次遊戲的結果,還有最後每個人獲勝的概率,記錄入指定的文件當中; e. 當輸入的數據不符合要求是,程序會輸出語句提示用戶輸入錯誤; f. 當以一種遊戲方法進行了遊戲時,程序會提示用戶是否以另一種遊戲方法進行遊戲。
( 4 ) 初步的測試計劃:按如下順序進行: a. 輸入 n 值爲 1 ,以測試第一種遊戲方法; b. 輸入 y 或 Y 繼續進行,接着輸入 n 值爲 2 ,以測試第二種遊戲方法; c. 輸入 n 值爲 3 ,以測試當輸入的 n 值不符合要求時程序的反應 .
三 概要設計
1 . 所有數據類型的定義及含義:
shooting :定義爲實型,含義是 0 到 1 的隨機數。 Winner :整型,用於標誌每次遊戲的結果,即獲勝者。 Player :整型,用於記錄人數。 Alive , Bob , Charlie :都是整型,且值只有 1 或 0 ,分別用於標誌三個人的死活。 a , b , c :整型的指針變量,分別指向 Alive , Bob , Charlie ,用於賦值給函數 shoot 的形參,表示被射擊的人。 n :整型變量,值只能是 1 或 2 ,用於標誌遊戲方法。 A , B , C :整型變量,分別用於記錄三個人在一千次遊戲當中獲勝的次數。 j :整型,用於一千次遊戲的計數器。 k :字符型變量,用於標誌遊戲是否繼續進行。 fp1 :指向結構體的指針變量,用於標誌指定的文件。 Player1 , Player2 , Player3 :實型變量,用於記錄每個人獲勝的概率。
2 . 函數的調用關係圖:
在這裏插入圖片描述
3 . 個程序模塊的功能:
void shoot ( int *targetAlive, double accuracy ) :模擬一次射擊過程,電腦產生一個 0 到 1 的隨機數,若此隨機數小於射擊者的概率,則被射擊者死,反之則活。 int startDuel(int n) :模擬一次完整的遊戲循環過程。 main ():模擬一千次遊戲過程,並對每個人獲勝的概率進行記錄。
4 . 各模塊之間的層次(調用)關係:
shoot 函數是一個獨立的函數。 startDuel 函數包含了 shoot 函數,其中若干次調用了 shoot 函數。 main 函數又包含了 startDuel 函數,其間一千次調用了 startDuel 函數。
在這裏插入圖片描述

#include<fstream>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <iostream>
using namespace std;
void shoot(int* targetAlive, double accuracy)/* 此函數模擬一次射擊過程 */
{
    int shooting;
    shooting = rand() / 100;/* 產生 0 到 1 的隨機數 */
    if (shooting < accuracy)
        *targetAlive = 0;/* 隨機數小於概率,該人死亡 */
    else
        *targetAlive = 1;/* 隨機數大於概率,該人活着 */
}
int startDuel(int n)/* 此函數模擬一次完整的遊戲過程 */
{
    int winner, player = 3;
    int Alive = 1, Bob = 1, Charlie = 1;/* 定義三個整型變量,並賦初值爲 1 ,表示每個人初始階段都是活着 */
    int* a, * b, * c;
    a = &Alive;
    b = &Bob;
    c = &Charlie;
    if (n == 1)/* 常規的遊戲方法, A 先打 */
    {
        shoot(c, 0.33);/*A 先打 C*/
        if (Charlie == 0)/* 若 C 被 A 打死,則進入 A 與 B 互打的循環,直到 A 與 B 之間只剩一人 */
        {
            player--;
            while (player > 1)
            {
                if (Bob && Alive)
                    shoot(a, 0.5);
                if (Alive == 0)
                    player--;
                else
                {
                    if (Bob && Alive)
                        shoot(b, 0.33);
                    if (Bob == 0)
                        player--;
                }
            }
        }
        else/* 若 C 活着,則進行下列過程 */
        {
            shoot(c, 0.5);/*B 打 C*/
            if (Charlie)/* 若 C 活着,則進行下列過程 */
            {
                shoot(b, 1.0); player--;/*C 打 B , B 肯定死,人數減一 */
                shoot(c, 0.33);/* 輪到 A 打 C*/
                if (Charlie == 0)
                    player--;/* 若 C 死,人數減一 */
                else
                {
                    shoot(a, 1.0);/* 若 C 活着,則 C 打 A , A 肯定死,人數減一 */
                    player--;
                }
            }
            else/* 若 C 被 B 打死,則進入 A 與 B 互打的循環,直到 A 與 B 之間只剩一人 */
            {
                while (player > 1)
                {
                    if (Alive && Bob)
                        shoot(b, 0.33);
                    if (Bob == 0)
                        player--;
                    else
                    {
                        if (Alive && Bob)
                            shoot(a, 0.5);
                        if (Alive == 0) player--;
                    }
                }
            }
        }

        if (Alive) winner = 1;/* 用 winner 標誌遊戲的結果 */
        if (Bob) winner = 2;
        if (Charlie) winner = 3;
        return winner;
    }
    else if (n == 2)/* 反常規遊戲方法, B 先打 */
    {
        shoot(c, 0.5);/*B 打 C*/
        if (Charlie == 0)/* 若 C 死,則進入 A 與 B 互打的循環,直到 A 與 B 之間只剩一人 */
        {
            while (player > 1)
            {
                if (Alive && Bob)
                    shoot(b, 0.33);
                if (Bob == 0)
                    player--;
                else
                {
                    if (Alive && Bob)
                        shoot(a, 0.5);
                    if (Alive == 0) player--;
                }
            }
        }
        else/* 若 C 活着,則進行下列過程 */
        {
            shoot(b, 1.0); player--;/*C 打 B , B 必死,人數減一 */
            shoot(c, 0.33);/* 輪到 A 打 C*/
            if (Charlie == 0) player--;/* 若 C 死,人數減一 */
            else
            {
                shoot(a, 1.0); player--;/* 若 C 活着,則 C 打 A , A 必死,人數減一 */
            }
        }
        if (Alive) winner = 1;/* 用 winner 標誌遊戲結果 */
        if (Bob) winner = 2;
        if (Charlie) winner = 3;
        return winner;
    }
}

int main()
{

    int A = 0, B = 0, C = 0, j, winner;
    int n;
    char k;
    float player1, player2, player3;
    // FILE* fp1; /* 定義一個指向文件的 FILE 型指針 */
    ofstream OutFile;            //實例一個寫文件對象
    cout << endl;

    cout << "\t\t-----The Greatest Puzzle,the wonderful game----\n" << endl;

    cout << "please input n(normal: n=1 ; unnormal: n=2):";

    cin >> n;
    if (n != 1 && n != 2)/* 若輸入的 n 不是 1 或 2 ,則提示用戶輸入錯誤並重新輸入 */
        cout << "Your input is error!Please try it again!";
    else
    {
        rand();/* 此函數使每次產生的隨機數不同 */
        OutFile.open("outfile.txt");
        if (!OutFile.is_open())/* 建立並打開一個只寫的字符文件 */
        {
            cout << "file cannot be open\n";
            exit(1);/* 打開文件不成功則退出 */
        }
        OutFile << n << endl;/* 把 n 的值記錄入文件 */
        for (j = 1; j <= 1000; j++)/* 一千次調用整個遊戲過程的函數 */
        {
            winner = startDuel(n);
            if (winner == 1) A++;/* 用 A , B , C 分別記錄三個人贏的次數 */
            if (winner == 2) B++;
            if (winner == 3) C++;
            OutFile << " " << endl;
            OutFile << "\nDi " << j <<" ci winner is  :\t "<< winner;/* 把每次的遊戲結果記錄入 fp1 指定的文件當中 */
            OutFile << "\n";
        }
        player1 = (float)A / 1000;
        player2 = (float)B / 1000;
        player3 = (float)C / 1000;
        cout << "player1 is " << player1 << " player2 is" << player2 << " player3 is " << player3;/* 打印每個人贏的概率 */
        OutFile << " " << endl;
        OutFile << "\nplayer1 is: " << player1 << " player2 is" << player2 << "  player3 is:" << player3 << endl;/* 把每個人贏的概率記錄入指定的文件當中 */
        OutFile << endl;
        A = 0, B = 0, C = 0, j = 1;/* 進入另一遊戲方法,對計數器重新賦初值 */
        cout << "\n Do you want to play the other one(Y or N):";/* 提示用戶嘗試另一種遊戲方法 */
        k = getche();
        if (k == 'y' || k == 'Y')/* 若用戶輸入 y ,則進入另一種遊戲方法 */
        {
            cout << endl;
            cout << "please input n(normal: n=1 ; unnormal: n=2):";
            cin >> n;
            if (n != 1 && n != 2)
                cout << "Your input is error!Please try it again!";
            else
            {
                rand();
                OutFile.open("outfile.txt");
                if (!OutFile.is_open())/* 建立並打開一個只寫的字符文件 */
                {
                    cout << "file cannot be open\n";
                    exit(1);/* 打開文件不成功則退出 */
                }
                OutFile << "The n is: " << n;
                for (j = 1; j <= 1000; j++)
                {
                    winner = startDuel(n);
                    if (winner == 1) A++;
                    if (winner == 2) B++;
                    if (winner == 3) C++;
                    OutFile << " ";
                    OutFile << "\nDi " <<j<< "ci winner is  :\t " << winner;
                    OutFile << "\n";
                }
                player1 = (float)A / 1000;
                player2 = (float)B / 1000;
                player3 = (float)C / 1000;
                cout << "player1 is " << player1 << " player2 is" << player2 << " player3 is " << player3;
                OutFile << " ";
                OutFile << "\nplayer1 is: " << player1 << " player2 is" << player2 << "  player3 is:" << player3 << endl;
                OutFile << "\n";
            }
        }
        else if (k == 'n' || k == 'N')/* 若用戶輸入 n ,則遊戲結束 */
            {
                cout << endl;
                cout << "The game is over ,thank you for playing!";
            }
            else/* 若用戶輸入其他字符,則提示用戶輸入錯誤 */
            {
                cout << endl;
                cout << "your input is error!";
            }
        OutFile.close();/* 關閉文件 */
        return 1;/* 返回一個值 */
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章