I'm building a connect 4 game using Processing (Java) and have come to a holt when trying to find the winner. I've posted the code could anyway tell me why this isn't working? or how I would remedy it.
Any help is greatly appreciated.
Thanks
if (whooseWon() == true) {
text = loadFont("Tahoma-Bold-50.vlw");
textFont(text, 50);
fill(255, 0, 0);
game = false;
if (whoWon == 1) {
text("Red Wins!", width/4, height/4);
text("Click to play again", 110, height/2);
} else if (whoWon == 2) {
fill(255, 255, 0);
text("yellow Wins!", width/4, height/4);
text("Click to play again", 110, height/2);
} else if (whoWon == 3) {
fill(255, 255, 0);
text("It's a Tie", width/4, height/4);
text("Click to play again", 110, height/2);
}
}
}
// click to play again functionality
void mousePressed() {
if (game == false) {
game = true;
setup();
}
}
// 21 vertical possibilities, 24 horizontal and 12 diagonally that's a total of 69 possibilities
// cols = j
// rows = i
boolean whooseWon() {
// horizontal
for (int i = 0; i < rows-3; i++) {
for (int j = 0; j < cols; j++) {
//red player
if (piece[i+1][j].getColour() == color(counter1) && piece[i+1]. [j].getColour() == color(counter1) &&
piece[i+2][j].getColour() == color(counter1) && piece[i+3][j].getColour() == color(counter1))
{
whoWon = 1;
return true;
}
if (piece[i][j].getColour() == color(counter2) && piece[i+1][j].getColour() == color(counter2) &&
piece[i+2][j].getColour() == color(counter2) && piece[i+3][j].getColour() == color(counter2))
{
whoWon = 2;
return true;
}
}
}
// vertical
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols-3; j++) {
//red player
if (piece[i][j].getColour() == color(counter1) && piece[i][j+1].getColour() == color(counter1) &&
piece[i][j+2].getColour() == color(counter1) && piece[i][j+3].getColour() == color(counter1))
{
whoWon = 1;
return true;
}
if (piece[i][j].getColour() == color(counter2) && piece[i][j+1].getColour() == color(counter2) &&
piece[i][j+2].getColour() == color(counter2) && piece[i][j+3].getColour() == color(counter2))
{
whoWon = 2;
return true;
}
}
}
//diagonal
for (int i = 0; i < rows-3; i++) {
for (int j = 0; j < cols-3; j++) {
//red player
if (piece[i][j].getColour() == color(counter1) && piece[i+1][j+1].getColour() == color(counter1) &&
piece[i+2][j+2].getColour() == color(counter1) && piece[i+3][j+3].getColour() == color(counter1))
{
whoWon = 1;
return true;
}
if (piece[i][j].getColour() == color(counter2) && piece[i+1][j+1].getColour() == color(counter2) &&
piece[i+2][j+2].getColour() == color(counter2) && piece[i+3][j+3].getColour() == color(counter2))
{
whoWon = 2;
return true;
}
}
}
//diagonal
for (int i = 0; i < rows-3; i++) {
for (int j = 0; j < cols; j++) {
//red player
if (piece[i][j].getColour() == color(counter2) && piece[i+1]
[j-1].getColour() == color(counter2) &&
piece[i+2][j-2].getColour() == color(counter2) && piece[i+3]
[j-3].getColour() == color(counter2))
{
whoWon = 1;
return true;
}
if (piece[i][j].getColour() == color(counter2) && piece[i+1]. [j+1].getColour() == color(counter2) &&
piece[i+2][j-2].getColour() == color(counter2) && piece[i+3]
[j-3].getColour() == color(counter2))
{
whoWon = 2;
return true;
}
}
}
return false;
}
`
You're making it pretty hard for people to help you. Instead of posting a disconnected snippet from your huge sketch, try to create an MCVE. This usually involves starting over with a blank sketch and only adding enough code to repeat the problem, without any of the extra stuff not directly related to it. We should be able to copy and paste the code into our own editors, hit run, and see the same thing as you. Otherwise we're all just guessing. You'll often solve your problem in the process of creating an MCVE!
That being said, I can help you try to debug your problem. You've said that you're getting an ArrayIndexOutOfBounds exception. Which line is the error on? I'm not asking that so you tell me. I'm asking that because it's the first question you should be asking yourself.
When you get it narrowed down to a specific line, then you need to backtrack to find out exactly what's going on. What indexes are being accessed? How many indexes do the arrays have? You've got a mismatch between the two, which is causing your problem.
Use the println() function to print out every value that might be part of this. That's at least the i and j variables, as well as row and columns, and piece.length and piece[yourIndexHere].length.
Then walk through your code line-by-line until you understand exactly what it's doing. Again, you'll have much better luck if you work from an MCVE instead of trying to parse through a big mess. Then if you get stuck, you can post a new question with that MCVE and it'll be much easier for us to help you. Good luck.
Related
I have basically everything in place to finish the tic tac toe game I've been working on, but am having trouble checking to see who won the game. Essentially, I'm trying to see if somebody won the game, and if they did, then to display a message saying which player won.
I've tried just brute-force checking every JButton row/column/diagonal but it doesn't seem to be working. I have the JButtons layed out in a 3 by 3 grid btw.
if((gameButton[0].getText().equals("X") && gameButton[1].getText().equals("X") && gameButton[2].getText().equals("X"))||
(gameButton[3].getText().equals("X") && gameButton[4].getText().equals("X") && gameButton[5].getText().equals("X"))||
(gameButton[6].getText().equals("X") && gameButton[7].getText().equals("X") && gameButton[8].getText().equals("X"))||
(gameButton[0].getText().equals("X") && gameButton[3].getText().equals("X") && gameButton[6].getText().equals("X"))||
(gameButton[1].getText().equals("X") && gameButton[4].getText().equals("X") && gameButton[7].getText().equals("X"))||
(gameButton[2].getText().equals("X") && gameButton[5].getText().equals("X") && gameButton[8].getText().equals("X"))||
(gameButton[0].getText().equals("X") && gameButton[4].getText().equals("X") && gameButton[8].getText().equals("X"))||
(gameButton[2].getText().equals("X") && gameButton[4].getText().equals("X") && gameButton[6].getText().equals("X"))) {
wonLabel.setText("Player X has won!");
}
else if((gameButton[0].getText().equals("O") && gameButton[1].getText().equals("O") && gameButton[2].getText().equals("O"))||
(gameButton[3].getText().equals("O") && gameButton[4].getText().equals("O") && gameButton[5].getText().equals("O"))||
(gameButton[6].getText().equals("O") && gameButton[7].getText().equals("O") && gameButton[8].getText().equals("O"))||
(gameButton[0].getText().equals("O") && gameButton[3].getText().equals("O") && gameButton[6].getText().equals("O"))||
(gameButton[1].getText().equals("O") && gameButton[4].getText().equals("O") && gameButton[7].getText().equals("O"))||
(gameButton[2].getText().equals("O") && gameButton[5].getText().equals("O") && gameButton[8].getText().equals("O"))||
(gameButton[0].getText().equals("O") && gameButton[4].getText().equals("O") && gameButton[8].getText().equals("O"))||
(gameButton[2].getText().equals("O") && gameButton[4].getText().equals("O") && gameButton[6].getText().equals("O"))) {
wonLabel.setText("Player O has won!");
}
I expected this to output a message of which player won, but when I interacted with the GUI and purposely made a certain row/column/diagonal either all "X" or "O", nothing happens. Any feedback/recommendations to make this more efficient would be welcome.
Might I suggest doing something like this, storing the text as a boolean array. After each time the button is pressed, set the point in the array to be true (if X) or false (if O). I'm going to assume that you already have a turn counter, with a boolean, it'll be referenced later.
Make sure that this boolean array is global!!!
boolean[3][3] check = new boolean[3][3];
In your actionEventListener having this run,
public void actionPerformed (ActionEvent e){
Object source = e.getSource();
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
if (source == board[i][j], turn == true){
check[i][j] = true;
}
else{
check[i][j] = false;
}
}
}
}
After this, you can probably just have this method, which runs after each turn, or however you see fit.
private void win (){
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
int winO = 0;
int winX = 0;
for (int x = 0; x < 2; x++)
{
if (check[i][j] == false)
{
winO++;
if (check[i+x][j+x] == false)
{
winO++;
System.out.println(winO);
}
}
else if (check[i][j] == true)
{
winX++;
if (check[i+x][j+x] == true)
{
winX++;
System.out.println(winX);
}
}
if (winO == 4)
{
wonLabel.setText("Player O has won!");
break;
}
else if (winX == 4)
{
wonLabel.setText("Player X has won!");
break;
}
}
}
}
}
Fair warning. This only checks for diagonals! If you want to check for horizontal / vertical, you'll have to add the x value to i and/or j individually
There might be more efficient ways to do this, but this is the best I can do, hope it helps
I'm learning how to use processing and tried to make a simple snake game, while doing it it does show (although it was cntrl+c cntrl+v from the first one, which was up) a Weir behavior in for loops specifically for going right or down.
i managed to fix the 'down' problem by simply changing
for(int k=0;k<56;k++)
to
for(int k=55;k<=0;k--)
which is exactly the same thing, isn't it? i am i missing something?
int [][] snakeHead = new int[60][60];
int game = 1;
int value = 0;
String s = "You lost\nPress SHIFT to Restart";
void setup(){
size(600,600);
frameRate(10);
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
snakeHead[i][k] = 0;
}
}
snakeHead[1][22] = 1;
game = 1;
value = 0;
}
void draw(){
background(0);
fill(255);
rect(20, 20, 560, 560);
if(game == 1){
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
if(snakeHead[i][k] == 1){
fill(0,255,0);
rect(20+i*10, 20+k*10, 10,10);
}
}
}
if(value == 1){
up();
}else if(value == 2){
down();
}else if(value == 3){
left();
}else if(value == 4){
right();
}
}
else{
textSize(32);
textAlign(CENTER);
fill(0,0,255);
text(s, 300, 300);
}
}
void keyPressed(){
if(key == CODED){
if(keyCode == UP){
value = 1;
}
else if(keyCode == DOWN){
value = 2;
}
else if(keyCode == LEFT){
value = 3;
}
else if(keyCode == RIGHT){
value = 4;
}else if(keyCode == SHIFT){
setup();
}
}
}
void up(){
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
if(snakeHead[i][k] == 1 && k == 0){
game = 0;
}else if(snakeHead[i][k] == 1){
snakeHead[i][k-1] = 1;
snakeHead[i][k]=0;
}
}
}
}
void down(){
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
if(snakeHead[i][k] == 1 && k == 55){
game = 0;
}else if(snakeHead[i][k] == 1 && k != 55){
snakeHead[i][k+1] = 1;
snakeHead[i][k] = 0;
}
}
}
}
void right(){
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
if(snakeHead[i][k] == 1 && i == 55){
game = 0;
}else if(snakeHead[i][k] == 1 && i != 55){
snakeHead[i+1][k] = 1;
snakeHead[i][k]=0;
}
}
}
}
void left(){
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
if(snakeHead[i][k] == 1 && i == 0){
game = 0;
}else if(snakeHead[i][k] == 1){
snakeHead[i-1][k] = 1;
snakeHead[i][k]=0;
}
}
}
}
Your problem in the right and down that in both you update the head down the loop (with i+1 or j+1) so the else block get execute more then once (in the up and left you doing i-1 and j-1 so it doesn't happens there).
Let look at the right function to demonstrate:
void right(){
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
if(snakeHead[i][k] == 1 && i == 55){
game = 0;
} else if(snakeHead[i][k] == 1 && i != 55){
snakeHead[i+1][k] = 1; // update the sankeHead to i+1 which will be reached in the next iteration in i so basiclly keep moving right till reach if block
snakeHead[i][k]=0;
}
} // end k loop
} // end i loop
}
To fix this all you need to do is add return because you only want to move the snakeHead once!
so:
void right(){
for(int i=0;i<56;i++){
for(int k=0;k<56;k++){
if(snakeHead[i][k] == 1 && i == 55){
game = 0;
return;
} else if(snakeHead[i][k] == 1 && i != 55){
snakeHead[i+1][k] = 1;
snakeHead[i][k]=0;
return;
}
} // end k loop
} // end i loop
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have problem with recognizing flushes and straights. I operate in 2D boolean array and it must be a boolean array nothing else. Could somebody help me in writing this method?
I already have logically incorrect methods, but I don't know how to solve it:
public static Boolean isFlush(boolean[][] hand) { // 5 cards same color
boolean found = false;
for (int i = 0; i < 4; i++) {
for(int j = 0; j < 9; j++){
if (hand[i][j] == true && hand[i][j+1] == true && hand[i][j+2] == true && hand[i][j+3] == true && hand[i][j+4] == true) {
found = true;
}
}}
System.out.println("Found from flush: " + found);
return found;
}
public static Boolean isStraight(boolean[][] hand) { // straight patter example 4,5,6,7,8
boolean found = false;
int pom = 0;
for(int i = 0; i<4; i++) {
for (int j = 0; j < 9; j++) {
if (hand[i][j] == true || hand[i][j+1] == true || hand[i][j+2] == true || hand[i][j+3] == true || hand[i][j+4])
pom++;
// System.out.println("straight value: "+i);
}
}
return pom==5;
}
Working Straight method but step by step writed
public static Boolean isStraight(boolean[][] hand) { // straight patter example 4,5,6,7,8
boolean found = false;
for (int j = 0; j < 9; j++) {
if ((hand[0][j] == true || hand[1][j] == true || hand[2][j] == true || hand[3][j] == true)
&& (hand[0][j+1] == true || hand[1][j+1] == true || hand[2][j+1] == true || hand[3][j+1] == true)
&& (hand[0][j+2] == true || hand[1][j+2] == true || hand[2][j+2] == true || hand[3][j+2] == true)
&& (hand[0][j+3] == true || hand[1][j+3] == true || hand[2][j+3] == true || hand[3][j+3] == true)
&& (hand[0][j+4] == true || hand[1][j+4] == true || hand[2][j+4] == true || hand[3][j+4] == true ))
found = true;
}
return found;
}
For what it is worth, here is the most efficient way to solve a straight, using DP
public static boolean isStraight(boolean[][] hand) {
int[] straightCounter = new int[13];
for (int j=0; j<13; j++) {
boolean isCard = hand[0][j] || hand[1][j] || hand[2][j] || hand[3][j];
if (isCard) {
if (j==0)
straightCounter[j]=1;
else
straightCounter[j]=straightCounter[j-1]+1;
if (straightCounter[j] == 5)
return true;
if (j==12 && straightCounter[j] == 4 && straightCounter[0] == 1)
return true; // the 10/J/Q/K/A scenario
}
}
return false;
}
something like the following
public static Boolean isFlush(boolean[][] hand) { // 5 cards same color
for (int i = 0; i < 4; i++) {
int count = 0;
for(int j = 0; j < 13; j++) {
if(hand[i][j]) {
count++;
}
}
if(count == 5) {
return true;
}
}
return false;
}
public static Boolean isStraight(boolean[][] hand) { // straight patter
for (int i = 0; i < 9; i++) {
int count = 0;
for(int j = 0; j < 5; j++) {
for(int k = 0; k < 4; k++) {
if (hand[k][i + j]) {
count++;
break;
}
}
}
if(count == 5) {
return true;
}
}
return false;
}
I am trying to create the Game of Life, but I am having issues with certain aspects of the code. First of all, when I click squares and tell the game of life to start by pushing the start button, all of the squares go blank instead of following the rules that I have described in the update method. Not matter what location or how many squares I push, they all go back to false as if I am resetting the game. I think my for loop is correct, but I think I may be missing something in one of my if statements. Any help would be appreciated.
public class GameOfLife
{
private int row;
private int col;
private boolean[][] grid;
private LifeBoard board;
public static void main(String[] args)
{
GameOfLife game = new GameOfLife();
}
public GameOfLife()
{
board = new LifeBoard( this );
grid = new boolean[board.getGridSize()][board.getGridSize()];
}
public void clickSquare( int row, int column )
{
if (grid[row][column] == false)
{
grid[row][column] = true;
}
else
{
grid[row][column] = false;
}
return;
}
public void resetGrid()
{
for (row = 0; row < grid.length; row++)
{
for (col = 0; col < grid[row].length; col++)
{
grid[row][col]= false;
}
}
return;
}
public void updateGrid()
{
boolean[][] grid2 = new boolean[grid.length][grid.length];
//Nested for loop to go through entire array
for (row = 0; row < grid.length; row++)
{
for ( col = 0; col < grid[row].length; col++)
{
int neighbors = 0;
/*If statements to determine if cell is alive and whether and then to
add neighbors depending upon position.*/
if (row > 0 && col > 0 && grid[row-1][col -1] == true)
{
neighbors++;
}
if (col > 0 && grid[row][col-1] == true)
{
neighbors++;
}
if (col > 0 && row < grid.length-1 && grid[row+1][col-1] == true)
{
neighbors++;
}
if (row > 0 && grid[row-1][col] == true)
{
neighbors++;
}
if (col < 0 && row < grid.length-1 && grid[row+1][row-1] == true)
{
neighbors++;
}
if (row > 0 && col < grid.length-1 && grid[row-1][col+1] == true)
{
neighbors++;
}
if (col < grid.length-1 && grid[row][col+1] == true)
{
neighbors++;
}
if (row < grid.length-1 && col < grid.length-1 && grid[row+1][col+1] == true)
{
neighbors++;
}
//If there are two or three neighbors than the grid remain true for those values
if (grid[row][col] == true)
{
if (neighbors == 2 || neighbors == 3 )
{
grid2[row][col] = true;
}
else
{
grid2[row][col] = false;
}
if (grid[row][col] == false)
{
if (neighbors > 2)
{
grid2[row][col] = false;
}
if (neighbors == 3)
{
grid2[row][col] = true;
}
}
}
}
grid = grid2;
}
}
public boolean[][] getGrid()
{
return grid;
}
Where you do:
if (grid[row][col] == true)
{
if (neighbors == 2 || neighbors == 3 )
{
grid2[row][col] = true;
}
else
{
grid2[row][col] = false;
}
if (grid[row][col] == false)
{
if (neighbors > 2)
{
grid2[row][col] = false;
}
if (neighbors == 3)
{
grid2[row][col] = true;
}
}
You forgot to close the first if. Also, it should be an else so the second block doesn't undo what the first block did.
Second, grid = grid2 should be set after you close the for loop. So you do not change grid in the middle of your iteration.
The Wikipedia article on Conway's Game of Life lists the following rules:
Any live cell with fewer than two live neighbours dies, as if caused by under-population.
Any live cell with two or three live neighbours lives on to the next generation.
Any live cell with more than three live neighbours dies, as if by overcrowding.
Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
Translating this into code:
if (grid[row][col]) {
if (neighbors < 2 || neighbors > 3) {
// 1. Any live cell with fewer than two live neighbours dies
// 3. Any live cell with more than three live neighbours dies
grid2[row][col] = false;
}
// 2. Any live cell with two or three live neighbours lives on. Does nothing.
} else if (neighbors == 3) {
// 4. Any dead cell with exactly three live neighbours becomes a live cell.
grid2[row][col] = true;
}
As a side note, the method clickSquare() just inverts the value in grid[row][column], so it could be implemented as simply:
public void clickSquare(int row, int column) {
grid[row][column] = !grid[row][column];
}
Can col be less than 0? Did you mean to use row twice instead of col and row?:
if (col < 0 && row < grid.length-1 && grid[row+1][row-1] == true)
{
neighbors++;
}
This is, I imagine, a really simple problem to solve however I just can't figure it out.
An array contains a list of integers and I want to return true if every number 'x' in the array is followed by the number 'y'.
So arrays with {x,3,4,y} or {x,x,y,4,5} or {5,8,x,x} would be false.
Whereas arrays with {x,y,4,1} or {x,y,5,1,x,y} would be true.
This is what I have tried so far:
for (int i = 0; i < nums.length-1; i++)
{
if (nums[i] == x && nums[i+1] == y)
{
return true;
}
else
{
return false;
}
}
return false;
My code however will only work for the first two elements in the array (so 0 and 1). It won't detect any integers further down in the array, so how do I do this?
Thank you.
I want to return true if every number 'x' in the array is followed by the number 'y'.
You need to get rid of the else and modify the checks like so:
for (int i = 0; i < nums.length - 1; i++)
{
if (nums[i] == x && nums[i + 1] != y)
{
return false;
}
}
return true;
Caveats:
This returns true if x is not present in the array. It's unclear from the question whether this is the behaviour you want.
This does not check whether x is the last element of the array. Again, it's not entirely clear what you'd expect to happen if it is.
When the code reaches a return statement it stops executing the function and returns the specified value, that's why your for is only executed once.
Since you want the condition to apply to ALL the elements in the array, you have to return false when you find a 2 that isn't followed by a 3. If the 2 is followed by a 3, you just keep checking the next position.
Like this:
for (int i = 0; i < nums.length-1; i++)
{
if(nums[i] == 2 && nums[i+1] != 3)
{
return false;
}
}
return true;
for (int i = 0; i < nums.length-1; i++) {
if (nums[i] == 2 && nums[i+1] != 3) {
return false;
}
}
return true;
This code will return False iff the 'x' number is not followed by 'y'.
for (int i = 0; i < nums.length-1; i++)
{
if(nums[i] == 2 && nums[i+1] != 3) {
return false;
}
}
return true;
for (int i = 0; i < nums.length-1; i++)
{
if(nums[i] == 2 && nums[i+1] == 3)
{
return true;
}
}
return false;
Your Code is returning in the first iteration always. because you have return written there in both If and else block.
remove the else case or just the return; from else case if there is any other logic inside.
int x = 2;
int y=3;
for (int i = 0; i < nums.length-1; i++) {
if (nums[i] == x && nums[i+1] != y) {
return false;
}
}
return true;
If you do not have x in the array, it will return true. and if you have any x that does not have y after it, it will return false.
Try out Following
boolean flag = false;
for (int i = 0; i <= (nums.length-1); i++) {
if(nums[i] == x) {
if (i == (nums.length-1)) {
if(nums[i] == x) {
flag = false;
}
} else {
if(nums[i+1] == y) {
flag = true;
} else {
flag = false;
break;
}
}
}
}
return flag;
You can try out the following:
if(nums[nums.length - 1] == x)
{
return false;
}
else
{
boolean flag = false;
for(i = 0; i < nums.length - 1; i++)
{
if(nums[i] == x)
{
if(nums[i + 1] == y)
{
flag = true;
}
else
{
flag = false;
break;
}
}
}
return flag;
}