DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T h

⟦a4cd16f9a⟧ TextFile

    Length: 12429 (0x308d)
    Types: TextFile
    Names: »human.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Challenge/human.c« 

TextFile

#include "challenge.h"

char help_always = FALSE;
char helped = FALSE;
char fin_text[] = "game is finished, you can back up only";

human_interface()
{
    int valid_input = FALSE;
    char input[4];
    int i, suit, value, ptr, r;

    if(help_always) {
	help('*', FALSE);
	helped = TRUE;
    }
    while(!valid_input) {
    again:
	ptr = COMMAND_POS;
	move(COMMAND_LINE, ptr);
	clrtoeol();
	i = -1;
    again1:
	refresh();
	while(TRUE) {
	    i++;
	    input[i] = getch();
	    if((input[i] == '\n') ||
	       (input[i] == '\r')) {
		if(i-- == 0) goto again;
		break;
	    }
	    if(input[i] == _tty.sg_kill) {
		goto again;
	    }
	    if((input[i] == ('L' & 037)) ||
	       (input[i] == ('R' & 037))) {
		i--;
		clearok(curscr, TRUE);
		goto again1;
	    }
	    if(input[i] == '?' && i == 0) {
		if(!helped) {
		    help('*', TRUE);
		}
		helped = TRUE;
		goto again;
	    }
	    if(input[i] == _tty.sg_erase) {
		if(ptr > 10) {
		    ptr--;
		    i -= 2;
		    move(COMMAND_LINE, ptr);
		    addch(' ');
		}
		move(COMMAND_LINE, ptr);
		refresh();
	    } else if((input[i] == ' ') ||
		  (input[i] == '\t')) {
		i--;
	    } else if((i == 3) ||
		  (input[i] < ' ') ||
		  (input[i] > '|')) {
		i--;
		putchar(007);
		fflush(stdout);
	    } else {
		move(COMMAND_LINE, ptr);
		addch(input[i]);
		refresh();
		ptr++;
	    }
	}
	input[++i] = 0;
	for(i = 0; i < 4; i++) {
	    if(isalpha(input[i]) && isupper(input[i])) {
		input[i] = tolower(input[i]);
	    }
	}
	if(input[0] == '!') {
	    if(input[2] == 0) {
		r = extended_command(input[1]);
		if(r != 0) {
		    if(helped) {
			help(' ', FALSE);
			helped = FALSE;
		    }
		    return(r);
		}
		goto again;
	    }
	} else {
	    i = 0;
	    suit = -1;
	    value = -1;
	    switch(input[0]) {
	    case 's':
	    case 'c':
	    case 'd':
	    case 'h':
		suit = get_suit(input, &i);
		value = get_value(input, &i);
		break;
	    default:
		value = get_value(input, &i);
		suit = get_suit(input, &i);
	    }
	    if((input[0] == 'p') && (input[1] == 0)) {
		if(top < 0) {
		    move(COMMAND_LINE - 1, 1);
		    clrtoeol();
		    printw("there is nothing to pick up");
		    goto again;
		}
		if(nr_computer == 0 || nr_human == 0) {
		    move(COMMAND_LINE - 1, 1);
		    clrtoeol();
		    printw(fin_text);
		    goto again;
		}
		i = PICK_UP;
		valid_input = TRUE;
	    } else if((input[0] == 'z') && (input[1] == 0) && analysing) {
		if(nr_computer == 0 && top < 0) {
		    move(COMMAND_LINE - 1, 1);
		    clrtoeol();
		    printw("computer has nothing to do");
		    goto again;
		}
		if(nr_computer == 0 || nr_human == 0) {
		    move(COMMAND_LINE - 1, 1);
		    clrtoeol();
		    printw(fin_text);
		    goto again;
		}
		i = PASS;
		valid_input = TRUE;
	    } else if((input[0] == 'b') && (input[1] == 0) && analysing) {
		if(nr_moves < 2) {
		    move(COMMAND_LINE - 1, 1);
		    clrtoeol();
		    printw("you have not yet done any move");
		    goto again;
		}
		i = BACK_UP;
		valid_input = TRUE;
	    } else if((suit >= 0) && (value >= 0)) {
		if((nr_computer == 0 || nr_human == 0) &&
			(nr_human != max_card)) {
		    move(COMMAND_LINE - 1, 1);
		    clrtoeol();
		    printw(fin_text);
		    goto again;
		}
		if(input[i] == 0) {
		    i = have_it(value * 4 + suit);
		    if(i >= 0) {
			if(!valid(HUMAN, i)) {
			    move(COMMAND_LINE - 1, 1);
			    clrtoeol();
			    printw("you can not play that card");
			    goto again;
			} else {
			    valid_input = TRUE;
			}
		    } else {
			move(COMMAND_LINE - 1, 1);
			clrtoeol();
			printw("you do not have that card");
			goto again;
		    }
		}
	    }
	}
	if(!valid_input) {
	    move(COMMAND_LINE - 1, 1);
	    clrtoeol();
	    printw("i do not understand, please retype");
	}
    }
    if(helped) {
	help(' ', FALSE);
	helped = FALSE;
    }
    return(i);
}

