首页 > 解决方案 > 输入所需的骰子数后,我的 Yatzee 游戏代码将无法继续运行?

问题描述

我正在为我的编程课做这个作业,这是一个 Yatzee/Yatzy 的游戏。它编译得很好,没有问题,我可以输入我想要的模具数量,当我输入时,程序就会自行结束,我不知道该怎么办......帮助。它在 C 中。

这是我编译运行程序时的编译器截图

    #include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <string.h>


#define DIES_YATZY 5
#define DIE_MAXEYES 6
#define MAX_POINTS_STRUCT 12

#define STEP(function, round)                   \
    roll_dies(dies, n);                         \
    points = function;                          \
    round_insert(rows, round, points, dies, n); \
    total += points

#define MAX(a, b) ((a) < (b) ? (b) : (a))


struct round
{
    char point[MAX_POINTS_STRUCT];
    char *dies;
};

enum rounds_enum
{
    HEADER_R,
    //UPPER SECTION:
    ONE_R,
    TWO_R,
    THREE_R,
    FOUR_R,
    FIVE_R,
    SIX_R,
    SUMS_R,
    BONUS_R,

    //LOWER SECTION:
    ONE_PAIR_R,
    TWO_PAIR_R,
    THREE_OF_A_KIND_R,
    FOUR_OF_A_KIND_R,
    SMALL_STRAIGHT_R,
    LARGE_STRAIGHT_R,
    FULL_HOUSE_R,
    CHANCE_R,
    YATZY_R,
    TOTAL_POINTS_R,
    MAX_ROUNDS,

};

enum table_char
{
    HORIZONTAL,
    VERTICAL,
    DOWN_AND_RIGHT,
    DOWN_AND_LEFT,
    UP_AND_RIGHT,
    UP_AND_LEFT,
    VERTICAL_AND_RIGHT,
    VERTICAL_AND_LEFT,
    DOWN_AND_HORIZONTAL,
    UP_AND_HORIZONTAL,
    VERTICAL_AND_HORIZONTAL,
    MAXI
};

static const char *const ROUND_NAMES[MAX_ROUNDS] = {
    /* Header */
    "Round",

    //UPPER SECTION
    "Ones",
    "Twos",
    "Threes",
    "Fours",
    "Fives",
    "Sixes",
    "Sum",
    "Bonus",

    //LOWER SECTION
    "One Pair",
    "Two Pairs",
    "Three of a Kind",
    "Four of a Kind",
    "Small Straight",
    "Large Straight",
    "Full House",
    "Chance",
    "Yatzy",
    "Total"};

static const char *const ROUND_MAXES[MAX_ROUNDS] = {
    /* Header */
    "Max",

    //UPPER SECITION
    "5",   /* Ones */
    "10",  /* Twos */
    "15",  /* Threes */
    "20",  /* Fours */
    "25",  /* Fives */
    "30",  /* Sixes */
    "105", /* Sum */
    "50",  /* Bonus */

    //LOWER SECTION
    "12", /* One Pair */
    "22", /* Two Pairs */
    "18", /* Three of a Kind */
    "24", /* Four of a kind */
    "15", /* Small Straight */
    "20", /* Large Straight */
    "28", /* Full House */
    "30", /* Chance */
    "50", /* Yatzy */
    "374" /* Total */
};


char *string_dupli(const char *const str);
int upper_section(int dies[], const size_t, struct round rounds[MAX_ROUNDS]);

int lower_section(int dies[], const size_t n, int points, struct round rounds[MAX_ROUNDS]);

void round_insert(struct round rounds[MAX_ROUNDS], const enum rounds_enum section, const int points, const int dies[], const size_t n);

void printf_round(struct round rounds[MAX_ROUNDS]);
void free_round(struct round rounds[MAX_ROUNDS]);

void roll_dies(int dies[], const size_t n);

int number_count(const int dies[], const size_t n, const int num);

