c - 输入所需的骰子数后,我的 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;
}
解决方案
推荐阅读
- scipy - Dymos: How to call solve_ivp method explicitly for solving Dynamics Equations?
- tensorflow - Dot product between constant vector and variable with batch size in Tensorflow
- c++ - 在 C++ 中创建一个 char 指针向量
- python - Patch wise feature vector comparison
- angular - 将数据从组件传递到对话框,但不是 2 路模型绑定
- heap - Do I have to make the possibilities of position of 4th minimum?
- java - Java trying to build a countdown but integer always returns 0
- sql - 如何比较oracle数据库中的两个日期
- android - Uploading images/files inside a PWA from PWABuilder
- angular - how to access another view and it's feature on separate screen through angular portal?