get_suit(input, i)
    char *input;
    int *i;
{
    if(*i > 3) {
	return(-1);
    }
    switch(*(input + (*i)++)) {
    case 's':
	return(SPADES);
    case 'c':
	return(CLUBS);
    case 'd':
	return(DIAMONDS);
    case 'h':
	return(HEARTS);
    }
    return(-1);
}

get_value(input, i)
    char *input;
    int *i;
{
    if(*i > 3) {
	return(-1);
    }
    switch(*(input + (*i)++)) {
    case 'a':
	return(ACE);
    case 'k':
	return(KING);
    case 'q':
	return(QUEEN);
    case 'j':
	return(JACK);
    case 't':
    case 'x':
	return(C_10);
    case '9':
	return(C_9);
    case '8':
	return(C_8);
    case '7':
	return(C_7);
    case '6':
	return(C_6);
    case '5':
	return(C_5);
    case '4':
	return(C_4);
    case '3':
	return(C_3);
    case '2':
	return(C_2);
    case '1':
	if(*(input + *i) != '0') {
	    return(ACE);
	}
	if((*(input + *i) == '0') && ((*i)++ <= 3)) {
	    return(C_10);
	}
    }
    return(-1);
}

help(c, do_print)
    char c, do_print;
{
    int i, count = 0;

    if(c == ' ') {
	move(COMMAND_LINE - 1,1);
	clrtoeol();
    }
    for(i = 0; i < nr_human; i++) {
	if(valid(HUMAN, i)) {
	    move(ROW(HUMAN,SUIT(human[i]),VALUE(human[i])),
		 COL(HUMAN,SUIT(human[i]),VALUE(human[i]))+2);
	    addch(c);
	    count++;
	}
    }
    if(do_print) {
	move(COMMAND_LINE - 1,1);
	clrtoeol();
	if(!count) {
	    printw("you cannot play any card, but you can pick-up");
	} else if(count > 1) {
	    printw("you can play the cards marked by an asterisk");
	} else {
	    printw("you can play the card marked by an asterisk");
	}
    }
}

have_it(card)
    int card;
{
    int i;

    for(i = 0; i < nr_human; i++) {
	if(human[i] == card) {
	    return(i);
	}
    }
    return(-1);
}

char *additional_commands[] = {
	"| extra commands:",
/* a */ "| !a stop analysis",
/* b */ 0,
/* c */ "| !c consult computer",
/* d */ "| !d propose a draw",
/* e */ 0,
/* f */ "| !f have a forced win",
/* g */ 0,
/* h */ 0, /* reserved for help toggling */
/* i */ "| !i give instructions",
/* j */ 0,
/* k */ 0,
/* l */ 0, /* reserved for log toggling */
/* m */ 0,
/* n */ 0,
/* o */ 0,
/* p */ 0,
/* q */ 0,
/* r */ "| !r resign",
#ifdef SHELL
/* s */ "| !s execute subshell",
#else
/* s */ 0, /* reserved for subshell execution */
#endif
/* t */ 0,
/* u */ 0,
/* v */ 0,
/* w */ "| !w clear this window",
/* x */ 0,
/* y */ 0,
/* z */ 0,
	"+---------------------",
0};

