From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v18i015: wf - simple program to make "Word Search" squares, Part01/01 Date: 12 Jul 1993 06:33:32 GMT Approved: billr@saab.CNA.TEK.COM Message-ID: <21r0js$gtd@ying.cna.tek.com> Submitted-by: srt@sun-dimas.aero.org (Scott 'Dr. Pain' Turner) Posting-number: Volume 18, Issue 15 Archive-name: wf/part01 Environment: #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'README' <<'END_OF_FILE' X WORDFIND X Mon Mar 8 14:14:15 1993 -- Scott Turner X XWF is a simple program to make "Word Search" squares. This is another Xcase of a simple game program that I was surprised to find didn't Xalready exist in the comp.sources.games archives; now it does. X XSee the man page for more information. END_OF_FILE if test 293 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(331 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 1 X README 1 X wf.6 1 X wf.c 1 X words 1 X words.2 1 END_OF_FILE if test 331 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(150 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# X# Makefile for WordFind Program X# X Xwf: wf.c X cc -O -o wf wf.c X Xclean: X rm *~ *.o wf X Xshar: X shar README Makefile wf.c wf.6 words words.2 > wf.shar END_OF_FILE if test 150 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'wf.6' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'wf.6'\" else echo shar: Extracting \"'wf.6'\" \(4020 characters\) sed "s/^X//" >'wf.6' <<'END_OF_FILE' X.TH WF 6 "Mar 8 1993" X.SH NAME Xwf \- simple program to create ``wordfind'' squares. X.SH SYNOPSIS Xwf [-hvdbarpc] [-x ] [-y ] [-t ] [-f <file>] X.SH DESCRIPTION XWF creates a word search puzzle that looks something like this: X X.ne 15 X.nf X.ft C X W*O*R*D F*I*N*D X X X +---------------+ X | L T A T I U D | X | T N U O L O Y | X | T I T I L A N | X | C A T U I T A | X | S I C U N T M | X | E E S U O H I | X | A I A D I U T | X | S A L O S O E | X +---------------+ X Xcat house Illinois dynamite X.ft P X.fi X XWordfind takes as input a file of words to hide in the word search Xsquare. By default the file is named "words" and located in the Xcurrent directory. Wordfind then tries to hide these words in a Xsquare (15x15 by default), and prints out the results as above on the Xstandard output. X X.SH OPTIONS X XThere are a variety of options to Wordfind: X X -h (Permit horizontal placement) X -v (Permit vertical placement) X -d (Permit diagonal placement) X -b (Permit backwards placement) X -a (Permit all placements) X XBy default, Wordfind will place words horizontally, vertically and Xdiagonally. Explicitly turning on a placement option turns off all of Xthe default placement options, i.e., ``wf -h'' places words only Xhorizontally. X X -r (Select randomly from wordlist) X XBy default, Wordfind tries to place words from the wordlist in the Xorder in which they appear. -r makes Wordfind try the wordlist in Xrandom order. X X -x <num> (Specify width of puzzle) X -y <num> (Specify height of puzzle) X XThe default size is 15x15; the maximum size is 20x20. X X -t <title> (Specify title of puzzle) X XThe default title is "W*O*R*D F*I*N*D". X X -p (Don't print words below the puzzle) X -c (Print clues instead of the words used) X XSee below for an explanation of "clues". X X -f <file> (Specify word list file) X XBy default Wordfind looks for a file named "words" in the current Xdirectory. -f can be used to override this. X X.SH THE WORD FILE X XThe word file has one word per line, optionally followed by a "clue". XA simple word file might look like this: X X.nf Xcat Xdog Xhouse XIllinois Xdynamite X.fi X XIt's important not to have any trailing blank lines in the file. X XIf you want the words at the bottom of the puzzle to be in Xalphabetical order (albeit line by line rather than by columns) you Xshould sort the input file. X XEach word can optionally be followed by a clue (up to 50 characters Xlong). This clue can be printed instead of the actual word by using Xthe -c option. This permits you to make, for instance, a wordfind Xsquare for a Spanish class: X X.nf Xgato cat Xpero dog Xcasa a house Xtonto fool X.fi X X.ne 15 X.ft C X.nf X W*O*R*D F*I*N*D X X X +---------------+ X | T C O E G O O | X | T R A A C T G | X | T P C S N T A | X | R T E O A O O | X | O E T R O T C | X | O A T N O A E | X | G G E N A A T | X +---------------+ X X cat dog house fool X.ft P X.fi X X.SH IMPLEMENTATION NOTES X X* Wordfind does not try to make the "best" wordfind square. It Xdoesn't do any search or clever tricks to try to fit in the most Xwords. Frankly, that's a bit too anal-retentive for a program to make Xword search puzzles, if you ask me. X X* Wordfind does do one clever thing: it fills in the unused spots in Xthe word square with letters chosen from the words that are actually Xin the word square. This makes the square a little more challenging. X X.SH BUGS X XNone. X X.SH AUTHOR X XScott R. Turner (srt@aerospace.aero.org) X END_OF_FILE if test 4020 -ne `wc -c <'wf.6'`; then echo shar: \"'wf.6'\" unpacked with wrong size! fi # end of 'wf.6' fi if test -f 'wf.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'wf.c'\" else echo shar: Extracting \"'wf.c'\" \(8416 characters\) sed "s/^X//" >'wf.c' <<'END_OF_FILE' X#include <stdio.h> X#include <ctype.h> X#include <string.h> X/* X * WORDFIND X * Mon Oct 26 10:00:50 1992 -- Scott R. Turner X * X * Build word search type puzzles. X * X */ X X/* X * The wordfind square. X * X */ X#define MAXX 20 X#define MAXY 20 Xchar wfs[MAXX][MAXY]; X X/* X * The word list. X * X */ X#define MAXWORDS 1000 X#define MAXWORDLEN 20 X#define MAXCLUELEN 50 Xint numwords = 0; Xchar wl[MAXWORDS][MAXWORDLEN]; Xchar clues[MAXWORDS][MAXCLUELEN]; Xint used[MAXWORDS]; X X/* X * Global Options X * X * -h Horizontal X * -v Vertical X * -d Diagonal X * -b Backwards X * X * -r Random selections from wordlist X * X * -x <num> Horizontal size of puzzle X * -y <num> Vertical size of puzzle X * X * -t <str> Title of puzzle X * -p Don't print words to find below puzzle X * -c print clues instead of words X * X * -f <file> Word list X * X */ Xint backwards = 0; Xint randselect = 0; Xint xsize = 15, ysize = 15; Xchar title[80] = "W*O*R*D F*I*N*D"; Xint printwords = 1, printclues = 0; Xchar wordfile[80] = "words"; X X/* X * First column is horizontal offset. X * Second column is vertical offset. X * X */ Xint dirs[8][2] = {{1,0}, X {0,1}, X {1,1}, X {1,-1}, X {-1,0}, X {0,-1}, X {-1,-1}, X {-1,1}}; X/* X * Which directions are permitted? X * X */ Xint permitted[8] = {0,0,0,0,0,0,0,0}; X Xmain (argc, argv) Xchar *argv[]; X{ X char s; X int i,j; X FILE *wf; X X while (--argc > 0) { X argv++; X if ((*argv)[0] == '-') { X s = (*argv)[1]; X switch (s) { X case 'a': X for(i=0;i<8;i++) permitted[i] = 1; X break; X case 'h': X permitted[0] = 1; X break; X case 'v': X permitted[1] = 1; X break; X case 'd': X permitted[2] = 1; X permitted[3] = 1; X break; X case 'b': X backwards = 1; X break; X case 'r': X randselect = 1; X break; X case 'p': X printwords = 0; X break; X case 'c': X printclues = 1; X break; X case 'x': X xsize = atoi((*++argv)); X if (xsize > 20) xsize = 20; X if (xsize < 1) xsize = 1; X argc--; X break; X case 'y': X ysize = atoi((*++argv)); X if (ysize > 20) ysize = 20; X if (ysize < 1) ysize = 1; X argc--; X break; X case 't': X (void) strcpy(title,(*++argv)); X argc--; X break; X case 'f': X (void) strcpy(wordfile,(*++argv)); X argc--; X break; X default: X fprintf(stderr,"Unknown option: %c\n",s); X fprintf(stderr,"Options:\n"); X fprintf(stderr," -h (Permit horizontal placement)\n"); X fprintf(stderr," -v (Permit vertical placement)\n"); X fprintf(stderr," -d (Permit diagonal placement)\n"); X fprintf(stderr," -b (Permit backwards placement)\n"); X fprintf(stderr," -a (Permit all placements)\n"); X fprintf(stderr," -r (Select randomly from wordlist)\n"); X fprintf(stderr," -x <num> (Specify width of puzzle)\n"); X fprintf(stderr," -y <num> (Specify height of puzzle)\n"); X fprintf(stderr," -t <title> (Specify title of puzzle)\n"); X fprintf(stderr," -p (Don't print words below the puzzle)\n"); X fprintf(stderr," -c (Print clues instead of the words used)\n") ; X fprintf(stderr," -f <file> (Specify word list file)\n"); X exit(1); X }; X } else { X (void) strcpy(wordfile,(*argv)); X }; X }; X X /* X * Do default placements? X * X */ X j = 0; X for(i=0;i<8;i++) j += permitted[i]; X if (!j) { X permitted[0] = 1; X permitted[1] = 1; X permitted[2] = 1; X }; X X /* X * Backwards check. X * X */ X if (backwards) X for(i=0;i<4;i++) permitted[i+4] = permitted[i]; X X /* X * See if we can read the word file. X * X */ X if ((wf = fopen(wordfile,"r")) == NULL) { X fprintf(stderr,"Unable to open wordfile: %s.\n",wordfile); X fprintf(stderr,"Specify correct wordfile with -f.\n"); X exit(-1); X }; X /* X * Word file consists of a word, a space and the remainder of the X * line, which is the "clue". X * X */ X while(fscanf(wf,"%s",wl[numwords]) != EOF) { X fgets(clues[numwords],MAXCLUELEN,wf); X for(i=strlen(clues[numwords])-1;isspace(clues[numwords][i]);i--) X clues[numwords][i] = 0; X numwords++; X }; X for(i=0;i<numwords;i++) used[i] = 0; X X /* X * Print the title, centered. X * X */ X for(i=0;i<((80-strlen(title))/2);i++) putchar(' '); X printf("%s\n\n",title); X X /* X * Initialize. X * X */ X for(i=0;i<xsize;i++) X for(j=0;j<ysize;j++) wfs[i][j] = 0; X X /* X * Now for each word in the wordlist, try to place the word X * somewhere in the puzzle. X * X */ X srandom(time(0)); X if (randselect) { X for(i=0;i<numwords;i++) { X j = random(0)%numwords; X while (used[j]) { X j = (j+1)%numwords; X }; X placeword(j); X } X } else { X for(i=0;i<numwords;i++) placeword(i); X }; X X /* X * Now go through and fill in all the spaces in the board. X * X */ X fillboard(); X X /* X * Print the board out. X * X */ X printboard(); X X /* X * Print out the words to be found. X * X */ X print_words(); X} X X/* X * Placeword X * X * Using the available options, try to place the current word in the X * puzzle. Return 0 if unable to do so. X * X */ Xint placeword(word) X int word; X{ X int tried[8]; X int i,x,y,start_dir,start_x,start_y; X X X /* X * Initialize the directions we've tried. X * X */ X for(i=0;i<8;i++) tried[i] = !permitted[i]; X X /* X * Start somewhere randomly and then cycle around until you get X * back to your starting point or you manage to place the word. X * X */ X i = start_dir = random(0)%8; X do { X if (!tried[i]) { X tried[i] = 1; X /* X * Pick a random starting spot somewhere on the board and start X * trying this direction from that spot. X * X */ X y = start_y = random(0)%ysize; X do { X x = start_x = random(0)%xsize; X do { X if (try(x,y,i,word,0)) { X try(x,y,i,word,1); X goto success; X }; X x=(x+1)%xsize; X } while (x != start_x); X y=(y+1)%ysize; X } while (y != start_y); X }; X i=(i+1)%8; X } while (i != start_dir); X used[word] = -1; X return(0); X success: X used[word] = 1; X return(1); X} X X/* X * TRY X * X * Try placing a word in a given location in a given direction. X * X */ Xint try(x,y,dir,word,place) X int x,y,dir,word,place; X{ X int len; X int cnt; X X /* X * The length of the word can be used to rule out some places X * immediately. X * X */ X len = strlen(wl[word]); X if (dirs[dir][0] == 1 && (len + x) > xsize) return(0); X if (dirs[dir][0] == -1 && (len - 1) > x) return(0); X if (dirs[dir][1] == 1 && (len + y) > ysize) return(0); X if (dirs[dir][1] == -1 && (len - 1) > y) return(0); X X /* X * Otherwise, we have to try to place the word. X * X */ X for(cnt=0;cnt<len;cnt++) { X if (wfs[x][y] != 0 && wfs[x][y] != wl[word][cnt]) { X return(0); X }; X if (place) wfs[x][y] = wl[word][cnt]; X x += dirs[dir][0]; X y += dirs[dir][1]; X }; X return(1); X}; X X/* X * Printboard X * X * Print the board. X * X */ Xint printboard() X{ X int i,j,prefix; X X prefix = (76-(xsize*2))/2; X X putchar('\n'); X for(i=0;i<prefix;i++) putchar(' '); X putchar('+'); X for(i=0;i<xsize;i++) { X putchar('-'); X putchar('-'); X }; X putchar('-'); X putchar('+'); X putchar('\n'); X for(j=0;j<ysize;j++) { X for(i=0;i<prefix;i++) putchar(' '); X putchar('|'); X putchar(' '); X for(i=0;i<xsize;i++) { X if (wfs[i][j] == 0) putchar(' '); X else putchar(toupper(wfs[i][j])); X putchar(' '); X }; X putchar('|'); X putchar('\n'); X }; X for(i=0;i<prefix;i++) putchar(' '); X putchar('+'); X for(i=0;i<xsize;i++) { X putchar('-'); X putchar('-'); X }; X putchar('-'); X putchar('+'); X putchar('\n'); X}; X X/* X * Fillboard X * X * Fill the spaces in the board with letters chosen randomly from the X * words we used. X * X */ Xint fillboard() X{ X int word,spot; X int i,j; X X for(i=0;i<xsize;i++) X for(j=0;j<ysize;j++) X if (wfs[i][j] == 0) { X do { X word = random(0)%numwords; X } while (used[word] == -1); X spot = random(0)%strlen(wl[word]); X wfs[i][j] = wl[word][spot]; X }; X}; X X/* X * Printwords X * X * Print out the words actually in the puzzle. X * X */ Xint print_words() X{ X int i, cnt; X X cnt = 0; X for(i=0;i<numwords;i++) X if (used[i] == 1) { X if (!(cnt%4)) putchar('\n'); X cnt++; X if (printclues) X printf("%-20s",clues[i]); X else X printf("%-20s",wl[i]); X }; X putchar('\n'); X putchar('\n'); X}; END_OF_FILE if test 8416 -ne `wc -c <'wf.c'`; then echo shar: \"'wf.c'\" unpacked with wrong size! fi # end of 'wf.c' fi if test -f 'words' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'words'\" else echo shar: Extracting \"'words'\" \(421 characters\) sed "s/^X//" >'words' <<'END_OF_FILE' Xsanctify Xsanctimonious Xsanction Xsanctity Xsanctuary Xsand Xsandal Xsandbag Xsandblast Xsandpaper Xsandpile Xsandpiper Xsandstone Xsandwich Xsandy Xsane Xsang Xsanguine Xsanitarium Xsanitary Xsank Xsans Xtreacherous Xtreachery Xtread Xtreadle Xtreadmill Xtreason Xtreasonous Xtreasure Xtreasury Xtreat Xtreatise Xtreaty Xtreble Xtree Xtreetop Xtrefoil Xtrek Xtrellis Xtremble Xtremendous Xtremor Xtrench Xtrenchant Xtrend Xtrendy Xtrepidation Xtrespass Xtress Xtrestle END_OF_FILE if test 421 -ne `wc -c <'words'`; then echo shar: \"'words'\" unpacked with wrong size! fi # end of 'words' fi if test -f 'words.2' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'words.2'\" else echo shar: Extracting \"'words.2'\" \(2533 characters\) sed "s/^X//" >'words.2' <<'END_OF_FILE' Xgato cat Xpero dog Xmantequila butter Xsilla chair Xsillon armchair Xhamburguesa hamburger Xalumno student Xamigo friend Xautomovil car Xcalle street Xcasa house Xcampo country Xcarta letter Xciudad city Xcomedor dining room Xcosa thing Xcuarto room Xdia day Xedificio building Xescritorio desk Xesposa wife Xfamilia family Xhermano brother Xhermana sister Xhijo son Xhija daughter Xhombre man Xlapiz pencil Xlengua tongue Xlugar place Xlibro book Xmadre mother Xmesa table Xmujer woman Xmaestro teacher Xmuchacho boy Xmuchacha girl Xnino small boy Xnina small girl Xobjeto object Xpadre father Xpapel paper Xplumafuente fountain pen Xpuerta door Xsala living room Xsenor sir Xsenora madame Xtio uncle Xtia aunt Xtren train Xventana window Xviaje trip Xprimavera Spring Xagente agent Xcommerciante businessman Xestudiante student Xejemplo example Xprimero first Xconversacion conversation Xnombre name Xpregunta question Xprogreso progress Xcomo like Xque that Xdonde where Xquien who Xal to the Xcon with Xporque because Xbueno good Xexcelente excellent Xgrande big Ximportante important Xmalo bad Xmi my Xmucho much Xnecesario necessary Xotro other Xpequeno small Xsentado seated Xsu his Xtodo all Xpoco little Xalli there Xaqui here Xbasta enough Xcasi almost Xdiligentemente diligently Xmuy very Xrapidamente rapidly Xsiempre always Xtambien also Xademas besides Xsi if Xya already Xalmuerzo lunch Xasiento seat Xcara face Xcamino road Xcliente client Xcoche car Xcomienzo beginning Xcostumbre custom Xcura priest Xdesayuno breakfast Xestrella star Xfiesta party Xhistoria history Xhuevo egg Xjugo juice Xluz light Xmanzana apple Xnaranja orange Xnorte north Xojo eye Xpanecillo roll Xpanqueques pancakes Xpelicula film Xpluma pen Xpostre dessert Xrecuerdo memory Xrio river Xsur South Xturista tourist Xtelefono telephone Xacordarse to remember Xbuscar to look for Xcaminar to walk Xcelebrar to celebrate Xcomer to eat Xcomerse to eat up Xcruzar to cross Xdeber to ought to Xdejar to let Xdesayunarse breakfast Xdormirse to fall asleep Xencontrar to find Xirse to go away Xhallar to find Xlavar to wash Xlevantarse to get up Xllevar to carry Xllamar to call Xponer to put Xoir to hear Xpermitir to permit Xpreferir to prefer Xreir to laugh Xsonreir to smile Xrecordar to remember Xsentarse to sit down Xsentir to regret Xsentirse to feel Xsignificar to mean Xtratar to try Xterminar to end Xvestirse to dress oneself Xvolver to return Xancho wide Xbarato cheap Xcaro expensive Xconocido well-known Xchico small Xdesocupado unoccupied Xjunto together Xmayor older Xocupado occupied Xobscuro dark Xraro rare Xtal such Xordinariamente ordinarily Xnaturalmente naturally Xtemprano early Xcontra against END_OF_FILE if test 2533 -ne `wc -c <'words.2'`; then echo shar: \"'words.2'\" unpacked with wrong size! fi # end of 'words.2' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0