I am trying to create a game in a terminal for a school assignment. No pop out windows or anything. The problem is a bug in the game itself. the 'x' should move until it hits the wall, but it gets stuck inside the wall. I am only learning java and also any tips for future posts or programming are appreciated.
import java.util.Scanner;
public class App {
public static void main(String[] args) throws Exception {
Scanner input = new Scanner(System.in);
int coordx = 1;
int coordy = 1;
while (true) {
// System.out.println("Move: ");
String move = input.nextLine();
switch (move) {
case "a":
while (!wall(coordy - 1, coordx)) {
coordx--;
}
break;
case "w":
while (!wall(coordy, coordx - 1)) {
coordy--;
}
break;
case "d":
while (!wall(coordy + 1, coordx)) {
coordx++;
}
break;
case "s":
while (!wall(coordy, coordx + 1)) {
coordy++;
}
break;
default:
break;
}
render(coordx, coordy);
}
}
public static void render(int chary, int charx) {
int[][] grid = new int[9][40];
for (int i = 0; i < 9; i++) {
System.out.print("\n");
for (int j = 0; j < 40; j++) {
if (i == charx && j == chary) {
grid[i][j] = 0;
System.out.print("x");
} else if (wall(i, j)) {
grid[i][j] = 2;
System.out.print("#");
} else {
grid[i][j] = 1;
System.out.print(" ");
}
}
}
}
public static boolean wall(int coordy, int coordx) {
if (coordx == 0 || coordx == 39 || coordy == 0 || coordy == 8) {
return true;
} else {
return false;
}
// return true;
}
}
I like little games like this very much and it's great to help somebody like you early on in their adventure threw programming.
I think you have some of the while contidions mixed up. For Example:
case "a":
while (!wall(coordy - 1, coordx)) {
coordx--;
As far as I understand your game it should be:
case "a":
while (!wall(coordy, coordx - 1)) {
coordx--;
Check the other conditions in your gameloob too.
Related
I am attempting to make an unbeatable Tic Tac Toe game using a simplified minimax algorithm. The code looks like this:
private static int findBestMove(String[][] board, boolean comp) {
// comp returns true if the computer is the one looking for the best move
// findBestMove is always called by the program as findBestMove(board, true)
// since the computer is the only one that uses it
// If the board in its current state is a win for the
// player, return -1 to indicate a loss
if (playerWon(board)) return -1;
// If the board in its current state is a win for the
// computer, return 1 to indicate a win
if (compWon(board)) return 1;
// If the board in its current state is a tie
// return 0 to indicate a tie
if (tie(board)) return 0;
// Set the default possible outcome as the opposite of what
// the respective player wants
int bestPossibleOutcome = comp ? -1 : 1;
// Loop through the board looking for empty spaces
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++)
// Once an empty space is found, create a copy of the board
// with that space occupied by the respective player
if (board[i][j].equals(" ")) {
String[][] newBoard = new String[3][3];
for (int a = 0; a < 3; a++) {
System.arraycopy(board[a], 0, newBoard[a], 0, 3);
}
newBoard[i][j] = comp ? "O" : "X";
// Recursively call findBestMove() on this copy
// and see what the outcome is
int outCome = findBestMove(newBoard, !comp);
// If this is the computer's turn, and the outcome
// is higher than the value currently stored as the
// best, replace it
if (comp && outCome > bestPossibleOutcome) {
bestPossibleOutcome = outCome;
// r and c are instance variables that store the row
// and column of what the computer's next move should be
r = i;
c = j;
// If this is the player's turn, and the outcome
// is lower than the value currently stored as the
// best, replace it
} else if (!comp && outCome < bestPossibleOutcome) {
bestPossibleOutcome = outCome;
}
}
}
}
// Return the ultimate value deemed to be the best
return bestPossibleOutcome;
}
The idea is that after I run this program, the instance variables r and c should contain the row and column, respectively, of the computer's best move. However, the program only successfully prevents a loss about half the time, and I can't tell if the other half is luck, or if the program is actually working.
I am aware that the computer will respond to every scenario exactly the same way each game. That is fine.
In the event anyone would like to run the program, I have included the full class below:
import java.util.Scanner;
public class TicTacToe {
private static int r;
private static int c;
private static void printBoard(String[][] board) {
System.out.println(" 0 1 2");
System.out.println("0 " + board[0][0] + " | " + board[0][1] + " | " + board[0][2] + " ");
System.out.println(" ---+---+---");
System.out.println("1 " + board[1][0] + " | " + board[1][1] + " | " + board[1][2] + " ");
System.out.println(" ---+---+---");
System.out.println("2 " + board[2][0] + " | " + board[2][1] + " | " + board[2][2] + " ");
}
private static boolean playerWon(String[][] board) {
return playerHasThreeInCol(board) || playerHasThreeInDiag(board) || playerHasThreeInRow(board);
}
private static boolean playerHasThreeInRow(String[][] board) {
for (int i = 0; i < 3; i++) {
if (board[i][0].equals(board[i][1]) && board[i][0].equals(board[i][2]) && board[i][0].equals("X")) return true;
}
return false;
}
private static boolean playerHasThreeInCol(String[][] board) {
for (int i = 0; i < 3; i++) {
if (board[0][i].equals(board[1][i]) && board[0][i].equals(board[2][i]) && board[0][i].equals("X")) return true;
}
return false;
}
private static boolean playerHasThreeInDiag(String[][] board) {
if (board[0][0].equals(board[1][1]) && board[0][0].equals(board[2][2]) && board[0][0].equals("X")) return true;
return board[0][2].equals(board[1][1]) && board[0][2].equals(board[2][0]) && board[0][2].equals("X");
}
private static boolean compWon(String[][] board) {
return compHasThreeInCol(board) || compHasThreeInDiag(board) || compHasThreeInRow(board);
}
private static boolean compHasThreeInRow(String[][] board) {
for (int i = 0; i < 3; i++) {
if (board[i][0].equals(board[i][1]) && board[i][0].equals(board[i][2]) && board[i][0].equals("O")) return true;
}
return false;
}
private static boolean compHasThreeInCol(String[][] board) {
for (int i = 0; i < 3; i++) {
if (board[0][i].equals(board[1][i]) && board[0][i].equals(board[2][i]) && board[0][i].equals("O")) return true;
}
return false;
}
private static boolean compHasThreeInDiag(String[][] board) {
if (board[0][0].equals(board[1][1]) && board[0][0].equals(board[2][2]) && board[0][0].equals("O")) return true;
return board[0][2].equals(board[1][1]) && board[0][2].equals(board[2][0]) && board[0][2].equals("O");
}
private static boolean tie(String[][] board) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j].equals(" ")) return false;
}
}
return true;
}
private static int findBestMove(String[][] board, boolean comp) {
if (playerWon(board)) return -1;
if (compWon(board)) return 1;
if (tie(board)) return 0;
int bestPossibleOutcome = comp ? -1 : 1;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j].equals(" ")) {
String[][] newBoard = new String[3][3];
for (int a = 0; a < 3; a++) {
System.arraycopy(board[a], 0, newBoard[a], 0, 3);
}
newBoard[i][j] = comp ? "O" : "X";
int outCome = findBestMove(newBoard, !comp);
if (comp && outCome > bestPossibleOutcome) {
bestPossibleOutcome = outCome;
r = i;
c = j;
} else if (!comp && outCome < bestPossibleOutcome) {
bestPossibleOutcome = outCome;
}
}
}
}
return bestPossibleOutcome;
}
private static void go() {
Scanner input = new Scanner(System.in);
String[][] board = new String[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = " ";
}
}
printBoard(board);
for (int i = 0;; i++) {
if (i % 2 == 0) {
while (true) {
System.out.println("Enter position: ");
String position = input.nextLine();
int row, column;
try {
row = Integer.parseInt(position.substring(0, 1));
column = Integer.parseInt(position.substring(1, 2));
} catch (Exception e) {
System.out.println("Invalid entry. ");
continue;
}
if (row < 0 || row > 2 || column < 0 || column > 2) {
System.out.println("That position is not on the board. ");
continue;
}
if (!board[row][column].equals(" ")) {
System.out.println("That space is already taken. ");
continue;
}
board[row][column] = "X";
break;
}
} else {
System.out.println("\nMy move: ");
findBestMove(board, true);
board[r][c] = "O";
}
printBoard(board);
if (playerWon(board)) {
System.out.println("You win!");
break;
} else if (compWon(board)) {
System.out.println("I win!");
break;
} else if (tie(board)) {
System.out.println("Tie game");
break;
}
}
}
public static void main(String[] args) {
go();
}
}
I'm not asking for anyone to rewrite the whole thing for me, but if you can point out any obvious mistakes or point me in the right direction, that would be appreciated. I am also open to any suggestions or comments that you may have.
I haven't extensively tested it yet, but I believe that I resolved the issue. The new code looks like this:
private static void findBestMove(String[][] board) {
double bestMove = Double.NEGATIVE_INFINITY;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j].equals(" ")) {
board[i][j] = "O";
double score = minimax(board, false);
board[i][j] = " ";
if (score > bestMove) {
bestMove = score;
r = i;
c = j;
}
}
}
}
}
private static double minimax(String[][] board, boolean comp) {
if (playerWon(board)) {
return -1;
}
if (compWon(board)) {
return 1;
}
if (tie(board)) return 0;
double bestScore;
if (comp) {
bestScore = Double.NEGATIVE_INFINITY;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j].equals(" ")) {
board[i][j] = "O";
double score = minimax(board, false);
board[i][j] = " ";
bestScore = Math.max(score, bestScore);
}
}
}
} else {
bestScore = Double.POSITIVE_INFINITY;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j].equals(" ")) {
board[i][j] = "X";
double score = minimax(board, true);
board[i][j] = " ";
bestScore = Math.min(score, bestScore);
}
}
}
}
return bestScore;
}
I abstracted the minimax algorithm away from the next move coordinate setter, which I think may have made a difference. Otherwise, it is very similar.
I am trying to build a treasure hunt game using test files I have been given. These texts files are of chars S,W,E,N and T which all correspond to directions except for T, which is the treasure. Everything works fine until it moves the length of the rows/columns. I suspect it has something to do with the for loops but I'm not certain. Is there a way to do this without for loops or does anyone have any advice to get this back on track?
Here is my Updated code so far:
import java.util.*;
public class NewGridGame {
public static final int FALL_OFF = -1;
public static final int GOING_IN_CIRCLES = -2;
private int row;
private int col;
private char[][] gameBoard;
NewGridGame(int conRow, int conCol, char[][] conGameBoard) {
row = conRow;
col = conCol;
gameBoard = new char[row][col];
for (int i = 0; i < gameBoard.length; i++) {
for (int j = 0; j < gameBoard[i].length; j++) {
gameBoard[i][j] = conGameBoard[i][j];
}
}
System.out.println(Arrays.deepToString(gameBoard));
}
public int playGame() {
boolean[][] beenHereBefore = new boolean[row][col];
int turns = 0;
int i = 0;
int j = 0;
while (true) {
if (beenHereBefore[i][j] == true) {
return GOING_IN_CIRCLES;
} else {
beenHereBefore[i][j] = true;
}
if (gameBoard[i][j] == 'N') {
if (i - 1 >= 0) {
i--;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'S') {
if (i + 1 < row) {
i++;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'E') {
if (j + 1 < col) {
j++;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'W') {
if (j - 1 >= 0) {
j--;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'T') {
return turns;
}
}
}
}
Here is an example of a test file as well.
ES
TW
this one should return 3, which is the number of moves (turns, in my code) but instead it gets to W (which takes 2 moves) and returns -2, which is only for when it's gone to a position more than once. Additionally, not all of the Arrays are squares, some are 1x200 or 4x5 for examples.
If you know that the board is such that, starting at (0, 0), you won't get stuck in a loop or move off the board you can just used something like this:
public int playGame()
{
int numMoves = 0;
int currentRow = 0;
int currentCol = 0;
while(gameBoard[currentRow][currentCol] != 'T')
{
switch (gameBoard[currentRow][currentCol])
{
case 'E': currentCol++; break;
case 'W': currentCol--; break;
case 'S': currentRow--; break;
case 'N': currentRow++; break;
default:
throw new IllegalStateException("Unrecognized Move");
}
numMoves++;
}
return numMoves;
}
You may want to use if-then-else instead of a switch.
If you need to check for loops or off-board moves you should be able to add these checks in.
So i'm trying to make a game of Connect Four in Java, instead I'm connecting 6 instead of 4.
I have a 2-dimensional array and X amount of players. I have to check if 6 blocks in succession (horizontal, vertical and diagonal) are marked by the same player. If they are, the program should print who won.
Now, I don't have problems with the checking or determining who won, though for the life of me I can't figure out how to prevent the program from crashing whenever it tries to check for a block that's outside the array.
Now, I'm trying to avoid using try-catch or plopping 8 loops one after the other, and instead use one method for all of the directions with just variation in the parameters but I can't seem to make it work :\
Does anyone have a suggestion on how this might work?
I'm a beginner in programming and I've possibly missed something so that's why I'm asking for help :)
Cheers
Edit: here's the code. It's a bit long, that's why i want to shorten it and make it work somehow. the Terminal class is the same as the System.out.println one.
void checkIfPlayerWins(Field field, Integer rowNumber, Integer colNumber) {
Integer counter = 1;
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber, colNumber + i)) {
counter++;
} else {
break;
}
}
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber - i, colNumber + i)) {
counter++;
} else {
break;
}
}
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber - i, colNumber)) {
counter++;
} else {
break;
}
}
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber - i, colNumber - i)) {
counter++;
} else {
break;
}
}
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber, colNumber - i)) {
counter++;
} else {
break;
}
}
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber + i, colNumber - i)) {
counter++;
} else {
break;
}
}
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber + i, colNumber)) {
counter++;
} else {
break;
}
}
for (int i = 1; i <= 6; i++) {
if (field.isOccupied(rowNumber + i, colNumber + i)) {
counter++;
} else {
break;
}
}
if (counter == 6) {
Terminal.printLine("");
}
}
here's the isOccupied method
boolean isOccupied(Integer x, Integer y) {
return !this.field[x][y].equals("**");
}
You could simply handle the case where you're attempting to check whether the Field is occupied at invalid coordinates in your isOccupied method:
boolean isOccupied(Integer x, Integer y) {
if(x < 0 || y < 0 || x >= numberOfColumns || y >= numberOfRows) {
// Attempting to check outside the grid: it's non-occupied.
return false;
}
return !this.field[x][y].equals("**");
}
My checkTie method in my TicTacToe program doesn't work and results in an out of bounds array and I can't see why.
Running this code will print the board and allow the game to run until either someone wins, or there are 3 _'s left and then it will end the game.
I'm not sure why that happens though, I believe it has something to do with my checkTie for loop. Also, if a tie was to occur either nothing happens or an Array out of bounds happens.
import java.util.Scanner;
public class TicTac {
public static int row, col;
public static Scanner scan = new Scanner(System.in);
public static char[][] board = new char[3][3];
public static char turn = 'X';
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = '_';
}
}
Play();
}
public static boolean Play() {
boolean playing = true;
PrintBoard();
while (playing) {
System.out.println();
System.out.print("Please enter row: ");
row = scan.nextInt() - 1;
System.out.print("Please enter column: ");
col = scan.nextInt() - 1;
board[row][col] = turn;
if (GameOver(row, col)) {
playing = false;
System.out.println("Game Over! Player " + turn + " wins!");
**I feel like this code below is where the problem is**
if (checkTie(board)) {
System.out.println("Tie Game!");
return true;
}
}
PrintBoard();
if (turn == 'X')
turn = '0';
else
turn = 'X';
}
return false;
}
public static void PrintBoard() {
for (int i = 0; i < 3; i++) {
System.out.println();
for (int j = 0; j < 3; j++) {
if (j == 0)
System.out.print("| ");
System.out.print(board[i][j] + " | ");
}
}
System.out.println();
}
public static boolean GameOver(int rMove, int cMove) {
// Check if perpendicular victory
if (board[0][cMove] == board[1][cMove] && board[0][cMove] == board[2][cMove])
return true;
if (board[rMove][0] == board[rMove][1] && board[rMove][0] == board[rMove][2])
return true;
// Check Diagonal Victory
if (board[0][2] == board[1][1] && board[0][0] == board[2][2] && board[1][1] != '_')
return true;
if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[1][1] != '_')
return true;
return false;
}
This is where the method to see if the game result is a tie.
public static boolean checkTie(char[][] board) {
int spacesLeft = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == '_') {
spacesLeft++;
}
}
}
if (spacesLeft == 0) {
return true;
} else {
return false;
}
}
}
I think you meant to do checkTie when gameOver returns false'. As things stand,checkTieis only ever called aftergameOver' has returned `true'.
I'm having a setback in the code for a Tic Tac Toe Java program. Every time I run it, the game board prints 3 times and o the second time, the X's all fill in a line saying that player X wins. I've been trying to figure it out, but I still can't find the problem going on with it. What I'm asking is, what is the main problem of the code printing out more than it needs to and to stop filling in the lines?
I hope I format this correctly.
import java.util.Scanner;
public class TicTacToeWork {
//Variable declaration.
public static char[][] GameBoard = new char[3][3];
public static Scanner keyboard = new Scanner(System.in);
public static int column, row;
public static char PlayerTurn = 'X';
public static void main(String args[]) {
for (int i = 0; i > 3; i++) {
for (int j = 0; j < 3; j++) {
GameBoard[i][j] = '_';
}
}
System.out.println("Enter coordinates of row then column to choose your space.");
Playing();
}
public static void Playing() {
boolean PlayerPlaying = true;
while (PlayerPlaying) {
boolean playing = true;
while (playing) {
row = keyboard.nextInt() - 1;
column = keyboard.nextInt() - 1;
GameBoard[row][column] = PlayerTurn;
if (EndGame(row, column)) {
playing = false;
System.out.println("Game over player " + PlayerTurn + " wins!");
}
BoardPrint();
if (PlayerTurn == 'X') {
PlayerTurn = 'O';
} else {
PlayerTurn = 'X';
}
}
}
}
public static void BoardPrint() {
//Print out the game board.
for (int i = 0; i < GameBoard.length; i++) {
for (int n = 0; n < 3; n++) {
System.out.println();
for (int j = 0; j < 3; j++) {
if (j == 0) {
System.out.print("| ");
}
System.out.print(GameBoard[i][j] + " | ");
}
}
System.out.println();
}
System.out.println();
}
public static boolean EndGame(int RowMove, int ColumnMove) {
//Deciding factors on who wins and ties.
if (GameBoard[0][ColumnMove] == GameBoard[1][ColumnMove]
&& GameBoard[1][ColumnMove] == GameBoard[2][ColumnMove]) {
return true;
}
if (GameBoard[RowMove][0] == GameBoard[1][RowMove]
&& GameBoard[RowMove][0] == GameBoard[RowMove][2]) {
return true;
}
if (GameBoard[0][0] == GameBoard[1][1] && GameBoard[0][0] == GameBoard[2][2]
&& GameBoard[1][1] != '_') {
return true;
}
if (GameBoard[0][2] == GameBoard[1][1] && GameBoard[0][2] == GameBoard[2][0]
&& GameBoard[1][1] != '_') {
return true;
} else {
return false;
}
}
}
Your BoardPrint method is all wrong. You have to do something like this..
public static void BoardPrint() {
System.out.println("-------------");
for (int i = 0; i < 3; i++) {
System.out.print("| ");
for (int j = 0; j < 3; j++) {
System.out.print(GameBoard[i][j] + " | ");
}
System.out.println();
System.out.println("-------------");
}
You are also going to have to redo your check for a win.
A little hint.. you are not using a Boolean method correctly. This line if(EndGame(row, column)) is saying if EndGame is true stop the game. The way you have your method set up it is not doing the check correctly. You would have to say "if not true" - so it would look like this if(!EndGame(row, column)) There are a couple of other errors but this should give you a good start on completing the project.