home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File PlainSquare.m
-
- Squares are the variables that guide the search. This file implements simple squares for plain depth first search.
-
- */
-
- #import <appkit/appkit.h>
-
- #import "Plain.h"
- #import "Puzzle.h"
- #import "Crossword.h"
- #import "CrosswordSquare.h"
- #import "Inspector.h"
-
-
- /* ———————————————————————————————————————————————————————————————————————————— */
-
-
- #define position(i) ((wordPosition *) [words elementAt: i])
- #define forword(c) ((c) == WILDCARD ? (c):(c) + 'a')
- #define forcell(c) ((c) == WILDCARD ? EMPTY:(c) + 'A')
-
-
- /* ———————————————————————————————————————————————————————————————————————————— */
-
-
- @implementation PlainSquare
-
- - (float) efficiency { return efficiency; }
-
-
- /* ———————————————————————————————————————————————————————————————————————————— */
-
-
- - initPuzzle: (id) thePuzzle cell: (id) theCell
- {
- [super init];
-
- puzzle = thePuzzle;
- cell = theCell;
- letter = WILDCARD;
- tried = 0;
- words = [[Storage alloc]
- initCount: 0 elementSize: sizeof(wordPosition) description: ""];
-
- return self;
- }
-
-
- - free
- {
- [words free];
- [super free];
-
- return self;
- }
-
-
- - addToWord: (id) word at: (int) i
- {
- wordPosition position;
-
- position.word = word;
- position.i = i;
- [words addElement: &position];
-
- return self;
- }
-
-
- - startOver
- {
- return self;
- }
-
-
- /* ———————————————————————————————————————————————————————————————————————————— */
-
-
- - setStatus: (int) flag
- {
- status |= flag;
- [self adjustColor];
-
- return self;
- }
-
-
- - clearStatus: (int) flag
- {
- status &= ~flag;
- [self adjustColor];
-
- return self;
- }
-
-
- - hilight
- {
- [self setStatus: HILIGHT];
- [[puzzle getCrossword] drawCellInside: cell];
-
- return self;
- }
-
-
- - unhilight
- {
- [self clearStatus: HILIGHT];
- [[puzzle getCrossword] drawCellInside: cell];
-
- return self;
- }
-
-
- - adjustColor
- {
- int i, n;
-
- n = status & ~(status - 1);
- i = 0;
- while (n > 0)
- {
- i++;
- n >>= 1;
- }
-
- [cell setColor: [[puzzle getInspector] getColor: i]];
- return self;
- }
-
-
- /* ———————————————————————————————————————————————————————————————————————————— */
-
-
- - (BOOL) fillNext
- {
- char choice;
-
- if ((choice = [self chooseLetter]) == WILDCARD) [self clear];
- [[self setLetter: choice] show];
-
- return (letter == WILDCARD) ? NO:YES;
- }
-
-
- - erase
- {
- [[[self clear] setLetter: WILDCARD] show];
- return self;
- }
-
-
- - clear
- {
- letter = WILDCARD;
- tried = 0;
-
- return self;
- }
-
-
- - show
- {
- [[puzzle getCrossword] putLetter: forcell(letter) inSquare: cell];
- DPSFlush();
-
- return self;
- }
-
-
- - setLetter: (char) theLetter
- {
- wordPosition * position;
- int i;
-
- if ((letter = theLetter) != WILDCARD) tried |= (1 << letter);
- i = [words count];
-
- while (i--)
- {
- position = position(i);
- [position->word changeLetter: position->i to: forword(letter)];
- }
-
- return self;
- }
-
-
- - (char) chooseLetter
- {
- int i, max;
- char best;
- BOOL findbest;
-
- best = WILDCARD;
- findbest = [[puzzle getInspector] getOption: BESTLETTER];
-
- for (max = 0, i = 0; i < LETTERS; i++)
- if ((count[i] > max) && !(tried & (1 << i)))
- {
- max = count[i];
- best = i;
- if (!findbest) break;
- }
-
- return best;
- }
-
-
- /* ———————————————————————————————————————————————————————————————————————————— */
-
-
- - update
- {
- wordPosition * position;
- countTable table;
- int i, j;
-
- if (letter == WILDCARD)
- {
- for (j = 0; j < LETTERS; j++) count[j] = 1;
- i = [words count];
-
- while (i--)
- {
- position = position(i);
- table = [position->word getCount];
- for (j = 0; j < LETTERS; j++) count[j] *= table[position->i][j];
- }
-
- for (i = 0, j = 0; j < LETTERS; j++) i += (count[j] != 0);
- if ([[puzzle getInspector] getOption: BESTSQUARE])
-
- efficiency = 1.0 / (i + 1.0); else
- efficiency = (i == 0) + 1.0;
- }
-
- return self;
- }
-
-
- @end