dimanche 12 mars 2023

Extremely off output in a random number generating program

I am trying to make a rng program with three players mediator, user, and a computer. A User choses a word and a key to use within the game and the number of sides to each of the three sided dice. They all throw a dice which is ramdonly generated. Whichever players sum of their dice roll is less than the number rolled by the mediator, they accumulate a letter of the chosen word where they have the opportunity to not gain a character towards their word if they roll high enough. The game loops until whichever player accumulates enough letters that equal the chosen word. Then, the losing players word then gets "ciphered" and the game ends.

This is my code

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


void update_key(char* key, int key_len, char* word, int word_len) {
    // Create a new key by repeating the original key until it matches the word length
    int num_repetitions = word_len / key_len + 1;
    char* new_key = malloc(num_repetitions * key_len + 1);
    for (int i = 0; i < num_repetitions; i++) {
        strcat(new_key, key);
    }
    // Trim the new key to match the word length
    new_key[word_len] = '\0';
    strncpy(key, new_key, key_len);
    free(new_key);
}

void cipher(char* word, int word_len, char* key, int key_len) {
    // Update the key if necessary
    if (key_len != word_len) {
        update_key(key, key_len, word, word_len);
    }
    // Initialize the modified alphabet and get its length
    char alphabet[] = "abcdefghijklmnopqrstuvwxyz ";
    int alphabet_len = strlen(alphabet);
    // Iterate over each character in the word
    for (int i = 0; i < word_len; i++) {
        // Convert uppercase characters to lowercase
        char c = word[i];
        if (c >= 'A' && c <= 'Z') {
            c += ('a' - 'A');
        }
        // Get the indices of the character in the word and the key
        int word_idx = strchr(alphabet, c) - alphabet;
        int key_idx = strchr(alphabet, key[i]) - alphabet;
        // Calculate the shift amount and wrap it if necessary
        int shift_amount = (word_idx + key_idx) % alphabet_len;

        // Encrypt the character using the shift amount
        word[i] = alphabet[shift_amount];
    }
}

int is_valid_seed(char* seed) {
    int seed_len = strlen(seed);
    if (seed_len < 1 || seed_len > 6) {
        return 0;
    }
    for (int i = 0; i < seed_len; i++) {
        if (seed[i] < '0' || seed[i] > '9') {
            return 0;
        }
    }
    int seed_value = atoi(seed);
    if (seed_value < 1 || seed_value > 999999) {
        return 0;
    }
    return 1;
}


int roll_dice(int dice_sides) {
    return rand() % dice_sides + 1;
}

int validate_dice_sides(char* dice_sides) {
    // Remove any whitespace characters from the input
    int j = 0;
    for (int i = 0; dice_sides[i] != '\0'; i++) {
        if (dice_sides[i] != ' ') {
            dice_sides[j++] = dice_sides[i];
        }
    }
    dice_sides[j] = '\0';
    
    // Parse the three integers from the input string
    int sides[3];
    int num_sides = sscanf(dice_sides, "%dx%dx%d", &sides[0], &sides[1], &sides[2]);
    if (num_sides != 3) {
        return 0;
    }
    
    // Check that all sides are within the range [1, 11]
    for (int i = 0; i < 3; i++) {
        if (sides[i] < 1 || sides[i] > 11) {
            return 0;
        }
    }
    
    return 1;
}
int is_valid_name(const char* player_one_name) {
    int length = strlen(player_one_name);
    if (length < 2 || length > 8) {  // check if name length is valid
        return 0;
    }
    for (int i = 0; i < length; i++) {
        if (!(player_one_name[i] >= 'a' && player_one_name[i] <= 'z') && !(player_one_name[i] >= 'A' && player_one_name[i] <= 'Z')) {
            // check if name contains non-alphabetic characters
            return 0;
        }
    }

    return 1;  // name is valid
}

int is_valid_word(const char* word){
    int length = strlen(word);
    if (length > 7) {  // check if name length is valid
        return 0;
    }
    for (int i = 0; i < length; i++) {
        if (!(word[i] >= 'a' && word[i] <= 'z') && !(word[i] >= 'A' && word[i] <= 'Z')) {
            // check if name contains non-alphabetic characters
            return 0;
        }
    }

    return 1;

}

int is_valid_key(const char* key, const char* word) {
    int key_length = strlen(key);
    int word_length = strlen(word);
    if (key_length < 1 || key_length > word_length) {
        return 0;
    }
    for (int i = 0; i < key_length; i++) {
        if (!((key[i] >= 'a' && key[i] <= 'z') || (key[i] >= 'A' && key[i] <= 'Z'))) {
            return 0;
        }
    }
    return 1;
}

    
    // Main game loop
