Commit 7f36cc04 authored by Chris's avatar Chris
Browse files

disable hold and roll again options on the final roll

parent f417431a
Loading
Loading
Loading
Loading
+56 −23
Original line number Diff line number Diff line
@@ -130,27 +130,34 @@ unsigned int calculate_selection_score(game_context *ctx, char *selection) {
    } else if (strcasecmp(selection, "sixes") == 0) {
        ctx->game_state.scorecard.sixes = sum_dice_matching_value(ctx->game_state.dice, 6);
        points_awarded = ctx->game_state.scorecard.sixes;
    } else if (strcasecmp(selection, "three_of_a_kind") == 0) {
    } else if (strcasecmp(selection, "three of a kind") == 0) {
        // sum all dice if 3 of a kind match; 0 otherwise
        printf("not implemented, scoring 0 for now");
//        printf("not implemented, scoring 0 for now");
        if (n_of_a_kind(ctx->game_state.dice, NUM_DICE, 3)) {
            ctx->game_state.scorecard.three_of_a_kind = sum_dice(ctx->game_state.dice);
        } else {
            ctx->game_state.scorecard.three_of_a_kind = 0;
        }
        points_awarded = ctx->game_state.scorecard.three_of_a_kind;
    } else if (strcasecmp(selection, "four_of_a_kind") == 0) {
    } else if (strcasecmp(selection, "four of a kind") == 0) {
        // sum all dice if 4 of a kind match; 0 otherwise
        printf("not implemented, scoring 0 for now");
        if (n_of_a_kind(ctx->game_state.dice, NUM_DICE, 4)) {
            ctx->game_state.scorecard.four_of_a_kind = sum_dice(ctx->game_state.dice);
        } else {
            ctx->game_state.scorecard.four_of_a_kind = 0;
        }
        points_awarded = ctx->game_state.scorecard.four_of_a_kind;
    } else if (strcasecmp(selection, "full_house") == 0) {
    } else if (strcasecmp(selection, "full house") == 0) {
        // 25 points for a combination of three of one number + two of another; 0 otherwise
        printf("not implemented, scoring 0 for now");
        ctx->game_state.scorecard.full_house = 0;
        points_awarded = ctx->game_state.scorecard.full_house;
    } else if (strcasecmp(selection, "small_straight") == 0) {
    } else if (strcasecmp(selection, "small straight") == 0) {
        // 30 points for a sequence of four consecutive numbers; 0 otherwise
        printf("not implemented, scoring 0 for now");
        ctx->game_state.scorecard.small_straight = 0;
        points_awarded = ctx->game_state.scorecard.small_straight;
    } else if (strcasecmp(selection, "large_straight") == 0) {
    } else if (strcasecmp(selection, "large straight") == 0) {
        // 40 points for a sequence of five consecutive numbers; 0 otherwise
        printf("not implemented, scoring 0 for now");
        ctx->game_state.scorecard.large_straight = 0;
@@ -158,19 +165,19 @@ unsigned int calculate_selection_score(game_context *ctx, char *selection) {
    } else if (strcasecmp(selection, "yahtc") == 0) {
        // 50 points for five of a kind; 0 otherwise
        printf("not implemented, scoring 0 for now");
        if (n_of_a_kind(ctx->game_state.dice, NUM_DICE, NUM_DICE)) {
            ctx->game_state.scorecard.yahtc = 50;
        } else {
            ctx->game_state.scorecard.yahtc = 0;
        }
        points_awarded = ctx->game_state.scorecard.yahtc;
    } else if (strcasecmp(selection, "chance") == 0) {
        // sum of all dice
        printf("not implemented, scoring 0 for now");
        ctx->game_state.scorecard.chance = 0;
        ctx->game_state.scorecard.chance = sum_dice(ctx->game_state.dice);
        points_awarded = ctx->game_state.scorecard.chance;
    }

    printf("for selection %s, points awarded: %d\n", selection, points_awarded);

    // default
    return 0;
    return points_awarded;
}

