/* $OpenBSD: misc.c,v 1.9 2003/06/03 03:01:40 millert Exp $ */ /* $NetBSD: misc.c,v 1.4 1995/03/24 05:01:54 cgd Exp $ */ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93"; #else static char rcsid[] = "$OpenBSD: misc.c,v 1.9 2003/06/03 03:01:40 millert Exp $"; #endif #endif /* not lint */ #include <sys/file.h> #include <termios.h> #include <stdarg.h> #include "mille.h" /* * @(#)misc.c 1.2 (Berkeley) 3/28/83 */ #define NUMSAFE 4 bool error(char *str, ...) { va_list ap; va_start(ap, str); wmove(Score, ERR_Y, ERR_X); vwprintw(Score, str, ap); wclrtoeol(Score); beep(); refresh(); va_end(ap); return FALSE; } CARD getcard() { int c, c1; for (;;) { while ((c = readch()) == '\n' || c == '\r' || c == ' ') continue; if (islower(c)) c = toupper(c); if (c == killchar() || c == erasechar()) return -1; addstr(unctrl(c)); clrtoeol(); switch (c) { case '1': case '2': case '3': case '4': case '5': case '6': c -= '0'; break; case '0': case 'P': case 'p': c = 0; break; default: beep(); addch('\b'); if (!isprint(c)) addch('\b'); c = -1; break; } refresh(); if (c >= 0) { while ((c1 = readch()) != '\r' && c1 != '\n' && c1 != ' ') if (c1 == killchar()) return -1; else if (c1 == erasechar()) { addch('\b'); clrtoeol(); refresh(); goto cont; } else beep(); return c; } cont: ; } } int check_ext(forcomp) bool forcomp; { if (End == 700) { if (Play == PLAYER) { if (getyn(EXTENSIONPROMPT)) { extend: if (!forcomp) End = 1000; return TRUE; } else { done: if (!forcomp) Finished = TRUE; return FALSE; } } else { PLAY *pp, *op; int i, safe, miles; pp = &Player[COMP]; op = &Player[PLAYER]; for (safe = 0, i = 0; i < NUMSAFE; i++) if (pp->safety[i] != S_UNKNOWN) safe++; if (safe < 2) goto done; if (op->mileage == 0 || onecard(op) || (op->can_go && op->mileage >= 500)) goto done; for (miles = 0, i = 0; i < NUMSAFE; i++) if (op->safety[i] != S_PLAYED && pp->safety[i] == S_UNKNOWN) miles++; if (miles + safe == NUMSAFE) goto extend; for (miles = 0, i = 0; i < HAND_SZ; i++) if ((safe = pp->hand[i]) <= C_200) miles += Value[safe]; if (miles + (Topcard - Deck) * 3 > 1000) goto extend; goto done; } } else goto done; } /* * Get a yes or no answer to the given question. Saves are * also allowed. Return TRUE if the answer was yes, FALSE if no. */ int getyn(promptno) int promptno; { char c; Saved = FALSE; for (;;) { leaveok(Board, FALSE); prompt(promptno); clrtoeol(); refresh(); switch (c = readch()) { case 'n': case 'N': addch('N'); refresh(); leaveok(Board, TRUE); return FALSE; case 'y': case 'Y': addch('Y'); refresh(); leaveok(Board, TRUE); return TRUE; case 's': case 'S': addch('S'); refresh(); Saved = save(); continue; case CTRL('L'): wrefresh(curscr); break; default: addstr(unctrl(c)); refresh(); beep(); break; } } } /* * Check to see if more games are desired. If not, and game * came from a saved file, make sure that they don't want to restore * it. Exit appropriately. */ void check_more() { On_exit = TRUE; if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000) { if (getyn(ANOTHERGAMEPROMPT)) return; else { /* * must do accounting normally done in main() */ if (Player[PLAYER].total > Player[COMP].total) Player[PLAYER].games++; else if (Player[PLAYER].total < Player[COMP].total) Player[COMP].games++; Player[COMP].total = 0; Player[PLAYER].total = 0; } } else if (getyn(ANOTHERHANDPROMPT)) return; if (!Saved && getyn(SAVEGAMEPROMPT)) if (!save()) return; die(0); } int readch() { int cnt; static char c; for (cnt = 0; read(STDIN_FILENO, &c, 1) <= 0; cnt++) if (cnt > 100) die(1); return c; }