My program isn't doing what I want it to do (x and o game / Tic Tac Toe)

At the Moment you make 0s and Xs in every cell.

(Each cell has its position as x[i],y[i]. Good)

But this is not correct. You want to make X or 0 only once in the clicked cell

So you can for loop over all cells and check if (dist(mouseX, mouseY, x[i],y[i]) < 60) and then draw the X for this x[i],y[i] only

1 Like

There is a nice tutorial about arrays

In our case they are like 2 parallel lists

1 Like

ok thanks will try it

1 Like

The positions of both arrays as text

this Sketch shows the positions with println



int[]x=
  {
  110, 300, 490, 
  110, 300, 490, 
  110, 300, 490
};
int[]y=
  {
  150, 150, 150, 
  300, 300, 300, 
  450, 450, 450
};


for (int i=0; i < x.length; i++) {
  println ("field "+i+" is " +" located at " + x[i] + " and " + y[i] + " (x and y)." );
}//for 


The positions of both arrays on the screen

This Sketch shows the positions as a graphic:



int[]x=
  {
  110, 300, 490, 
  110, 300, 490, 
  110, 300, 490
};
int[]y=
  {
  150, 150, 150, 
  300, 300, 300, 
  450, 450, 450
};


size(600, 600); 

for (int i=0; i < x.length; i++) {
  fill(255); // white 
  ellipse (x[i], y[i], 17, 17);
  fill(0); // black
  text( i, x[i]+19, y[i]);
}//for 


Matching the mouse position to the positions of both arrays

And here is a Sketch that receives the mouse inputs and checks the distance to the 9 fields. When this distance is <50 we draw a X.



int[]x=
  {
  110, 300, 490, 
  110, 300, 490, 
  110, 300, 490
};
int[]y=
  {
  150, 150, 150, 
  300, 300, 300, 
  450, 450, 450
};

void setup() {
  size(600, 600);
}//func 

void draw() {
  for (int i=0; i < x.length; i++) {
    fill(255); // white 
    ellipse (x[i], y[i], 17, 17);
    fill(0); // black
    textSize(14); 
    text( i, x[i]+19, y[i]);
  }//for
}//func 

void mousePressed() {
  for (int i=0; i < x.length; i++) {
    //check the distance between mouse and the field #i
    if (dist(mouseX, mouseY, x[i], y[i]) < 50) {
      textSize(44); 
      text( "X", x[i]-3, y[i]+13);
    }//if
  }//for
}//func 
//

1 Like

thanks but i find this confusing,i dont know how i would apply this to my program.

Ah, I just wanted to show you how the arrays work together, one array gives the x-position for one point, the other array gives you the y position.

In the last example, you can see how the program searches the tic tac toe position nearest the mouse position (using a for-loop) and draws a X there.

This is similar to what you have to do in your mouseClicked() function. You want to achieve that not all X’s are drawn at once but only one X in the position you clicked on the tic tac toe board.

Chrisir

PImage background; // image for background 
char player='X';   // this tells us whose turn it is during the game
int score=0;       // the score

//Program screens
final int mainMenu = 0;//defines mainMenu
final int game     = 1;//defines game
int state = mainMenu;//sets mainmenu as first screen player sees


void setup() {
  size(600, 600);//sets screen size
  background=loadImage("yo.jpg");//sets picture for background
  strokeWeight(6);//sets the width of the stroke
}

void draw() {
  switch(state) {//this functions switches the state of the program

  case mainMenu:
    runMenu();//sets the screen for the main menu
    break;

  case game:
    runGame();//sets the screen for the game
    break;
  }
  
}



void runMenu() {
  if (background==null)//sets the condition for which the background changes 
    background(255); //sets background to white
  else 
  background(background);//sets background to image

  fill(0); // black text 
  textSize(32);//sets text size
  text("X and O game", 100, 100);//displays X and O game
  textSize(21);//sets text size
  text("Press 'a' to begin the game", 150, 180);//displays press a to begin the game
  if (key=='a') {//states what happens if a key is pressed
    background(110);//sets background colour
    state=game;//takes player to game
  }
}

