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

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

Please post your entire code

the one above is my entire code but i changed my mouseClicked function to showWhoseTurnAnd_AI_Manager()

Ar start of mouseClicked say

if (player==‘X’)
return;

I am afraid you need both functions

One is to handle the Human input

One to call moveAI

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 mouseClicked() {
  if (state != game)//this is to make sure we are in the right state
    return; // leave
    if(player=='X')
    return;

  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 
//
void showWhoseTurnAnd_AI_Manager() {
  if (player=='X') {
    // display message 
    println("AI thinks");
    fill(0, 255, 0);
    text("AI thinks", 33, height-33);
    moveAI();  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  AI places X here !
  } else {
    // display message 
    fill(0); 
    text("Your move, Player O.", 33, height-33);
  }
}

I tried but ai doesn’t play anything

a few errors:

player='0'; 

must be X

Also, remember to store Human’s move into clicked as well:

clicked[i]='0';

Otherwise the AI could make a move on a cell that is already occupied by ‘0’.

Remark 1

But the AI is only to demonstrate how to combine Human player with AI player.

It is only a random “AI”. It figures out which cells of the board are empty and chooses one of the cells randomly (using shuffle) to make the move.

For a smart AI you need a strategy.

For example the AI must see when it can make a move to win.

This means,

  • when it finds a line with two X’s, it must make a move in the same line on the empty field to WIN.
  • when it finds a line with two 0’s, it must make a move in the same line on the empty field to hinder the Human to win.
  • When he finds an empty cell where two lines cross and both lines have one X and two empty cells, then must take this empty cell to make a fork.

A line here is either horizontal, vertical or diagonal line of three cells where a player can win.

These rules can be achieved by count scores for each cell and then make the AI move on the highest scoring cell. That’s what JoseMY discussed above.

Remark 2

You need a detector for Win and for Draw/Tie.

I hope you get a full understanding of the Sketch.

My apologies that this is so hard.

Have a happy new year!

Warm regards,

Chrisir

Hi, Chrisr!

I’m glad to see you finally made it!
I hope you found useful some of my hints, though it seems you finally went your own way.

1 Like

I made a 3D Tic tac toe now with an AI based on your rules

I also made a random player and the AI played the random player overnight with 156000 games. It didn’t loose one game.
(now >260.000 games but I don’t think that automatically means, the AI plays perfect)

Great!! I like how you tested the optimal values!

1 Like