unsigned int calculate_total_score(struct scorecard_st *scorecard) {
@@ -189,7 +196,6 @@ unsigned int calculate_total_score(struct scorecard_st *scorecard) {
            + (scorecard->chance >= 0 ? scorecard->chance : 0);
}


unsigned int can_continue_playing(struct scorecard_st *scorecard) {
    return scorecard->aces == SCORE_UNSCORED
           || scorecard->twos == SCORE_UNSCORED
@@ -206,7 +212,6 @@ unsigned int can_continue_playing(struct scorecard_st *scorecard) {
           || scorecard->chance == SCORE_UNSCORED;
}


void hold_dice_with_menu(struct die_st *dice, unsigned int num_dice) {
    menu_item dice_hold_selections[num_dice];
    for (int i = 0; i < num_dice; i++) {
@@ -246,11 +251,11 @@ char *get_player_score_selection_with_menu(struct scorecard_st *scorecard) {
            {.title = "fours", .command = "fours", .multi_selected = 0, .enabled = scorecard->fours == SCORE_UNSCORED},
            {.title = "fives", .command = "fives", .multi_selected = 0, .enabled = scorecard->fives == SCORE_UNSCORED},
            {.title = "sixes", .command = "sixes", .multi_selected = 0, .enabled = scorecard->sixes == SCORE_UNSCORED},
            {.title = "three of a kind", .command = "three_of_a_kind", .multi_selected = 0, .enabled = scorecard->three_of_a_kind == SCORE_UNSCORED},
            {.title = "four of a kind", .command = "four_of_a_kind", .multi_selected = 0, .enabled = scorecard->four_of_a_kind == SCORE_UNSCORED},
            {.title = "small straight", .command = "small_straight", .multi_selected = 0, .enabled = scorecard->small_straight == SCORE_UNSCORED},
            {.title = "large straight", .command = "large_straight", .multi_selected = 0, .enabled = scorecard->large_straight == SCORE_UNSCORED},
            {.title = "full house", .command = "full_house", .multi_selected = 0, .enabled = scorecard->full_house == SCORE_UNSCORED},
            {.title = "three of a kind", .command = "three of a kind", .multi_selected = 0, .enabled = scorecard->three_of_a_kind == SCORE_UNSCORED},
            {.title = "four of a kind", .command = "four of a kind", .multi_selected = 0, .enabled = scorecard->four_of_a_kind == SCORE_UNSCORED},
            {.title = "small straight", .command = "small straight", .multi_selected = 0, .enabled = scorecard->small_straight == SCORE_UNSCORED},
            {.title = "large straight", .command = "large straight", .multi_selected = 0, .enabled = scorecard->large_straight == SCORE_UNSCORED},
            {.title = "full house", .command = "full house", .multi_selected = 0, .enabled = scorecard->full_house == SCORE_UNSCORED},
            {.title = "yahtc", .command = "yahtc", .multi_selected = 0, .enabled = scorecard->yahtc == SCORE_UNSCORED},
            {.title = "chance", .command = "chance", .multi_selected = 0, .enabled = scorecard->chance == SCORE_UNSCORED},
    };
@@ -267,3 +272,31 @@ int sum_dice_matching_value(struct die_st *dice, unsigned int value) {
    }
    return sum;
}

int sum_dice(struct die_st *dice) {
    int sum = 0;
    for (unsigned int i = 0; i < NUM_DICE; i++) {
        sum += (int)dice[i].value;
    }
    return sum;
}

// I know this is uglier than it could be, but I don't have a hash map implementation in C and don't want to allocate the memory to track which values we've seen before.
// so this will be okay
unsigned int n_of_a_kind(struct die_st *dice, unsigned int num_dice, unsigned int n) {
    if (n > num_dice) {
        printf("n_of_a_kind(): error: n is greater than num_dice");
    }
    for (unsigned int i = 0; i < num_dice - 1; i++) {
        int num_dice_with_same_value = 1;
        for (unsigned int j = i + 1; j < num_dice; j++) {
            if (dice[i].value == dice[j].value) {
                num_dice_with_same_value++;
            }
            if (num_dice_with_same_value == n) {
                return 1;
            }
        }
    }
    return 0;
}
+3 −1
Original line number Diff line number Diff line
@@ -53,12 +53,14 @@ void roll_and_print(game_context *ctx, unsigned int *out_dice_values, unsigned i
void clear_held_values(game_context *ctx);
unsigned int can_continue_playing(struct scorecard_st *scorecard);
void hold_dice_with_menu(struct die_st *dice, unsigned int num_dice);
int sum_dice_matching_value(struct die_st *dice, unsigned int value);
int sum_dice(struct die_st *dice);

// scorecard functions
unsigned int calculate_selection_score(game_context *ctx, char *selection);
unsigned int calculate_total_score(struct scorecard_st *scorecard);
void initialize_scorecard(struct scorecard_st *scorecard);
char *get_player_score_selection_with_menu(struct scorecard_st *scorecard);
int sum_dice_matching_value(struct die_st *dice, unsigned int value);
unsigned int n_of_a_kind(struct die_st *dice, unsigned int num_dice, unsigned int n);

#endif //DICELOGIC_H
+11 −10
Original line number Diff line number Diff line
@@ -54,14 +54,7 @@ int main(void) {
unsigned int take_turn(game_context *ctx, unsigned int num_dice) {
    clear_held_values(ctx);
    unsigned int next_roll_dice_values[num_dice];
    const menu_item in_turn_menu[] = {
            {.title = "Hold dice", .command = "enter_hold_selection", .enabled = 1},
            {.title = "Roll again", .command = "roll", .enabled = 1},
            {.title = "Score", .command = "score", .enabled = 1},
            {.title = "End game", .command = "quit", .enabled = 1},
    };
    const unsigned int num_menu_items = sizeof(in_turn_menu) / sizeof(menu_item);
    for (unsigned int which_roll_number = ROLL_NUMBER_OFFSET; which_roll_number < ROLLS_PER_TURN; which_roll_number++) {
    for (unsigned int which_roll_number = ROLL_NUMBER_OFFSET; which_roll_number < ROLLS_PER_TURN + ROLL_NUMBER_OFFSET; which_roll_number++) {
        // print roll number
        printf("Roll %d\n", which_roll_number);
//        sleep_ms(1000);
@@ -74,17 +67,25 @@ unsigned int take_turn(game_context *ctx, unsigned int num_dice) {
        //      (also don't allow user to roll again if on the third roll)
        unsigned int ready_for_next_roll = 0;
        while (!ready_for_next_roll) {
            const menu_item in_turn_menu[] = {
                    {.title = "Hold dice", .command = "enter_hold_selection", .enabled = which_roll_number < 3},
                    {.title = "Roll again", .command = "roll", .enabled = which_roll_number < 3},
                    {.title = "Score", .command = "score", .enabled = 1},
                    {.title = "End game", .command = "quit", .enabled = 1},
            };
            const unsigned int num_menu_items = sizeof(in_turn_menu) / sizeof(menu_item);
            const char *player_action = menu_prompt(in_turn_menu, num_menu_items);
            if (strcasecmp(player_action, "enter_hold_selection") == 0) {
                // enter the menu for which dice to hold
                hold_dice_with_menu(ctx->game_state.dice, NUM_DICE);
            } else if (strcasecmp(player_action, "roll") == 0) {
                printf("Rolling again...\n");
//                printf("Rolling again...\n");
                ready_for_next_roll = 1;
            } else if (strcasecmp(player_action, "score") == 0) {
                // enter the score menu
                char *selection = get_player_score_selection_with_menu(&ctx->game_state.scorecard);
                calculate_selection_score(ctx, selection);
                unsigned int points_awarded = calculate_selection_score(ctx, selection); // todo we should use the return value for this to assign the point value, not do it within get_player_score_selection()
                printf("for selection %s, points awarded: %d\n", selection, points_awarded);
                return 0; // 0 signifies user_quit == false, which will move on to the next turn
            } else if (strcasecmp(player_action, "quit") == 0) {
                // todo this could be more robust or interactive. maybe add the final score?