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("**");
}
Related
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.
I need to create a method to check wether the tictactoe game is PLAYING, DRAW, XWIN or OWIN. However, I am having difficulty writing the code to check if X or O has won, given that the size of the gameboard and the size needed to win (sizeWin) are changing according to the user's input. AND I am forced to use a 1D array for the game board. I simply do not know where to go from here. My latest idea was to use nested for loops to check for a win by row, column or diagonal but I'm not sure how to implement it. If anyone has any tips on how to approach this problem or has any other solutions I would be very grateful
private void setGameState(int i) {
// Check rows
getLines();
getColumns();
getSizeWin();
for (row = 0; row == lines; row++) {
for (col = 0; col == columns; col++) {
}
}
}
public TicTacToeGame(int lines, int columns, int sizeWin) {
// linesXcolumns game, starts with X, need sizeWin in a line/column/diag to win
this.lines = lines;
this.columns = columns;
CellValue currentCellValue = CellValue.X;
this.sizeWin = sizeWin;
// Creating board according to given size
int size = lines * columns;
this.board = new CellValue[size];
// Setting up board to be empty
for (int i = 0; i < size; i++) {
board[i] = CellValue.EMPTY;
}
}
PS. If someone were to call the operator TicTacToe(3,4,3), a game board of 3 lines and 4 columns would print. And the number of X's or O's to win would be 3.
CAM$ java TicTacToe 3 4 3
| | |
---------------
| | |
---------------
| | |
It is a little more complicated than it looks but after you get it it's simple. I've made a function that works just fine:
private static String checkGameState() {
// Looking for errors.
if (rowCount <= 0 || columnCount <= 0) {
return "ERROR: Illegal board size: " + rowCount + "*" + columnCount;
}
if (boradContent.length != rowCount * columnCount) {
return "ERROR: boradContent not compatible with rowSize and columnSize.";
}
if (sizeWin > rowCount && sizeWin > columnCount) {
return "ERROR: Board is too small for this sizeWin: " + sizeWin + ".";
}
String gameState = "PLAYING";
// Checking rows
for (int i = 0; i < rowCount; i++) {
char currentChar = getField(i, 0);
int score = 1;
for (int j = 1; j < columnCount; j++) {
if (currentChar == getField(i, j)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
if (j > columnCount - sizeWin) {
break;
}
score = 1;
currentChar = getField(i, j);
}
}
}
// Checking columns
for (int j = 0; j < columnCount; j++) {
char currentChar = getField(0, j);
int score = 1;
for (int i = 1; i < rowCount; i++) {
if (currentChar == getField(i, j)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
if (j > rowCount - sizeWin) {
break;
}
score = 1;
currentChar = getField(i, j);
}
}
}
// Checking diagonally
// Checking diagonally - from top-left to bottom-right
for (int i = 0; i < rowCount - sizeWin + 1; i++) {
for (int j = 0; j < columnCount - sizeWin + 1; j++) {
char currentChar = getField(i, j);
int score = 1;
for (int k = 1; k < sizeWin; k++) {
if (currentChar == getField(i + k, j + k)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
break;
}
}
}
}
// Checking diagonally - from top-right to bottom-left
for (int i = 0; i < rowCount - sizeWin + 1; i++) {
for (int j = sizeWin -1; j < columnCount; j++) {
char currentChar = getField(i, j);
int score = 1;
for (int k = 1; k < sizeWin; k++) {
if (currentChar == getField(i + k, j - k)) {
score++;
if (score >= sizeWin) {
if (gameState.equals("PLAYING")) {
gameState = currentChar + "WIN";
} else if (!gameState.equals(currentChar + "WIN")) {
gameState = "DRAW";
return gameState;
}
}
} else {
break;
}
}
}
}
return gameState;
}
It is worth to mention that the rowCount, columnCount, sizeWin and boradContent variables are class level variables and i used a getField(int X, int Y) method that is not a very complicated thing but is more useful. It just converts the given field coordinates to the place in a 1D array and returns it's content:
private static char getField(int X, int Y) {
return boradContent[X * columnCount + Y];
}
am trying to find four of a kind in a five-card poker hand. but it's not working and couldn't figure out why.
public boolean hasFourOfaKind(String hand) {
int counter = 0;
char x = 0;
for (int i = 0; i < hand.length(); i++)
{
if (i == 0) {
x = hand.charAt(0);
} else if (x == hand.charAt(i)) {
counter++;
}
}
if (counter >= 4) {
return true;
} else {
return false;
}
}
the same problem here am trying to check whether the given four-card hand is a badugi
public boolean hasFourCardBadugi(String hand) {
int diffcounter = 0;
char badugi = 0;
for (int i = 0; i < hand.length(); i++) {
if (i == 0) {
badugi = hand.charAt(0);
} else if (badugi != hand.charAt(i)) {
diffcounter++;
}
}
if (diffcounter >= 10) {
return true;
} else {
return false;
}
}
Let's look at your for loop.
for (int i = 0; i < hand.length(); i++)
{
if (i == 0) {
x = hand.charAt(0);
} else if (x == hand.charAt(i)) {
counter++;
}
}
In this part
if (i == 0) {
x = hand.charAt(0);
}
You set x to the first card. But you never count that card. You need to add:
if (i == 0) {
x = hand.charAt(0);
counter++;
}
Of course this still has the issue that it will not detect hands where the four of a kind does not match the first card (ace two two two two), but you should be able to work that out now that the basic bug is fixed. One way to do it would just involve a second loop.
I need to find the first match in this task. Probably i am just missing something. As you can see, i found the last match.I am not copied the first half of the code. Thank you.
for (int i = 0; i <= n - 1; i++) {
if (iv[i] == a) {
hely = i;
}
}
if (hely == -1) {
System.out.println("text");
} else {
System.out.println("text " + a + " text " + (hely + 1) + "text");
}
break the loop when you find first match.
for (int i = 0; i <= n - 1; i++) {
if (iv[i] == a) {
hely = i;
break;
}
}
You need to exit the for loop after finding the first match:
for (int i = 0; i <= n - 1; i++) {
if (iv[i] == a) {
hely = i;
break;
}
}
I need the loop to iterate through A1,A2..A8..B8...H8 but it stops at C3 for some reason. For the life of me I cannot figure out why this loop within a loop is not running.
P.S letters is just an arraylist of the alphabet {A,B,C...Z} and getValue() just returns a value depending on how much a letter is worth.
int bestMove = 0;
for(int i = 0; i < 8; i++){
for(int x = 0; x < 8; x++){
System.out.println(letters.get(i) + "" + (x+1));
int distanceRow = currentRow - i;
int distanceCol = currentCol - x;
distanceRow = Math.abs(distanceRow);
distanceCol = Math.abs(distanceCol);
if(currentRow == i && currentCol == x){
System.out.println("if");
} else if (distanceRow - distanceCol == 0) {
bestMove = getValue(getPiece(i, x));
System.out.print("else if");
System.out.println(letters.get(i) + "" + (x+1));
} else {
System.out.print(letters.get(i) + "" + (x+1));
System.out.println("else");
}
}
Edit: I tested it as was suggested and it seems theres an error with this method although I dont know what since it just returns a value
public int getValue(String piece) {
if (piece.equals(w1)) {
return 1;
} else if (piece.equals(w2)) {
return 3;
} else if (piece.equals(w3)) {
return 3;
} else if (piece.equals(w4)) {
return 5;
} else if (piece.equals(w5)) {
return 9;
}
return 0;
}