Single put routine overlapping words during iteration

Joined
Dec 16, 2022
Messages
6
Reaction score
0
I am trying to have a simple loop for random words that may be placed horizontally and/or vertically and/or diagonally depending on the allowed space and wordLength. Below, is what I came up with but there is significant overlapping and broken words. Is there a way to have the loop in a single 'put' routine for all direction?
All my attempts have resulted in buggier outcomes. Thanks


C:
//Check horizontal orientation and place the word if available spaces allow it
void putHorizzontalWord(char word[10])
{
    int rRow, rCol , ok , i;

    do
    {
        rRow = rand() % 10;
        rCol = rand() % 10;

        ok = 1;
        if(rCol + strlen(word) < 10)
        {
            for(i = 0;i < strlen(word);i++)
            {
                if(puzzle[rRow][rCol + i] == '*' ||
                    puzzle[rRow][rCol + i] == word[i])
                {
                    puzzle[rRow][rCol + i] = word[i];
                }
                else
                {
                    ok = 0;
                }
            }
        }
        else
        {
            ok = 0;
        }
    }
    while(ok == 0);
}

//Check vertical orientation and place the word if available spaces allow it
void putVerticalWord(char word[10]) //this, doesn't seem to work'
{
    int rRow, rCol , ok , i;

    do
    {
        rRow = rand() % 10;
        rCol = rand() % 10;

        ok = 0;
        if(rRow + strlen(word) < 10)
        {
            for(i = 0;i < strlen(word);i++)
            {
                if(puzzle[rRow + i][rCol] == '*' ||
                    puzzle[rRow + i][rCol] == word[i])
                {
                    puzzle[rRow + i][rCol] = word[i];
                }
                else
                {
                    ok = 1;
                }
            }
        }
        else
        {
            ok = 1;
        }
    }
    while(ok == 1);
}

//Check diagonal orientation and place the word if available spaces allow it
void putDiagonalWord(char word[10]) //this, doesn't seem to work'
{
    int rRow, rCol , ok , i;

    do
    {
        rRow = rand() % 10;
        rCol = rand() % 10;

        ok = 2;
        if(rRow + strlen(word) < 10)
        {
            for(i = 0;i < strlen(word);i++)
            {
                if(puzzle[rRow + i][rCol + i] == '*' ||
                    puzzle[rRow + i][rCol + i] == word[i])
                {
                    puzzle[rRow + i][rCol + i] = word[i];
                }
                else
                {
                    ok = 2;
                }
            }
        }
        else
        {
            ok = 1;
        }
    }
    while(ok == 0);
}

void fillPuzzleWithWords()
{
    int i , orientation;
    getFourRandomWords();

    for(i=0; i<4; i++)
    {
        orientation = rand() % 3;
        if(orientation == 0)
        {
            putHorizzontalWord(fourWords[i]);
        }
        else if(orientation == 1)
        {
            putVerticalWord(fourWords[i]);
        }
        else
        {
            putDiagonalWord(fourWords[i]);
        }
    }
}
 
Joined
Jan 8, 2023
Messages
27
Reaction score
2
hmmm It looks like the ok variable is not being initialized correctly in each function. The ok variable should be set to 1 if the word can be placed, and 0 if it cannot. However, in the putVerticalWord function, ok is set to 0 if the word can be placed and 1 if it cannot. Similarly, in the putDiagonalWord function, ok is set to 2 if the word can be placed. This is likely causing the overlapping and broken words you are seeing in the puzzle.

One way to fix this is to initialize ok to 1 before the loop in each function, and then set it to 0
 
Joined
Dec 16, 2022
Messages
6
Reaction score
0
"thugbunny"
Thank you for your reply.

your suggestion helped, a little. Meaning that now the results are less messy than what they used to be. However, still not solving the overlapping and/or broken words (I attached the pics of three consecutive executions).