void game_logic(char* player_one_name, int seed, int dice_sides, char* word, char* key) {
    // Seed the random number generator
    srand(seed);
    
    // Initialize player scores
    int player1_word_count = 0;
    int player2_word_count = 0;
    
    int player1_word_index = 0;
    int player2_word_index = 0;

    
    // Get the length of the word and key
    int word_length = strlen(word);
    int key_len = strlen(key);
    
    int player1_loses = 0;
    int player2_loses = 0;
    int i;
    // Play rounds until a winner is determined
    int round = 1;
    while (!player1_loses && !player2_loses) {
        // Roll the dice
        int mediator_roll = roll_dice(dice_sides);
        int player_one_roll = roll_dice(dice_sides);
        int player_two_roll = roll_dice(dice_sides);

        if (player_one_roll < player_two_roll) {
            player1_word_count++;
            player1_word_index++;
            if (player2_word_index > 0) {
                player2_word_count--;
                player2_word_index--;
            }
        } else if (player_one_roll < player_one_roll) {
            player2_word_count++;
            player2_word_index++;
            if (player1_word_index > 0) {
                player1_word_count--;
                player1_word_index--;
            }
        } else {
        }
        if (player1_word_count == word_length) {
            player1_loses = 1;
        }
        if (player2_word_count == word_length) {
            player2_loses = 1;
        }
        
        printf("Round %d:\n", round);
        printf("Mediator dice roll: %d\n", mediator_roll);
        printf("%s dice roll: %d\n", player_one_name, player_one_roll);
        printf("Computer dice roll: %d\n", player_two_roll);
        
        for (i = 0; i < player1_word_index; i++) {
            printf("%s's word is currently: %s", player_one_name, word[i] + key);
        }
        for (i = 0; i < player2_word_index; i++) {
            printf("Computer's word is currently: %s", word[i] + key);
        }
        printf("\n\n");

        round++;
    }

    if (player1_loses){
        printf("%s has lost the game...their word will now be ciphered!\n", player_one_name);
        printf("New key is being created to match the length of the word...");
        printf("%s's orginal word was %s\n", player_one_name, word);
        cipher(word, word_length, key, key_len);
        printf("%s's encrypted word is now %s\n", player_one_name, word);
        }
    if (player2_loses){
        printf("Computer has lost the game...their word will now be ciphered!\n");
        printf("New key is being created to match the length of the word...");
        printf("Computer's orginal word was %s\n", word);
        cipher(word, word_length, key, key_len);
        printf("Computer's encrypted word is now %s\n", word);
        }
        
}
int main() {
    // Initialize variables
    char player_one_input[51], player_one_name[50], dice_sides_input[21], dice_sides[20],word_input[51], word[50], key_input[51],key[50];
    int seed_input[8], seed[7]
    
    // Get input from user
    printf("Welcome to the game of HorseDiceCipher!\n");

    printf("Please enter in your name player one: ");
    fgets(player_one_input, sizeof(player_one_input), stdin);
    sscanf(player_one_input, "%[^\n]", player_one_name);
    while (!is_valid_name(player_one_name)){
        printf("Invalid name value. Please enter a valid name value (2-8 letters, no numbers): ");
        fgets(player_one_input, sizeof(player_one_input), stdin);
        sscanf(player_one_input, "%[^\n]", player_one_name);
    }
    
    
    printf("Please enter a seed value: ");
    fgets(seed_input, sizeof(seed_input), stdin);
    sscanf(seed_input, "%[^\n]", seed);
    while (!is_valid_seed(seed)) {
        printf("Invalid seed value. Please enter a valid seed value: ");
        fgets(seed_input, sizeof(seed_input), stdin);
        sscanf(seed_input, "%[^\n]", seed);
    }
    srand(atoi(seed));

    printf("Please enter the sides of the dice to use: ");
    fgets(dice_sides_input, sizeof(dice_sides_input), stdin);
    sscanf(dice_sides_input, "%[^\n]", dice_sides);
    while (!validate_dice_sides(dice_sides)) {
        printf("Invalid dice sides. Please enter the sides of the dice to use: ");
        fgets(dice_sides_input, sizeof(dice_sides_input), stdin);
        sscanf(dice_sides_input, "%[^\n]", dice_sides);
    }
    
    printf("Please enter a word to use for the game: ");
    fgets(word_input, sizeof(word_input), stdin);
    sscanf(word_input, "%[^\n]", word);
    while (!is_valid_word(word)) {
        printf("Invalid word. Please enter the word to use(7 characters and must only contain alphabetical characters): ");
        fgets(word_input, sizeof(word_input), stdin);
        sscanf(word_input, "%[^\n]", word);
    }



    printf("Please enter a key to use for the game: ");
    fgets(key_input, sizeof(key_input), stdin);
    sscanf(key_input, "%[^\n]", key);
    while (!is_valid_key(key, word)) {
        printf("Invalid key. Please enter a key between 1 and %d characters: ", strlen(word));
        fgets(key_input, sizeof(key_input), stdin);
        sscanf(key_input, "%[^\n]", key);
    }

    cipher(word, strlen(word), key, strlen(key));
    printf("----------------------------------------------------\n");
    printf("The game of HorseDiceCipher is beginning now!\n");
    game_logic(player_one_name, seed, dice_sides, word, key);

    return 0;
}

Everything went well until I entered the input which was: Scooby 86578 3x3x3 tacocat dogZ

the output should look like this:

Round 6 of dice rolls is starting now!

 Mediator has rolled all three dice... their sum is 7

 Scooby has rolled all three dice... their sum is 5

 Computer has rolled all three dice... their sum is 7

 Scooby's word is currently t

 Computer's word is currently ta

 Round 7 of dice rolls is starting now!

 Mediator has rolled all three dice... their sum is 6

 Scooby has rolled all three dice... their sum is 8

 Computer has rolled all three dice... their sum is 5

 Scooby's word is currently

 Computer's word is currently tac

but mine looks like this

Round 3:

Mediator dice roll: 1457

Scooby dice roll: 25237

Computer dice roll: 12608


Round 4:

Mediator dice roll: 11245

Scooby dice roll: 971

Computer dice roll: 28850

Scooby's word is currently:

it used to put gibberish that is not even part of the word before, but it doesn't even produce anything now.

What is wrong with my code? Thank you.




Aucun commentaire:

Enregistrer un commentaire