|
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