void runGame() {
  textSize(32);//sets text size
  fill(0, 102, 153);//determines text colour
  text("X and 0 game", 210, 40);//displays x and o game

  // draw grid 
  stroke(0);//sets the colour of the lines to black
  line(200, 100, 200, 500);//creates the first vertical line
  line(400, 100, 400, 500);//creates the second vertical line
  line(100, 100+400/3, 500, 100+400/3);//draws the first horizontal line
  line(100, 250+400/3, 500, 250+400/3);//draws the second horizontal lin

  
  if (player=='X') { //states what happens when its player x's turn 
    deleteFooter();
    fill(0, 102, 153);//sets text colour
    textSize(32);//sets text size
    text("It’s X’s turn", 100, 550);//displays its x turn
  } else {//states what happens if its not player x's turn
    deleteFooter(); 
    textSize(32);//sets text size
    fill(0, 102, 153);//sets text colour
    text("It’s 0’s turn", 100, 550);//displays its o's turn
  }
}



void mouseClicked() {
  if (state != game)//this is to make sure we are in the right state
    return; // leave
  
  if (player=='X') {  //sets the condition for what happens when its player x's turn
  for(int i=0;i<x.length;i++){
    if(dist(mouseX,mouseY,x[i],y[i])<50){
    stroke(0, 255, 0); //sets the color for the letter X to green
    line(mouseX+50, mouseY-50, mouseX-50, mouseY+50);//draws the first line of the letter X
    line(mouseX-50, mouseY-50, mouseX+50, mouseY+50);//draws the second line of the letter X

    player='0';//this statement states that its 0's turn now
  } else {
   for(int i=0;i<x.length;i++){
    if(dist(mouseX,mouseY,x[i],y[i])<50){ 
    stroke(255, 0, 0);//changes the colour of the circle to red
    noFill();//this gives the ellipse just the outline and makes it hollow
    ellipse(mouseX, mouseY, 100, 100);//draws a circle

    player='X';//this statement states that its X's turn now
  }
}
  }
}


void deleteFooter() {
  // make a rect to delete the old text "It’s 0’s turn"/"It’s X’s turn"
  fill(110);//fills rectangle
  noStroke(); //no stroke
  rect(0, 520, width, 200);//draws a rectangle
}

like this?

Does it work? You need to test it.

You must close the for loop within this if-clause

You don’t want to draw at mouse position but where x and y array tells you

Sorrry but im still so confused.i dont know how to apply this.

It’s almost like here, just use the index from the for loop instead of 0

thanks i finally got it sorry i dont understand things easily

1 Like

You are welcome!

Does it work now?

yes thank u so much sorry for taking ur time from ur busy schedule.

1 Like

Next step

Now the idea is that you can place X and 0 in array clicked[].
Because the index of x[] and y[] is now i and when you make the move you can at the same time say clicked[i] = player;. Thus the array clicked[] stores your board (with the moves that are made on it).

Check if field is empty

Then before placing the move you can check if the chosen field is empty.
Otherwise the move is not allowed.

  • The array clicked[] must be empty in the field:
if(clicked[i]==' ') {    // space sign in ' '
    // make move  
}

Detect a Win and Draw/Tie

Then you can detect a Win using array clicked[].

Besides: a Draw/Tie is when 9 moves have been made (just count them) (and also no Win)

Chrisir

HI where would I call moveai in my program is it in the run menu?

No, runMenu() is there to show the menu.

It belongs in the game function ( runGame())

PImage background; // image for background 
char player='X';   // this tells us whose turn it is during the game
int score=0;       // the score
int moveAI='0';

//Program screens
final int mainMenu = 0;//defines mainMenu
final int game     = 1;//defines game
int state = mainMenu;//sets mainmenu as first screen player sees
int[]x=
  {
  110, 300, 490, 
  110, 300, 490, 
  110, 300, 490
};
int[]y=
  {
  150, 150, 150, 
  300, 300, 300, 
  450, 450, 450
};
char[] clicked =  
  {
  ' ', ' ', ' ', 
  ' ', ' ', ' ', 
  ' ', ' ', ' '
};


void setup() {
  size(600, 600);//sets screen size
  background=loadImage("yo.jpg");//sets picture for background
  strokeWeight(6);//sets the width of the stroke
}

void draw() {
  switch(state) {//this functions switches the state of the program

  case mainMenu:
    runMenu();//sets the screen for the main menu
    break;

  case game:
    runGame();//sets the screen for the game
    break;
  }
}



void runMenu() {
  if (background==null)//sets the condition for which the background changes 
    background(255); //sets background to white
  else 
  background(background);//sets background to image

  fill(0); // black text 
  textSize(32);//sets text size
  text("X and O game", 100, 100);//displays X and O game
  textSize(21);//sets text size
  text("Press 'a' to begin the game", 150, 180);//displays press a to begin the game
  if (key=='a') {//states what happens if a key is pressed
    background(110);//sets background colour
    state=game;//takes player to game
  }
}

void runGame() {
  textSize(32);//sets text size
  fill(0, 102, 153);//determines text colour
  text("X and 0 game", 210, 40);//displays x and o game

  // draw grid 
  stroke(0);//sets the colour of the lines to black
  line(200, 100, 200, 500);//creates the first vertical line
  line(400, 100, 400, 500);//creates the second vertical line
  line(100, 100+400/3, 500, 100+400/3);//draws the first horizontal line
  line(100, 250+400/3, 500, 250+400/3);//draws the second horizontal lin


  if (player=='X') { //states what happens when its player x's turn 
    deleteFooter();
    fill(0, 102, 153);//sets text colour
    textSize(32);//sets text size
    text("It’s X’s turn", 100, 550);//displays its x turn
  } else {//states what happens if its not player x's turn
    deleteFooter(); 
    textSize(32);//sets text size
    fill(0, 102, 153);//sets text colour
    text("It’s 0’s turn", 100, 550);//displays its o's turn
  }
}



void showWhoseTurnAnd_AI_Manager() {
  if (state != game)//this is to make sure we are in the right state
    return; // leave

  if (player=='X') {  //sets the condition for what happens when its player x's turn
    for (int i=0; i<x.length; i++) {
      if (dist(mouseX, mouseY, x[i], y[i])<50) {
        stroke(0, 255, 0); //sets the color for the letter X to green
        line(x[i]+50, y[i]-50, x[i]-50, y[i]+50);//draws the first line of the letter X
        line(x[i]-50, y[i]-50, x[i] +50, y[i] +50);//draws the second line of the letter X
        
      }
    }

    player='0';//this statement states that its 0's turn now
  } else {
    for (int i=0; i<x.length; i++) {
      if (dist(mouseX, mouseY, x[i], y[i])<50) {
        stroke(255, 0, 0);//changes the colour of the circle to red
        noFill();//this gives the ellipse just the outline and makes it hollow
        ellipse(x[i], y[i], 100, 100);//draws a circle
        moveAI();
      }
    }


    player='X';//this statement states that its X's turn now
  }
}

void deleteFooter() {
  // make a rect to delete the old text "It’s 0’s turn"/"It’s X’s turn"
  fill(110);//fills rectangle
  noStroke(); //no stroke
  rect(0, 520, width, 200);//draws a rectangle
}



Hi I tried the ai but it says moveAI(); doesn’t exist am I doing something wrong?

You need to have the function moveAI in your code!!

And call

from runGame please

1 Like

Your goal is that a Human plays against the AI

AI plays X

Your showWhoseTurnAnd_AI_Manager() function is not correct

There is no human move with X anymore

1 Like
PImage background; // image for background 
char player='0';   // this tells us whose turn it is during the game
char playerAI='X';
int score=0;       // the score

//Program screens
final int mainMenu = 0;//defines mainMenu
final int game     = 1;//defines game
int state = mainMenu;//sets mainmenu as first screen player sees
int[]x=
  {
  110, 300, 490, 
  110, 300, 490, 
  110, 300, 490
};
int[]y=
  {
  150, 150, 150, 
  300, 300, 300, 
  450, 450, 450
};
char[] clicked =  
  {
  ' ', ' ', ' ', 
  ' ', ' ', ' ', 
  ' ', ' ', ' '
};


void setup() {
  size(600, 600);//sets screen size
  background=loadImage("yo.jpg");//sets picture for background
  strokeWeight(6);//sets the width of the stroke
}

void draw() {
  switch(state) {//this functions switches the state of the program

  case mainMenu:
    runMenu();//sets the screen for the main menu
    break;

  case game:
    runGame();//sets the screen for the game
    break;
  }
}



void runMenu() {
  if (background==null)//sets the condition for which the background changes 
    background(255); //sets background to white
  else 
  background(background);//sets background to image

  fill(0); // black text 
  textSize(32);//sets text size
  text("X and O game", 100, 100);//displays X and O game
  textSize(21);//sets text size
  text("Press 'a' to begin the game", 150, 180);//displays press a to begin the game
  if (key=='a') {//states what happens if a key is pressed
    background(110);//sets background colour
    state=game;//takes player to game
  }
}

void runGame() {
  textSize(32);//sets text size
  fill(0, 102, 153);//determines text colour
  text("X and 0 game", 210, 40);//displays x and o game

  // draw grid 
  stroke(0);//sets the colour of the lines to black
  line(200, 100, 200, 500);//creates the first vertical line
  line(400, 100, 400, 500);//creates the second vertical line
  line(100, 100+400/3, 500, 100+400/3);//draws the first horizontal line
  line(100, 250+400/3, 500, 250+400/3);//draws the second horizontal lin


  if (player=='X') { //states what happens when its player x's turn 
    deleteFooter();
    fill(0, 102, 153);//sets text colour
    textSize(32);//sets text size
    text("It’s X’s turn", 100, 550);//displays its x turn
  } else {//states what happens if its not player x's turn
    deleteFooter(); 
    textSize(32);//sets text size
    fill(0, 102, 153);//sets text colour
    text("It’s 0’s turn", 100, 550);//displays its o's turn
  }
  showWhoseTurnAnd_AI_Manager();
}



void showWhoseTurnAnd_AI_Manager() {
  if (state != game)//this is to make sure we are in the right state
    return; // leave

  if (player=='X') {  //sets the condition for what happens when its player x's turn
    for (int i=0; i<x.length; i++) {
      if (dist(mouseX, mouseY, x[i], y[i])<50) {
        stroke(0, 255, 0); //sets the color for the letter X to green
        line(x[i]+50, y[i]-50, x[i]-50, y[i]+50);//draws the first line of the letter X
        line(x[i]-50, y[i]-50, x[i] +50, y[i] +50);//draws the second line of the letter X
        moveAI();
      }
    }

    player='0';//this statement states that its 0's turn now
  } else {
    for (int i=0; i<x.length; i++) {
      if (dist(mouseX, mouseY, x[i], y[i])<50) {
        stroke(255, 0, 0);//changes the colour of the circle to red
        noFill();//this gives the ellipse just the outline and makes it hollow
        ellipse(x[i], y[i], 100, 100);//draws a circle
        
      }
    }


    player='X';//this statement states that its X's turn now
  }
}

void deleteFooter() {
  // make a rect to delete the old text "It’s 0’s turn"/"It’s X’s turn"
  fill(110);//fills rectangle
  noStroke(); //no stroke
  rect(0, 520, width, 200);//draws a rectangle
}
// AI player 0
// A stupid AI plays a random move on an empty field/cell 

void moveAI() {
  // make a list of empty cells on the board 
  IntList possibleMoves=new IntList(); 

  for (int i = 0; i<clicked.length; i++) {  
    if (clicked[i] == ' ') { 
      possibleMoves.append(i);
    }//if
  }//for

  // Shuffle the list 
  possibleMoves.shuffle(); 

  // Success 
  // Make the move. Since we shuffled the list, we can always take possible move #0 from the list 
  clicked[possibleMoves.get(0)]=playerAI;   // make / record move
  player='0'; // change turn
}//func 
//

Sorry I tried it again but x and o plays in the same place and the game crashes