|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T h
Length: 12429 (0x308d)
Types: TextFile
Names: »human.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Challenge/human.c«
#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