mirror of
https://github.com/fooflington/wordsearch-c.git
synced 2025-06-08 20:40:59 +00:00
initial commit
This commit is contained in:
commit
77fe861eb9
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
Debug/wordsearch
|
||||||
|
Release/wordsearch
|
||||||
|
*.o
|
||||||
|
*.d
|
||||||
|
*.swp
|
||||||
|
.cproject
|
||||||
|
.project
|
||||||
|
.settings
|
44
Debug/makefile
Normal file
44
Debug/makefile
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
-include ../makefile.init
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
|
||||||
|
# All of the sources participating in the build are defined here
|
||||||
|
-include sources.mk
|
||||||
|
-include src/subdir.mk
|
||||||
|
-include subdir.mk
|
||||||
|
-include objects.mk
|
||||||
|
|
||||||
|
ifneq ($(MAKECMDGOALS),clean)
|
||||||
|
ifneq ($(strip $(C_DEPS)),)
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
-include ../makefile.defs
|
||||||
|
|
||||||
|
# Add inputs and outputs from these tool invocations to the build variables
|
||||||
|
|
||||||
|
# All Target
|
||||||
|
all: wordsearch
|
||||||
|
|
||||||
|
# Tool invocations
|
||||||
|
wordsearch: $(OBJS) $(USER_OBJS)
|
||||||
|
@echo 'Building target: $@'
|
||||||
|
@echo 'Invoking: GCC C Linker'
|
||||||
|
gcc -o "wordsearch" $(OBJS) $(USER_OBJS) $(LIBS)
|
||||||
|
@echo 'Finished building target: $@'
|
||||||
|
@echo ' '
|
||||||
|
|
||||||
|
# Other Targets
|
||||||
|
clean:
|
||||||
|
-$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) wordsearch
|
||||||
|
-@echo ' '
|
||||||
|
|
||||||
|
.PHONY: all clean dependents
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
-include ../makefile.targets
|
8
Debug/objects.mk
Normal file
8
Debug/objects.mk
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
USER_OBJS :=
|
||||||
|
|
||||||
|
LIBS :=
|
||||||
|
|
17
Debug/sources.mk
Normal file
17
Debug/sources.mk
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
OBJ_SRCS :=
|
||||||
|
ASM_SRCS :=
|
||||||
|
C_SRCS :=
|
||||||
|
O_SRCS :=
|
||||||
|
S_UPPER_SRCS :=
|
||||||
|
EXECUTABLES :=
|
||||||
|
OBJS :=
|
||||||
|
C_DEPS :=
|
||||||
|
|
||||||
|
# Every subdirectory with source files must be described here
|
||||||
|
SUBDIRS := \
|
||||||
|
src \
|
||||||
|
|
33
Debug/src/subdir.mk
Normal file
33
Debug/src/subdir.mk
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Add inputs and outputs from these tool invocations to the build variables
|
||||||
|
C_SRCS += \
|
||||||
|
../src/dir.c \
|
||||||
|
../src/grid.c \
|
||||||
|
../src/rnd.c \
|
||||||
|
../src/wordsearch.c
|
||||||
|
|
||||||
|
OBJS += \
|
||||||
|
./src/dir.o \
|
||||||
|
./src/grid.o \
|
||||||
|
./src/rnd.o \
|
||||||
|
./src/wordsearch.o
|
||||||
|
|
||||||
|
C_DEPS += \
|
||||||
|
./src/dir.d \
|
||||||
|
./src/grid.d \
|
||||||
|
./src/rnd.d \
|
||||||
|
./src/wordsearch.d
|
||||||
|
|
||||||
|
|
||||||
|
# Each subdirectory must supply rules for building sources it contributes
|
||||||
|
src/%.o: ../src/%.c
|
||||||
|
@echo 'Building file: $<'
|
||||||
|
@echo 'Invoking: GCC C Compiler'
|
||||||
|
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
|
||||||
|
@echo 'Finished building: $<'
|
||||||
|
@echo ' '
|
||||||
|
|
||||||
|
|
44
Release/makefile
Normal file
44
Release/makefile
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
-include ../makefile.init
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
|
||||||
|
# All of the sources participating in the build are defined here
|
||||||
|
-include sources.mk
|
||||||
|
-include src/subdir.mk
|
||||||
|
-include subdir.mk
|
||||||
|
-include objects.mk
|
||||||
|
|
||||||
|
ifneq ($(MAKECMDGOALS),clean)
|
||||||
|
ifneq ($(strip $(C_DEPS)),)
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
-include ../makefile.defs
|
||||||
|
|
||||||
|
# Add inputs and outputs from these tool invocations to the build variables
|
||||||
|
|
||||||
|
# All Target
|
||||||
|
all: wordsearch
|
||||||
|
|
||||||
|
# Tool invocations
|
||||||
|
wordsearch: $(OBJS) $(USER_OBJS)
|
||||||
|
@echo 'Building target: $@'
|
||||||
|
@echo 'Invoking: GCC C Linker'
|
||||||
|
gcc -o "wordsearch" $(OBJS) $(USER_OBJS) $(LIBS)
|
||||||
|
@echo 'Finished building target: $@'
|
||||||
|
@echo ' '
|
||||||
|
|
||||||
|
# Other Targets
|
||||||
|
clean:
|
||||||
|
-$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) wordsearch
|
||||||
|
-@echo ' '
|
||||||
|
|
||||||
|
.PHONY: all clean dependents
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
-include ../makefile.targets
|
8
Release/objects.mk
Normal file
8
Release/objects.mk
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
USER_OBJS :=
|
||||||
|
|
||||||
|
LIBS :=
|
||||||
|
|
17
Release/sources.mk
Normal file
17
Release/sources.mk
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
OBJ_SRCS :=
|
||||||
|
ASM_SRCS :=
|
||||||
|
C_SRCS :=
|
||||||
|
O_SRCS :=
|
||||||
|
S_UPPER_SRCS :=
|
||||||
|
EXECUTABLES :=
|
||||||
|
OBJS :=
|
||||||
|
C_DEPS :=
|
||||||
|
|
||||||
|
# Every subdirectory with source files must be described here
|
||||||
|
SUBDIRS := \
|
||||||
|
src \
|
||||||
|
|
33
Release/src/subdir.mk
Normal file
33
Release/src/subdir.mk
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
################################################################################
|
||||||
|
# Automatically-generated file. Do not edit!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Add inputs and outputs from these tool invocations to the build variables
|
||||||
|
C_SRCS += \
|
||||||
|
../src/dir.c \
|
||||||
|
../src/grid.c \
|
||||||
|
../src/rnd.c \
|
||||||
|
../src/wordsearch.c
|
||||||
|
|
||||||
|
OBJS += \
|
||||||
|
./src/dir.o \
|
||||||
|
./src/grid.o \
|
||||||
|
./src/rnd.o \
|
||||||
|
./src/wordsearch.o
|
||||||
|
|
||||||
|
C_DEPS += \
|
||||||
|
./src/dir.d \
|
||||||
|
./src/grid.d \
|
||||||
|
./src/rnd.d \
|
||||||
|
./src/wordsearch.d
|
||||||
|
|
||||||
|
|
||||||
|
# Each subdirectory must supply rules for building sources it contributes
|
||||||
|
src/%.o: ../src/%.c
|
||||||
|
@echo 'Building file: $<'
|
||||||
|
@echo 'Invoking: GCC C Compiler'
|
||||||
|
gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
|
||||||
|
@echo 'Finished building: $<'
|
||||||
|
@echo ' '
|
||||||
|
|
||||||
|
|
3
src/STYLE.md
Normal file
3
src/STYLE.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Indented using:
|
||||||
|
|
||||||
|
astyle --style=java
|
37
src/dir.c
Normal file
37
src/dir.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "dir.h"
|
||||||
|
#include "rnd.h"
|
||||||
|
|
||||||
|
int directions[] = {
|
||||||
|
DIRECTION_N,
|
||||||
|
DIRECTION_NE,
|
||||||
|
DIRECTION_E,
|
||||||
|
DIRECTION_SE,
|
||||||
|
DIRECTION_S,
|
||||||
|
DIRECTION_SW,
|
||||||
|
DIRECTION_W,
|
||||||
|
DIRECTION_NW
|
||||||
|
};
|
||||||
|
|
||||||
|
int get_direction(int simple) {
|
||||||
|
if (simple) {
|
||||||
|
if (random_number(0, 1) == 0) {
|
||||||
|
return DIRECTION_E;
|
||||||
|
} else {
|
||||||
|
return DIRECTION_S;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return directions[random_number(0, NUM_DIRECTIONS)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_DIR_MAIN
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int n = 32;
|
||||||
|
while (--n > 0) {
|
||||||
|
printf("%d\n", get_direction(1));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
19
src/dir.h
Normal file
19
src/dir.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef WORDSEARCH_DIR
|
||||||
|
#define WORDSEARCH_DIR
|
||||||
|
|
||||||
|
enum direction {
|
||||||
|
DIRECTION_N,
|
||||||
|
DIRECTION_NE,
|
||||||
|
DIRECTION_E,
|
||||||
|
DIRECTION_SE,
|
||||||
|
DIRECTION_S,
|
||||||
|
DIRECTION_SW,
|
||||||
|
DIRECTION_W,
|
||||||
|
DIRECTION_NW
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_DIRECTIONS 8
|
||||||
|
|
||||||
|
int get_direction(int simple);
|
||||||
|
|
||||||
|
#endif
|
232
src/grid.c
Normal file
232
src/grid.c
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
// #define DEBUG
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "rnd.h"
|
||||||
|
#include "dir.h"
|
||||||
|
#include "grid.h"
|
||||||
|
|
||||||
|
enum exitcodes {
|
||||||
|
EXIT_WORDTOOLONG,
|
||||||
|
};
|
||||||
|
|
||||||
|
bounds *get_bounds(int height, int width, enum direction direction, int length) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("get_bounds(height=%d, width=%d, direction=%d, length=%d) -> ", height, width, direction, length);
|
||||||
|
#endif
|
||||||
|
if (length > height || length > width) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
length--;
|
||||||
|
|
||||||
|
bounds *b = (bounds *) malloc(sizeof(bounds));
|
||||||
|
|
||||||
|
b->min_x = 0;
|
||||||
|
b->max_x = width-1;
|
||||||
|
b->min_y = 0;
|
||||||
|
b->max_y = height-1;
|
||||||
|
if (direction == DIRECTION_N ||
|
||||||
|
direction == DIRECTION_NE || direction == DIRECTION_NW) {
|
||||||
|
b->min_y = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == DIRECTION_W ||
|
||||||
|
direction == DIRECTION_NW || direction == DIRECTION_SW) {
|
||||||
|
b->min_x = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == DIRECTION_E ||
|
||||||
|
direction == DIRECTION_NE || direction == DIRECTION_SE) {
|
||||||
|
b->max_x = width - length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == DIRECTION_S ||
|
||||||
|
direction == DIRECTION_SW || direction == DIRECTION_SE) {
|
||||||
|
b->max_y = height - length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("%d <= x <= %d & %d <= y <= %d\n", b->min_x, b->max_x, b->min_y, b->max_y);
|
||||||
|
#endif
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int move_x(int x, enum direction d) {
|
||||||
|
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);
|
||||||
|
#ifdef INITCHECK
|
||||||
|
free_grid(grid, height);
|
||||||
|
exit(0);
|
||||||
|
#endif
|
||||||
|
for(int i=0; i<count; i++) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Placing word %d: %s\n", i, words[i]);
|
||||||
|
#endif
|
||||||
|
int tries = 0;
|
||||||
|
int placed = 0;
|
||||||
|
while(tries++ < WORDSEARCH_MAXTRIES && placed == 0) {
|
||||||
|
char **g = place_word(words[i], grid, height, width, simple);
|
||||||
|
if(g) {
|
||||||
|
placed = 1;
|
||||||
|
grid = g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
print_grid(grid, height);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef DONOTFILL
|
||||||
|
/* Now the words are done, we need to fill in the blanks */
|
||||||
|
for (int x=0; x<height; x++) {
|
||||||
|
for (int y=0; y<width; y++) {
|
||||||
|
if(grid[x][y] == '_') {
|
||||||
|
grid[x][y] = get_random_letter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
char** place_word(char *word, char **grid, int height, int width, int simple) {
|
||||||
|
int dir = get_direction(simple);
|
||||||
|
bounds *b;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("place_word(%s, ...), direction=%d\n", word, dir);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
b = get_bounds(height, width, dir, strlen(word));
|
||||||
|
if (b) {
|
||||||
|
/* 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);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Attempting to place word `%s' starting @ %d,%d going %d\n", word, x, y, dir);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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] != '_') {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Checking (%d,%d)\n", x, y);
|
||||||
|
#endif
|
||||||
|
if(tempgrid[y][x] != word[i]) {
|
||||||
|
/* Failed to place word */
|
||||||
|
free_grid(tempgrid, height);
|
||||||
|
free(b);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* word crossed ok! */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tempgrid[y][x] = word[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
x = move_x(x, dir);
|
||||||
|
y = move_y(y, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Placed word %s\n", word);
|
||||||
|
print_grid(tempgrid, height);
|
||||||
|
printf("Swapping references...\n");
|
||||||
|
#endif
|
||||||
|
free_grid(grid, height);
|
||||||
|
free(b);
|
||||||
|
grid = tempgrid;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Dumping current grid:\n");
|
||||||
|
print_grid(grid, height);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
} 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) {
|
||||||
|
// printf("print_grid(): \n");
|
||||||
|
for(int i=0; i<height; i++) {
|
||||||
|
if(grid[i] == NULL) {
|
||||||
|
printf("row error (i=%d)\n", i);
|
||||||
|
} else {
|
||||||
|
printf("%s\n", grid[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
src/grid.h
Normal file
27
src/grid.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef WORDSEARCH_GRID
|
||||||
|
#define WORDSEARCH_GRID
|
||||||
|
#include "dir.h"
|
||||||
|
|
||||||
|
#define WORDSEARCH_MAXTRIES 500
|
||||||
|
|
||||||
|
char **make_grid(char **words, int height, int width, int simple, int count);
|
||||||
|
|
||||||
|
typedef struct bounds {
|
||||||
|
int min_y;
|
||||||
|
int max_y;
|
||||||
|
int min_x;
|
||||||
|
int max_x;
|
||||||
|
} bounds;
|
||||||
|
|
||||||
|
/* returns NULL if cannot fit word; caller needs to free() the response */
|
||||||
|
bounds *get_bounds(int height, int width, enum direction direction, int length);
|
||||||
|
|
||||||
|
char** 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);
|
||||||
|
void print_grid(char** grid, int height);
|
||||||
|
|
||||||
|
#endif
|
121
src/rnd.c
Normal file
121
src/rnd.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "rnd.h"
|
||||||
|
|
||||||
|
/* https://www.math.cornell.edu/~mec/2003-2004/cryptography/subs/frequencies.html */
|
||||||
|
|
||||||
|
#define ALPHABET_SIZE 26
|
||||||
|
#define RND_MAXINT 10000
|
||||||
|
|
||||||
|
struct letter_frequency {
|
||||||
|
int p; /* pegged to 10000 rather than 1 */
|
||||||
|
char c;
|
||||||
|
} letter_frequencies[] = {
|
||||||
|
{
|
||||||
|
7, 'Z'
|
||||||
|
}, {
|
||||||
|
10, 'J'
|
||||||
|
}, {
|
||||||
|
11, 'Q'
|
||||||
|
}, {
|
||||||
|
17, 'X'
|
||||||
|
}, {
|
||||||
|
69, 'K'
|
||||||
|
}, {
|
||||||
|
111, 'V'
|
||||||
|
}, {
|
||||||
|
149, 'B'
|
||||||
|
}, {
|
||||||
|
182, 'P'
|
||||||
|
}, {
|
||||||
|
203, 'G'
|
||||||
|
}, {
|
||||||
|
209, 'W'
|
||||||
|
}, {
|
||||||
|
211, 'Y'
|
||||||
|
}, {
|
||||||
|
230, 'F'
|
||||||
|
}, {
|
||||||
|
261, 'M'
|
||||||
|
}, {
|
||||||
|
271, 'C'
|
||||||
|
}, {
|
||||||
|
288, 'U'
|
||||||
|
}, {
|
||||||
|
398, 'L'
|
||||||
|
}, {
|
||||||
|
432, 'D'
|
||||||
|
}, {
|
||||||
|
592, 'H'
|
||||||
|
}, {
|
||||||
|
602, 'R'
|
||||||
|
}, {
|
||||||
|
628, 'S'
|
||||||
|
}, {
|
||||||
|
695, 'N'
|
||||||
|
}, {
|
||||||
|
731, 'I'
|
||||||
|
}, {
|
||||||
|
768, 'O'
|
||||||
|
}, {
|
||||||
|
812, 'A'
|
||||||
|
}, {
|
||||||
|
910, 'T'
|
||||||
|
}, {
|
||||||
|
1202, 'E'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* from http://stackoverflow.com/questions/822323/how-to-generate-a-random-number-in-c */
|
||||||
|
int random_number(int min_num, int max_num) {
|
||||||
|
static int initialised = 0;
|
||||||
|
int result = 0;
|
||||||
|
int low_num = 0;
|
||||||
|
int hi_num = 0;
|
||||||
|
if (min_num < max_num) {
|
||||||
|
low_num = min_num;
|
||||||
|
hi_num = max_num + 1; // this is done to include max_num in output.
|
||||||
|
} else {
|
||||||
|
low_num = max_num + 1; // this is done to include max_num in output.
|
||||||
|
hi_num = min_num;
|
||||||
|
}
|
||||||
|
if (!initialised) {
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
// srand(time(NULL));
|
||||||
|
srand(tv.tv_usec);
|
||||||
|
initialised = 1;
|
||||||
|
}
|
||||||
|
result = (rand() % (hi_num - low_num)) + low_num;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
char get_random_letter() {
|
||||||
|
int rnd = random_number(0, RND_MAXINT);
|
||||||
|
for (int i = 0; i < ALPHABET_SIZE; i++) {
|
||||||
|
if (rnd < letter_frequencies[i].p) {
|
||||||
|
return letter_frequencies[i].c;
|
||||||
|
}
|
||||||
|
rnd -= letter_frequencies[i].p;
|
||||||
|
}
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_RND_MAIN
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
int main() {
|
||||||
|
int n = 10000;
|
||||||
|
while (--n > 0) {
|
||||||
|
// printf("%c", get_random_letter());
|
||||||
|
int r = random_number(0,10);
|
||||||
|
assert(r >= 0);
|
||||||
|
assert(r <= 10);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
7
src/rnd.h
Normal file
7
src/rnd.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef WORDSEARCH_RND
|
||||||
|
#define WORDSEARCH_RND
|
||||||
|
|
||||||
|
char get_random_letter();
|
||||||
|
int random_number(int min_num, int max_num);
|
||||||
|
|
||||||
|
#endif
|
19
src/tags
Normal file
19
src/tags
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Mdir dir.c /^int main() {$/
|
||||||
|
Mrnd rnd.c /^int main() {$/
|
||||||
|
Mwordsearch wordsearch.c /^int main(int argc, char **argv) {$/
|
||||||
|
bounds grid.h /^} bounds;$/
|
||||||
|
direction dir.h /^enum direction {$/
|
||||||
|
exitcodes grid.c /^enum exitcodes {$/
|
||||||
|
free_grid grid.c /^void free_grid(char** grid, int height) {$/
|
||||||
|
get_bounds grid.c /^bounds *get_bounds(int height, int width, enum dir/
|
||||||
|
get_direction dir.c /^int get_direction(int simple) {$/
|
||||||
|
get_random_letter rnd.c /^char get_random_letter() {$/
|
||||||
|
init_grid grid.c /^char **init_grid(char** old, int height, int width/
|
||||||
|
letter_frequency rnd.c /^struct letter_frequency {$/
|
||||||
|
make_grid grid.c /^char **make_grid(char **words, int height, int wid/
|
||||||
|
move_x grid.c /^int move_x(int x, enum direction d) {$/
|
||||||
|
move_y grid.c /^int move_y(int y, enum direction d) {$/
|
||||||
|
place_word grid.c /^char** place_word(char *word, char **grid, int hei/
|
||||||
|
print_grid grid.c /^void print_grid(char** grid, int height) {$/
|
||||||
|
random_number rnd.c /^int random_number(int min_num, int max_num) {$/
|
||||||
|
strtoupper wordsearch.c /^#define strtoupper(X) for(char* c=X; *c=toupper(*c/
|
46
src/wordsearch.c
Normal file
46
src/wordsearch.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
============================================================================
|
||||||
|
Name : wordsearch.c
|
||||||
|
Author : Matthew Slowe
|
||||||
|
Version :
|
||||||
|
Copyright : MIT
|
||||||
|
Description : Hello World in C, Ansi-style
|
||||||
|
============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "grid.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define strtoupper(X) for(char* c=X; *c=toupper(*c); ++c)
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
// Reading parameters
|
||||||
|
if(argc < 3) {
|
||||||
|
fprintf(stderr, "Usage: %s <height> <width> [ words ... ]\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
int width, height;
|
||||||
|
height = atoi(argv[1]);
|
||||||
|
width = atoi(argv[2]);
|
||||||
|
|
||||||
|
char *words[argc-3];
|
||||||
|
int words_count = argc-3;
|
||||||
|
for(int i=0; i<words_count; i++) {
|
||||||
|
words[i] = malloc(strlen(argv[i+3]));
|
||||||
|
strcpy(words[i], argv[i+3]);
|
||||||
|
strtoupper(words[i]);
|
||||||
|
}
|
||||||
|
// if(argc > 2) {
|
||||||
|
//
|
||||||
|
// } else {
|
||||||
|
// char *words[4] = { "test", "word", "longer", "verylong" };
|
||||||
|
// }
|
||||||
|
|
||||||
|
char **grid = make_grid(words, height, width, 0, words_count);
|
||||||
|
print_grid(grid, height);
|
||||||
|
free_grid(grid, height);
|
||||||
|
}
|
439
tests/words-long.in
Normal file
439
tests/words-long.in
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
gaping
|
||||||
|
panicky
|
||||||
|
lock
|
||||||
|
purple
|
||||||
|
geese
|
||||||
|
massive
|
||||||
|
judge
|
||||||
|
hateful
|
||||||
|
helpless
|
||||||
|
uppity
|
||||||
|
public
|
||||||
|
cheat
|
||||||
|
head
|
||||||
|
scare
|
||||||
|
fax
|
||||||
|
adhesive
|
||||||
|
laugh
|
||||||
|
fancy
|
||||||
|
whip
|
||||||
|
strong
|
||||||
|
lethal
|
||||||
|
scintillating
|
||||||
|
decision
|
||||||
|
match
|
||||||
|
route
|
||||||
|
steadfast
|
||||||
|
drip
|
||||||
|
ossified
|
||||||
|
rail
|
||||||
|
trade
|
||||||
|
dock
|
||||||
|
sweet
|
||||||
|
wrap
|
||||||
|
stew
|
||||||
|
jewel
|
||||||
|
penitent
|
||||||
|
finger
|
||||||
|
tearful
|
||||||
|
cold
|
||||||
|
dayostage
|
||||||
|
instinctive
|
||||||
|
birds
|
||||||
|
kill
|
||||||
|
kettle
|
||||||
|
welcome
|
||||||
|
plough
|
||||||
|
dolls
|
||||||
|
telling
|
||||||
|
alleged
|
||||||
|
chemical
|
||||||
|
provide
|
||||||
|
roll
|
||||||
|
seat
|
||||||
|
knotty
|
||||||
|
hospital
|
||||||
|
white
|
||||||
|
cup
|
||||||
|
battle
|
||||||
|
straight
|
||||||
|
wandering
|
||||||
|
gate
|
||||||
|
holistic
|
||||||
|
freezing
|
||||||
|
nine
|
||||||
|
rat
|
||||||
|
head
|
||||||
|
accept
|
||||||
|
fretful
|
||||||
|
box
|
||||||
|
theory
|
||||||
|
apparel
|
||||||
|
duck
|
||||||
|
skip
|
||||||
|
judge
|
||||||
|
amount
|
||||||
|
file
|
||||||
|
sail
|
||||||
|
develop
|
||||||
|
eminent
|
||||||
|
used
|
||||||
|
sore
|
||||||
|
upbeat
|
||||||
|
jelly
|
||||||
|
cough
|
||||||
|
incandescent
|
||||||
|
point
|
||||||
|
person
|
||||||
|
laugh
|
||||||
|
squeak
|
||||||
|
ink
|
||||||
|
skirt
|
||||||
|
cellar
|
||||||
|
talk
|
||||||
|
youthful
|
||||||
|
tame
|
||||||
|
knowledgeable
|
||||||
|
pull
|
||||||
|
bat
|
||||||
|
launch
|
||||||
|
deer
|
||||||
|
jumpy
|
||||||
|
holiday
|
||||||
|
horses
|
||||||
|
last
|
||||||
|
punish
|
||||||
|
muddle
|
||||||
|
occur
|
||||||
|
bomb
|
||||||
|
delicious
|
||||||
|
unaccountable
|
||||||
|
mitten
|
||||||
|
quilt
|
||||||
|
smile
|
||||||
|
market
|
||||||
|
childlike
|
||||||
|
ignore
|
||||||
|
puzzled
|
||||||
|
trip
|
||||||
|
coal
|
||||||
|
spiritual
|
||||||
|
chop
|
||||||
|
flower
|
||||||
|
harmonious
|
||||||
|
thaw
|
||||||
|
teeth
|
||||||
|
drink
|
||||||
|
natural
|
||||||
|
six
|
||||||
|
skin
|
||||||
|
replace
|
||||||
|
beg
|
||||||
|
cheerful
|
||||||
|
conscious
|
||||||
|
spectacular
|
||||||
|
sassy
|
||||||
|
contain
|
||||||
|
existence
|
||||||
|
blink
|
||||||
|
tawdry
|
||||||
|
ladybug
|
||||||
|
suit
|
||||||
|
grandiose
|
||||||
|
pack
|
||||||
|
border
|
||||||
|
act
|
||||||
|
warlike
|
||||||
|
overt
|
||||||
|
husky
|
||||||
|
page
|
||||||
|
mess up
|
||||||
|
unnatural
|
||||||
|
snails
|
||||||
|
shaky
|
||||||
|
bird
|
||||||
|
abhorrent
|
||||||
|
bucket
|
||||||
|
label
|
||||||
|
healthy
|
||||||
|
approval
|
||||||
|
grass
|
||||||
|
pale
|
||||||
|
faithful
|
||||||
|
pump
|
||||||
|
neck
|
||||||
|
passenger
|
||||||
|
rinse
|
||||||
|
zip
|
||||||
|
imagine
|
||||||
|
pot
|
||||||
|
board
|
||||||
|
outgoing
|
||||||
|
plot
|
||||||
|
green
|
||||||
|
machine
|
||||||
|
descriptive
|
||||||
|
advice
|
||||||
|
kick
|
||||||
|
guarded
|
||||||
|
massive
|
||||||
|
sail
|
||||||
|
furtive
|
||||||
|
bouncy
|
||||||
|
continue
|
||||||
|
precede
|
||||||
|
mindless
|
||||||
|
pleasant
|
||||||
|
obeisant
|
||||||
|
present
|
||||||
|
huge
|
||||||
|
produce
|
||||||
|
quaint
|
||||||
|
refuse
|
||||||
|
shrill
|
||||||
|
woozy
|
||||||
|
flawless
|
||||||
|
excellent
|
||||||
|
list
|
||||||
|
witty
|
||||||
|
sofa
|
||||||
|
open
|
||||||
|
tin
|
||||||
|
hug
|
||||||
|
gaze
|
||||||
|
empty
|
||||||
|
disarm
|
||||||
|
wrong
|
||||||
|
lethal
|
||||||
|
agreeable
|
||||||
|
superb
|
||||||
|
sigh
|
||||||
|
dock
|
||||||
|
supreme
|
||||||
|
soothe
|
||||||
|
cracker
|
||||||
|
flimsy
|
||||||
|
chin
|
||||||
|
overjoyed
|
||||||
|
spot
|
||||||
|
exotic
|
||||||
|
synonymous
|
||||||
|
fat
|
||||||
|
acceptable
|
||||||
|
naughty
|
||||||
|
dam
|
||||||
|
regret
|
||||||
|
spark
|
||||||
|
toy
|
||||||
|
tap
|
||||||
|
apologise
|
||||||
|
entertain
|
||||||
|
open
|
||||||
|
concern
|
||||||
|
striped
|
||||||
|
abusive
|
||||||
|
tan
|
||||||
|
hammer
|
||||||
|
bright
|
||||||
|
bless
|
||||||
|
spy
|
||||||
|
spoon
|
||||||
|
paper
|
||||||
|
stitch
|
||||||
|
arch
|
||||||
|
seed
|
||||||
|
slippery
|
||||||
|
air
|
||||||
|
troubled
|
||||||
|
materialistic
|
||||||
|
pleasant
|
||||||
|
stitch
|
||||||
|
ugliest
|
||||||
|
bulb
|
||||||
|
leg
|
||||||
|
dependent
|
||||||
|
spill
|
||||||
|
number
|
||||||
|
spot
|
||||||
|
toad
|
||||||
|
rhetorical
|
||||||
|
marvelous
|
||||||
|
earsplitting
|
||||||
|
redundant
|
||||||
|
multiply
|
||||||
|
title
|
||||||
|
wealthy
|
||||||
|
detail
|
||||||
|
queen
|
||||||
|
hum
|
||||||
|
bat
|
||||||
|
combative
|
||||||
|
rough
|
||||||
|
muddled
|
||||||
|
snore
|
||||||
|
rainstorm
|
||||||
|
assorted
|
||||||
|
hungry
|
||||||
|
temporary
|
||||||
|
wash
|
||||||
|
compare
|
||||||
|
person
|
||||||
|
tense
|
||||||
|
parcel
|
||||||
|
use
|
||||||
|
man
|
||||||
|
hang
|
||||||
|
bubble
|
||||||
|
sleepy
|
||||||
|
scarf
|
||||||
|
teeny-tiny
|
||||||
|
excellent
|
||||||
|
used
|
||||||
|
invincible
|
||||||
|
abstracted
|
||||||
|
unusual
|
||||||
|
hideous
|
||||||
|
gifted
|
||||||
|
rob
|
||||||
|
homely
|
||||||
|
aspiring
|
||||||
|
health
|
||||||
|
friends
|
||||||
|
baby
|
||||||
|
political
|
||||||
|
mammoth
|
||||||
|
miss
|
||||||
|
pump
|
||||||
|
throat
|
||||||
|
haircut
|
||||||
|
delightful
|
||||||
|
side
|
||||||
|
x-ray
|
||||||
|
arithmetic
|
||||||
|
plant
|
||||||
|
brass
|
||||||
|
knot
|
||||||
|
panoramic
|
||||||
|
pig
|
||||||
|
sort
|
||||||
|
rake
|
||||||
|
second
|
||||||
|
thaw
|
||||||
|
comparison
|
||||||
|
whistle
|
||||||
|
female
|
||||||
|
hurt
|
||||||
|
shade
|
||||||
|
delirious
|
||||||
|
reminiscent
|
||||||
|
fog
|
||||||
|
confuse
|
||||||
|
question
|
||||||
|
flawless
|
||||||
|
fat
|
||||||
|
chess
|
||||||
|
efficacious
|
||||||
|
grape
|
||||||
|
bitter
|
||||||
|
nation
|
||||||
|
necessary
|
||||||
|
grumpy
|
||||||
|
vase
|
||||||
|
resonant
|
||||||
|
gaping
|
||||||
|
force
|
||||||
|
smiling
|
||||||
|
stir
|
||||||
|
improve
|
||||||
|
interrupt
|
||||||
|
cowardly
|
||||||
|
sturdy
|
||||||
|
wave
|
||||||
|
concentrate
|
||||||
|
giant
|
||||||
|
follow
|
||||||
|
reject
|
||||||
|
fire
|
||||||
|
cure
|
||||||
|
hill
|
||||||
|
nail
|
||||||
|
ice
|
||||||
|
psychotic
|
||||||
|
vacation
|
||||||
|
serious
|
||||||
|
simplistic
|
||||||
|
kitty
|
||||||
|
quiet
|
||||||
|
agreeable
|
||||||
|
avoid
|
||||||
|
elderly
|
||||||
|
cattle
|
||||||
|
add
|
||||||
|
doubtful
|
||||||
|
quill
|
||||||
|
try
|
||||||
|
zinc
|
||||||
|
icicle
|
||||||
|
jam
|
||||||
|
wink
|
||||||
|
muddle
|
||||||
|
hellish
|
||||||
|
month
|
||||||
|
thirsty
|
||||||
|
paltry
|
||||||
|
pick
|
||||||
|
sponge
|
||||||
|
hobbies
|
||||||
|
productive
|
||||||
|
truck
|
||||||
|
toys
|
||||||
|
taste
|
||||||
|
tin
|
||||||
|
territory
|
||||||
|
meat
|
||||||
|
discovery
|
||||||
|
romantic
|
||||||
|
pointless
|
||||||
|
quixotic
|
||||||
|
free
|
||||||
|
stupid
|
||||||
|
selection
|
||||||
|
advice
|
||||||
|
grade
|
||||||
|
road
|
||||||
|
brief
|
||||||
|
evasive
|
||||||
|
tenuous
|
||||||
|
challenge
|
||||||
|
plausible
|
||||||
|
reflect
|
||||||
|
axiomatic
|
||||||
|
look
|
||||||
|
irritate
|
||||||
|
damaging
|
||||||
|
uninterested
|
||||||
|
pathetic
|
||||||
|
coat
|
||||||
|
kneel
|
||||||
|
step
|
||||||
|
spy
|
||||||
|
group
|
||||||
|
unadvised
|
||||||
|
trousers
|
||||||
|
window
|
||||||
|
nerve
|
||||||
|
fit
|
||||||
|
preach
|
||||||
|
name
|
||||||
|
toy
|
||||||
|
screeching
|
||||||
|
box
|
||||||
|
type
|
||||||
|
kettle
|
||||||
|
head
|
||||||
|
nauseating
|
||||||
|
excuse
|
||||||
|
amuse
|
||||||
|
hammer
|
||||||
|
cars
|
||||||
|
mug
|
9
tests/words.in
Normal file
9
tests/words.in
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Kitchen
|
||||||
|
Lounge
|
||||||
|
Study
|
||||||
|
Ballroom
|
||||||
|
Conservatory
|
||||||
|
Billiard Room
|
||||||
|
Library
|
||||||
|
Hall
|
||||||
|
Dining Room
|
Loading…
x
Reference in New Issue
Block a user