char *n_additional_commands[sizeof(additional_commands)];

char always_help[] = {
	"| !h always help"};
char never_help[] = {
	"| !h help on request"};

char start_logging[] = {
	"| !l start logging"};
char stop_logging[] = {
	"| !l stop logging"};

#ifdef SHELL
char *getenv();
#endif

#define ADDCOM(c)    n_additional_commands[c-'a'+1]

char display_window = TRUE;

display_extra()
{
    char c, i, count = 0;

    for(i = 0; i < sizeof(additional_commands); i++) {
	n_additional_commands[i] = additional_commands[i];
    }
    if(!analysing) {
	ADDCOM('a') = 0;
	ADDCOM('c') = 0;
    }
    if(help_always) {
	ADDCOM('h') = never_help;
    } else {
	ADDCOM('h') = always_help;
    }
    if(analysing) {
	ADDCOM('l') = 0;
    } else if(logfile == NULL) {
	ADDCOM('l') = start_logging;
    } else {
	ADDCOM('l') = stop_logging;
    }
    if(analysing) {
	ADDCOM('d') = 0;
	ADDCOM('f') = 0;
	ADDCOM('r') = 0;
    }
    for(i = 0; i < 'z'-'a'+3; i++) {
	if(n_additional_commands[i] != 0) {
	    move(count, R_MARGIN);
	    if(display_window) {
		printw(n_additional_commands[i]);
	    }
	    clrtoeol();
	    count++;
	}
    }
    for(;count < COMMENT_LINE - 1; count++) {
	move(count, R_MARGIN);
	clrtoeol();
    }
}

extended_command(c)
    char c;
{
    char i, count;

    if(isalpha(c) && isupper(c)) {
	c = tolower(c);
    }
    c = option(c);
    display_extra();
    return(c);
}

int command_line = FALSE;

option(c)
    char c;
{
    char i, res = 0, *str;

    switch(c) {
    case 'a':
	if(command_line) {
	    break;
	}
	prw("exiting analysis mode");
	sleep(1);
	res = ANAL_END;
	break;
    case 'c':
	if(command_line) {
	    break;
	}
	if(!analysing) {
	    prw("i do not understand this command");
	    break;
	}
	prw("");
	move(COMMAND_LINE, COMMAND_POS);
	clrtoeol();
	printw("consulting..");
	refresh();
	i = strategy(HUMAN);
	move(COMMAND_LINE - 1, 1);
	if(i < MAX_CARD) {
	    printw("computer suggests ");
	    display_full(human[i]);
	} else {
	    printw("computer suggests to pick up");
	}
	break;
    case 'd':
	if(command_line) {
	    break;
	}
	if(analysing) {
	    prw("i do not understand this command");
	    break;
	}
	prw("consulting your opponent");
	refresh();
	sleep(1);
	if(!accept_draw()) {
	    prw("the computer does not accept");
	} else {
	    prw("the computer gleefully accepts");
	    res = DRAWN;
	}
	if(res == DRAWN) {
	    refresh();
	    sleep(1);
	}
	break;
    case 'f':
	if(command_line) {
	    break;
	}
	if(analysing) {
	    prw("i do not understand this command");
	    break;
	}
	prw("do you really have a forced win? (y/n) ");
	refresh();
	if(!yesno()) {
	    prw("");
	    break;
	}
	prw("I have to consult your opponent");
	refresh();
	sleep(1);
	if(winning(HUMAN)) {
	    prw("the computer agrees");
	    res = WIN;
	} else {
	    prw("the computer does not think so; you have to show it");
	}
	if(res == WIN) {
	    refresh();
	    sleep(1);
	}
	break;
    case 'h':
	help_always = !help_always;
	if(help_always) {
	    help('*', FALSE);
	    helped = TRUE;
	    prw("will always mark possible cards");
	} else {
	    help(' ', FALSE);
	    helped = FALSE;
	    prw("will mark possible cards on request only");
	}
	if(command_line) {
	    sleep(1);
	}
	break;
    case 'i':
	if(command_line) {
	    break;
	}
	put_instructions(FALSE);
	printw("enter space to return\n");
	refresh();
	getch();
	redraw();
	break;
    case 'l':
	if(logfile == NULL) {
	    open_log();
	    if(logfile == NULL) {
		prw("cannot open logfile");
	    } else {
		prw("logging started on file \"challenge.log\"");
	    }
	} else {
	    prw("logging stopped");
	    record_stop();
	    move_logged = 0;
	}
	if(command_line) {
	    sleep(1);
	}
	break;
    case 'r':
	if(command_line || analysing) {
	    break;
	}
	prw("do you really want to resign? (y/n) ");
	refresh();
	if(!yesno()) {
	    prw("");
	    break;
	}
	prw("the computer accepts");
	refresh();
	sleep(1);
	res = RESIGN;
	break;
#ifdef SHELL
    case 's':
	if(command_line) {
	    break;
	}
	if(child()) {
	    if(str = getenv("SHELL")) {
		execl(str, str, (char *) 0);
	    } else {
		execl("/bin/sh", "sh", (char *) 0);
	    }
	    printf("%s: cannot execute", str);
	    sleep(1);
	    exit(1);
	}
	redraw();
	res = 0;
	break;
#endif
    case 'w':
	display_window = !display_window;
	if(!display_window && !command_line) {
	    prw("you get the window back when you enter the same command");
	}
	break;
    default:
	if(!command_line) {
	    prw("i do not understand this command");
	}
    }
    return(res);
}

