mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-21 23:00:43 -08:00
211 lines
5.7 KiB
Java
211 lines
5.7 KiB
Java
import java.util.Arrays;
|
|
import java.util.InputMismatchException;
|
|
import java.util.Scanner;
|
|
|
|
/**
|
|
* GOMOKO
|
|
* <p>
|
|
* Converted from BASIC to Java by Aldrin Misquitta (@aldrinm)
|
|
*/
|
|
public class Gomoko {
|
|
|
|
private static final int MIN_BOARD_SIZE = 7;
|
|
private static final int MAX_BOARD_SIZE = 19;
|
|
|
|
public static void main(String[] args) {
|
|
printIntro();
|
|
Scanner scan = new Scanner(System.in);
|
|
int boardSize = readBoardSize(scan);
|
|
|
|
boolean continuePlay = true;
|
|
while (continuePlay) {
|
|
int[][] board = new int[boardSize][boardSize];
|
|
//initialize the board elements to 0
|
|
for (int[] ints : board) {
|
|
Arrays.fill(ints, 0);
|
|
}
|
|
|
|
System.out.println("\n\nWE ALTERNATE MOVES. YOU GO FIRST...");
|
|
|
|
boolean doneRound = false;
|
|
while (!doneRound) {
|
|
Move playerMove = null;
|
|
boolean validMove = false;
|
|
while (!validMove) {
|
|
playerMove = readMove(scan);
|
|
if (playerMove.i == -1 || playerMove.j == -1) {
|
|
doneRound = true;
|
|
System.out.println("\nTHANKS FOR THE GAME!!");
|
|
System.out.print("PLAY AGAIN (1 FOR YES, 0 FOR NO)? ");
|
|
final int playAgain = scan.nextInt();
|
|
scan.nextLine();
|
|
if (playAgain == 1) {
|
|
continuePlay = true;
|
|
break;
|
|
} else {
|
|
continuePlay = false;
|
|
break;
|
|
}
|
|
} else if (!isLegalMove(playerMove, boardSize)) {
|
|
System.out.println("ILLEGAL MOVE. TRY AGAIN...");
|
|
} else if (board[playerMove.i - 1][playerMove.j - 1] != 0) {
|
|
System.out.println("SQUARE OCCUPIED. TRY AGAIN...");
|
|
} else {
|
|
validMove = true;
|
|
}
|
|
}
|
|
|
|
if (!doneRound) {
|
|
board[playerMove.i - 1][playerMove.j - 1] = 1;
|
|
Move computerMove = getComputerMove(playerMove, board, boardSize);
|
|
if (computerMove == null) {
|
|
computerMove = getRandomMove(board, boardSize);
|
|
}
|
|
board[computerMove.i - 1][computerMove.j - 1] = 2;
|
|
|
|
printBoard(board);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//*** COMPUTER TRIES AN INTELLIGENT MOVE ***
|
|
private static Move getComputerMove(Move playerMove, int[][] board, int boardSize) {
|
|
for (int e = -1; e <= 1; e++) {
|
|
for (int f = -1; f <= 1; f++) {
|
|
if ((e + f - e * f) != 0) {
|
|
var x = playerMove.i + f;
|
|
var y = playerMove.j + f;
|
|
final Move newMove = new Move(x, y);
|
|
if (isLegalMove(newMove, boardSize)) {
|
|
if (board[newMove.i - 1][newMove.j - 1] != 0) {
|
|
newMove.i = newMove.i - e;
|
|
newMove.i = newMove.j - f;
|
|
if (!isLegalMove(newMove, boardSize)) {
|
|
return null;
|
|
} else {
|
|
if (board[newMove.i - 1][newMove.j - 1] == 0) {
|
|
return newMove;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static void printBoard(int[][] board) {
|
|
for (int[] ints : board) {
|
|
for (int cell : ints) {
|
|
System.out.printf(" %s", cell);
|
|
}
|
|
System.out.println();
|
|
}
|
|
}
|
|
|
|
//*** COMPUTER TRIES A RANDOM MOVE ***
|
|
private static Move getRandomMove(int[][] board, int boardSize) {
|
|
boolean legalMove = false;
|
|
Move randomMove = null;
|
|
while (!legalMove) {
|
|
randomMove = randomMove(boardSize);
|
|
legalMove = isLegalMove(randomMove, boardSize) && board[randomMove.i - 1][randomMove.j - 1] == 0;
|
|
|
|
}
|
|
return randomMove;
|
|
}
|
|
|
|
private static Move randomMove(int boardSize) {
|
|
int x = (int) (boardSize * Math.random() + 1);
|
|
int y = (int) (boardSize * Math.random() + 1);
|
|
return new Move(x, y);
|
|
}
|
|
|
|
private static boolean isLegalMove(Move move, int boardSize) {
|
|
return (move.i >= 1) && (move.i <= boardSize) && (move.j >= 1) && (move.j <= boardSize);
|
|
}
|
|
|
|
private static void printIntro() {
|
|
System.out.println(" GOMOKO");
|
|
System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
|
|
System.out.println("\n\n");
|
|
System.out.println("WELCOME TO THE ORIENTAL GAME OF GOMOKO.");
|
|
System.out.println("\n");
|
|
System.out.println("THE GAME IS PLAYED ON AN N BY N GRID OF A SIZE");
|
|
System.out.println("THAT YOU SPECIFY. DURING YOUR PLAY, YOU MAY COVER ONE GRID");
|
|
System.out.println("INTERSECTION WITH A MARKER. THE OBJECT OF THE GAME IS TO GET");
|
|
System.out.println("5 ADJACENT MARKERS IN A ROW -- HORIZONTALLY, VERTICALLY, OR");
|
|
System.out.println("DIAGONALLY. ON THE BOARD DIAGRAM, YOUR MOVES ARE MARKED");
|
|
System.out.println("WITH A '1' AND THE COMPUTER MOVES WITH A '2'.");
|
|
System.out.println("\nTHE COMPUTER DOES NOT KEEP TRACK OF WHO HAS WON.");
|
|
System.out.println("TO END THE GAME, TYPE -1,-1 FOR YOUR MOVE.\n ");
|
|
}
|
|
|
|
private static int readBoardSize(Scanner scan) {
|
|
System.out.print("WHAT IS YOUR BOARD SIZE (MIN 7/ MAX 19)? ");
|
|
|
|
boolean validInput = false;
|
|
int input = 0;
|
|
while (!validInput) {
|
|
try {
|
|
input = scan.nextInt();
|
|
if (input < MIN_BOARD_SIZE || input > MAX_BOARD_SIZE) {
|
|
System.out.printf("I SAID, THE MINIMUM IS %s, THE MAXIMUM IS %s.\n", MIN_BOARD_SIZE, MAX_BOARD_SIZE);
|
|
} else {
|
|
validInput = true;
|
|
}
|
|
} catch (InputMismatchException ex) {
|
|
System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE\n");
|
|
validInput = false;
|
|
} finally {
|
|
scan.nextLine();
|
|
}
|
|
}
|
|
return input;
|
|
}
|
|
|
|
private static Move readMove(Scanner scan) {
|
|
System.out.print("YOUR PLAY (I,J)? ");
|
|
boolean validInput = false;
|
|
Move move = new Move();
|
|
while (!validInput) {
|
|
String input = scan.nextLine();
|
|
final String[] split = input.split(",");
|
|
try {
|
|
move.i = Integer.parseInt(split[0]);
|
|
move.j = Integer.parseInt(split[1]);
|
|
validInput = true;
|
|
} catch (NumberFormatException nfe) {
|
|
System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE\n? ");
|
|
}
|
|
|
|
}
|
|
return move;
|
|
}
|
|
|
|
private static class Move {
|
|
int i;
|
|
int j;
|
|
|
|
public Move() {
|
|
}
|
|
|
|
public Move(int i, int j) {
|
|
this.i = i;
|
|
this.j = j;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Move{" +
|
|
"i=" + i +
|
|
", j=" + j +
|
|
'}';
|
|
}
|
|
}
|
|
|
|
}
|