I am new here and also new with coding. I was given an assignment to find a 'bug' in a simple crossword program, written in C, that could, generate (unwanted) duplicate words; and I was asked to fix it!
Only 6 weeks into the course and I don't have a clue where to start (perhaps a little too advanced, if you ask for my 'ignorant' opinion); do I add an 'if' loop to check whether two word are the same? is there a simpler way to spot the catch? All tips and suggestions are appreciated
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 10
#define COLUMNS 10
char puzzle[ROWS][COLUMNS];
char allWords[20][10] = {
"GIRL", "BOY", "SHIP", "CAT", "FOG",
"KITE", "BAG", "STAMP", "ZOOM", "JOY",
"CAR", "BUS", "VAN", "BOAT", "BIKE",
"TURBO", "SCHOOL", "COVID", "VIRUS", "STAR"
};
char fourWords[4][10];
char getRandomCharacter()
{
int r = (rand() % 26) 65;
return (char)r;
}
void getFourRandomWords() // This code can generate duplicate words -- try to fix it
{
int i;
for (i = 0; i < 4; i ) {
strcpy(fourWords[i], allWords[rand() % 20]);
}
}
void createBlankPuzzle()
{
int i, j;
for (i = 0; i < ROWS; i ) {
for (j = 0; j < COLUMNS; j ) {
puzzle[i][j] = '*';
}
}
}
void displayPuzzel()
{
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");
}
}
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);
}
void fillPuzzleWithWords()
{
int i, orientation;
getFourRandomWords();
for (i = 0;i < 4;i ) {
orientation = 0; //rand() % 3; // To generate a random number from 0, 1, & 2
if (orientation == 0) {
putHorizzontalWord(fourWords[i]);
} else
if(orientation == 1)
{
// put word vertical
} else {
// put word diagonal
}
}
}
int main(void)
{
srand(time(NULL));
createBlankPuzzle();
fillPuzzleWithWords();
displayPuzzel();
getchar();
return 0;
}
I executed the code about 10 times and it did reproduced the same word three times. The thing is that I do not understand how the word are picked/chosen from that list hence I do not know how to interact with these lines.
CodePudding user response:
In order to produce distinct words, you can simply iterate over the words selected so far to check if the newly drawn word is different from all the previous ones:
void getFourRandomWords(void) {
// draw 4 words from the list, no duplicates
int i, j;
for (i = 0; i < 4;) {
const char *w = allWords[rand() % 20];
for (j = 0; j < i; j ) {
if (strcmp(fourWords[i], w) == 0)
break;
}
if (j == i) {
// add the word if it compared different from all previous ones
strcpy(fourWords[i], w);
i ;
}
}
}
The above naive method may be very inefficient if choosing n from n, as a matter of fact it is not even guaranteed to finish.
Here is a different approach to cap the number of iterations:
void getFourRandomWords(void) {
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]);
}
}
Here is yet another approach with a single loop and linear time and space complexity:
void getFourRandomWords(void) {
// list of possible word numbers
int draws[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
// draw 4 words from the list, no duplicates
for (int i = 0; i < 4; i ) {
// draw a number from i to 19
int n = i rand() % (20 - i);
// select the word from the list
strcpy(fourWords[i], allWords[draws[n]]);
// swap the word number and the i-th slot
// this way the selected number is removed from the list
draws[n] = draws[i];
}
}
CodePudding user response:
thank you so much for the time spent on it and PLEASE, do not apologize for helping. I re-posted bcos I thought I had finished: fix that error and goodbye. It would have been superb but, of course, it wasn't.
I just found out that after seven-1hr lectures we have to:
- Start by defining a 2D array of asterisks.
- Implement a function to display the array of asterisks.
- Decide which 4 words to use for this puzzle.
- Populate the 2D array of asterisks with the words that the user will have to guess.
- Fill the reset of the 2D array with randomly generated characters.
- Allow the user to play the game by guessing the words.
I have never coded and I am not even doing a computer programming course.
If any willing volunteer would kindly tip even just on 1 of these 6 points, I would be forever grateful.