check_options(c)
    char *c;
{
    command_line = TRUE;
    while(*c != 0) {
	option(*c++);
    }
    command_line = FALSE;
}

prw(c)
    char *c;
{
    if(command_line) {
	printf(c);
	printf("\n");
    } else {
	move(COMMAND_LINE - 1, 1);
	printw(c);
	clrtoeol();
    }
}

/* should be interfaced with strategy */
winning(player)
    int player;
{
    char hand[4][MAX_SUIT], count[4], tops[4];
    int suit, value, diff, i, j;

    if(player == COMPUTER) {
	return(FALSE);
    }
    if(top >= 0) {
	return(FALSE);
    }
    for(i = 0; i < 4; i++) {
	count[i] = 0;
	tops[i] = 0;
	for(j = 0; j < size; j++) {
	    hand[i][j] = FALSE;
	}
    }
    for(i = 0; i < nr_human; i++) {
	suit = SUIT(human[i]);
	value = VALUE(human[i]);
	hand[suit][value] = TRUE;
	count[suit]++;
    }
    for(i = 0; i < 4; i++) {
	for(j = 0; j < size && hand[i][j]; j++) {
	    tops[i]++;
	}
    }
    if(tops[SPADES] >= nr_human - 1) {
	return(TRUE);
    }
    if(count[SPADES] == size) {
	i = count[CLUBS] + count[DIAMONDS] + count[HEARTS];
	j = tops[CLUBS] + tops[DIAMONDS] + tops[HEARTS];
	return((i - j) <= 1);
    }
    return(tops[HEARTS] >= nr_human + 1);
}

#ifdef SHELL
/* free after hack */
child()
{
    int f = fork();

    move(COMMAND_LINE + 1, 0);
    clrtoeol();
    refresh();
    if(f == 0) {        /* child */
	endwin();
	return(TRUE);
    }
    if(f == -1) {    /* cannot fork */
	printw("fork failed, try again");
	refresh();
	sleep(1);
	return(FALSE);
    }
    /* fork succeeded; wait for child to exit */
    endwin();
    signal(SIGINT,SIG_IGN);
    signal(SIGQUIT,SIG_IGN);
    wait((union wait *) 0);
    initscr();
    crmode();
    noecho();
    clear();
    signal(SIGINT, nasty);
    signal(SIGQUIT, nasty);
    return(FALSE);
}
#endif