int number_of_kinds(const int dies[], const size_t n, const int num);
int pairs_of_two(const int dies[], const size_t n);
int straight_up(const int dies[], const size_t n, const int straight_up_array[DIES_YATZY]);
int fuld_house(const int dies[], const size_t n);

int yaaatzy(const int dies[], const size_t n);

int dies_of_round(const enum rounds_enum round_id);
void printf_mellem(const char *chars[MAXI],
                   const enum table_char left,
                   const enum table_char cross,
                   const enum table_char right,
                   const size_t round_length,
                   const size_t round_maxi_length,
                   const size_t points_length,
                   const size_t dies_length);

void printf_filled(const char *const str, const size_t length);


void number_of_eyes(const int dies[], const size_t n, int eyes[DIE_MAXEYES]);
int sum_up(const int array[], const size_t n);
int int_rev_cmp(const void *const a, const void *const b);
void printf_times(const char *const str, const size_t n);

int main(void)
{
    struct round rounds[MAX_ROUNDS];
    int *dies;
    int n;
    int points;

    strcpy(rounds[HEADER_R].point, "Points");

    srand((unsigned int)time(NULL));

    while (1)
    {
        printf("Input your desired number of dies, game will end if your input is lower than %d: ", DIES_YATZY);
        fflush(stdout);

        if (scanf("%d", &n) != 1)
        {
            fprintf(stderr, "Error\n");
            return EXIT_FAILURE;
        }

        if (n < DIES_YATZY)
        {
            return EXIT_SUCCESS;
        }

        rounds[HEADER_R].dies = string_dupli("Dice rolls");

        dies = (int *)malloc((size_t)n * sizeof(dies[0]));

        points = upper_section(dies, (size_t)n, rounds);
        points = lower_section(dies, (size_t)n, points, rounds);

        round_insert(rounds, TOTAL_POINTS_R, points, dies, (size_t)n);

        printf_round(rounds);

        free_round(rounds);
        free(dies);
    }

    return EXIT_SUCCESS;
}

char *string_dupli(const char *const str)
{
    size_t len;
    char *duplied_string;

    len = strlen(str);

    duplied_string = (char *)malloc(len + 1);

    strcpy(duplied_string, str);

    return duplied_string;
}

int upper_section(int dies[], const size_t n, struct round rows[MAX_ROUNDS])
{
    enum rounds_enum i;
    int points, total = 0;

    for(i = ONE_R; i <= SIX_R; i++) {STEP(number_count(dies, n, (int)i), i);}

    round_insert(rows, SUMS_R, total, dies, n);

    points = total >= 63 ? 50 : 0;
    round_insert(rows, BONUS_R, points, dies, n);

    total += points;

    return total;
}

int lower_section(int dies[], const size_t n, int total, struct round rows[MAX_ROUNDS])
{
    int points;
    const int small_straight[DIES_YATZY] = {1, 2, 3, 4, 5};
    const int large_straight[DIES_YATZY] = {2, 3, 4, 5, 6};

     STEP(number_of_kinds(dies, n, 2), ONE_PAIR_R);
     STEP(pairs_of_two(dies, n), TWO_PAIR_R);
     STEP(number_of_kinds(dies, n, 3), THREE_OF_A_KIND_R);
    STEP(number_of_kinds(dies, n, 4), FOUR_OF_A_KIND_R);
    STEP(straight_up(dies, n, small_straight), SMALL_STRAIGHT_R);
    STEP(straight_up(dies, n, large_straight), LARGE_STRAIGHT_R);
    STEP(fuld_house(dies, n), FULL_HOUSE_R);
    
    STEP(yaaatzy(dies, n), YATZY_R);

    return total;
}

