2016-05-29 17 views
0

次の関数は、質問と回答のある種類のゲームの一部です。私は質問の複雑さによるランダム化に問題があります。いくつかの質問は複数回現れ、最初の質問もすべてのレベルに現れますが、これは起こるべきではありません。助けてください!リンクされたリストのノードをランダム化すると、Cプログラム

typedef struct 
{ 
    char question[300]; 
    char date[30], author[30], ansr1[80], ansr2[80], ansr3[80], ansr4[80]; 
    int id, correctAnsr, level; 
} game; 

typedef struct Node 
{ 
    game data; 
    struct Node* next; 
} node; 

void printRandom1(node *head) 
{ 
    if (isEmpty(head)) 
     return; 

    srand(time(NULL)); 

    node *result = head->data.question; 

    node *current = head; 
    int n; 
    for (n = 17; current != NULL; n++) 
    { 
     if (rand() % n == 0 && current->data.level == 0) 
      result = current->data.question; 
     current = current->next; 
    } 
    printf("%s\n", result); 
    int i, ans; 

    printf("1.-%s\n", result->data.ansr1); 
    printf("2.-%s\n", result->data.ansr2); 
    printf("3.-%s\n", result->data.ansr3); 
    printf("4.-%s\n", result->data.ansr4); 

    printf("Enter the correct answer: "); 
    scanf("%d", &ans); 
    if (ans == result->data.correctAnsr) 
     printf("CORRECT ANSWER!\n"); 
    else 
    { 
     printf("WRONG ANSWER\n"); 
     printf("GAME OVER"); 
     printf("The correct answer is: %d\n", result->data.correctAnsr); 
     return menu(); 
     exit(1); 
    } 
} 
+0

...これだけの例としてそれを取るしてくださいコードをチェックすることに多くの時間をかけていない=頭部> data.question。結果はノードポインタではなく、charポインタです。申し訳ありませんが、私は携帯電話に乗っていますが、バッククォートは見つかりませんでした。 – ELKA

+0

ありがとうございます。だから私はどのように回答のためのポインタを配置する必要があります。私は聞いて申し訳ありませんが、私は本当にこれで悪いです –

答えて

1

広告「いくつかの質問には回以上現れる」:あなたはとにかく使用質問を追跡していないためである - あなたのランダムな選択方法は、常に関係なく、すべての質問(のリストから選択し、彼らはすでにされている場合尋ねられたか否か)。

は、広告「は、最初にもあらゆるレベルに表示されます」:私の賭けはあなたのランダムな選択方法は、(非常に奇妙である)質問を選択することが保証されていないことである(result = current->data.question部分はかなり高い確率で実行されない可能性があり、すなわち)。この場合、最初の値はresultです(これが最初の質問です)。

以下は、コードの変更版です。いくつかの発言:

  • リンクリストの質問数を数えます。それは等しい確率で答えの中から選択ランダム選択のために必要とされている(正しいように - いくつかの無視でき偏りがあるが、ここではおそらく重要ではありません)

  • 使用答えは、新たなリンクリストで追跡され

  • レベルロジックは実装されていません。

  • current変数はリンク解除プロセスを簡略化するポインタです(以前のリンクを維持する必要はありません)。エントリポインタこうして)

コード:

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

typedef struct 
    { 
    char question[300]; 
    char date[30], author[30], ansr1[80], ansr2[80], ansr3[80], ansr4[80]; 
    int id, correctAnsr, level; 
} question; 

typedef struct questionListNode { 
    question data; 
    struct questionListNode* next; 
} questionListNode; 

typedef struct { 
    questionListNode* headAvailable; // Your former head variable 
    questionListNode* headUsed; // Initialize this to NULL 
    int numberOfAvailableNodes; // Number of nodes in headAvailable 
    int numberOfCorrectAnswers; // Number of nodes in headUsed 
} game; 

void printRandom1(game* currentGame) 
{ 
    if (currentGame->headAvailable == NULL || currentGame->numberOfAvailableNodes <= 0) { 
     printf("No more questions, you've won!\n"); 
     exit(1); 
    } 

    srand(time(NULL)); // Consider moving this to the start of main() 

    int chosenIndex = rand() % currentGame->numberOfAvailableNodes; 
    questionListNode** current = &(currentGame->headAvailable); 
    while ((chosenIndex > 0) && (*current != NULL)) { // the second check is for safety 
     current = &((*current)->next); 
     chosenIndex--; 
    } 

    questionListNode* currentQuestion = (*current); 
    if (currentQuestion == NULL) { 
     printf("Internal error: available count mismatch!\n"); 
     exit(1); 
    } 
    printf("%s\n", currentQuestion->data.question); 
    int i, ans; 

    printf("1.-%s\n", currentQuestion->data.ansr1); 
    printf("2.-%s\n", currentQuestion->data.ansr2); 
    printf("3.-%s\n", currentQuestion->data.ansr3); 
    printf("4.-%s\n", currentQuestion->data.ansr4); 

    printf("Enter the correct answer: "); 
    scanf("%d", &ans); 
    if (ans != currentQuestion->data.correctAnsr) { 
     printf("WRONG ANSWER\n"); 
     printf("GAME OVER\n"); 
     printf("The correct answer is: %d\n", currentQuestion->data.correctAnsr); 
     exit(1); 
    } 
    printf("CORRECT ANSWER!\n"); 
    // Remove currentQuestion from the available list 
    (*current) = currentQuestion->next; 
    // Put currentQuestion into used list 
    currentQuestion->next = currentGame->headUsed; 
    currentGame->headUsed = currentQuestion; 
    // Update counters 
    currentGame->numberOfAvailableNodes--; 
    currentGame->numberOfCorrectAnswers++; 
} 

int main(int c, char** t) 
{ 
    game g; 
    g.headAvailable = NULL; 
    g.headUsed = NULL; 
    g.numberOfAvailableNodes = 0; 
    g.numberOfCorrectAnswers = 0; 

    questionListNode q1 = { { "Question 1", "", "", "A1*", "B1", "C1", "D1", 1, 1, 0 }, NULL }; 
    questionListNode q2 = { { "Question 2", "", "", "A2", "B2*", "C2", "D2", 2, 2, 0 }, &q1 }; 
    questionListNode q3 = { { "Question 3", "", "", "A3", "B3*", "C3", "D3", 3, 2, 0 }, &q2 }; 

    g.headAvailable = &q3; 
    g.numberOfAvailableNodes = 3; 

    while (1) 
     printRandom1(&g); 
} 

いくつかの追加(ランダム)ノート:

  • 私はリンクリストが

  • は、いくつかの接頭辞であなたのtypedefを命名を検討し、このタスクのための最良のデータ構造であることを確認していない(例えば、あなたが(代わりにあなたが戻って一緒に2つのリンクリストに参加して、カウンターに

幸運をリセットする必要があります)exit()のゲームを再起動したい場合はt_gamet_node

  • 免責事項:私はノードの結果に

  • 関連する問題