This would not be a problem if I manage to replace all asterisks with random letters. I have already a function for it but it seems to break the entire code if I implement it so, it's commented it out until i figure out how

Code:
//Create a grid filled only with asterisks
void createBlankPuzzle()
{
    int i , j;

    for(i=0; i<ROWS; i++)
    {
        for(j=0; j<COLUMNS; j++)
        {
            puzzle [i][j] = '*';
        }
    }
}
/*
//Create a grid filled with random characters
void createNewPuzzle()
{
    int i , j;

    for(i=0; i<ROWS; i++)
    {
        for(j=0; j<COLUMNS; j++)
        {
            puzzle [i][j] = getRandomCharacter();
        }
    }
}
*/
//Display the character-populated grid
void displayPuzzle()
{
    int i , j , rowNum = 0;
    char x = 'A';

    // First display column names
    printf("  ");
    for(i=0; i<COLUMNS; i++)
    {
        printf("%c ",x + i);
    }
    printf("\n");

    for(i = 0;i < ROWS;i++)
    {
        printf("%d " ,rowNum);
        rowNum++;
        for(j=0; j<COLUMNS; j++)
        {
            printf("%c ", puzzle[i][j]);
        }
        printf("\n");
    }
}
 

Attachments

  • Screenshot_20230108_084319.jpg
    Screenshot_20230108_084319.jpg
    50.2 KB · Views: 6
  • Screenshot_20230108_084454.jpg
    Screenshot_20230108_084454.jpg
    46.9 KB · Views: 6
  • Screenshot_20230108_084519.jpg
    Screenshot_20230108_084519.jpg
    46.4 KB · Views: 6
Joined
Jan 8, 2023
Messages
27
Reaction score
2
C:
#define ROWS 10
#define COLUMNS 10
#define MAX_WORDS 20

char puzzle[ROWS][COLUMNS];

typedef struct {
    int row;
    int col;
    int direction;  // 0 for horizontal, 1 for vertical
    char *word;
} Word;

Word words[MAX_WORDS];
int numWords = 0;

// Populate the puzzle with asterisks
void createBlankPuzzle() {
    int i, j;
    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLUMNS; j++) {
            puzzle[i][j] = '*';
        }
    }
}