void round_insert(struct round rounds[MAX_ROUNDS], const enum rounds_enum round_id, const int points, const int dies[], const size_t n)
{
    size_t dies_str_size;
    size_t i;
    char *cur;
    const char *str = " ";

    struct round round_struct;
    sprintf(round_struct.point, "%d", points);

    dies_str_size = n * 2 - 1;

    round_struct.dies = (char *)malloc(dies_str_size + 1);
    cur = round_struct.dies;

    for(i = 0; i < n; i++)
    {
        sprintf(cur, "%d%s", dies[i], str);
        if (i == n - 2)
        cur += 2;
    }
    rounds[round_id] = round_struct;
}

void printf_round(struct round rounds[MAX_ROUNDS])
{
    struct round rnd;
    size_t round_len = 0;
    size_t max_len = 0;
    size_t points_len = 0;
    size_t dies_len = 0;
    enum rounds_enum i;
    const char **chars = 0;
    
    for(i = HEADER_R; i < MAX_ROUNDS; i++)
    {
        rnd = rounds[i];

        round_len = MAX(round_len, strlen(ROUND_NAMES[i]));
        max_len = MAX(max_len, strlen(ROUND_MAXES[i]));
        points_len = MAX(points_len, strlen(rnd.point));
        if (dies_of_round(i)) {dies_len = MAX(dies_len, strlen(rnd.dies));}

    }

    for(i = HEADER_R; i < MAX_ROUNDS; i++)
    {
        rnd = rounds[i];

       if(i == HEADER_R)
       {
           printf_mellem(chars, DOWN_AND_RIGHT, DOWN_AND_HORIZONTAL, DOWN_AND_LEFT, round_len, max_len, points_len, dies_len);

       }

          printf("%s ", chars[VERTICAL]);
    printf_filled(ROUND_NAMES[i], round_len);

    printf(" %s ", chars[VERTICAL]);
    printf_filled(ROUND_MAXES[i], max_len);

    printf(" %s ", chars[VERTICAL]);
    printf_filled(rnd.point, points_len);

    printf(" %s ", chars[VERTICAL]);
    printf_filled(dies_of_round(i) ? rnd.dies : "", dies_len);
    printf(" %s\n", chars[VERTICAL]);


       if (i != TOTAL_POINTS_R) {
        printf_mellem(chars, VERTICAL_AND_RIGHT, VERTICAL_AND_HORIZONTAL, VERTICAL_AND_LEFT, round_len, max_len, points_len, dies_len);
    } else {
      printf_mellem(chars, UP_AND_RIGHT, UP_AND_HORIZONTAL, UP_AND_LEFT, round_len, max_len, points_len, dies_len);
    }
  }
    
}

void free_round(struct round rounds[MAX_ROUNDS])
{
    enum rounds_enum i;
    for (i = HEADER_R; i < MAX_ROUNDS; i++) {free(rounds[i].dies);}

}

void roll_dies(int dies[], const size_t n)
{
    size_t i;
    for(i = 0; i < n; i++) {dies[i] = (rand() % DIE_MAXEYES) + 1; }
}

int number_count(const int dies[], const size_t n, const int number)
{
    int count[DIE_MAXEYES];

    number_of_eyes(dies, n, count);

    return count[number - 1] > DIES_YATZY ? number * DIES_YATZY
                                        : count[number - 1] * number;

}

int two_pairs(const int dies[], const size_t n)
{
  int count[DIE_MAXEYES];
  int i;
  int found_pairs = 0;
  int points = 0;

  number_of_eyes(dies, n, count);


  /* Finds pairs if it has found 2 return points */
  for (i = DIE_MAXEYES - 1; i >= 0; i--) {
    if (count[i] >= 2) {
      points += (i + 1) * 2;
      found_pairs++;

      if (found_pairs == 2) { return points; }
    }
  }

  return 0;
}

/* Awards points for the small straight and large straight rounds */
int straight_up(const int dies[],
  const size_t n,
  const int straight_up_array[DIES_YATZY])
{
  int count[DIE_MAXEYES];
  int i, found = 1;

  number_of_eyes(dies, n, count);

  for (i = 0; i < 5; i++) {
    if (count[straight_up_array[i] - 1] == 0) {
      found = 0;
      break;
    }
  }

  if (found) { return sum_up(straight_up_array, 5); }

  return 0;
}

