Skip to content

Commit d824b73

Browse files
Merge pull request #913 from aldrinm/queen
72. Queen ported to Java
2 parents 8b40cc8 + c9f9128 commit d824b73

File tree

1 file changed

+370
-0
lines changed

1 file changed

+370
-0
lines changed

72_Queen/java/Queen.java

Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
import java.util.List;
2+
import java.util.Optional;
3+
import java.util.Scanner;
4+
5+
/**
6+
* QUEEN
7+
* <p>
8+
* Converted from BASIC to Java by Aldrin Misquitta (@aldrinm)
9+
*/
10+
public class Queen {
11+
12+
public static final int WINNING_POSITION = 158;
13+
public static final int FORFEIT_MOVE = 0;
14+
15+
// @formatter:off
16+
private static final int[] S = {
17+
81, 71, 61, 51, 41, 31, 21, 11,
18+
92, 82, 72, 62, 52, 42, 32, 22,
19+
103, 93, 83, 73, 63, 53, 43, 33,
20+
114, 104, 94, 84, 74, 64, 54, 44,
21+
125, 115, 105, 95, 85, 75, 65, 55,
22+
136, 126, 116, 106, 96, 86, 76, 66,
23+
147, 137, 127, 117, 107, 97, 87, 77,
24+
158, 148, 138, 128, 118, 108, 98, 88
25+
};
26+
// @formatter:on
27+
28+
private static final Scanner scanner = new Scanner(System.in);
29+
30+
31+
public static void main(String[] args) {
32+
printWithTab("QUEEN", 33);
33+
printWithTab("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY", 15);
34+
System.out.println("\n\n");
35+
36+
askAndShowInstructions();
37+
38+
boolean anotherGame;
39+
do {
40+
printBoard();
41+
42+
Move firstMove = getUserFirstMove();
43+
if (firstMove.move == 0) {
44+
printWonByForfeit();
45+
}
46+
47+
if (isTopmostRowOrRightmostColumn(firstMove)) {
48+
playOneGame(firstMove);
49+
}
50+
51+
anotherGame = askForAnotherGame();
52+
53+
} while (anotherGame);
54+
55+
56+
System.out.println("\nOK --- THANKS AGAIN.");
57+
}
58+
59+
/**
60+
* Play one game starting with the first move from the user
61+
*/
62+
private static void playOneGame(Move firstMove) {
63+
boolean gameInProgress = true;
64+
Move userMove = firstMove;
65+
66+
while (gameInProgress) {
67+
68+
if (userMove.move == WINNING_POSITION) {
69+
//players wins
70+
printCongratulatoryMessage();
71+
gameInProgress = false;
72+
} else {
73+
74+
ComputerMove computerMove = getComputerMove(userMove);
75+
76+
System.out.printf("COMPUTER MOVES TO SQUARE %d\n", computerMove.move);
77+
78+
if (computerMove.move == WINNING_POSITION) {
79+
printComputerWins();
80+
gameInProgress = false;
81+
} else {
82+
userMove = getValidUserMove(computerMove);
83+
84+
if (userMove.move == FORFEIT_MOVE) {
85+
printWonByForfeit();
86+
gameInProgress = false;
87+
} else if (userMove.move == WINNING_POSITION) {
88+
printCongratulatoryMessage();
89+
gameInProgress = false;
90+
}
91+
}
92+
}
93+
}
94+
}
95+
96+
/**
97+
* Get the user's first move
98+
*/
99+
private static Move getUserFirstMove() {
100+
boolean validMove;
101+
Move move;
102+
do {
103+
System.out.print("WHERE WOULD YOU LIKE TO START? ");
104+
int movePosition = scanner.nextInt();
105+
move = new Move(movePosition);
106+
validMove = false;
107+
if (!isTopmostRowOrRightmostColumn(move)) {
108+
System.out.println("PLEASE READ THE DIRECTIONS AGAIN.");
109+
System.out.println("YOU HAVE BEGUN ILLEGALLY.");
110+
System.out.println();
111+
} else {
112+
validMove = true;
113+
}
114+
scanner.nextLine();
115+
} while (!validMove);
116+
return move;
117+
}
118+
119+
/**
120+
* Prompt and get a valid move from the user. Uses the computer's latest move to validate the next move.
121+
*/
122+
private static Move getValidUserMove(ComputerMove latestComputerMove) {
123+
boolean validUserMove = false;
124+
Move userMove = null;
125+
while (!validUserMove) {
126+
userMove = getUserMove();
127+
if (!validateUserMove(userMove, latestComputerMove)) {
128+
System.out.println("\nY O U C H E A T . . . TRY AGAIN");
129+
} else {
130+
validUserMove = true;
131+
}
132+
}
133+
return userMove;
134+
}
135+
136+
private static void printWonByForfeit() {
137+
System.out.println("\nIT LOOKS LIKE I HAVE WON BY FORFEIT.\n");
138+
}
139+
140+
private static boolean validateUserMove(Move userMove, ComputerMove computerMove) {
141+
if (userMove.move <= computerMove.move) {
142+
return false;
143+
}
144+
145+
if (userMove.move == FORFEIT_MOVE || userMove.move == WINNING_POSITION) {
146+
return true;
147+
}
148+
149+
int tensValueUser = userMove.move / 10;
150+
int unitsValueUser = userMove.move - (tensValueUser * 10);
151+
int unitsValueComputer = computerMove.u;
152+
int tensValueComputer = computerMove.t;
153+
int p = unitsValueUser - unitsValueComputer;
154+
if (p != 0) {
155+
if ((tensValueUser - tensValueComputer) != p) {
156+
return (tensValueUser - tensValueComputer) == 2 * p;
157+
} else {
158+
return true;
159+
}
160+
} else {
161+
int l = tensValueUser - tensValueComputer;
162+
return l > 0;
163+
}
164+
}
165+
166+
private static Move getUserMove() {
167+
System.out.print("WHAT IS YOUR MOVE? ");
168+
int movePosition = scanner.nextInt();
169+
scanner.nextLine();
170+
return new Move(movePosition);
171+
}
172+
173+
private static void printComputerWins() {
174+
System.out.println("\nNICE TRY, BUT IT LOOKS LIKE I HAVE WON.");
175+
System.out.println("THANKS FOR PLAYING.\n");
176+
}
177+
178+
private static boolean askForAnotherGame() {
179+
System.out.print("ANYONE ELSE CARE TO TRY? ");
180+
do {
181+
String response = Queen.scanner.nextLine();
182+
if (response.equals("NO")) {
183+
return false;
184+
} else if (response.equals("YES")) {
185+
return true;
186+
} else {
187+
System.out.println("PLEASE ANSWER 'YES' OR 'NO'.");
188+
}
189+
} while (true);
190+
}
191+
192+
private static boolean isTopmostRowOrRightmostColumn(Move move) {
193+
return move.unitsPlaceValue == 1 || move.unitsPlaceValue == move.tensPlaceValue;
194+
}
195+
196+
private static ComputerMove getComputerMove(Move userMove) {
197+
int unitsValueUser = userMove.unitsPlaceValue;
198+
int tensValueUser = userMove.tensPlaceValue;
199+
200+
List<Integer> moveRandomlyFromPositions = List.of(41, 44, 73, 75, 126, 127);
201+
202+
if (moveRandomlyFromPositions.contains(userMove.move)) {
203+
//random move
204+
return getMovePositionInRandomDirection(unitsValueUser, tensValueUser);
205+
} else {
206+
207+
for (int k = 7; k >= 1; k--) {
208+
// consider same row first, left-most position
209+
Optional<ComputerMove> move = evaluatePositionAndGetMove(unitsValueUser, tensValueUser + k);
210+
if (move.isPresent()) return move.get();
211+
212+
//try same column, bottom-most
213+
move = evaluatePositionAndGetMove(unitsValueUser + k, tensValueUser + k);
214+
if (move.isPresent()) return move.get();
215+
216+
//now left-most at the bottom-most
217+
move = evaluatePositionAndGetMove(unitsValueUser + k, tensValueUser + k + k);
218+
if (move.isPresent()) return move.get();
219+
}
220+
221+
//else move one step in a random direction
222+
return getMovePositionInRandomDirection(unitsValueUser, tensValueUser);
223+
}
224+
225+
}
226+
227+
private static Optional<ComputerMove> evaluatePositionAndGetMove(int newUnitsValue, int newTensValue) {
228+
EvaluationResult result = evaluateComputerMove(newUnitsValue, newTensValue);
229+
if (result.favourablePosition) {
230+
return Optional.of(new ComputerMove(result.move));
231+
}
232+
return Optional.empty();
233+
}
234+
235+
private static EvaluationResult evaluateComputerMove(int u, int t) {
236+
int m = 10 * t + u;
237+
if (m == 158 || m == 127 || m == 126 || m == 75 || m == 73) {
238+
return new EvaluationResult(m, true);
239+
} else {
240+
return new EvaluationResult(m, false);
241+
}
242+
}
243+
244+
private static void printCongratulatoryMessage() {
245+
System.out.println();
246+
System.out.println("C O N G R A T U L A T I O N S . . .");
247+
System.out.println();
248+
System.out.println("YOU HAVE WON--VERY WELL PLAYED.");
249+
System.out.println("IT LOOKS LIKE I HAVE MET MY MATCH.");
250+
System.out.println("THANKS FOR PLAYING---I CAN'T WIN ALL THE TIME.");
251+
System.out.println();
252+
253+
}
254+
255+
private static ComputerMove getMovePositionInRandomDirection(int u1, int t1) {
256+
double randomValue = Math.random();
257+
258+
if (randomValue > 0.6) {
259+
// Move directly down
260+
return new ComputerMove(calculateMove(u1, t1, 1, 1));
261+
} else if (randomValue > 0.3) {
262+
// Move down left
263+
return new ComputerMove(calculateMove(u1, t1, 1, 2));
264+
} else {
265+
// Move left
266+
return new ComputerMove(calculateMove(u1, t1, 0, 1));
267+
}
268+
}
269+
270+
private static int calculateMove(int u, int t, int uChange, int tChange) {
271+
int newU = u + uChange;
272+
int newT = t + tChange;
273+
return 10 * newT + newU; // Combine units and tens to corresponding position value
274+
}
275+
276+
277+
private static void printBoard() {
278+
System.out.println();
279+
for (int A = 0; A <= 7; A++) {
280+
for (int B = 0; B <= 7; B++) {
281+
int I = 8 * A + B;
282+
System.out.printf(" %d ", S[I]);
283+
}
284+
System.out.println();
285+
System.out.println();
286+
System.out.println();
287+
}
288+
System.out.println();
289+
}
290+
291+
private static void askAndShowInstructions() {
292+
do {
293+
System.out.print("DO YOU WANT INSTRUCTIONS? ");
294+
String wish = scanner.nextLine();
295+
if (wish.equals("NO")) {
296+
break;
297+
} else if (wish.equals("YES")) {
298+
showInstructions();
299+
break;
300+
} else {
301+
System.out.println("PLEASE ANSWER 'YES' OR 'NO'.");
302+
}
303+
} while (true);
304+
}
305+
306+
private static void printWithTab(String message, int tab) {
307+
for (int i = 0; i < tab; i++) {
308+
System.out.print(" ");
309+
}
310+
System.out.println(message);
311+
}
312+
313+
314+
private static void showInstructions() {
315+
System.out.println("WE ARE GOING TO PLAY A GAME BASED ON ONE OF THE CHESS");
316+
System.out.println("MOVES. OUR QUEEN WILL BE ABLE TO MOVE ONLY TO THE LEFT,");
317+
System.out.println("DOWN, OR DIAGONALLY DOWN AND TO THE LEFT.");
318+
System.out.println();
319+
System.out.println("THE OBJECT OF THE GAME IS TO PLACE THE QUEEN IN THE LOWER");
320+
System.out.println("LEFT HAND SQUARE BY ALTERNATING MOVES BETWEEN YOU AND THE");
321+
System.out.println("COMPUTER. THE FIRST ONE TO PLACE THE QUEEN THERE WINS.");
322+
System.out.println();
323+
System.out.println("YOU GO FIRST AND PLACE THE QUEEN IN ANY ONE OF THE SQUARES");
324+
System.out.println("ON THE TOP ROW OR RIGHT HAND COLUMN.");
325+
System.out.println("THAT WILL BE YOUR FIRST MOVE.");
326+
System.out.println("WE ALTERNATE MOVES.");
327+
System.out.println("YOU MAY FORFEIT BY TYPING '0' AS YOUR MOVE.");
328+
System.out.println("BE SURE TO PRESS THE RETURN KEY AFTER EACH RESPONSE.");
329+
System.out.println();
330+
}
331+
332+
333+
private static class ComputerMove {
334+
private final int move;
335+
private final int u;
336+
private final int t;
337+
338+
private ComputerMove(int move) {
339+
this.move = move;
340+
this.t = move / 10;
341+
this.u = move - (t * 10);
342+
}
343+
344+
}
345+
346+
private static class EvaluationResult {
347+
private final int move;
348+
private final boolean favourablePosition;
349+
350+
public EvaluationResult(int move, boolean favourablePosition) {
351+
this.move = move;
352+
this.favourablePosition = favourablePosition;
353+
}
354+
355+
356+
}
357+
358+
private static class Move {
359+
private final int move;
360+
private final int unitsPlaceValue;
361+
private final int tensPlaceValue;
362+
363+
private Move(int move) {
364+
this.move = move;
365+
this.tensPlaceValue = move / 10;
366+
this.unitsPlaceValue = move % 10;
367+
}
368+
369+
}
370+
}

0 commit comments

Comments
 (0)