// Add a new word to the puzzle and data structure
void addWord(char *word, int row, int col, int direction) {
    int i;
    if (numWords >= MAX_WORDS) {
        return;  // Cannot add more words
    }
    // Check if the word fits within the grid boundaries
    if (direction == 0) {  // Horizontal
        if (col + strlen(word) > COLUMNS) {
            return;  // Word does not fit horizontally
        }
    } else {  // Vertical
        if (row + strlen(word) > ROWS) {
            return;  // Word does not fit vertically
        }
    }
    // Check if the word overlaps with any existing words
    for (i = 0; i < numWords; i++) {
        if (words[i].direction == direction) {
            if (direction == 0) {  // Horizontal
                if (row == words[i].row && col <= words[i].col + strlen(words[i].word) && col + strlen(word) > words[i].col) {
                    return;  // Overlap detected
                }
            } else {  // Vertical
                if (col == words[i].col && row <= words[i].row + strlen(words[i].word) && row + strlen(word) > words[i].row) {
                    return;  // Overlap detected
                }
            }
        }
    }
    // Add the word to the puzzle and data structure
    for (i = 0; i < strlen(word); i++) {
        puzzle[row][col] = word[i];
        if (direction == 0) {
            col++;
        } else {
            row++;
        }

maybe try adding this to your code and give it a try to see if it works i put comments to help
 
Joined
Dec 16, 2022
Messages
6
Reaction score
0
"thugbunny"
thank you very much again for your effort.
Your code seems much more elegant than mine and it looks like what i wanted to achieve in the first place, i.e. a single iteration for all possible word orientations.
However, since I am a beginner I have tried to comment out my three orientation-functions and inserted yours and, it breaks the entire code. Maybe I should let you see what I have come up so far, below:

C:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <curses.h>

#define ROWS 10
#define COLUMNS 10
#define MAX_WORDS 4 //just added this from your code

//Creating two arrays Columns and Rows
char puzzle[ROWS][COLUMNS];


//List of words from which four will be picked up by the program, with which the user to play will search
char allWords[20][10] = {"GIRL" , "BOY" , "SHIP" , "CAT" , "FOG" , "KITE" , "BAG" , "STAMP" , "ZOOM" , "JOY", "CAR" , "BUS" , "VAN" , "BOAT" , "BIKE" , "TURBO" , "SCHOOL" , "DOVIC" , "VIRUS" , "STAR"};

char fourWords[4][10];

//creates random characters from ASCII starting at 65 (=A)
char getRandomCharacter()
{
    int r = (rand() % 26) + 65;
    return (char)r;
}

//pick 4 random words from a list of 20
void getFourRandomWords() {
    int draws[4];
    // draw 4 words from the list, no duplicates
    for (int i = 0; i < 4; i++) {
        int n = rand() % (20 - i);
        int j;
        for (j = 4 - i; j < 4 && n >= draws[j]; j++) {
            draws[j - 1] = draws[j];
            n++;
        }
        draws[j - 1] = n;
        strcpy(fourWords[i], allWords[n]);
    }
}

// word to be displayed/searched by the user (I CAN'T GET THIS PART WO WORK)
void displayWords(){
    int words = (rand() % 4);
    printf("%d\n " , words);
}


//Create a grid filled only with asterisks
void createBlankPuzzle()
{
    int i , j;

    for(i=0; i<ROWS; i++)
    {
        for(j=0; j<COLUMNS; j++)
        {
            puzzle [i][j] = '*';
        }
    }
}
/*
//Create a grid filled with random characters
void createNewPuzzle()
{
    int i , j;

    for(i=0; i<ROWS; i++)
    {
        for(j=0; j<COLUMNS; j++)
        {
            puzzle [i][j] = getRandomCharacter();
        }
    }
}
*/
//Display the character-populated grid
void displayPuzzle()
{
    int i , j , rowNum = 0;
    char x = 'A';

    // First display column names
    printf("  ");
    for(i=0; i<COLUMNS; i++)
    {
        printf("%c ",x + i);
    }
    printf("\n");

    for(i = 0;i < ROWS;i++)
    {
        printf("%d " ,rowNum);
        rowNum++;
        for(j=0; j<COLUMNS; j++)
        {
            printf("%c ", puzzle[i][j]);
        }
        printf("\n");
    }
}

//this is your code
typedef struct {
    int row;
    int col;
    int direction;  // 0 for horizontal, 1 for vertical
    char *word;
} Word;

Word words[MAX_WORDS];
int numWords = 0;

// Add a new word to the puzzle and data structure
void addWord(char *word, int row, int col, int direction) {
    int i;
    if (numWords >= MAX_WORDS) {
        return;  // Cannot add more words
    }
    // Check if the word fits within the grid boundaries
    if (direction == 0) {  // Horizontal
        if (col + strlen(word) > COLUMNS) {
            return;  // Word does not fit horizontally
        }
    } else {  // Vertical
        if (row + strlen(word) > ROWS) {
            return;  // Word does not fit vertically
        }
    }
    // Check if the word overlaps with any existing words
    for (i = 0; i < numWords; i++) {
        if (words[i].direction == direction) {
            if (direction == 0) {  // Horizontal
                if (row == words[i].row && col <= words[i].col + strlen(words[i].word) && col + strlen(word) > words[i].col) {
                    return;  // Overlap detected
                }
            } else {  // Vertical
                if (col == words[i].col && row <= words[i].row + strlen(words[i].word) && row + strlen(word) > words[i].row) {
                    return;  // Overlap detected
                }
            }
        }
    }
    // Add the word to the puzzle and data structure
    for (i = 0; i < strlen(word); i++) {
        puzzle[row][col] = word[i];
        if (direction == 0) {
            col++;
        } else {
            row++;
        }
// and this is where mine was before, commented out below

/*
//Check horizontal orientation and place the word if available spaces allow it
void putHorizzontalWord(char word[10])
{
    int rRow, rCol , ok , i;

    do
    {
        rRow = rand() % 10;
        rCol = rand() % 10;

        ok = 1;
        if(rCol + strlen(word) < 10)
        {
            for(i = 0;i < strlen(word);i++)
            {
                if(puzzle[rRow][rCol + i] == '*' ||
                    puzzle[rRow][rCol + i] == word[i])
                {
                    puzzle[rRow][rCol + i] = word[i];
                }
                else
                {
                    ok = 0;
                }
            }
        }
        else
        {
            ok = 0;
        }
    }
    while(ok == 0);
}

//Check vertical orientation and place the word if available spaces allow it
void putVerticalWord(char word[10]) //this, doesn't seem to work'
{
    int rRow, rCol , ok , i;

    do
    {
        rRow = rand() % 10;
        rCol = rand() % 10;

        ok = 1;
        if(rRow + strlen(word) < 10)
        {
            for(i = 0;i < strlen(word);i++)
            {
                if(puzzle[rRow + i][rCol] == '*' ||
                    puzzle[rRow + i][rCol] == word[i])
                {
                    puzzle[rRow + i][rCol] = word[i];
                }
                else
                {
                    ok = 0;
                }
            }
        }
        else
        {
            ok = 0;
        }
    }
    while(ok == 0);
}

//Check diagonal orientation and place the word if available spaces allow it
void putDiagonalWord(char word[10]) //this, doesn't seem to work'
{
    int rRow, rCol , ok , i;

    do
    {
        rRow = rand() % 10;
        rCol = rand() % 10;

        ok = 1;
        if(rRow + strlen(word) < 10)
        {
            for(i = 0;i < strlen(word);i++)
            {
                if(puzzle[rRow + i][rCol + i] == '*' ||
                    puzzle[rRow + i][rCol + i] == word[i])
                {
                    puzzle[rRow + i][rCol + i] = word[i];
                }
                else
                {
                    ok = 0;
                }
            }
        }
        else
        {
            ok = 0;
        }
    }
    while(ok == 0);
}

void fillPuzzleWithWords()
{
    int i , orientation;
    getFourRandomWords();

    for(i=0; i<4; i++)
    {
        orientation = rand() % 3;
        if(orientation == 0)
        {
            putHorizzontalWord(fourWords[i]);
        }
        else if(orientation == 1)
        {
            putVerticalWord(fourWords[i]);
        }
        else
        {
            putDiagonalWord(fourWords[i]);
        }
    }
}
*/


//Create a user-interactive menu
void mainMenu()
{
    char menuChoice;
    do
    {
        printf("\n~~~ DAILY CROSSWORD ~~~\n");
        printf("1. New game\n");
        printf("2. Exit\n");
        menuChoice = getchar();

        switch (menuChoice)
        {
            case '1': displayPuzzle();
                printf("\n------------------------");
                printf("\nUse coordinate to solve\nthe puzzle; i.e. C3, G3\n");
                printf("------------------------\n");
                printf("\n"); break;
        }

    } while (menuChoice != '2');
}

int main(int argc, char *argv[])
{
    srand(time(NULL));

    createBlankPuzzle();
    displayPuzzle();
    //fillPuzzleWithWords();


    mainMenu();
    getchar();
    getFourRandomWords();
    printf("Thank you for playing today! :)\nGood Bye");
    return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Boomer trying to learn coding in C and C++ 6
C language. work with text 3
Help with Loop 0
Lexical Analysis on C++ 1
Arduino Chess Clock 0
Fibonacci 0
Crossword 2
Problem with codewars. 5

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top