Repository navigation
Expand file tree
/
Copy pathguessnumber.java
More file actions
executable file
·173 lines (156 loc) · 8.08 KB
/
Copy pathguessnumber.java
File metadata and controls
executable file
·173 lines (156 loc) · 8.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* Guess my number game
*
* --A Java version of a silly game I made on my programmable
* calculator when I was bored in math class in 1987, with a couple of
* additions like input validation and computer guesses.
*
* Copyright (c) 2007 Matthew Helmke for the old Python 2 version
* Copyright (c) 2025 Matthew Helmke for the Java version (this one)
* Input handling revised 2026-10-12 with assistance from Claude Code
* (claude.ai/code) using the claude-opus-5-5 model
*
* To compile (Linux):
* javac guessnumber.java
* To run:
* java guessnumber
*
* This program is free software; you can redistribute it and\or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Random;
public class guessnumber {
// Read one line, ending at a line feed, which is dropped. Returns null at
// end of input when nothing is left; a last line with no line feed is still
// returned. Scanner.nextLine and BufferedReader.readLine are not used: both
// also end a line at a carriage return, and Scanner at U+0085, U+2028, and
// U+2029 too, so "3", a carriage return, and "0" would read as two guesses.
static String readLine(BufferedReader input) throws IOException {
int c = input.read();
if (c == -1) {
return null;
}
StringBuilder line = new StringBuilder();
while (c != -1 && c != '\n') {
line.append((char) c);
c = input.read();
}
return line.toString();
}
public static void main(String[] args) throws IOException {
try (BufferedReader input = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8))) {
Random random = new Random();
int lowmax = 1;
int highmax = 100;
// Get a random number, or a fixed one from GMN_SECRET for parity testing.
// As with a guess, the value must be all digits, and parseInt can then
// fail only on a number too large for an int, which is out of range.
int secretnumber = random.nextInt(highmax - lowmax + 1) + lowmax;
String gmnSecret = System.getenv("GMN_SECRET");
if (gmnSecret != null && gmnSecret.matches("\\d+")) {
int gmnValue;
try {
gmnValue = Integer.parseInt(gmnSecret);
} catch (NumberFormatException e) {
gmnValue = Integer.MAX_VALUE;
}
if (gmnValue >= 1 && gmnValue <= 100) {
secretnumber = gmnValue;
}
}
int userguess;
int computerguess;
int totalguesses = 0;
// Print a description of the game, with rules, to the screen
System.out.println("Welcome to Guess My Number!\n\nThe computer will select a random whole number between 1 and 100.\nYour goal is to guess that number. You will get a turn, then a computer\nplayer will get a turn. Each of you are aware of the other's guesses.\nThe first one to guess the number correctly will win. Try to guess in\nas few turns as possible.\n\nHere we go!\n\n");
// the main bit
while (true) {
System.out.print("What is your guess? ");
// let the user input any number they want
// read the whole line; scanner.next() would read one word and skip empty lines
String userguessunvalidated = readLine(input);
if (userguessunvalidated == null) {
break; // end of input
}
// remove leading and trailing spaces and tabs
userguessunvalidated = userguessunvalidated.replaceAll("^[ \\t]+|[ \\t]+$", "");
// verify the guess is a whole number
if (!userguessunvalidated.matches("\\d+")) {
System.out.println("Only whole numbers from 1 to 100 are allowed.\nPlease try again.\n");
continue;
}
// verify the guess is in range; the input is all digits, so parseInt
// can fail only when the number is too large for an int, which is out of range
try {
userguess = Integer.parseInt(userguessunvalidated);
} catch (NumberFormatException e) {
userguess = Integer.MAX_VALUE;
}
if (userguess < 1 || userguess > 100) {
System.out.println("Only whole numbers from 1 to 100 are allowed. Your guess is out of range.\nPlease try again.\n");
continue;
}
// this is a real guess, so count it
totalguesses++;
// some taunts for silly errors in user guesses
if (userguess < lowmax) {
System.out.println("That guess was lower than a previous guess that was too low. Pay attention!\n");
}
if (userguess > highmax) {
System.out.println("Wake up! That guess was higher than an earlier guess that was too high.\n");
}
// evaluate the guess
if (userguess == secretnumber) {
System.out.println("\n*********************************************\n Your guess is correct! Congratulations!\n It took " + totalguesses + " total guesses.\n*********************************************\n");
return;
} else if (userguess > secretnumber) {
System.out.println("Your guess is too high.\n");
if (userguess <= highmax) {
highmax = userguess - 1;
}
} else {
System.out.println("Your guess is too low.\n");
if (userguess >= lowmax) {
lowmax = userguess + 1;
}
}
// computer uses the midpoint (binary search) within current bounds
computerguess = (lowmax + highmax) / 2;
totalguesses++;
if (computerguess == secretnumber) {
System.out.println("**********************************************\n The computer's guess of " + computerguess + " is correct!\n It took " + totalguesses + " total guesses.\n**********************************************\n");
return;
} else if (computerguess > secretnumber) {
System.out.println("The computer guessed " + computerguess + " and that was too high.\nPlease try again.\n");
highmax = computerguess - 1;
} else {
System.out.println("The computer guessed " + computerguess + " and that was too low.\nPlease try again.\n");
lowmax = computerguess + 1;
}
// more taunts and a forced guess limit
if (totalguesses == 8) {
System.out.println("\nThis is a hard number, isn't it?\n");
} else if (totalguesses == 10) {
System.out.println("\nWow! You are really bad at this.\n");
} else if (totalguesses >= 12) {
System.out.println("\nYou're taking too long, I can't handle it any more.\n\nG A M E O V E R\n");
return;
}
}
}
}
}