Tic-Tac-Toe Help

So I'm working on a simple tic-tac-toe game and everything runs as inteded, except for one little thing. The last move of a game doesn't show up properly on the board, it just shows the win/full board prompt and clears the board. Maybe I'm just tired but I can'r for the life of me figure out why this is, no matter how much I experiment. I figured that since my displayCurrentBoard function is called before the prompt, it should appear but it seems not to be the case. Help is very much appreciated.

import javax.swing.JOptionPane;
import ddf.minim.*;

PImage pencil;
PImage xMark;
PImage oMark;
PImage game;
PImage start;
PImage howto;
Minim minim;
AudioPlayer player1;
int penX = -400;
int penY = -400;
boolean Xturn = true;
int [][] board = new int[3][3];
int xState = 1;
int yState = 1;
int filledNum = 0;
int xNum = 0;
int yNum = 0;
int screen = 0;

void setup()
{
  size(600,600);
  minim = new Minim(this);
  player1 = minim.loadFile("bgmusic.mp3");
  start = loadImage("start.png");
  howto = loadImage("instruct.png");
  game = loadImage("board.png");
  pencil = loadImage("pointer.png");
  xMark = loadImage("x.png");
  oMark = loadImage("o.png");
  background(game);
  player1.play();
}

void draw()
{
  if(screen == 0)
  {
    image(start,0,0);
  }

  if(screen == 1)
  {
    image(howto,0,0);
  }

  if(screen == 2)
  {
  image(game,0,0);
  displayCurrentBoard();
  image(pencil,penX,penY);
  text("(" + xState + "," + yState + ")", 10, 593);
  if(Xturn)
  {
    text("It is X's turn.",500 , 593);
  }
  else
  {
    text("It is O's turn.",500 , 593);
  }
  }

  if(checkXwin())
  {
    displayResults(1);
  }

    if(checkOwin())
  {
    displayResults(2);
  }

  if(checkNoWin())
  {
    displayResults(3);
  }

}

void keyPressed()
{
  if(key == 'a')
  {
   if(Xturn  && (board[xState - 1][yState - 1] != 1 && board[xState - 1][yState - 1] != 2))
   {
       board[xState - 1][yState - 1] = 1;
       Xturn = false;
   }
   else if ((board[xState - 1][yState - 1] != 1 && board[xState - 1][yState - 1] != 2))
   {
     board[xState - 1][yState - 1] = 2;
     Xturn = true;
   }
  }

  if(key == 's')
  {
    if(screen < 2)
    {
      screen++;
    }
  }

  if(key == CODED)  //Used to take input from keyboard
  {
    if(keyCode == UP) //Moves cursor up if within proper boundaries
    {
      if(penY != -400)
      {
        penY = penY - 200;
          if(yState != 1) //registers new position
            {
             yState--; 
            }
      }
    }

    if(keyCode == DOWN)
    {
         if(penY != 0)
      {
        penY = penY + 200;
        if(yState != 3)
        {
          yState++;
        }
      }
    }

    if(keyCode == LEFT)
    {
         if(penX != -400)
      {
        penX = penX - 200;
        if( xState != 1)
        {
          xState--;
        }
      }
    }

    if(keyCode == RIGHT)
    {
         if(penX != 0)
      {
        penX = penX + 200;
        if (xState != 3)
        {
         xState++; 
        }
      }
    }

  }
}

void displayCurrentBoard()
{
  for(int i = 0; i < 3; i++)
  {
    for(int j = 0; j < 3; j++)
    {
      if(board[i][j] == 1)
      {
        image(xMark,(i * 200),(j * 200));
      }
      else if(board[i][j] == 2)
      {
        image(oMark, (i * 200), (j * 200));
      }
    }
  }
}

