# Tic-Tac-Toe not working

**URL:** <https://discourse.processing.org/t/tic-tac-toe-not-working/130>\
**Category:** Coding Questions\
**Created:** [May 19, 2018, 7:38am UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130 "2018-05-19T07:38:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mikegiannak](https://avatars.discourse-cdn.com/v4/letter/m/96bed5/32.png) [@mikegiannak](https://discourse.processing.org/u/mikegiannak)\
**Post date:** [May 19, 2018, 7:38am UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130/1 "2018-05-19T07:38:24Z")

</div>

So me and a friend are trying to make a tic-tac-toe game. Everything was going fine and I ran into this problem: The program is working as long as you don’t press on a cell you have already put an X or an O. Though we have made our program so it wouldn’t have such a problem. Whenever you press a cell you have already put an X or an O the program freezes and doesn’t even let you press Esc. do not care about the width/height stuff it is all correct for sure. just pls check the mousePressed function and the Cell class. Thank you.

1. cell[0] is top left
2. cell[1] is top middle
3. cell[2] is top right
4. cell[3] is middle left etc.

Also pl is a variable to determine who has the cell. 2 means it is neutral 1 that it is an X and 0 means an O

This is the class in one tab:

```auto
class Cells{
  
  float x;
  float y; 
  int pl = 2;
  int count;
  
  Cells(float xpos,float ypos,int num){
    x = xpos;
    y = ypos;
    count = num;
  }
  
  void xoro(int num){
    strokeWeight(8);
    if(num == 1){
      stroke(255,0,0);
      line(width/42.6+x,height/42.6+y,width/3.87+x,height/3.87+y);
      line(width/42.6+x,height/3.87+y,width/3.87+x,height/42.6+y);
      }
    else if(num == 0){
      stroke(0,0,255);
      noFill();
      ellipse(width/7.1+x,height/7.1+y,width/4.26,height/4.26);
      }
    }

```

and the main program in another:

```auto
Cells[] cell = new Cells[9];
int moves = 9;
float adjx,adjy;
boolean win = false;
int m;

void setup(){
    //fullScreen();
    size(640,640);
    if (width >= height){
      adjx = (width - height)/2;
      adjy = 0;
      width=height;
    }
    else{
      adjy = (height - width)/2;
      adjx = 0;
      height=width;
    }
    background(0);
    stroke(150);
    strokeWeight(1);
    line(adjx+(width/12.8),adjy+(height/3.5+height/12.8),adjx+(width-width/12.8),adjy+(height/3.5+height/12.8));
    line(adjx+(width/12.8),adjy+(height-height/2.5+(height/12.8)/2),adjx+(width-width/12.8),adjy+(height-height/2.5+(height/12.8)/2));
    line(adjx+(width/3.5+width/12.8),adjy+(height-height/12.8),adjx+(width/3.5+width/12.8),adjy+(height/12.8));
    line(adjx+(width-width/2.5+(width/12.8)/2),adjy+(height-height/12.8),adjx+(width-width/2.5+(width/12.8)/2),adjy+(height/12.8));
    stroke(100);
    text("Press Esc to exit",adjx+(width/2-35),adjy+(height-height/128));
    cell[0] = new Cells(adjx+(width/12.8),adjy+(height/12.8), 0);
    cell[1] = new Cells(adjx+(width/3.5+width/12.8),adjy+(height/12.8), 1);
    cell[2] = new Cells(adjx+(width-width/2.5+(width/12.8)/2),adjy+(height/12.8), 2);
    cell[3] = new Cells(adjx+(width/12.8),adjy+(height/3.5+height/12.8), 3);
    cell[4] = new Cells(adjx+(width/3.5+width/12.8),adjy+(height/3.5+height/12.8), 4);
    cell[5] = new Cells(adjx+(width-width/2.5+(width/12.8)/2),adjy+(height/3.5+height/12.8), 5);
    cell[6] = new Cells(adjx+(width/12.8),adjy+(height-height/2.5+(height/12.8)/2), 6);
    cell[7] = new Cells(adjx+(width/3.5+width/12.8),adjy+(height-height/2.5+(height/12.8)/2), 7);
    cell[8] = new Cells(adjx+(width-width/2.5+(width/12.8)/2),adjy+(height-height/2.5+(height/12.8)/2), 8);
}

  
void draw(){
}

void mousePressed(){
    m = moves % 2;
    win = false;
    while(win == false){
        if (moves > 0){
          if (mouseX<adjx+(width/3.5+width/12.8) && mouseY<adjy+(height/3.5+height/12.8) && mouseX>adjx && mouseY>adjy && cell[0].pl == 2){
            cell[0].xoro(m);
            cell[0].pl = m; 
            win = true;
          }
          if (mouseX<adjx+(width-width/2.5+(width/12.8)/2) && mouseY<adjy+(height/3.5+height/12.8) && mouseX>adjx+(width/3.5+width/12.8) && mouseY>adjy && cell[1].pl == 2){
            cell[1].xoro(m);
            cell[1].pl = m;
            win = true;
          }
          if (mouseX<adjx+width && mouseY<adjy+(height/3.5+height/12.8) && mouseX>adjx+(width-width/2.5+(width/12.8)/2) && mouseY>adjy && cell[2].pl == 2){
            cell[2].xoro(m);
            cell[2].pl = m;
            win = true;
          }
          if (mouseX<adjx+(width/3.5+width/12.8) && mouseY<adjy+(height-height/2.5+(height/12.8)/2) && mouseX>adjx && mouseY>adjy+(height/3.5+height/12.8) && cell[3].pl == 2){
            cell[3].xoro(m);
            cell[3].pl = m;
            win = true;
          }
          if (mouseX<adjx+(width-width/2.5+(width/12.8)/2) && mouseY<adjy+(height-height/2.5+(height/12.8)/2) && mouseX>adjx+(width/3.5+width/12.8) && mouseY>adjy+(height/3.5+height/12.8) && cell[4].pl == 2){
            cell[4].xoro(m);
            cell[4].pl = m;
            win = true;
          }
          if (mouseX<adjx+width && mouseY<adjy+(height-height/2.5+(height/12.8)/2) && mouseX>adjx+(width-width/2.5+(width/12.8)/2) && mouseY>adjy+(height/3.5+height/12.8) && cell[5].pl == 2){
            cell[5].xoro(m);
            cell[5].pl = m;
            win = true;
          }
          if (mouseX<adjx+(width/3.5+width/12.8) && mouseY<adjy+height && mouseX>adjx && mouseY>adjy+(height-height/2.5+(height/12.8)/2) && cell[6].pl == 2){
            cell[6].xoro(m);
            cell[6].pl = m;
            win = true;
          }
          if (mouseX<adjx+(width-width/2.5+(width/12.8)/2) && mouseY<adjy+height && mouseX>adjx+(width/3.5+width/12.8) && mouseY>adjy+(height-height/2.5+(height/12.8)/2) && cell[7].pl == 2){
            cell[7].xoro(m);
            cell[7].pl = m;
            win = true;
          }
          if (mouseX<adjx+width && mouseY<adjy+height && mouseX>adjx+(width-width/2.5+(width/12.8)/2) && mouseY>adjy+(height-height/2.5+(height/12.8)/2) && cell[8].pl == 2){
            cell[8].xoro(m);
            cell[8].pl = m;
            win = true;
          }
          if (win == true){
            moves--;
          }
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [May 19, 2018, 9:03am UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130/2 "2018-05-19T09:03:36Z")

</div>

Your sketch is getting stuck in an infinite loop! When you click, your `mousePressed()` function is called, and there’s a while loop in there that runs until `win` is no longer `false`.

Normally, `win` would get set to `true` by one of the blocks in a conditional statement inside the loop. But if you click a cell that is already occupied, then none of those conditions will ever be met!

You could simply fix this by removing the while loop… I don’t think it is useful anyway. Your code has several other major issues too, however, and so I feel they should also be addressed…

You have a Cells class, but this class represents just one cell, not many cells. So call your class Cell, not Cells.

Inside your Cell class would be a great place to have “was this Cell clicked on?” logic, but instead you have a mass of messy if statements in `mousePressed()`. Bleh.

Your `draw()` function is empty. But you are drawing things! You should do all your drawing in `draw()`!

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [May 19, 2018, 9:18am UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130/3 "2018-05-19T09:18:08Z")

</div>

This code is still not perfect - there is a lot you could clean up - but it’s certainly better (and fixes your click -\> infinite loop issue):

```auto
class Cell {
  float x;
  float y; 
  int pl = 2;
  int count;

  Cell(float xpos, float ypos, int num) {
    x = xpos;
    y = ypos;
    count = num;
  }
  void draw() {
    strokeWeight(8);
    if (pl == 1) {
      stroke(255, 0, 0);
      line(width/42.6+x, height/42.6+y, width/3.87+x, height/3.87+y);
      line(width/42.6+x, height/3.87+y, width/3.87+x, height/42.6+y);
    } else if (pl == 0) {
      stroke(0, 0, 255);
      noFill();
      ellipse(width/7.1+x, height/7.1+y, width/4.26, height/4.26);
    }
  }
  void mousePressed(){
    if( over() && pl == 2 ){
      pl = turn;
      turn++;
      turn%=2;
    }
  }
  boolean over(){
    return(mouseX > x && mouseX < x + width/3.5 && mouseY > y && mouseY < y + height/3.5);
  }
}

Cell[] cells = new Cell[9];
int moves = 9;
float adjx, adjy;
boolean win = false;
int m;
int turn;

void setup() {
  //fullScreen();
  size(640, 640);
  if (width >= height) {
    adjx = (width - height)/2;
    adjy = 0;
    width=height;
  } else {
    adjy = (height - width)/2;
    adjx = 0;
    height=width;
  }
  cells[0] = new Cell(adjx+(width/12.8), adjy+(height/12.8), 0);
  cells[1] = new Cell(adjx+(width/3.5+width/12.8), adjy+(height/12.8), 1);
  cells[2] = new Cell(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height/12.8), 2);
  cells[3] = new Cell(adjx+(width/12.8), adjy+(height/3.5+height/12.8), 3);
  cells[4] = new Cell(adjx+(width/3.5+width/12.8), adjy+(height/3.5+height/12.8), 4);
  cells[5] = new Cell(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height/3.5+height/12.8), 5);
  cells[6] = new Cell(adjx+(width/12.8), adjy+(height-height/2.5+(height/12.8)/2), 6);
  cells[7] = new Cell(adjx+(width/3.5+width/12.8), adjy+(height-height/2.5+(height/12.8)/2), 7);
  cells[8] = new Cell(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height-height/2.5+(height/12.8)/2), 8);
}

void draw() {
  background(0);
  draw_board();
  for(int i=0;i<cells.length;cells[i++].draw());
}

void draw_board(){
  stroke(150);
  strokeWeight(1);
  line(adjx+(width/12.8), adjy+(height/3.5+height/12.8), adjx+(width-width/12.8), adjy+(height/3.5+height/12.8));
  line(adjx+(width/12.8), adjy+(height-height/2.5+(height/12.8)/2), adjx+(width-width/12.8), adjy+(height-height/2.5+(height/12.8)/2));
  line(adjx+(width/3.5+width/12.8), adjy+(height-height/12.8), adjx+(width/3.5+width/12.8), adjy+(height/12.8));
  line(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height-height/12.8), adjx+(width-width/2.5+(width/12.8)/2), adjy+(height/12.8));
  stroke(100);
  text("Press Esc to exit", adjx+(width/2-35), adjy+(height-height/128));
}

void mousePressed() {
  for(int i=0;i<cells.length;cells[i++].mousePressed());
}

```

---

<div class="post-metadata">

**Author:** ![mikegiannak](https://avatars.discourse-cdn.com/v4/letter/m/96bed5/32.png) [@mikegiannak](https://discourse.processing.org/u/mikegiannak)\
**Post date:** [May 19, 2018, 10:01am UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130/4 "2018-05-19T10:01:07Z")

</div>

Oh, that is really nice (especially the turn thing :P). So we are new to processing and programming generally. So could you please explain the return of the boolean over(). Thanks a lot really really helped.

P.S. You may freak out but our plan is after making the multiplayer version, ( which we have already actually made in python mode but it is really messy) we are planning to impor a neural network to play with the user. Propably with back propagation.

---

<div class="post-metadata">

**Author:** ![mikegiannak](https://avatars.discourse-cdn.com/v4/letter/m/96bed5/32.png) [@mikegiannak](https://discourse.processing.org/u/mikegiannak)\
**Post date:** [May 19, 2018, 10:45am UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130/5 "2018-05-19T10:45:52Z")

</div>

Oh, ok. never mind I understood the way of thinking. I was stuck with the x and y and then I realised I could have used them in such way. I will need your help though on something else.

```auto
void check(){
    stroke(255);
    strokeWeight(2);
    if (cells[0].pl==cells[1].pl && cells[1].pl==cells[2].pl){
        line(adjx+width/8,adjy+height/4.57,adjx+width-width/8,adjy+height/4.57);
        noLoop();
    }
    if (cells[3].pl==cells[4].pl && cells[4].pl==cells[5].pl){
        line(adjx+width/8,adjy+height/2,adjx+width-width/8,adjy+height/2);
        noLoop();
    }
    if (cells[6].pl==cells[7].pl && cells[7].pl==cells[8].pl){
        line(adjx+width/8,adjy+height-height/4.57,adjx+width-width/8,adjy+height-height/4.57);
        noLoop();
    }
    if (cells[0].pl==cells[4].pl && cells[4].pl==cells[8].pl){
        line(adjx+width/8,adjy+height/8,adjx+width-width/8,adjy+height-height/8);
        noLoop();
    }
    if (cells[2].pl==cells[4].pl && cells[4].pl==cells[6].pl){
        line(adjx+width-width/8,adjy+height/8,adjx+width/8,adjy+height-height/8);
        noLoop();
    }
    if (cells[0].pl==cells[3].pl && cells[3].pl==cells[6].pl){
        line(adjx+width/4.57,adjy+width/8,adjx+width/4.57,adjy+height-height/8);
        noLoop();
    }
    if (cells[1].pl==cells[4].pl && cells[4].pl==cells[7].pl){
        line(adjx+width/2,adjy+height/8,adjx+width/2,adjy+height-height/8);
        noLoop();
    }
    if (cells[2].pl==cells[5].pl && cells[5].pl==cells[8].pl){
        line(adjx+width-width/4.57,adjy+height/8,adjx+width-width/4.57,adjy+height-height/8);
        noLoop();
    }
}

```

You said it is better to try and draw anything inside the Draw() function. so could yoy please tell me how could I convert this function so I draw the line in the draw ?

also forgot to mention that I changed the pl and now for each cell it is the count of it + 10 so this funtion works properly

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [May 19, 2018, 2:23pm UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130/6 "2018-05-19T14:23:15Z")

</div>

Instead of drawing things when you know they should appear, you need to have data that tells draw everything it should be drawing.

That is, instead of:

1. We know we need to draw a thing!
2. Draw the thing now!

Do:

1. We know we need to draw a thing!
2. Store or change a value in memory that `draw()` uses to know what to draw in a way that will cause this thing to be drawn.
3. Make sure what `draw()` draws is based on the values stored in memory.

Here’s the same code as above, but with the “win lines” added. Notice that if a win line should be drawn or not is now stored in the new `winLines` array, and a function that `draw()` calls, `draw_win_lines()`, uses that array to know which lines to draw.

The values in this array are only updated when a win check occurs, and that check only needs to occur when the user has clicked (because a new piece might have been placed).

```auto
class Cell {
  float x;
  float y; 
  int pl = 2;
  int count;

  Cell(float xpos, float ypos, int num) {
    x = xpos;
    y = ypos;
    count = num;
  }
  void draw() {
    strokeWeight(8);
    if (pl == 1) {
      stroke(255, 0, 0);
      line(width/42.6+x, height/42.6+y, width/3.87+x, height/3.87+y);
      line(width/42.6+x, height/3.87+y, width/3.87+x, height/42.6+y);
    } else if (pl == 0) {
      stroke(0, 0, 255);
      noFill();
      ellipse(width/7.1+x, height/7.1+y, width/4.26, height/4.26);
    }
  }
  void mousePressed() {
    if ( over() && pl == 2 ) {
      pl = turn;
      turn++;
      turn%=2;
    }
  }
  boolean over() {
    return(mouseX > x && mouseX < x + width/3.5 && mouseY > y && mouseY < y + height/3.5);
  }
}

Cell[] cells = new Cell[9];
int moves = 9;
float adjx, adjy;
boolean win = false;
int m;
int turn;

void setup() {
  //fullScreen();
  size(640, 640);
  if (width >= height) {
    adjx = (width - height)/2;
    adjy = 0;
    width=height;
  } else {
    adjy = (height - width)/2;
    adjx = 0;
    height=width;
  }
  cells[0] = new Cell(adjx+(width/12.8), adjy+(height/12.8), 0);
  cells[1] = new Cell(adjx+(width/3.5+width/12.8), adjy+(height/12.8), 1);
  cells[2] = new Cell(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height/12.8), 2);
  cells[3] = new Cell(adjx+(width/12.8), adjy+(height/3.5+height/12.8), 3);
  cells[4] = new Cell(adjx+(width/3.5+width/12.8), adjy+(height/3.5+height/12.8), 4);
  cells[5] = new Cell(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height/3.5+height/12.8), 5);
  cells[6] = new Cell(adjx+(width/12.8), adjy+(height-height/2.5+(height/12.8)/2), 6);
  cells[7] = new Cell(adjx+(width/3.5+width/12.8), adjy+(height-height/2.5+(height/12.8)/2), 7);
  cells[8] = new Cell(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height-height/2.5+(height/12.8)/2), 8);
}

void draw() {
  background(0);
  draw_board();
  for (int i=0; i<cells.length; cells[i++].draw());
  draw_win_lines();
}

void draw_board() {
  stroke(150);
  strokeWeight(1);
  line(adjx+(width/12.8), adjy+(height/3.5+height/12.8), adjx+(width-width/12.8), adjy+(height/3.5+height/12.8));
  line(adjx+(width/12.8), adjy+(height-height/2.5+(height/12.8)/2), adjx+(width-width/12.8), adjy+(height-height/2.5+(height/12.8)/2));
  line(adjx+(width/3.5+width/12.8), adjy+(height-height/12.8), adjx+(width/3.5+width/12.8), adjy+(height/12.8));
  line(adjx+(width-width/2.5+(width/12.8)/2), adjy+(height-height/12.8), adjx+(width-width/2.5+(width/12.8)/2), adjy+(height/12.8));
  stroke(100);
  text("Press Esc to exit", adjx+(width/2-35), adjy+(height-height/128));
}

void mousePressed() {
  for (int i=0; i<cells.length; cells[i++].mousePressed());
  check_for_win();
}

boolean[] winLines = new boolean[8];

void draw_win_lines() {
  stroke(255);
  strokeWeight(2);
  for ( int i = 0; i<8; i++) {
    if ( winLines[i] ) { 
      switch( i ) {
      case 0:
        line(adjx+width/8, adjy+height/4.57, adjx+width-width/8, adjy+height/4.57);
        break;
      case 1:
        line(adjx+width/8, adjy+height/2, adjx+width-width/8, adjy+height/2);
        break;
      case 2:
        line(adjx+width/8, adjy+height-height/4.57, adjx+width-width/8, adjy+height-height/4.57);
        break;
      case 3:
        line(adjx+width/8, adjy+height/8, adjx+width-width/8, adjy+height-height/8);
        break;
      case 4:
        line(adjx+width-width/8, adjy+height/8, adjx+width/8, adjy+height-height/8);
        break;
      case 5:
        line(adjx+width/4.57, adjy+width/8, adjx+width/4.57, adjy+height-height/8);
        break;
      case 6:
        line(adjx+width/2, adjy+height/8, adjx+width/2, adjy+height-height/8);
        break;
      case 7:
        line(adjx+width-width/4.57, adjy+height/8, adjx+width-width/4.57, adjy+height-height/8);
        break;
      }
    }
  }
}

void check_for_win() {
  int[][] wins = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 4, 8}, {2, 4, 6}, {0, 3, 6}, {1, 4, 7}, {2, 5, 8}};
  for ( int i = 0; i<8; i++) {
    if ( cells[wins[i][0]].pl==cells[wins[i][1]].pl && cells[wins[i][1]].pl==cells[wins[i][2]].pl && cells[wins[i][0]].pl != 2 ) {
      winLines[i] = true;
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![mikegiannak](https://avatars.discourse-cdn.com/v4/letter/m/96bed5/32.png) [@mikegiannak](https://discourse.processing.org/u/mikegiannak)\
**Post date:** [May 20, 2018, 8:21am UTC](https://discourse.processing.org/t/tic-tac-toe-not-working/130/7 "2018-05-20T08:21:26Z")

</div>

Wow, we didn’t evenknow you can make a boolean list… Ok so again thanks a lot .We might come in contact at some point again 😛
