Files
Arquivotheca.SunOS-4.1.4/games/tool/boggletool/lists.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

333 lines
8.7 KiB
C

#ifndef lint
static char sccsid[] = "@(#)lists.c 1.1 94/10/31 Copyr 1985 Sun Micro";
#endif
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
/*
* lists.c: manage the lists of words found by the human and the computer
*/
#include <suntool/tool_hs.h>
#include <stdio.h>
#include "defs.h"
#define MAXWORDS 1000 /* maximum number of words that can be input */
struct item { /* item in a list of words */
char *word; /* pointer to memory for word */
int x, y; /* location on screen (not defined for computer's words) */
} humanwords[MAXWORDS], compwords[MAXWORDS]; /* the two lists */
int humanwordcnt, compwordcnt; /* index of next free space in respective list */
char *malloc();
/*
* freehumanwords: free malloc'ed space in human word list
*/
freehumanwords()
{
while (humanwordcnt)
if (humanwords[--humanwordcnt].word != NULL)
free(humanwords[humanwordcnt]);
}
/*
* freecompwords: free malloc'ed space in computer word list
*/
freecompwords()
{
while (compwordcnt)
if (compwords[--compwordcnt].word != NULL)
free(compwords[compwordcnt]);
}
/*
* addhumanword: add a word to human list; also caches the screen location
* of the word for redisplay
*/
addhumanword(str, x, y)
char *str; /* word to add */
int x, y; /* screen position where word is drawn */
{
if (humanwordcnt >= MAXWORDS) {
fprintf(stderr, "Too many words!\n");
exit(1);
}
humanwords[humanwordcnt].word = malloc(strlen(str) + 1);
if (humanwords[humanwordcnt].word == NULL) {
fprintf(stderr, "Out of memory!\n");
exit(1);
}
strcpy(humanwords[humanwordcnt].word, str);
humanwords[humanwordcnt].x = x;
humanwords[humanwordcnt].y = y;
humanwordcnt++;
}
/*
* addcompword: add a word to computer list
*/
addcompword(str)
char *str; /* word to add */
{
if (compwordcnt >= MAXWORDS) {
fprintf(stderr, "Too many words!\n");
exit(1);
}
compwords[compwordcnt].word = malloc(strlen(str) + 1);
if (compwords[compwordcnt].word == NULL) {
fprintf(stderr, "Out of memory!\n");
exit(1);
}
compwords[compwordcnt].x = compwords[compwordcnt].y = -1;
strcpy(compwords[compwordcnt++].word, str);
}
/*
* isduplicate: return true if human has already typed in the word str
*/
isduplicate(str)
char *str; /* word to check */
{
int index;
for (index = 0; index < humanwordcnt; index++) {
if (humanwords[index].word == NULL)
continue;
if (!strcmp(humanwords[index].word, str)) {
if (humanwords[index].x >= 0 && humanwords[index].y >= 0) {
feedback_x = humanwords[index].x;
feedback_y = humanwords[index].y;
feedback_w = min(strlen(str), MAXWORDLEN) * fontwidth;
pw_write(bogwin, feedback_x, feedback_y, feedback_w, fontheight, PIX_NOT(PIX_DST), NULL, 0, 0);
} else {
feedback_w = -1; /* off screen */
}
return(1);
}
}
return(0);
}
/*
* comparelists: sort the human's words and remove them from the computer's
* word list to end up with a list of words the human did not
* find
*/
comparelists()
{
int compare(), i1, i2, i3, val;
qsort(humanwords, humanwordcnt, sizeof(struct item), compare);
i1 = 0;
while (i1 < humanwordcnt - 1) { /* remove duplicates in human list */
if (!strcmp(humanwords[i1].word, humanwords[i1 + 1].word)) {
for (i2 = i1 + 1; i2 < humanwordcnt - 1; i2++)
humanwords[i2].word = humanwords[i2 + 1].word;
humanwordcnt--;
} else {
i1++;
}
}
i1 = i2 = 0; /* remove human's words from computer list */
while (i1 < humanwordcnt) {
while (strcmp(humanwords[i1].word, compwords[i2].word))
i2++;
--compwordcnt;
for (i3 = i2; i3 < compwordcnt; i3++)
compwords[i3].word = compwords[i3 + 1].word;
i1++;
}
}
compare(a, b)
struct item *a, *b;
{
if (a->word == NULL)
return(1);
if (b->word == NULL)
return(-1);
return(strcmp(a->word, b->word));
}
/*
* displaylists: display the two lists of words (words human found and
* words in grid that human didn't find)
*/
#define nextline(x, y) \
y += fontheight; \
x = (y < DISPLAY_BOTTOM) ? DISPLAY_RIGHT + BOARD_SPACING : 0; \
if (x % ((MAXWORDLEN + 1) * fontwidth) != 0) \
x += ((MAXWORDLEN + 1) * fontwidth) - (x % ((MAXWORDLEN + 1) * fontwidth))
displaylists()
{
int x, y, index, len;
long inqueue;
struct inputevent ie;
pw_write(bogwin, DISPLAY_RIGHT, 0, bogwidth - DISPLAY_RIGHT, DISPLAY_BOTTOM, PIX_SRC, 0, 0, 0);
pw_write(bogwin, 0, DISPLAY_BOTTOM, bogwidth, bogheight - DISPLAY_BOTTOM, PIX_SRC, 0, 0, 0);
y = -fontheight;
nextline(x, y);
if (humanwordcnt > 0) {
pw_text(bogwin, x, y + fontoffset, PIX_SRC, bogfont, "Words you found:");
nextline(x, y);
for (index = 0; index < humanwordcnt; index++) {
len = strlen(humanwords[index].word);
if (x + len * fontwidth > bogwidth) {
nextline(x, y);
}
pw_text(bogwin, x, y + fontoffset, PIX_SRC, bogfont, humanwords[index].word);
humanwords[index].x = x;
humanwords[index].y = y;
len = (len / 10 + 1) * 10;
x += len * fontwidth;
}
nextline(x, y);
nextline(x, y);
}
if (compwordcnt > 0) {
pw_text(bogwin, x, y + fontoffset, PIX_SRC, bogfont, "Words you missed:");
nextline(x, y);
for (index = 0; index < compwordcnt; index++) {
len = strlen(compwords[index].word);
if ((x + (len * fontwidth)) > bogwidth) {
nextline(x, y); /* brace are mandatory!!! */
}
pw_text(bogwin, x, y + fontoffset, PIX_SRC, bogfont, compwords[index].word);
compwords[index].x = x;
compwords[index].y = y;
len = (len / 10 + 1) * 10;
x += len * fontwidth;
}
nextline(x, y);
nextline(x, y);
}
pw_text(bogwin, x, y + fontoffset, PIX_SRC, bogfont, "Type any capital letter to play again...");
}
/*
* drawtypein: redraw the human's typed in words when the display size
* changes (rescale to fit the new window)
*/
drawtypein()
{
int index;
int full, len, c;
char buf[MAXWORDLEN+1];
buf[MAXWORDLEN] = '\0';
full = 0;
typein_x = typein_y = leftmargin = -1;
for (index = 0; index < humanwordcnt; index++) {
if (full || (full = nextscreenpos(&leftmargin, &typein_x, &typein_y))) { /* screen is full */
humanwords[index].x = humanwords[index].y = -1;
} else {
strncpy(buf, humanwords[index].word, MAXWORDLEN);
pw_text(bogwin, typein_x, typein_y + fontoffset, PIX_SRC, bogfont, buf);
if (strlen(humanwords[index].word) > MAXWORDLEN)
pw_write(bogwin, MAXWORDLEN * fontwidth, typein_y, fontwidth, fontheight, PIX_SRC, tri_right_pr, 0, 0);
humanwords[index].x = leftmargin;
humanwords[index].y = typein_y;
}
}
if (full)
pw_write(bogwin, leftmargin, typein_y, fontwidth * MAXWORDLEN,
fontheight, PIX_SRC, NULL, 0, 0);
else
(void) nextscreenpos(&leftmargin, &typein_x, &typein_y);
if (cwordlen != 0) {
if (cwordlen > MAXWORDLEN) {
pw_write(bogwin, leftmargin, typein_y, fontwidth, fontheight, PIX_SRC, tri_left_pr, 0, 0);
c = cwordlen - SCROLL_OVERLAP;
typein_x += fontwidth;
} else {
c = 0;
}
for (; c < cwordlen; c++) {
pw_char(bogwin, typein_x, typein_y + fontoffset, PIX_SRC, bogfont, cword[c]);
typein_x += fontwidth;
}
}
drawcursor();
if (feedback_w) { /* note: feedback_w < 0 means feedback was off screen */
feedback_w = 0; /* redraw feedback in the right place */
(void) isduplicate(cword);
}
}
/*
* removefeedback: make the position of the word that used to be displayed
* at x,y undefined so no feedback will be displayed; used
* when there are too many words to fit on the screen, and
* thus some of them must be overwritten
*/
removefeedback(x, y)
register x, y;
{
register index;
for (index = 0; index < humanwordcnt; index++) {
if (humanwords[index].x == x && humanwords[index].y == y) {
humanwords[index].x = humanwords[index].y = -1;
return;
}
}
}
#define isonword(x, y, wx, wy, ww) (x >= wx && x < wx + ww && y >= wy && y < wy + fontheight)
/*
* mouseonword: determine the word pointed to by the mouse at x,y and
* return a pointer to it
*/
char *
mouseonword(x, y)
register x, y;
{
register index;
register width;
for (index = 0; index < humanwordcnt; index++) {
if (state == PLAYING) {
width = MAXWORDLEN;
} else {
width = strlen(humanwords[index].word);
width += width - width % MAXWORDLEN;
}
width *= fontwidth;
if (isonword(x, y, humanwords[index].x, humanwords[index].y, width))
return(humanwords[index].word);
}
if (state == PLAYING) {
if (isonword(leftmargin, typein_y, humanwords[index].x, humanwords[index].y, MAXWORDLEN * fontwidth)) {
cword[cwordlen] = '\0';
return(cword);
}
return(NULL);
}
for (index = 0; index < compwordcnt; index++) {
width = strlen(compwords[index].word);
width += width - width % MAXWORDLEN;
width *= fontwidth;
if (isonword(x, y, compwords[index].x, compwords[index].y, width))
return(compwords[index].word);
}
return(NULL);
}