Gut and rebuild YES() with cleaner approach that doesn't rely on packing.
The new support functions get_input() and echo_input() (and others not made yet) will eventually replace GETIN() and MAPLIN().
This commit is contained in:
parent
0dd961701f
commit
550734fd3f
6 changed files with 116 additions and 25 deletions
|
@ -792,7 +792,7 @@ static int pour(token_t verb, token_t obj)
|
||||||
static int quit(FILE *input)
|
static int quit(FILE *input)
|
||||||
/* Quit. Intransitive only. Verify intent and exit if that's what he wants. */
|
/* Quit. Intransitive only. Verify intent and exit if that's what he wants. */
|
||||||
{
|
{
|
||||||
if (YES(input, REALLY_QUIT, OK_MAN, OK_MAN))
|
if (YES(REALLY_QUIT, OK_MAN, OK_MAN))
|
||||||
terminate(quitgame);
|
terminate(quitgame);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
|
@ -820,7 +820,7 @@ static int read(FILE *input, token_t verb, token_t obj)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
if (obj == OYSTER && !game.clshnt) {
|
if (obj == OYSTER && !game.clshnt) {
|
||||||
game.clshnt = YES(input, CLUE_QUERY, WAYOUT_CLUE, OK_MAN);
|
game.clshnt = YES(CLUE_QUERY, WAYOUT_CLUE, OK_MAN);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
PSPEAK(obj, OBJTXT[obj] + game.prop[obj]);
|
PSPEAK(obj, OBJTXT[obj] + game.prop[obj]);
|
||||||
|
|
5
advent.h
5
advent.h
|
@ -83,6 +83,7 @@ extern bool oldstyle, editline, prompt;
|
||||||
/* b is not needed for POSIX but harmless */
|
/* b is not needed for POSIX but harmless */
|
||||||
#define READ_MODE "rb"
|
#define READ_MODE "rb"
|
||||||
#define WRITE_MODE "wb"
|
#define WRITE_MODE "wb"
|
||||||
|
extern void* xmalloc(size_t size);
|
||||||
extern char* xstrdup(const char*);
|
extern char* xstrdup(const char*);
|
||||||
extern void packed_to_token(long, char token[]);
|
extern void packed_to_token(long, char token[]);
|
||||||
extern void speak(const char*);
|
extern void speak(const char*);
|
||||||
|
@ -90,7 +91,9 @@ extern void PSPEAK(vocab_t,int);
|
||||||
extern void RSPEAK(vocab_t);
|
extern void RSPEAK(vocab_t);
|
||||||
extern void SETPRM(long,long,long);
|
extern void SETPRM(long,long,long);
|
||||||
extern bool GETIN(FILE *,token_t*,token_t*,token_t*,token_t*);
|
extern bool GETIN(FILE *,token_t*,token_t*,token_t*,token_t*);
|
||||||
extern long YES(FILE *,vocab_t,vocab_t,vocab_t);
|
extern void echo_input(FILE*, char*, char*);
|
||||||
|
extern char* get_input(void);
|
||||||
|
extern bool YES(vocab_t, vocab_t, vocab_t);
|
||||||
extern long GETTXT(bool,bool,bool);
|
extern long GETTXT(bool,bool,bool);
|
||||||
extern token_t MAKEWD(long);
|
extern token_t MAKEWD(long);
|
||||||
extern long VOCAB(long,long);
|
extern long VOCAB(long,long);
|
||||||
|
|
8
main.c
8
main.c
|
@ -135,7 +135,7 @@ int main(int argc, char *argv[])
|
||||||
game.loc = LOC_START;
|
game.loc = LOC_START;
|
||||||
game.limit = 330;
|
game.limit = 330;
|
||||||
if (!rfp) {
|
if (!rfp) {
|
||||||
game.novice = YES(stdin, WELCOME_YOU, CAVE_NEARBY, NO_MESSAGE);
|
game.novice = YES(WELCOME_YOU, CAVE_NEARBY, NO_MESSAGE);
|
||||||
if (game.novice)game.limit = 1000;
|
if (game.novice)game.limit = 1000;
|
||||||
} else {
|
} else {
|
||||||
restore(rfp);
|
restore(rfp);
|
||||||
|
@ -251,11 +251,11 @@ static void checkhints(FILE *cmdin)
|
||||||
|
|
||||||
/* Fall through to hint display */
|
/* Fall through to hint display */
|
||||||
game.hintlc[hint] = 0;
|
game.hintlc[hint] = 0;
|
||||||
if (!YES(cmdin, HINTS[hint][3], NO_MESSAGE, OK_MAN))
|
if (!YES(HINTS[hint][3], NO_MESSAGE, OK_MAN))
|
||||||
return;
|
return;
|
||||||
SETPRM(1, HINTS[hint][2], HINTS[hint][2]);
|
SETPRM(1, HINTS[hint][2], HINTS[hint][2]);
|
||||||
RSPEAK(HINT_COST);
|
RSPEAK(HINT_COST);
|
||||||
game.hinted[hint] = YES(cmdin, WANT_HINT, HINTS[hint][4], OK_MAN);
|
game.hinted[hint] = YES(WANT_HINT, HINTS[hint][4], OK_MAN);
|
||||||
if (game.hinted[hint] && game.limit > WARNTIME)
|
if (game.hinted[hint] && game.limit > WARNTIME)
|
||||||
game.limit += WARNTIME * HINTS[hint][2];
|
game.limit += WARNTIME * HINTS[hint][2];
|
||||||
}
|
}
|
||||||
|
@ -485,7 +485,7 @@ static void croak(FILE *cmdin)
|
||||||
terminate(endgame);
|
terminate(endgame);
|
||||||
}
|
}
|
||||||
/* FIXME: Arithmetic on message numbers */
|
/* FIXME: Arithmetic on message numbers */
|
||||||
else if (game.numdie == MAXDIE || !YES(cmdin, WATCH_IT + game.numdie * 2, WHICH_WAY + game.numdie * 2, OK_MAN))
|
else if (game.numdie == MAXDIE || !YES(WATCH_IT + game.numdie * 2, WHICH_WAY + game.numdie * 2, OK_MAN))
|
||||||
terminate(endgame);
|
terminate(endgame);
|
||||||
else {
|
else {
|
||||||
game.place[WATER] = game.place[OIL] = NOWHERE;
|
game.place[WATER] = game.place[OIL] = NOWHERE;
|
||||||
|
|
107
misc.c
107
misc.c
|
@ -10,6 +10,17 @@
|
||||||
#include "linenoise/linenoise.h"
|
#include "linenoise/linenoise.h"
|
||||||
#include "newdb.h"
|
#include "newdb.h"
|
||||||
|
|
||||||
|
void* xmalloc(size_t size)
|
||||||
|
{
|
||||||
|
void* ptr = malloc(size);
|
||||||
|
if (ptr == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Out of memory!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
char* xstrdup(const char* s)
|
char* xstrdup(const char* s)
|
||||||
{
|
{
|
||||||
char* ptr = strdup(s);
|
char* ptr = strdup(s);
|
||||||
|
@ -185,25 +196,101 @@ bool GETIN(FILE *input,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long YES(FILE *input, vocab_t x, vocab_t y, vocab_t z)
|
void echo_input(FILE* destination, char* input_prompt, char* input)
|
||||||
|
{
|
||||||
|
size_t len = strlen(input_prompt) + strlen(input) + 1;
|
||||||
|
char* prompt_and_input = (char*) xmalloc(len);
|
||||||
|
strcpy(prompt_and_input, input_prompt);
|
||||||
|
strcat(prompt_and_input, input);
|
||||||
|
fprintf(destination, "%s\n", prompt_and_input);
|
||||||
|
free(prompt_and_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* get_input()
|
||||||
|
{
|
||||||
|
// Set up the prompt
|
||||||
|
char input_prompt[] = "> ";
|
||||||
|
if (!prompt)
|
||||||
|
input_prompt[0] = '\0';
|
||||||
|
|
||||||
|
// Print a blank line if game.blklin tells us to.
|
||||||
|
if (game.blklin == true)
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
char* input;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (editline)
|
||||||
|
input = linenoise(input_prompt);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input = NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
if (isatty(0))
|
||||||
|
printf("%s", input_prompt);
|
||||||
|
getline(&input, &n, stdin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == NULL) // Got EOF; quit.
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
else if (input[0] == '#') // Ignore comments.
|
||||||
|
continue;
|
||||||
|
else // We have a 'normal' line; leave the loop.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip trailing newlines from the input
|
||||||
|
input[strcspn(input, "\n")] = 0;
|
||||||
|
|
||||||
|
linenoiseHistoryAdd(input);
|
||||||
|
|
||||||
|
if (!isatty(0))
|
||||||
|
echo_input(stdout, input_prompt, input);
|
||||||
|
|
||||||
|
if (logfp)
|
||||||
|
echo_input(logfp, input_prompt, input);
|
||||||
|
|
||||||
|
return(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YES(vocab_t question, vocab_t yes_response, vocab_t no_response)
|
||||||
/* Print message X, wait for yes/no answer. If yes, print Y and return true;
|
/* Print message X, wait for yes/no answer. If yes, print Y and return true;
|
||||||
* if no, print Z and return false. */
|
* if no, print Z and return false. */
|
||||||
{
|
{
|
||||||
token_t reply, junk1, junk2, junk3;
|
char* reply;
|
||||||
|
bool outcome;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
RSPEAK(x);
|
RSPEAK(question);
|
||||||
GETIN(input, &reply, &junk1, &junk2, &junk3);
|
|
||||||
if (reply == MAKEWD(250519) || reply == MAKEWD(25)) {
|
reply = get_input();
|
||||||
RSPEAK(y);
|
|
||||||
return true;
|
char* firstword = (char*) xmalloc(strlen(reply));
|
||||||
|
sscanf(reply, "%s", firstword);
|
||||||
|
|
||||||
|
for (int i = 0; i < strlen(firstword); ++i)
|
||||||
|
firstword[i] = tolower(firstword[i]);
|
||||||
|
|
||||||
|
int yes = strncmp("yes", reply, sizeof("yes") - 1);
|
||||||
|
int y = strncmp("y", reply, sizeof("y") - 1);
|
||||||
|
int no = strncmp("no", reply, sizeof("no") - 1);
|
||||||
|
int n = strncmp("n", reply, sizeof("n") - 1);
|
||||||
|
|
||||||
|
if (yes == 0 || y == 0) {
|
||||||
|
RSPEAK(yes_response);
|
||||||
|
outcome = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (reply == MAKEWD(1415) || reply == MAKEWD(14)) {
|
else if (no == 0 || n == 0) {
|
||||||
RSPEAK(z);
|
RSPEAK(no_response);
|
||||||
return false;
|
outcome = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
RSPEAK(PLEASE_ANSWER);
|
RSPEAK(PLEASE_ANSWER);
|
||||||
}
|
}
|
||||||
|
linenoiseFree(reply);
|
||||||
|
return(outcome);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Line-parsing routines (GETTXT, MAKEWD, PUTTXT, SHFTXT) */
|
/* Line-parsing routines (GETTXT, MAKEWD, PUTTXT, SHFTXT) */
|
||||||
|
|
|
@ -44,7 +44,7 @@ int suspend(FILE *input)
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
|
|
||||||
RSPEAK(SUSPEND_WARNING);
|
RSPEAK(SUSPEND_WARNING);
|
||||||
if (!YES(input, THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
|
if (!YES(THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
|
||||||
game.saved = game.saved + 5;
|
game.saved = game.saved + 5;
|
||||||
|
|
||||||
while (fp == NULL) {
|
while (fp == NULL) {
|
||||||
|
@ -83,7 +83,7 @@ int resume(FILE *input)
|
||||||
|
|
||||||
if (game.loc != 1 || game.abbrev[1] != 1) {
|
if (game.loc != 1 || game.abbrev[1] != 1) {
|
||||||
RSPEAK(RESUME_ABANDON);
|
RSPEAK(RESUME_ABANDON);
|
||||||
if (!YES(input, THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
|
if (!YES(THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fp == NULL) {
|
while (fp == NULL) {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
|
||||||
Welcome to Adventure!! Would you like instructions?
|
Welcome to Adventure!! Would you like instructions?
|
||||||
|
|
||||||
> > >
|
> n
|
||||||
|
|
||||||
You are standing at the end of a road before a small brick building.
|
You are standing at the end of a road before a small brick building.
|
||||||
Around you is a forest. A small stream flows out of the building and
|
Around you is a forest. A small stream flows out of the building and
|
||||||
down a gully.
|
down a gully.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue