xref: /openbsd-src/games/hangman/getguess.c (revision 2010f3c835ae4bf769b9e69e53a37d2dfeb4a7e5)
1*2010f3c8Smestre /*	$OpenBSD: getguess.c,v 1.15 2016/01/04 17:33:24 mestre Exp $	*/
2df930be7Sderaadt /*	$NetBSD: getguess.c,v 1.5 1995/03/23 08:32:43 cgd Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*
5df930be7Sderaadt  * Copyright (c) 1983, 1993
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt  * modification, are permitted provided that the following conditions
10df930be7Sderaadt  * are met:
11df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
167a09557bSmillert  * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
18df930be7Sderaadt  *    without specific prior written permission.
19df930be7Sderaadt  *
20df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt  * SUCH DAMAGE.
31df930be7Sderaadt  */
32df930be7Sderaadt 
335122c280Smestre #include <ctype.h>
345122c280Smestre #include <curses.h>
35*2010f3c8Smestre #include <termios.h>
365122c280Smestre #include <unistd.h>
375122c280Smestre 
38df930be7Sderaadt #include "hangman.h"
39df930be7Sderaadt 
40df930be7Sderaadt /*
41df930be7Sderaadt  * getguess:
42df930be7Sderaadt  *	Get another guess
43df930be7Sderaadt  */
441ed0e75dSpjanzen void
getguess(void)453eb8c9edSjsg getguess(void)
46df930be7Sderaadt {
478f46ce03Spjanzen 	int	i;
4824a46d3dStedu 	unsigned char	ch, uch;
498f46ce03Spjanzen 	bool	correct;
50df930be7Sderaadt 
51df930be7Sderaadt 	leaveok(stdscr, FALSE);
52df930be7Sderaadt 	for (;;) {
53df930be7Sderaadt 		move(PROMPTY, PROMPTX + sizeof "Guess: ");
54df930be7Sderaadt 		refresh();
55df930be7Sderaadt 		ch = readch();
5624a46d3dStedu 		if (isalpha(ch)) {
5724a46d3dStedu 			if (isupper(ch))
5824a46d3dStedu 				ch = tolower(ch);
5965b0e16cStedu 			if (Guessed[ch - 'a']) {
6065b0e16cStedu 				move(MESGY, MESGX);
6165b0e16cStedu 				clrtoeol();
621ed0e75dSpjanzen 				mvprintw(MESGY, MESGX, "Already guessed '%c'",
631ed0e75dSpjanzen 				    ch);
6465b0e16cStedu 			} else
65df930be7Sderaadt 				break;
6624a46d3dStedu 		} else if (isdigit(ch)) {
67f005acd6Stedu 			if (Guessed[ch - '0' + 26]) {
68f005acd6Stedu 				move(MESGY, MESGX);
69f005acd6Stedu 				clrtoeol();
70f005acd6Stedu 				mvprintw(MESGY, MESGX, "Already guessed '%c'",
71f005acd6Stedu 				    ch);
72f005acd6Stedu 			} else
73f005acd6Stedu 				break;
741ed0e75dSpjanzen 		} else
751ed0e75dSpjanzen 			if (ch == CTRL('D'))
761ed0e75dSpjanzen 				die(0);
7765b0e16cStedu 			else {
7865b0e16cStedu 				move(MESGY, MESGX);
7965b0e16cStedu 				clrtoeol();
801ed0e75dSpjanzen 				mvprintw(MESGY, MESGX,
811ed0e75dSpjanzen 				    "Not a valid guess: '%s'", unctrl(ch));
82df930be7Sderaadt 			}
8365b0e16cStedu 	}
84df930be7Sderaadt 	leaveok(stdscr, TRUE);
85df930be7Sderaadt 	move(MESGY, MESGX);
86df930be7Sderaadt 	clrtoeol();
87df930be7Sderaadt 
8824a46d3dStedu 	if (isalpha(ch))
89df930be7Sderaadt 		Guessed[ch - 'a'] = TRUE;
90f005acd6Stedu 	else
91f005acd6Stedu 		Guessed[ch - '0' + 26] = TRUE;
92df930be7Sderaadt 	correct = FALSE;
9324a46d3dStedu 	uch = toupper(ch);
94df930be7Sderaadt 	for (i = 0; Word[i] != '\0'; i++)
95df930be7Sderaadt 		if (Word[i] == ch) {
96df930be7Sderaadt 			Known[i] = ch;
97df930be7Sderaadt 			correct = TRUE;
98dac5d0ceSmiod 		} else if (Word[i] == uch) {
99dac5d0ceSmiod 			Known[i] = uch;
100dac5d0ceSmiod 			correct = TRUE;
101df930be7Sderaadt 		}
102df930be7Sderaadt 	if (!correct)
103df930be7Sderaadt 		Errors++;
104df930be7Sderaadt }
105df930be7Sderaadt 
106df930be7Sderaadt /*
107df930be7Sderaadt  * readch;
108df930be7Sderaadt  *	Read a character from the input
109df930be7Sderaadt  */
11024a46d3dStedu unsigned char
readch(void)1113eb8c9edSjsg readch(void)
112df930be7Sderaadt {
1131ed0e75dSpjanzen 	int	cnt;
1141ed0e75dSpjanzen 	char	ch;
115df930be7Sderaadt 
116df930be7Sderaadt 	cnt = 0;
117df930be7Sderaadt 	for (;;) {
11854dea640Sderaadt 		if (read(STDIN_FILENO, &ch, sizeof ch) <= 0) {
119df930be7Sderaadt 			if (++cnt > 100)
1201ed0e75dSpjanzen 				die(0);
1211ed0e75dSpjanzen 		} else
1221ed0e75dSpjanzen 			if (ch == CTRL('L')) {
123df930be7Sderaadt 				wrefresh(curscr);
12415eabdf8Stholo 				mvcur(0, 0, curscr->_cury, curscr->_curx);
1251ed0e75dSpjanzen 			} else
126df930be7Sderaadt 				return ch;
127df930be7Sderaadt 	}
128df930be7Sderaadt }
129