/* Awards points for the full house round */
int fuld_house(const int dies[], const size_t n)
{
  int i;
  int count[DIE_MAXEYES];

  int found_three = 0;
  int found_what = -1;

  number_of_eyes(dies, n, count);

  for (i = DIE_MAXEYES - 1; i >= 0; i--) {
    if (count[i] >= 3) {
      found_what = i;
      found_three = 1;
      break;
    }
  }

  if (found_three) {

    for (i = DIE_MAXEYES - 1; i >= 0; i--) {
      if (found_what != i && count[i] >= 2) {
        return (found_what + 1) * 3 + (i + 1) * 2;
      }
    }
  }

  return 0;
}




/* Awards points for the yatzy round */
int yaaatzy(const int dies[], const size_t n)
{
  if (number_of_kinds(dies, n, DIES_YATZY) == 0) { return 0; }
  return 50;
}

int number_of_kinds(const int dies[], const size_t n, const int num)
{
  int i;
  int counts[DIE_MAXEYES];

  number_of_eyes(dies, n, counts);


  for (i = DIE_MAXEYES - 1; i >= 0; i--) {
    if (counts[i] >= num) { return (i + 1) * num; }
  }

  return 0;
}

int pairs_of_two(const int dies[], const size_t n)
{
  int counts[DIE_MAXEYES];
  int i;
  int found_pairs = 0;
  int points = 0;

  number_of_eyes(dies, n, counts);


  /* Finds pairs if it has found 2 return points */
  for (i = DIE_MAXEYES - 1; i >= 0; i--) {
    if (counts[i] >= 2) {
      points += (i + 1) * 2;
      found_pairs++;

      if (found_pairs == 2) { return points; }
    }
  }

  return 0;
}

int dies_of_round(const enum rounds_enum rnd)
{
    return !(rnd == SUMS_R || rnd == BONUS_R || rnd == TOTAL_POINTS_R);

}

void printf_mellem(const char *chars[MAXI], const enum table_char left, const enum table_char cross, const enum table_char right, const size_t round_len, const size_t max_len, const size_t points_len, const size_t dies_len)
{
    printf("%s%s", chars[left], chars [HORIZONTAL]);
    
    printf_times(chars[HORIZONTAL], round_len);
    
    printf("%s%s%s", chars[HORIZONTAL], chars[cross], chars[HORIZONTAL]);
    printf_times(chars[HORIZONTAL], points_len);

    printf("%s%s%s", chars[HORIZONTAL], chars[cross], chars[HORIZONTAL]);
    printf_times(chars[HORIZONTAL], max_len);

    printf("%s%s%s", chars[HORIZONTAL], chars[cross], chars[HORIZONTAL]);
    printf_times(chars[HORIZONTAL], dies_len);
}

void printf_times(const char *const str, const size_t n)
{
    size_t i;
    for(i = 0; i < n; i++) {printf("%s", str);}
}

int int_rev_cmp(const void *const a, const void *const b)
{
    return *(const int *const)b - *(const int *const)a;

}

void printf_filled(const char *const str, const size_t length)
{
  size_t str_len;

  str_len = strlen(str);

  printf("%s", str);

  printf_times(" ", length - str_len);
}

void number_of_eyes(const int dies[], const size_t n, int eyes[DIE_MAXEYES])
{
  size_t i;
  int die;

  /* Set everything to 0 */
  memset(eyes, 0, DIE_MAXEYES * sizeof(eyes[0]));

  /* Count the sides */
  for (i = 0; i < n; i++) {
    die = dies[i];
    assert(die >= 1 && die <= 6);
    eyes[dies[i] - 1]++;
  }
}

int sum_up(const int arr[], const size_t n)
{
  size_t i;
  int sum = 0;

  for (i = 0; i < n; i++) { sum += arr[i]; }

  return sum;
}

标签: c

解决方案


推荐阅读