boolean checkXwin()
{
  if((board[0][0] == 1 && board [1][0] == 1 && board[2][0] == 1) ||
     (board[0][1] == 1 && board [1][1] == 1 && board[2][1] == 1) ||
     (board[0][2] == 1 && board [1][2] == 1 && board[2][2] == 1) ||
     (board[0][0] == 1 && board [0][1] == 1 && board[0][2] == 1) ||
     (board[1][0] == 1 && board [1][1] == 1 && board[1][2] == 1) ||
     (board[2][0] == 1 && board [2][1] == 1 && board[2][2] == 1) ||
     (board[0][0] == 1 && board [1][1] == 1 && board[2][2] == 1) ||
     (board[0][2] == 1 && board [1][1] == 1 && board[2][0] == 1))
     {
        return true;
      }
  else
  {
  return false;
  }
}


boolean checkOwin()
{
  if((board[0][0] == 2 && board [1][0] == 2 && board[2][0] == 2) ||
     (board[0][1] == 2 && board [1][1] == 2 && board[2][1] == 2) ||
     (board[0][2] == 2 && board [1][2] == 2 && board[2][2] == 2) ||
     (board[0][0] == 2 && board [0][1] == 2 && board[0][2] == 2) ||
     (board[1][0] == 2 && board [1][1] == 2 && board[1][2] == 2) ||
     (board[2][0] == 2 && board [2][1] == 2 && board[2][2] == 2) ||
     (board[0][0] == 2 && board [1][1] == 2 && board[2][2] == 2) ||
     (board[0][2] == 2 && board [1][1] == 2 && board[2][0] == 2))
     {
        return true;
      }
  else
  {
  return false;
  }
}

boolean checkNoWin()
{
  filledNum = 0;
  for(int i = 0; i < 3; i++)
  {
    for(int j = 0; j < 3; j++)
    {
      if(board[i][j] == 1 || board[i][j] == 2)
      {
        filledNum++;
      }
    }
  }
  if(filledNum == 9)
  {
    displayCurrentBoard();
    //clearBoard();
    return true;
  }
  else
  {
    return false;
  }
}

void clearBoard()
{
  displayCurrentBoard();
   for(int i = 0; i < 3; i++)
  {
    for(int j = 0; j < 3; j++)
    {
      board[i][j] = 0;     
    }
  }
}

void displayResults(int i)
{
  displayCurrentBoard();

  switch(i)
  {
    case 1: JOptionPane.showMessageDialog(null, "X Wins.  Restarting...");
            clearBoard();
            break;
    case 2: JOptionPane.showMessageDialog(null, "O Wins.  Restarting...");
            clearBoard();
            break;
    case 3: JOptionPane.showMessageDialog(null, "The board is full.  Restarting...");
            clearBoard();
            break;
  }
}
Tagged:

Answers

  • This is going to be pretty hard for us to debug, since we don't have access to those files. Can you either create an MCVE that doesn't use images, or post the images for us to use?

    But without debugging it, here is what I think is happening. Keep in mind that Processing uses double buffering, so anything you call from the draw() function is drawn to the offscreen buffer, which only gets drawn to the screen at the end of the draw() function. Think about it this way:

    void draw(){
       background(0); //draw the background of the offscreen buffer
       ellipse(10, 10, 10, 10); //draw ellipse to offscreen buffer
    } //when draw finishes, draw the entire offscreen buffer to the screen
    

    Now, the problem is that JOptionPane blocks the execution of the code until you dismiss the dialog. So the draw() function will never exit, so the offscreen buffer will not be drawn to the screen!

    void draw(){
       background(0); //draw the background of the offscreen buffer
       ellipse(10, 10, 10, 10); //draw ellipse to offscreen buffer
    
       //this line blocks the code until you hit OK
       JOptionPane.showMessageDialog(null, "Blocked!");
    
    } //when draw finishes, draw the entire offscreen buffer to the screen
    

    So you see that even though it looks like you're drawing your game to the screen first, you're actually drawing it to the offscreen buffer- and the dialog is blocking that offscreen buffer from being drawn to the screen.

    The solution is to use a non-modal dialog (google is your friend) or to just draw the "you won" text on the screen using Processing.

Sign In or Register to comment.