ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hello everyone, this is my 1st post in the programming forum at linux.questions, although I have been a member for years; posting mainly in the slackware section.
I am going crazy on an apparently very simple task, I was told, which is filling a 10x10 grid of a word-finder puzzle with random letters instead of asterisks.
I have asked other C programming forums and I received a few replies of tens-and-tens sentences of explaining and very few lines of actual C code to insert/correct. I never thought of linux.questions simply because I didn't know it had a programming sub-forum in it so, this is my last chance to ask/find help.
I am trying to create a simple word-finder puzzle on a 10x10 grid with a selection of 4 random words, out of about 20 words, where the user had to guess the words coordinates.
The program is very elementary, as i am a beginner in C. I have managed to:
1) create a 10x10 ROWS COLUMNS grid
2) fill it up with asterisks as a starting screen
3) create a user menu' with only 2 options: a) play game or b) exit
The menu' seems to work(ish) however, when the player chooses to play (a), a new grid should appear filled with random letters (not characters) and the four words. Again, I have somehow managed to get the words in a very buggy words-orientation function call but the asterisks remain and I have no letters. And I can't understand where the 'hole' is.
I would be thankful if someone could tell me to add what and where avoiding another A4 page of explaining (no offense). I am a beginner. Literally I started coding, on a part-time self-taught basis about 10wks ago.
I have attached a scrnshot to better visualize ...
p.s.: Tech. note: I am writing the code using KDevelop 5.10 and, I believe it is compiling with the latest gcc package. I am on a slackware current box
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <curses.h>
#define ROWS 10
#define COLUMNS 10
//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");
}
}
//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();
displayWords();
printf("Thank you for playing today! :)\nGood Bye");
return 0;
}
I have asked other C programming forums and I received a few replies of tens-and-tens sentences of explaining and very few lines of actual C code to insert/correct.
...
I would be thankful if someone could tell me to add what and where avoiding another A4 page of explaining (no offense). I am a beginner. Literally I started coding, on a part-time self-taught basis about 10wks ago.
If you always seek to copy-paste code you will remain a beginner.
If someone gives you a response that you don't understand, say where you get stuck and ask for clarification on that point.
If an entire response is verbose or difficult to comprehend, it's ok to point that out and ask for simplification and/or a step-by-step explanation.
Quote:
the asterisks remain and I have no letters. And I can't understand where the 'hole' is.
Does KDevelop and/or your compiler have an option to identify unused functions?
They should be telling you that getRandomCharacter isn't being called...
I don't understand why is it a problem. I mean you want to learn and they wanted to teach you something.
Did you try debugging your code? https://docs.kde.org/trunk5/en/kdeve...-kdevelop.html
What do you expect now? Should we fix your code or help you to fix it?
I don't understand why is it a problem. I mean you want to learn and they wanted to teach you something.
Did you try debugging your code? https://docs.kde.org/trunk5/en/kdeve...-kdevelop.html
What do you expect now? Should we fix your code or help you to fix it?
Maybe,I did not explain myself clearly, or enough.
Of course i have always been thankful for explanations and pointers but I guess If i go and do an apprenticeship as a mechanic, the explaining of how the combustion engine works would not be enough for me to start taking an engine apart. And, I suppose that would be the same for an electrician, a medic, or a chicken-feeder.
I did ask for clarification and often it seems that programmers are either too busy or to 'posh' to explain basic concepts in simple english. Here is an example of a response I had (copy&pasted straight from the other forum)
Quote:
A different "put" routine for each direction is not needed. One routine could do all 8 directions. Less code, less bugs.
The only difference between placing a word one way or another is "change in x" (-1,0,1) and "change in y" (-1,0,1) as the program moves through the word, and those can be arguments.
Selecting a word at random, and then searching for a place it will fit, is one way, but there are easier ways. (With a better chance of interesting overlaps happening.)
Like, select a random place, and then search for a word.
Start with a grid of "?" characters.
(1) Pick a random position, direction, and word length. If valid, copy what's there in the grid, into a string.
"??E???K" for example.
(2) Search a dictionary (just a list of words) file for matches (treat ? as a wildcard).
(3) Select one (if there are any) of the matches at random, and insert it into the grid.
Repeat (1) to (3) for a reasonable amount of time.
(4) Replace remaining ? with random letters.
There is a teach yourself Python book, and it has a free dictionary on its web site.
Here's a grid made from that text file. Step (4) has not been done.
here is another one from the same forum
Quote:
You ask about filling the grid with random letters?
Well, I wrote some function last week. It's in C# but still I think it may help You. Ale the fun in coding is possibiliy of making Your own tools. This is one of mine.
another one, slightly different question on the same program but different forum
Quote:
If you really want to check if you have enough space you need to perform an initial iteration to verify that all characters that you want to overwrite are still asterisks.
What is the reason for having only a single put() function? do you want to write into whatever direction the word fits?
and yet, another one
Code:
Here's something to study.
Code:
#include<stdio.h>
#include<stdlib.h>
#define GRID_W 10
#define GRID_H 10
int isValidPos(int row, int col) {
return row >= 0 && row < GRID_H &&
col >= 0 && col < GRID_W;
}
int allowed(char grid[GRID_H][GRID_W], int row, int col, int deltar, int deltac, const char *word) {
int result = 1;
while ( result && *word ) {
result = isValidPos(row, col); // it's in the grid
result = result && (grid[row][col] == ' ' || grid[row][col] == *word); // the cell is free, or matches
if ( result ) {
row += deltar; // next pos in the chosen dir
col += deltac;
word++; // next char
}
}
return result;
}
void addWord(char grid[GRID_H][GRID_W], int row, int col, int deltar, int deltac, const char *word) {
if ( allowed(grid, row, col, deltar, deltac, word) ) {
while ( *word ) {
grid[row][col] = *word;
row += deltar; // next pos in the chosen dir
col += deltac;
word++; // next char
}
}
}
void initGrid(char grid[GRID_H][GRID_W]) {
for ( int r = 0 ; r < GRID_H ; r++ ) {
for ( int c = 0 ; c < GRID_W ; c++ ) {
grid[r][c] = ' ';
}
}
}
void printGrid(const char grid[GRID_H][GRID_W]) {
for ( int r = 0 ; r < GRID_H ; r++ ) {
for ( int c = 0 ; c < GRID_W ; c++ ) {
putchar(grid[r][c]);
}
putchar('\n');
}
}
int main ()
{
char grid[GRID_H][GRID_W];
initGrid(grid);
addWord(grid, 0, 0, 1, 1, "hello"); // diagonal hello
addWord(grid, 4, 3, 0, 1, "world"); // horizontal world through end of hello
addWord(grid, 9, 9, -1, -1, "bye");
printGrid(grid);
return 0;
}
$ gcc foo.c
$ ./a.out
h
e
l
l
world
e
y
b
different functions from the one I have, commands I have never even heard of in 8wks of watching tutorials... I wonder whether people forget the meaning of 'beginner' once they specialize on a subject whether it being medicine or feeding chicken.
Surely, I am not trying to get some work done for free, as this will definitely fails the-idea-of-the-year for a million $ making project.
And i know that everyone is busy and I accept the fact that i may/may not get a reply but I wonder what the use is to spend time typing things such the one above rather than writing things like:
- add this there
- put that line down
- delete that
- etc.....
I would consider it very kind and incredibly helpful.
Now, i hope that my straight forwardness did not upset anyone and I will still gratefully appreciate all replies, technical or not.
p.s.: by the way, in each and everyone of those copy-pates quotes, I always asked for more clarification or maybe short examples and either I had no responses anymore or more complicated answer than the initial ones.
Please do not bring dissatisfaction with answers from other forums into this one. They are irrelevant and posting an A4 page of them here is not helpful.
Programming is literally the process of organizing some set of variables or values and simple discrete operations on them, into a sequence which produces some desired result. Different languages may use different notations (syntax) and provide different features and function (libraries) to perform those discrete operations, but the ideas are all similar and (usually) well grounded in simple concepts from other realms, notably mathematics.
So the goal for a learning beginner, and those providing help, is usually best served by communicating an understanding of those concepts, how they are supported in the target language and how to use them to accomplish some task, and not so much by providing code.
I would suggest that you begin by focusing on some specific aspect of the task at hand, finding a word and starting point for placement for example, and try to fully understand at least two or three ways to approach the problem and the advantages/disadvantages of each. Learn how to implement each of those ideas into code and how to test if it works as expected (the essential act of programming). Then move on to the next simple operation.
When you are finished you will have both a sequence of operations which produce the desired result - and an understanding of how and why it works!
Please do not bring dissatisfaction with answers from other forums into this one. They are irrelevant and posting an A4 page of them here is not helpful.
Programming is literally the process of organizing some set of variables or values and simple discrete operations on them, into a sequence which produces some desired result. Different languages may use different notations (syntax) and provide different features and function (libraries) to perform those discrete operations, but the ideas are all similar and (usually) well grounded in simple concepts from other realms, notably mathematics.
So the goal for a learning beginner, and those providing help, is usually best served by communicating an understanding of those concepts, how they are supported in the target language and how to use them to accomplish some task, and not so much by providing code.
I would suggest that you begin by focusing on some specific aspect of the task at hand, finding a word and starting point for placement for example, and try to fully understand at least two or three ways to approach the problem and the advantages/disadvantages of each. Learn how to implement each of those ideas into code and how to test if it works as expected (the essential act of programming). Then move on to the next simple operation.
When you are finished you will have both a sequence of operations which produce the desired result - and an understanding of how and why it works!
Good luck!
Thank you and, feel free to moderate the inappropriate post if you wish.
edit: I forgot to add, that I have ran KDevelop debug and it returns no errors for the code, as it is, compiles ok; it just doesn't fill up the grid with random letters
Per your comments in the other thread, let's keep the discussion here, in this thread, at least until we can identify a specific problem that would be most appropriate in another thread. Keeping the discussion in one place and unmodified (except for egregious rule violations) helps others to follow the discussion more easily.
I have not yet had time to try to follow the code you posted so still no help to offer there, but I find this statement confusing:
Quote:
... a new grid should appear filled with random letters (not characters) and the four words
Just to be precise, what do you mean by letters not characters?
Per your comments in the other thread, let's keep the discussion here, in this thread, at least until we can identify a specific problem that would be most appropriate in another thread. Keeping the discussion in one place and unmodified (except for egregious rule violations) helps others to follow the discussion more easily.
I have not yet had time to try to follow the code you posted so still no help to offer there, but I find this statement confusing:
Just to be precise, what do you mean by letters not characters?
My bad in explaining, apologies.
By letters I meant only the alphabet (A to Z) and, by no characters I meant no numbers and/or random symbols such as these "£$(_~@>"
The reason you see multiple menus is due to the fact that the stdin buffer contains two characters i.e 1 and the new line character and loops around again for each.
I don't claim to be a good programmer but one way to 'fix' the problem is using the following. It accepts characters until a new line is entered.
Code:
while((menuChoice = getchar()) == '\n');
It does not look like createNewPuzzle is every called which a I assume is what is supposed to fill the puzzle with random characters.
The reason you see multiple menus is due to the fact that the stdin buffer contains two characters i.e 1 and the new line character and loops around again for each.
I don't claim to be a good programmer but one way to 'fix' the problem is using the following. It accepts characters until a new line is entered.
Code:
while((menuChoice = getchar()) == '\n');
Finally some help!
thank you so much.
It would have taken me months to learn it on my own. One problem down.
Quote:
It does not look like createNewPuzzle is every called which a I assume is what is supposed to fill the puzzle with random characters.
Yes, it is supposed to fill the puzzle with new words. I need to work on that too. But i believe that it will get complicated (for me) so, i have put it on the to-do list. I believe that I have to create a new function with a loop that would 'kinda' restart the program?
It appears the function to place the words is working but you may just need to adjust your createNewPuzzle function to place random characters where * exist. Your menu loop is awkward but it appears like you are trying to display the words to search after the menu loop which would never be called unless you exit the program.
It appears the function to place the words is working but you may just need to adjust your createNewPuzzle function to place random characters where * exist. Your menu loop is awkward but it appears like you are trying to display the words to search after the menu loop which would never be called unless you exit the program.
The entire 'createNewPuzzle' function is commented out. If I uncomment it, yes it shows the random letters in the grid but somehow it breaks the whole program as in a) no words are shown anymore and b) the menu' disappears
If you change the createNewPuzzle to only place random characters where an element has a * that just fix your problems. If I understand your program.
createBlankPuzzle() Fills the array with *
fillPuzzleWithWords() Places words in the array
NewcreateNewPuzzle() Modify function to fill "empty" elements with random characters.
displayPuzzle() display array.
If you change the createNewPuzzle to only place random characters where an element has a * that just fix your problems. If I understand your program.
createBlankPuzzle() Fills the array with *
fillPuzzleWithWords() Places words in the array
NewcreateNewPuzzle() Modify function to fill "empty" elements with random characters.
displayPuzzle() display array.
Grr, ok, i never thought about that. it should work. I will change the function tonight
Quote:
Are words supposed to wrap around the puzzle?
No, but i gave up on that. I spent 2mnths on it, also trying to understand loops and asking for help. Everyone was sending me to books and tutorials and that's all i managed to do. Then, i thought that If i manage to fill up the grid with random letters, it wouldn't matter much but, then again, not a very tech minded solution
by the way, i have a normal job and this is only some kind of past-time/hobby so, i am not working on it everyday and often when i return to it after some time I have to go back to re-learn what I did and why, (mid-life crisis issues)
I would suggest that you begin by focusing on some specific aspect of the task at hand, finding a word and starting point for placement for example, and try to fully understand at least two or three ways to approach the problem and the advantages/disadvantages of each. Learn how to implement each of those ideas into code and how to test if it works as expected (the essential act of programming). Then move on to the next simple operation.
The key is divide-and-conquer ie write only one fn and get that working, then put that aside in a file and work on the next fn and so on.
Finally start adding the fns one by one to the main program file and ensure each new addition works in harmony with the existing code before bringing in the next fn.
This works for any language. In general do not try to write and then debug an entire program in one go, it gets exponentially harder as the num of lines increases.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.