|
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 m
Length: 14231 (0x3797) Types: TextFile Names: »main.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Challenge/main.c«
#define EXTERN #include "challenge.h" int quit(); /* main program performs program parameter checking, curses initialization and game set up */ main(argc,argv) int argc; char *argv[]; { char c; /* parameter checking. valid parameters are -s and -d */ while(argc > 1) { if(argv[1][0] == '-') { switch(argv[1][1]) { case 'd': depth = atoi(&argv[1][2]); if(depth < 0) { printf("depth should be 0 or larger\n"); exit(0); } break; case 's': size = atoi(&argv[1][2]); if(size < 1 || size > 8) { printf("size should be between 1 and 8\n"); exit(0); } break; case 'a': no_scoring = TRUE; analysing = TRUE; if(argv[1][2] != 0) { logfile = fopen(&argv[1][2], "r"); if(logfile == NULL) { printf("cannot open game file\n"); exit(0); } } break; case 'o': check_options(&argv[1][2]); break; default: usage(); } } else usage(); argv++; argc--; } /* general initializations */ seed = time(0); #ifdef TIMER signal(SIGALRM,timer); #endif signal(SIGQUIT,quit); signal(SIGINT,quit); initscr(); crmode(); noecho(); clear(); if(!analysing) { move(COMMAND_LINE - 2, 1); printw("do you want instructions? (y/n) "); refresh(); if(yesno()) { put_instructions(TRUE); clear(); } move(COMMAND_LINE - 1, 1); printw("do you want a demonstration game? (y/n) "); refresh(); if(yesno()) { for(;;) { demo = COMPUTER; init(); redraw(); do_demo(); move(COMMAND_LINE + 1,1); clrtoeol(); move(COMMAND_LINE,1); clrtoeol(); printw("another demo? (y/n) "); refresh(); if(!yesno()) { break; } } human_score = 0; computer_score = 0; demo = 0; } move(COMMAND_LINE,1); clrtoeol(); printw("do you want me to start? (y/n) "); refresh(); if(yesno()) { start_player = COMPUTER; } signal(SIGINT, nasty); signal(SIGQUIT, nasty); } /* loop through games */ for(;;) { if(!analysing || no_scoring) { init(); redraw(); } else if(!no_scoring) { move(COMMENT_LINE, 1); clrtoeol(); move(COMMAND_LINE - 1, 1); clrtoeol(); move(COMMAND_LINE, 1); clrtoeol(); printw("command:"); move(COMMAND_LINE + 1, 1); clrtoeol(); printw("you have now the additional b command available for back-up"); display_extra(); refresh(); } play_challenge(start_player); move(COMMAND_LINE + 1,1); clrtoeol(); move(COMMAND_LINE,1); clrtoeol(); signal(SIGINT, quit); signal(SIGQUIT, quit); printw("another game? (y/n) "); if(!analysing) { printw("or analyse game? (a) "); } refresh(); while(TRUE) { c = getch(); if(c == 'N') c = 'n'; if(c == 'Y') c = 'y'; if((c == 'n') || (c == 'y') || ((c == 'a') && !analysing)) { break; } (void) putchar(007); fflush(stdout); } refresh(); if(c == 'n') { break; } if(analysing && !no_scoring) { analysing = FALSE; logfile = save_logfile; } else if(c == 'a') { analysing = TRUE; save_logfile = logfile; logfile = NULL; } if(!analysing) { signal(SIGINT, nasty); signal(SIGQUIT, nasty); interchange(&start_player); } } quit(); } /* play the game; alternate between computer strategy and human. stop when the game is finished or the result is one of RESIGN, DRAWN, WIN. the computer strategy should not return WIN, and DRAWN only if the human is consulted! PASS is only permitted to restart a game with the proper player starting. */ play_challenge(player) int player; { int finished; int card, card1; again: finished = FALSE; if(analysing) { player = HUMAN; } while(!finished) { move(COMMAND_LINE, COMMAND_POS); if(player == COMPUTER) { clrtoeol(); printw("thinking...."); move(COMMENT_LINE, 1); clrtoeol(); refresh(); card = strategy(COMPUTER); card1 = card; if(card < MAX_CARD) { card1 = computer[card]; } } else { clrtoeol(); refresh(); card = human_interface(); if(card == ANAL_END) { return; } card1 = card; if(card < MAX_CARD) { card1 = human[card]; } } if(card1 == PICK_UP) { save_pick_up(); } if(card != BACK_UP) { moves[nr_moves++] = card1; } if(logfile != NULL && !analysing) { record(player, card1); } if(card != PASS) { move(COMMAND_LINE - 1, 1); clrtoeol(); if(card <= PICK_UP) { finished = do_move(player, card); } else if(card != BACK_UP) { finished = TRUE; break; } move(COMMAND_LINE - 1, 1); clrtoeol(); if(card != BACK_UP) { if(player == COMPUTER) { if(card != PICK_UP) { printw("computer plays "); display_full(top); } else { printw("computer picks up"); } } } else { back_up(COMPUTER); back_up(HUMAN); move(COMMAND_LINE - 1, 1); printw("backed_up one move"); } } if(!finished && card != BACK_UP) { interchange(&player); } } if(player == COMPUTER) { if(card <= PICK_UP) { printw(", and wins"); if(!analysing) { computer_score += 2; } } else if(card == RESIGN) { printw("computer resigns"); if(!analysing) { human_score += 2; } } else { printw("game is a draw"); if(!analysing) { computer_score++; human_score++; } } /* NOTE: no case for WIN! */ } else { if(card <= PICK_UP || card == WIN) { printw("you win"); if(card != WIN) { moves[nr_moves++] = PASS; } else { nr_moves--; } if(!analysing) { human_score += 2; } } else if(card == RESIGN) { printw("you resign"); nr_moves--; if(!analysing) { computer_score += 2; } } else { printw("the game is a draw"); nr_moves--; if(!analysing) { computer_score++; human_score++; } } } if(analysing) { goto again; } if(logfile != NULL && !analysing) { record_end(); } } save_pick_up() { int i; unsigned long pu = 0l; for(i = 0; i < nr_table; i++) { pu += (1 << table[i]); } pick_ups[nr_moves] = pu; } back_up(player) { int i, j, m, *nr_deck; char *deck; unsigned long pu; if(player == COMPUTER) { deck = &computer[0]; nr_deck = &nr_computer; } else { deck = &human[0]; nr_deck = &nr_human; } m = moves[--nr_moves]; if(m == PASS) { return; } if(m != PICK_UP) { deck[(*nr_deck)++] = m; print_card(player, m); for(i = 0; i < nr_table; i++) { if(table[i] == m) { table[i] = table[--nr_table]; clear_card(TABLE, m); break; } } } else { pu = pick_ups[nr_moves]; i = 0; while(i < max_card && pu != 0L) { if(pu & 1) { table[nr_table++] = i; print_card(TABLE, i); } i++; pu >>= 1; } for(i = 0; i < nr_table; i++) { m = table[i]; for(j = 0; j < *nr_deck; j++) { if(deck[j] == m) { deck[j] = deck[--(*nr_deck)]; clear_card(player, m); } } } } if(nr_moves > 0) { top = moves[nr_moves - 1]; if(top == PICK_UP) { top = -1; } } else { top = -1; } print_top(top); } /* check the validity of the card played; card is an index to the hand */ valid(player, card) int player, card; { int value, suit, tvalue, tsuit, *nr_deck; char *deck; if(player == COMPUTER) { deck = &computer[0]; nr_deck = &nr_computer; } else { deck = &human[0]; nr_deck = &nr_human; } if(card == PICK_UP) { return(nr_table > 0); } if(card >= *nr_deck) { return(FALSE); } if(nr_table == 0) { return(TRUE); } value = VALUE(deck[card]); suit = SUIT(deck[card]); tvalue = VALUE(top); tsuit = SUIT(top); if(suit == tsuit && value < tvalue) { return(TRUE); } if((player == COMPUTER && suit != SPADES) || (player == HUMAN && suit != HEARTS)) { return(FALSE); } return(suit != tsuit); } /* executes players move; card is an index to the hand */ do_move(player, card) int player; char card; { int i, *nr_deck; char *deck; if(player == COMPUTER) { deck = &computer[0]; nr_deck = &nr_computer; } else { deck = &human[0]; nr_deck = &nr_human; } if(card != PICK_UP) { top = deck[card]; table[nr_table++] = top; print_card(TABLE, top); print_top(top); deck[card] = deck[--(*nr_deck)]; clear_card(player, top); return(*nr_deck == 0); } else { for(i = 0; i < nr_table; i++) { deck[(*nr_deck)++] = table[i]; print_card(player, table[i]); clear_card(TABLE, table[i]); } nr_table = 0; top = -1; print_top(top); return(FALSE); } } /* set up a new game */ init() { char cards[MAX_CARD]; int i; char *c, *h; int s = size * 4; int j, value, suit, card; size2 = size * 2; max_card = size * 4; if(no_scoring) { if(logfile != NULL) { read_game(); return; } for(i = 0; i < max_card; i++) { human[i] = i; } nr_human = max_card; nr_computer = 0; nr_table = 0; top = -1; nr_moves = 0; move_logged = 0; return; } for(i = 0; i < max_card; i++) { cards[i] = i; table[i] = -1; } top = -1; c = &computer[0]; h = &human[0]; for(i = max_card - 1; i >= size2; i--) { j = rnd(s--); card = cards[j]; cards[j] = cards[i]; value = VALUE(card); suit = SUIT(card); if(suit <= CLUBS) { *c++ = card; *h++ = (3 - suit) + value * 4; } } for(i = 0; i < size2; i++) { card = cards[i]; value = VALUE(card); suit = SUIT(card); if(suit <= CLUBS) { *h++ = card; *c++ = (3 - suit) + value * 4; } } for(i = size2; i < max_card; i++) { *h++ = -1; *c++ = -1; } nr_computer = size2; nr_human = size2; nr_table = 0; for(i = 0; i < max_card; i++) { s_computer[i] = computer[i]; s_human[i] = human[i]; } nr_moves = 0; move_logged = 0; } draw_score() { if(no_scoring) { move(0, MARGIN + size2); if(start_player == HUMAN) { printw(" human vs. computer "); } else { printw(" computer vs. human "); } } else { move(0, MARGIN + size2); if(demo != 0) { printw("computer %2d vs. robot %2d", computer_score, human_score); } else if(start_player == HUMAN) { printw("human %2d vs. computer %2d", human_score, computer_score); } else { printw("computer %2d vs. human %2d", computer_score, human_score); } } } /* draw or redraw the play */ redraw() { int i; clear(); draw_score(); move(COMPUTER, MARGIN); printw("computer: SPADES:"); move(COMPUTER + 1, MARGIN); printw(" clubs:"); move(COMPUTER + 2, MARGIN); printw(" diamonds:"); move(COMPUTER + 3, MARGIN); printw(" hearts:"); move(TABLE, MARGIN); printw(" table: spades:"); move(TABLE + 1, MARGIN); printw(" clubs:"); move(TABLE + 2, MARGIN); printw(" diamonds:"); move(TABLE + 3, MARGIN); printw(" hearts:"); move(HUMAN, MARGIN); printw(" you: spades:"); move(HUMAN + 1, MARGIN); printw(" clubs:"); move(HUMAN + 2, MARGIN); printw(" diamonds:"); move(HUMAN + 3, MARGIN); printw(" HEARTS:"); move(TABLE + 1, 1); printw("top:"); move(COMMAND_LINE, 1); printw("command:"); move(COMMAND_LINE + 1, 1); printw("enter: card to play, or p for pick-up, or ? for help, or ! for extra commands"); for(i = 0; i < nr_computer; i++) { print_card(COMPUTER, computer[i]); } for(i = 0; i < nr_table; i++) { print_card(TABLE, table[i]); } for(i = 0; i < nr_human; i++) { print_card(HUMAN, human[i]); } print_top(top); display_extra(); } /* print a card */ print_card(player, card) int player; char card; { int value, suit; value = VALUE(card); suit = SUIT(card); move(ROW(player,suit,value),COL(player,suit,value)); if(card < 0) { printw(" "); return; } display_value(value); } /* clear the position of a card */ clear_card(player, card) int player; char card; { int value, suit; value = VALUE(card); suit = SUIT(card); move(ROW(player,suit,value),COL(player,suit,value)); printw(" "); } /* print the top card */ print_top(card) char card; { move(TABLE + 2, 1); display(card); } /* display card: suit and value */ display(card) char card; { int value, suit; value = VALUE(card); suit = SUIT(card); if(card < 0) { printw("---"); return; } display_value(value); printw("%c", "scdh"[suit]); } /* display value of card */ display_value(value) int value; { if(value == C_10) { printw("1"); } else { printw(" "); } printw("%c", "AKQJ098765432"[value]); } /* display the name of the card in full */ char *values[] = { "ace", "king", "queen", "jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"}; char *suits[] = { "spades", "clubs", "diamonds", "hearts"}; display_full(card) char card; { int value, suit; value = VALUE(card); suit = SUIT(card); printw(values[value]); printw(" of "); printw(suits[suit]); } /* interchange players */ interchange(p) int *p; { *p = COMPUTER + HUMAN - *p; } /* require y or n answer */ yesno() { char c = 0; while((c != 'n') && (c != 'y')) { c = getch(); if(c == 'N') c = 'n'; if(c == 'Y') c = 'y'; if((c != 'n') && (c != 'y')) { (void) putchar(007); fflush(stdout); } } return(c == 'y'); } quit() { #ifdef TIMER alarm(0); #endif move(COMMAND_LINE + 1, 0); clrtoeol(); refresh(); endwin(); if(!no_scoring) { printf("your final score was %d, the computer had %d\n", human_score, computer_score); } exit(0); } nasty() { #ifdef TIMER alarm(0); #endif move(COMMENT_LINE, 1); clrtoeol(); move(COMMAND_LINE, 1); clrtoeol(); printw("just when i had such a good game going!"); computer_score += 2; quit(); } rnd(mod) int mod; { if(mod <= 0) { return(0); } return((((seed = seed*11109+13849) >> 16) & 0xffff) % mod); } usage() { printf("usage: challenge [-s#] [-d#]\n"); exit(0); }