misc.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* $NetBSD: misc.c,v 1.11 2003/08/07 09:37:25 agc Exp $ */
  2. /*
  3. * Copyright (c) 1983, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the University nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #include <sys/cdefs.h>
  31. #ifndef lint
  32. #if 0
  33. static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93";
  34. #else
  35. __RCSID("$NetBSD: misc.c,v 1.11 2003/08/07 09:37:25 agc Exp $");
  36. #endif
  37. #endif /* not lint */
  38. #include <sys/file.h>
  39. #include <termios.h>
  40. #include <stdarg.h>
  41. #include "mille.h"
  42. #ifndef unctrl
  43. #include "unctrl.h"
  44. #endif
  45. /*
  46. * @(#)misc.c 1.2 (Berkeley) 3/28/83
  47. */
  48. #define NUMSAFE 4
  49. bool
  50. error(const char *str, ...)
  51. {
  52. va_list ap;
  53. va_start(ap, str);
  54. wmove(Score, ERR_Y, ERR_X);
  55. vwprintw(Score, str, ap);
  56. wclrtoeol(Score);
  57. putchar('\07');
  58. refresh();
  59. va_end(ap);
  60. return FALSE;
  61. }
  62. CARD
  63. getcard()
  64. {
  65. int c, c1;
  66. for (;;) {
  67. while ((c = readch()) == '\n' || c == '\r' || c == ' ')
  68. continue;
  69. if (islower(c))
  70. c = toupper(c);
  71. if (c == killchar() || c == erasechar())
  72. return -1;
  73. addstr(unctrl(c));
  74. clrtoeol();
  75. switch (c) {
  76. case '1': case '2': case '3':
  77. case '4': case '5': case '6':
  78. c -= '0';
  79. break;
  80. case '0': case 'P': case 'p':
  81. c = 0;
  82. break;
  83. default:
  84. putchar('\07');
  85. addch('\b');
  86. if (!isprint(c))
  87. addch('\b');
  88. c = -1;
  89. break;
  90. }
  91. refresh();
  92. if (c >= 0) {
  93. while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ')
  94. if (c1 == killchar())
  95. return -1;
  96. else if (c1 == erasechar()) {
  97. addch('\b');
  98. clrtoeol();
  99. refresh();
  100. goto cont;
  101. }
  102. else
  103. write(0, "\07", 1);
  104. return c;
  105. }
  106. cont: ;
  107. }
  108. }
  109. int
  110. check_ext(forcomp)
  111. bool forcomp;
  112. {
  113. if (End == 700)
  114. if (Play == PLAYER) {
  115. if (getyn(EXTENSIONPROMPT)) {
  116. extend:
  117. if (!forcomp)
  118. End = 1000;
  119. return TRUE;
  120. }
  121. else {
  122. done:
  123. if (!forcomp)
  124. Finished = TRUE;
  125. return FALSE;
  126. }
  127. }
  128. else {
  129. PLAY *pp, *op;
  130. int i, safe, miles;
  131. pp = &Player[COMP];
  132. op = &Player[PLAYER];
  133. for (safe = 0, i = 0; i < NUMSAFE; i++)
  134. if (pp->safety[i] != S_UNKNOWN)
  135. safe++;
  136. if (safe < 2)
  137. goto done;
  138. if (op->mileage == 0 || onecard(op)
  139. || (op->can_go && op->mileage >= 500))
  140. goto done;
  141. for (miles = 0, i = 0; i < NUMSAFE; i++)
  142. if (op->safety[i] != S_PLAYED
  143. && pp->safety[i] == S_UNKNOWN)
  144. miles++;
  145. if (miles + safe == NUMSAFE)
  146. goto extend;
  147. for (miles = 0, i = 0; i < HAND_SZ; i++)
  148. if ((safe = pp->hand[i]) <= C_200)
  149. miles += Value[safe];
  150. if (miles + (Topcard - Deck) * 3 > 1000)
  151. goto extend;
  152. goto done;
  153. }
  154. else
  155. goto done;
  156. }
  157. /*
  158. * Get a yes or no answer to the given question. Saves are
  159. * also allowed. Return TRUE if the answer was yes, FALSE if no.
  160. */
  161. int
  162. getyn(promptno)
  163. int promptno;
  164. {
  165. char c;
  166. Saved = FALSE;
  167. for (;;) {
  168. leaveok(Board, FALSE);
  169. prompt(promptno);
  170. clrtoeol();
  171. refresh();
  172. switch (c = readch()) {
  173. case 'n': case 'N':
  174. addch('N');
  175. refresh();
  176. leaveok(Board, TRUE);
  177. return FALSE;
  178. case 'y': case 'Y':
  179. addch('Y');
  180. refresh();
  181. leaveok(Board, TRUE);
  182. return TRUE;
  183. case 's': case 'S':
  184. addch('S');
  185. refresh();
  186. Saved = save();
  187. continue;
  188. case CTRL('L'):
  189. wrefresh(curscr);
  190. break;
  191. default:
  192. addstr(unctrl(c));
  193. refresh();
  194. putchar('\07');
  195. break;
  196. }
  197. }
  198. }
  199. /*
  200. * Check to see if more games are desired. If not, and game
  201. * came from a saved file, make sure that they don't want to restore
  202. * it. Exit appropriately.
  203. */
  204. void
  205. check_more()
  206. {
  207. On_exit = TRUE;
  208. if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
  209. if (getyn(ANOTHERGAMEPROMPT))
  210. return;
  211. else {
  212. /*
  213. * must do accounting normally done in main()
  214. */
  215. if (Player[PLAYER].total > Player[COMP].total)
  216. Player[PLAYER].games++;
  217. else if (Player[PLAYER].total < Player[COMP].total)
  218. Player[COMP].games++;
  219. Player[COMP].total = 0;
  220. Player[PLAYER].total = 0;
  221. }
  222. else
  223. if (getyn(ANOTHERHANDPROMPT))
  224. return;
  225. if (!Saved && getyn(SAVEGAMEPROMPT))
  226. if (!save())
  227. return;
  228. die(0);
  229. }
  230. int
  231. readch()
  232. {
  233. int cnt;
  234. static char c;
  235. for (cnt = 0; read(0, &c, 1) <= 0; cnt++)
  236. if (cnt > 100)
  237. exit(1);
  238. return c;
  239. }