mirror of
https://github.com/fooflington/wordsearch.git
synced 2025-04-21 16:19:08 +00:00
getting there...
This commit is contained in:
parent
2027d6b61e
commit
86463e38bf
@ -1,7 +1,6 @@
|
|||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "rnd.h"
|
#include "rnd.h"
|
||||||
|
|
||||||
|
|
||||||
int directions[] = {
|
int directions[] = {
|
||||||
DIRECTION_N,
|
DIRECTION_N,
|
||||||
DIRECTION_NE,
|
DIRECTION_NE,
|
||||||
@ -13,8 +12,8 @@ int directions[] = {
|
|||||||
DIRECTION_NW
|
DIRECTION_NW
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int get_direction(int simple)
|
||||||
int get_direction(int simple) {
|
{
|
||||||
if (simple) {
|
if (simple) {
|
||||||
if (random_number(0, 1) == 0) {
|
if (random_number(0, 1) == 0) {
|
||||||
return DIRECTION_E;
|
return DIRECTION_E;
|
||||||
@ -29,7 +28,8 @@ int get_direction(int simple) {
|
|||||||
#ifdef DEBUG_DIR_MAIN
|
#ifdef DEBUG_DIR_MAIN
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
int n = 32;
|
int n = 32;
|
||||||
while (--n > 0) {
|
while (--n > 0) {
|
||||||
printf("%d\n", get_direction(1));
|
printf("%d\n", get_direction(1));
|
||||||
|
197
src/grid.c
Normal file → Executable file
197
src/grid.c
Normal file → Executable file
@ -1,69 +1,198 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "rnd.h"
|
#include "rnd.h"
|
||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "grid.h"
|
#include "grid.h"
|
||||||
|
|
||||||
bounds *get_bounds(int height, int width, enum direction direction, int length) {
|
enum exitcodes {
|
||||||
|
EXIT_WORDTOOLONG,
|
||||||
|
};
|
||||||
|
|
||||||
|
bounds *get_bounds(int height, int width, enum direction direction, int length)
|
||||||
|
{
|
||||||
if (length > height || length > width) {
|
if (length > height || length > width) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
length--;
|
||||||
|
|
||||||
bounds *b = (bounds *) malloc(sizeof(bounds));
|
bounds *b = (bounds *) malloc(sizeof(bounds));
|
||||||
|
|
||||||
b->min_x = 0;
|
b->min_x = 0;
|
||||||
b->max_x = width;
|
b->max_x = width-1;
|
||||||
b->min_y = 0;
|
b->min_y = 0;
|
||||||
b->max_y = height;
|
b->max_y = height-1;
|
||||||
if(
|
if (direction == DIRECTION_N ||
|
||||||
direction == DIRECTION_N ||
|
direction == DIRECTION_NE || direction == DIRECTION_NW) {
|
||||||
direction == DIRECTION_NE ||
|
|
||||||
direction == DIRECTION_NW
|
|
||||||
) {
|
|
||||||
b->min_y = length;
|
b->min_y = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(
|
if (direction == DIRECTION_W ||
|
||||||
direction == DIRECTION_W ||
|
direction == DIRECTION_NW || direction == DIRECTION_SW) {
|
||||||
direction == DIRECTION_NW ||
|
|
||||||
direction == DIRECTION_SW
|
|
||||||
) {
|
|
||||||
b->min_x = length;
|
b->min_x = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(
|
if (direction == DIRECTION_E ||
|
||||||
direction == DIRECTION_E ||
|
direction == DIRECTION_NE || direction == DIRECTION_SE) {
|
||||||
direction == DIRECTION_NE ||
|
|
||||||
direction == DIRECTION_SE
|
|
||||||
) {
|
|
||||||
b->max_x = width - length;
|
b->max_x = width - length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(
|
if (direction == DIRECTION_S ||
|
||||||
direction == DIRECTION_S ||
|
direction == DIRECTION_SW || direction == DIRECTION_SE) {
|
||||||
direction == DIRECTION_SW ||
|
|
||||||
direction == DIRECTION_SE
|
|
||||||
) {
|
|
||||||
b->max_y = height - length;
|
b->max_y = height - length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
char** makegrid (char** words, int height, int width, int simple) {
|
int move_x(int x, enum direction d) {
|
||||||
return NULL;
|
if(
|
||||||
|
d == DIRECTION_E ||
|
||||||
|
d == DIRECTION_NE ||
|
||||||
|
d == DIRECTION_SE
|
||||||
|
) {
|
||||||
|
x++;
|
||||||
|
} else if (
|
||||||
|
d == DIRECTION_W ||
|
||||||
|
d == DIRECTION_NW ||
|
||||||
|
d == DIRECTION_SW
|
||||||
|
) {
|
||||||
|
x--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int move_y(int y, enum direction d) {
|
||||||
|
if(
|
||||||
|
d == DIRECTION_N ||
|
||||||
|
d == DIRECTION_NE ||
|
||||||
|
d == DIRECTION_NW
|
||||||
|
) {
|
||||||
|
y--;
|
||||||
|
} else if (
|
||||||
|
d == DIRECTION_S ||
|
||||||
|
d == DIRECTION_SE ||
|
||||||
|
d == DIRECTION_SW
|
||||||
|
) {
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **make_grid(char **words, int height, int width, int simple, int count)
|
||||||
|
{
|
||||||
|
char **grid = init_grid(NULL, height, width);
|
||||||
|
for(int i=0; i<count; i++) {
|
||||||
|
int tries = 0;
|
||||||
|
int placed = 0;
|
||||||
|
while(tries++ < WORDSEARCH_MAXTRIES && placed == 0) {
|
||||||
|
if(place_word(words[i], grid, height, width, simple)) {
|
||||||
|
placed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int place_word(char *word, char **grid, int height, int width, int simple)
|
||||||
|
{
|
||||||
|
int dir = get_direction(simple);
|
||||||
|
bounds *b;
|
||||||
|
|
||||||
|
if (b = get_bounds(height, width, dir, strlen(word))) {
|
||||||
|
/* word will probably fit... */
|
||||||
|
int x, y;
|
||||||
|
x = random_number(b->min_x, b->max_x);
|
||||||
|
y = random_number(b->min_y, b->max_y);
|
||||||
|
|
||||||
|
char** tempgrid = init_grid(grid, height, width);
|
||||||
|
/* Now we have two copies of the grid, try to place the word... */
|
||||||
|
int i;
|
||||||
|
for(i=0; i<strlen(word); i++) {
|
||||||
|
if(!isalpha(word[i])) continue;
|
||||||
|
if(tempgrid[y][x] != '_') {
|
||||||
|
if(tempgrid[y][x] != word[i]) {
|
||||||
|
/* Failed to place word */
|
||||||
|
free_grid(tempgrid, height);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* word crossed ok! */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tempgrid[y][x] = word[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
x = move_x(x, dir);
|
||||||
|
y = move_y(y, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_grid(grid, height);
|
||||||
|
free(b);
|
||||||
|
grid = tempgrid;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* word can't fit */
|
||||||
|
printf("[ERR] Word too long to place in this grid: %s\n", word);
|
||||||
|
exit(EXIT_WORDTOOLONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clones or creates an empty grid - pass NULL in as old to get an empty grid */
|
||||||
|
char **init_grid(char** old, int height, int width)
|
||||||
|
{
|
||||||
|
int row, cell;
|
||||||
|
char **new = malloc(height * sizeof(char*));
|
||||||
|
|
||||||
|
for (row=0; row < height; row++) {
|
||||||
|
new[row] = malloc(width * sizeof(char));
|
||||||
|
for (cell=0; cell < width; cell++) {
|
||||||
|
if(old) {
|
||||||
|
new[row][cell] = old[row][cell];
|
||||||
|
} else {
|
||||||
|
new[row][cell] = '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_grid(char** grid, int height) {
|
||||||
|
for (int i=0; i<height; i++) {
|
||||||
|
free(grid[i]);
|
||||||
|
}
|
||||||
|
free(grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_grid(char** grid, int height);
|
||||||
|
void print_grid(char** grid, int height) {
|
||||||
|
for(int i=0; i<height; i++) {
|
||||||
|
if(grid[i] == NULL) {
|
||||||
|
printf("row error\n");
|
||||||
|
} else {
|
||||||
|
printf("%s\n", grid[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_GRID_MAIN
|
#ifdef DEBUG_GRID_MAIN
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main() {
|
int main()
|
||||||
int dir = get_direction(0);
|
{
|
||||||
bounds* bounds = get_bounds(10, 10, dir, 8);
|
char *words[4] = {
|
||||||
printf("DIR=%d => %d < height < %d & %d < width < %d\n",
|
"test",
|
||||||
dir,
|
"word",
|
||||||
bounds->min_y, bounds->max_y,
|
"longer",
|
||||||
bounds->min_x, bounds->max_x
|
"verylong"
|
||||||
);
|
};
|
||||||
free(bounds);
|
char **grid = make_grid(words, 10, 10, 0, 4);
|
||||||
|
print_grid(grid, 4);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#define WORDSEARCH_MAXTRIES 500
|
#define WORDSEARCH_MAXTRIES 500
|
||||||
|
|
||||||
char** makegrid (char** words, int height, int width, int simple);
|
char **make_grid(char **words, int height, int width, int simple, int count);
|
||||||
|
|
||||||
typedef struct bounds {
|
typedef struct bounds {
|
||||||
int min_y;
|
int min_y;
|
||||||
@ -15,4 +15,11 @@ typedef struct bounds {
|
|||||||
/* returns NULL if cannot fit word; caller needs to free() the response */
|
/* returns NULL if cannot fit word; caller needs to free() the response */
|
||||||
bounds *get_bounds(int height, int width, enum direction direction, int length);
|
bounds *get_bounds(int height, int width, enum direction direction, int length);
|
||||||
|
|
||||||
|
int place_word(char *word, char **grid, int height, int width, int simple);
|
||||||
|
|
||||||
|
char **init_grid(char** old, int height, int width);
|
||||||
|
void free_grid(char** grid, int height);
|
||||||
|
int move_x(int x, enum direction d);
|
||||||
|
int move_y(int y, enum direction d);
|
||||||
|
|
||||||
#endif
|
#endif
|
63
src/rnd.c
63
src/rnd.c
@ -13,36 +13,37 @@ struct letter_frequency {
|
|||||||
int p; /* pegged to 10000 rather than 1 */
|
int p; /* pegged to 10000 rather than 1 */
|
||||||
char c;
|
char c;
|
||||||
} letter_frequencies[] = {
|
} letter_frequencies[] = {
|
||||||
{7, 'Z'},
|
{
|
||||||
{10, 'J'},
|
7, 'Z'}, {
|
||||||
{11, 'Q'},
|
10, 'J'}, {
|
||||||
{17, 'X'},
|
11, 'Q'}, {
|
||||||
{69, 'K'},
|
17, 'X'}, {
|
||||||
{111, 'V'},
|
69, 'K'}, {
|
||||||
{149, 'B'},
|
111, 'V'}, {
|
||||||
{182, 'P'},
|
149, 'B'}, {
|
||||||
{203, 'G'},
|
182, 'P'}, {
|
||||||
{209, 'W'},
|
203, 'G'}, {
|
||||||
{211, 'Y'},
|
209, 'W'}, {
|
||||||
{230, 'F'},
|
211, 'Y'}, {
|
||||||
{261, 'M'},
|
230, 'F'}, {
|
||||||
{271, 'C'},
|
261, 'M'}, {
|
||||||
{288, 'U'},
|
271, 'C'}, {
|
||||||
{398, 'L'},
|
288, 'U'}, {
|
||||||
{432, 'D'},
|
398, 'L'}, {
|
||||||
{592, 'H'},
|
432, 'D'}, {
|
||||||
{602, 'R'},
|
592, 'H'}, {
|
||||||
{628, 'S'},
|
602, 'R'}, {
|
||||||
{695, 'N'},
|
628, 'S'}, {
|
||||||
{731, 'I'},
|
695, 'N'}, {
|
||||||
{768, 'O'},
|
731, 'I'}, {
|
||||||
{812, 'A'},
|
768, 'O'}, {
|
||||||
{910, 'T'},
|
812, 'A'}, {
|
||||||
{1202, 'E'},
|
910, 'T'}, {
|
||||||
};
|
1202, 'E'},};
|
||||||
|
|
||||||
/* from http://stackoverflow.com/questions/822323/how-to-generate-a-random-number-in-c */
|
/* from http://stackoverflow.com/questions/822323/how-to-generate-a-random-number-in-c */
|
||||||
int random_number(int min_num, int max_num) {
|
int random_number(int min_num, int max_num)
|
||||||
|
{
|
||||||
static int initialised = 0;
|
static int initialised = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int low_num = 0;
|
int low_num = 0;
|
||||||
@ -62,7 +63,8 @@ int random_number(int min_num, int max_num) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char get_random_letter() {
|
char get_random_letter()
|
||||||
|
{
|
||||||
int rnd = random_number(0, RND_MAXINT);
|
int rnd = random_number(0, RND_MAXINT);
|
||||||
for (int i = 0; i < ALPHABET_SIZE; i++) {
|
for (int i = 0; i < ALPHABET_SIZE; i++) {
|
||||||
if (rnd < letter_frequencies[i].p) {
|
if (rnd < letter_frequencies[i].p) {
|
||||||
@ -76,7 +78,8 @@ char get_random_letter() {
|
|||||||
#ifdef DEBUG_RND_MAIN
|
#ifdef DEBUG_RND_MAIN
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
int n = 32;
|
int n = 32;
|
||||||
while (--n > 0) {
|
while (--n > 0) {
|
||||||
printf("%c", get_random_letter());
|
printf("%c", get_random_letter());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user