Index / 2017 / Assignment 06
768×768 · p5.js instance mode
8 PDE files 871 lines
// Assignment_06.pde
/* [ ---------------------------------------- [ INFO ] ----------------------------------------- ]

Assignment 06: Tic Tac Toe
Vincent Nguyen
05/01/2017

[ ---------------------------------------- [ BLURB ] ---------------------------------------- ]

Hello!

For this assignment, I wanted to include another theme to use as a "skin" over my program.
This time, I decided to go with Overwatch. There's not much more to say about this assignment.
The win/loss check process will be explained further in the attached Google Doc. Hope you enjoy.

As always, thanks for reading!

Vincent

[ ---------------------------------- [ TABLE OF CONTENTS ] ---------------------------------- ]

01. SETTING UP GLOBAL VARIABLES
02. VOID SETUP() AND ASSIGNING VALUES
03. VOID DRAW() AND A MENU SWITCH

[ --------------------------------------- [ CREDITS ] --------------------------------------- ]

[ Images ]

01. overwatch  [ http://www.overwatch.com.ar/foro/uploads/monthly_2016_05/100.png.2c687e97e3326129bb27bce2e96d0b4c.png ]
02. blackwatch [ http://pl.overwatch.wikia.com/wiki/Plik:Blackwatch.png ]
03. title      [ https://supernovicedotnet.files.wordpress.com/2016/04/overwatch_logo.png ]
04. kingsrow   [ http://vignette4.wikia.nocookie.net/overwatch/images/5/54/Kings_Row_009.jpg ]

[ Sound ]

01. introMusic [ https://www.youtube.com/watch?v=xdwNAD7YPGI ]
02. menuMusic  [ https://www.youtube.com/watch?v=Q1oXMy9VZQA ]
03. gameMusic  [ https://www.youtube.com/watch?v=MRhkZsRs0t4 ]
04. hit        [ http://ow.thnuclub.com/?tag=83 ]

*/

// ============================== [ 01. SETTING UP GLOBAL VARIABLES ] ============================== //


//Images, integers, booleans
PImage overwatch, blackwatch, kingsrow, title;
int cols, rows, state, textState;
boolean singleplayer, debug;

//Audio
import ddf.minim.*;
Minim minim;
AudioPlayer introMusic, menuMusic, gameMusic, hit;

//Objects
Button ai, two, exit;
Cell[][] board;
Game tictactoe;

// ============================== [ 02. VOID SETUP() AND ASSIGNING VALUES ] ============================== //

void setup() {
  size(768, 768); //typical setup stuff
  smooth(8); //anti-aliasing
  
  //set every mode to corner...
  rectMode(CORNER);
  ellipseMode(CORNER);
  imageMode(CORNER);
  
  //i lied.
  textAlign(CENTER, CENTER);
  
  //start off with singleplayer tic-tac-toe enabled
  singleplayer = true;
  //debug just shows me which situations the AI has chosen to play
  debug = false;
  
  //load images
  overwatch = loadImage("overwatch.png");
  blackwatch = loadImage("blackwatch.png");
  kingsrow = loadImage("kingsrow.jpg");
  title = loadImage("title.png");
  
  //a whole lot of audio things
  minim = new Minim(this);
  
  hit = minim.loadFile("hit.mp3");
  hit.setGain(-2);
  introMusic = minim.loadFile("collection.mp3");
  introMusic.setGain(-12);
  menuMusic = minim.loadFile("menu.mp3");
  menuMusic.setGain(-12);
  gameMusic = minim.loadFile("roundstart.mp3");
  gameMusic.setGain(-8);
  
  //load audio, then set the gain so that hopefully it will not blow out anyone's eardrums.
  //hopefully.
  
  //menu state & text state (for intro)
  state = 0;
  textState = 0;
  
  //sets the board size
  cols = rows = 3;
  board = new Cell[cols][rows];
  
  //the main menu buttons
  ai = new Button("Singleplayer", 0, height/16*7);
  two = new Button("2 Players", 0, height/16*9);
  exit = new Button("Exit", 0, height/16*11);
  
  //creates a new tic-tac-toe game and resets it
  tictactoe = new Game();
  tictactoe.reset();
}

// ============================== [ 03. VOID DRAW() AND A MENU SWITCH ] ============================== //

void draw() {
  
  audio(); //audio function
  
  /* [NOTES]
  
  for state:
  0 = intro
  1 = main menu
  2 = main game
  
  */
  
  switch (state) { //a simple menu switch
    case 0: drawIntro(); break;
    case 1: drawMenu(); break;
    case 2: drawGame(); break;
    default: drawIntro(); break;
  }
}

// Audio.pde
void audio() { //a simple audio function... no, really.

  /* [NOTES]
   
   for state:
   0 = intro
   1 = main menu
   2 = main game
   
   */

  if (state == 0) { //intro screen...

    if ( !introMusic.isPlaying() ) { //check if intro music is not playing...
      introMusic.cue(0); //if not, reset it
    }

    introMusic.play(); //and play it.
    
  } else if (state == 1) { //main menu...

    introMusic.pause(); //pause other audio first, just in case you're a sassy soo
    gameMusic.pause(); //who skips dialogue in story driven games, grumble grumble.

    if ( !menuMusic.isPlaying() ) { //check if menu music is not playing
      menuMusic.cue(0); //if not, reset it
    }

    menuMusic.play();//and play it.
    
  } else if (state == 2) { //game time...

    menuMusic.pause(); //pause the menu music

    if ( !gameMusic.isPlaying() ) { //same as before, check...
      gameMusic.cue(0); //and reset!
    }

    gameMusic.play(); //play the game music!
  }
}

// Button.pde
class Button { //we've gone over this a million times now...

  //variables
  PVector p;
  float w, h, o; //o = opacity
  String t;

  Button(String text, float tempX, float tempY) {
    p = new PVector(tempX, tempY);
    w = width; //the entire width of the window! Yeah, we're cool now!
    h = 60; //not the entire height...
    o = 0; //opacity starts at 0
    t = text; //it's simple stuff, really.
  }

  void display() {
    noStroke(); //i do not like strokes
    o -= 2; //"fading away" effect... i like it :D
    
    if (mouseOver(p.x,p.y,w,h)) { //if mouse is over button...
      o = 100; //set the opacity to 100
      if (click()) { //if mouse clicks...
        o = 150; //set opacity to 150
      } 
    }
    
    fill(#E8E8E8, o); //fill grey, according to opacity
    rect(p.x, p.y, w, h); //draw rectangle

    fill(#FFFFFF);
    textSize(32); //draw text on button
    text(t, p.x+w/2, p.y+h/2);
  }
  
  boolean mouseOver(float x, float y, float w, float h) { //the same rollover function as before, now tuned for corner mode!
    if (mouseX >= (x) && mouseX <= (x+w) && mouseY >= (y) && mouseY <= (y+h)) {
          return true;
        } else {
          return false;
        }
  }
  
  boolean click() { //oh yes, tuned for corner mode as well!
    if (mouseOver(p.x, p.y, w, h) == true) {
      if (mousePressed) {
        
        if ( !hit.isPlaying() ) { //this is new? Ah yes, the audio for button clicks.
          hit.cue(0); //if it's not playing, reset it,
        }
        hit.play(); //and play it.
          
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
}

// Cell.pde
class Cell { //The meat of the game.

  //Not fun to document... but it's better than documenting Game.

  //Super simple variables. State is explained further below
  PVector p;
  float w, h;
  int state;

  Cell(float tempX, float tempY, float tempW, float tempH) {
    p = new PVector(tempX, tempY);
    w = tempW;
    h = tempH;
    state = 0;
  }
  
  /* [NOTE]
  
  for state:
  0 = blank space
  1 = cross (X) [in this case, Overwatch]
  2 = circle (O) [in this case, Blackwatch]
  
  */
  
  void click(float mx, float my) { //oh yes oh yes, the click function
    
    if (mx >= p.x && mx <= (p.x+w) && my >= p.y && my <= (p.y+h)) { //mx and my is basically mouseX and mouseY... or A POSSIBLE WAY FOR AI TO CLICK??

      if (state == 0) { //if state of cell is 0...
      
        //draw a cool highlight thing
        noStroke();
        fill(#FFFFFF, 50);
        rect(p.x, p.y, w, h);
        
        if (tictactoe.player == 2) { //but how can there be 3 players??? Maybe... a robot?
          state = 2; //set cell to circle
          tictactoe.player = 0; //return control to player... human player, of course.
          tictactoe.full += 1; //full will be explained in the game class... in short, a check method for ties
        }
        
        if (mousePressed) { //if mouse is clicked...

          if (tictactoe.player == 0) { //if player = 0 (ie: the first gent/lady)
          
            state = 1; //set cell to cross
            
            if (singleplayer) { //if singleplayer is enabled...
              tictactoe.player = 2; //who is this mysterious 3rd contender?
            } else if (!singleplayer) { //if no singleplayer...
              tictactoe.player = 1; //set turn to player = 1 (ie: the second gent/lady)
            }
            
            tictactoe.full += 1; //add to the tie check method
            
          } else if (tictactoe.player == 1) { //if player = 1 (ie: the second gent/lady)
            
            //wow there's much less in here...
            state = 2; //set cell to circle
            tictactoe.player = 0; //return control to first gent/lady
            tictactoe.full += 1; //add to the tie check method
            
          }
          
          if ( !hit.isPlaying() ) { //return of the hit sound, for cells now.
            hit.cue(0); //same as before, check if playing. If not, reset.
          }
          hit.play(); //play sound
          mousePressed = false; //disable mouse to prevent speedruns
        }
      }
    }
  }

  void display() { //display function
  
    strokeWeight(5); //i like strokes now
    noFill();

    if (state == 1) { //if cross...
    
      //if you would like to go without images, enable this??
      //stroke(255, 100, 100);
      //line(p.x, p.y, (p.x+w), (p.y+h));
      //line((p.x+w), p.y, p.x, (p.y+h));
      
      //but no one wants that...
      image(overwatch,p.x+10,p.y+10,w-20,h-20);
      
    } else if (state == 2) { //if circle...
    
      //same as before
      //stroke(100, 100, 255);
      //ellipse(p.x+5, p.y+5, w-10, h-10);
      
      //images are better
      image(blackwatch,p.x+10,p.y+10,w-20,h-20);
      
    }
    
    //draw a grid
    stroke(#FFFFFF,50);
    rect(p.x, p.y, w, h);
  }
  
  //lonely return function
  int getState() {
    return state;
  }
}

// drawGame.pde
void drawGame() { //simple simple function
  
  background(#); //dark colours for maximum edge
  
  tictactoe.display(); //display the board
  
  if (!tictactoe.gameover) { //if game isn't over yet
    
    tictactoe.interaction(); //allow mouse interaction
    tictactoe.checkWin(); //check for wins
    
    if (singleplayer) { //if singleplayer is enabled
      tictactoe.AI(); //unleash the beast
    }
    
  } else { //otherwise, (ie: game is over)

    fill(#000000, 220); //black
    rect(0, 0, width, height); //rectangle

    fill(255);
    textSize(72); //display "win" text based on winner
    
    if (tictactoe.winner == 1) {
      text("Overwatch wins!", width/2, height/2);
    } else if (tictactoe.winner == 2) {
      text("Blackwatch wins!", width/2, height/2);
    } else if (tictactoe.winner == 0 && tictactoe.full == 9) {
      text("Tie!", width/2, height/2);
    }
    
    textSize(36); //display return text
    text("press SPACEBAR to restart\npress ESC to return to main menu", width/2, height/8*7); 
  }
}

void keyPressed() { //to restart game or return to menu

  if (state == 2) { //if on game screen
  
    if (tictactoe.gameover) { //and game is over
      
      if (key == ' ') { //and key is spacebar
        
        tictactoe = new Game(); //restart the game!
        tictactoe.reset();
        
      } else if (key == ESC) { //if key is escape
        
        key = 0; //disable the key so processing doesn't exit
        tictactoe = new Game(); //reset game for next time
        tictactoe.reset();
        background(0); // clean up background
        state = 1; //return to main menu
        
      }
    }
  }
}

// drawIntro.pde
void drawIntro() { //I literally stole this from my previous assignment
  //because i like it so much.
  
  String intro = ""; //string for the text you read
  
  fill(#000000, 20); //black background, opacity creates "fading" effect
  rect(0,0, width, height);

  fill(#FFFFFF, 10); //tooltip in case anyone needs it
  text("Click to Continue", width/2, height/16*15);

  fill(#FFFFFF, 100); //set text starts here

  if (textState == 0) {
    intro = "Hello!";
  } else if (textState == 1) {
    intro = "Welcome to Vincent Nguyen's\nAssignment 06: Tic Tac Toe";
  } else if (textState == 2) {
    intro = "This time I decided to go with an\nOverwatch theme as it is one of my\nfavourite games to play";
  } else if (textState == 3) {
    intro = "Your job as an Overwatch agent\n is to defeat the Blackwatch\nin a round of Tic Tac Toe!";
  } else if (textState == 4) {
    intro = "Do your best to beat the competition\nand secure freedom!";
  } else if (textState == 5) {
    intro = "Best of luck!\n-Vincent";
  } else if (textState == 6) {
    state = 1;
  } //set text ends here
  
  textSize(36);
  text(intro, width/2, height/2); //draw text

  if (mousePressed) { //clicking the mouse advances the text
    textState++;
    mousePressed = false;
  }
  
}

// drawMenu.pde
void drawMenu() { //barebones menu
  
  background(0);
  tint(#FFFFFF,80);
  image(kingsrow, 0, 0, width, height); //draw a tinted image of king's row
  
  //display la 3 buttons
  ai.display();
  two.display();
  exit.display();
  
  //display la sub-title
  fill(255);
  textSize(72);
  text("Tic-Tac-Toe", width/2, height/32*9);
  
  //display la actual title
  tint(#FFFFFF);
  image(title,width/16,height/8);
  
  //click detecto
  if (ai.click()) { //one player
    
    singleplayer = true; //enable singleplayer
    state++; //move onto game
    mousePressed = false;
    
  } else if (two.click()) { //two player
    
    singleplayer = false; //disable singleplayer
    state++; //move onto game
    mousePressed = false;
    
  } else if (exit.click()) {
    exit(); //goodbye
  }
}

// Game.pde
class Game { //I had to document this before so i wouldn't get myself confused and lost.

  //welcome to the reckoning.
  
  //simple variables
  int player, winner, full;
  boolean gameover;

  Game() {
    player = 0; //starts off with player one
    winner = 0; //no winner. not yet.
    full = 0; //used to check whether a tie has occurred. Further explanation found below in checkWin()
    gameover = false; //game is not over yet.
  }

  void reset() {
    for (int i = 0; i < cols; i++) { //resets the board using a for loop. 
      for (int j = 0; j < rows; j++) { //creates new cells to play with.
        board[i][j] = new Cell(width/3*i, height/3*j, width/3, height/3);
      }
    }
  }

  void display() {
    for (int i = 0; i < cols; i++) { //displays every cell on the board
      for (int j = 0; j < rows; j++) { //using a for loop, again.
        board[i][j].display();
      }
    }
  }
  
  void interaction() {
    for (int i = 0; i < cols; i++) { //what's this, another one??
      for (int j = 0; j < rows; j++) { //it's just mouse interaction with the cells.
        board[i][j].click(mouseX, mouseY);
      }
    }
  }
  
  void checkWin() { //The beast among beasts... until we get to player 3, anyway.
  
  for (int i = 0; i < cols; i++) { //for loop used all throughout.

           //==========[ Check vertical & horizontal for both cross and circle ]==========//
           
           //-----[ CROSS BEGINS HERE ]-----//
           
           if (board[i][0].getState() == 1 &&
               board[i][1].getState() == 1 &&
               board[i][2].getState() == 1) { //detects whether any vertical column contains all crosses...
               
               //Cross win vertical
               winner = 1; //set winner to cross
               gameover = true; //end game
        
    } else if (board[0][i].getState() == 1 &&
               board[1][i].getState() == 1 &&
               board[2][i].getState() == 1) { //detects whether any horizontal row contains all crosses...

               //Cross win horizontal
               winner = 1;
               gameover = true;
               
           //-----[ CIRCLE BEGINS HERE ]-----//
               
    } else if (board[i][0].getState() == 2 &&
               board[i][1].getState() == 2 &&
               board[i][2].getState() == 2) { //detects whether any vertical column contains all circles...

               //Circle win vertical
               winner = 2;
               gameover = true;
               
    } else if (board[0][i].getState() == 2 &&
               board[1][i].getState() == 2 &&
               board[2][i].getState() == 2) { //detects whether any horizontal row contains all circles...

               //Circle win horizontal
               winner = 2;
               gameover = true;
    }

           //==========[ Check diagonals for both cross and circle ]==========//
           
           //-----[ CROSS BEGINS HERE ]-----//
           
           if (board[0][0].getState() == 1 &&
               board[1][1].getState() == 1 &&
               board[2][2].getState() == 1) { //if diagonal from top left to bottom right are all crosses...
  
               //Cross win diagonal [\] <-- what it looks like
               winner = 1;
               gameover =  true;
        
    } else if (board[0][2].getState() == 1 &&
               board[1][1].getState() == 1 &&
               board[2][0].getState() == 1) { //if diagonal from top right to bottom left are all crosses...

               //Cross win diagonal [/]
               winner = 1;
               gameover = true;
               
           //-----[ CIRCLE BEGINS HERE ]-----//
               
    } else if (board[0][0].getState() == 2 &&
               board[1][1].getState() == 2 &&
               board[2][2].getState() == 2) { //if diagonal from top left to bottom right are all circles...

               //Circle win diagonal [\]
               winner = 2;
               gameover = true;
               
    } else if (board[0][2].getState() == 2 &&
               board[1][1].getState() == 2 &&
               board[2][0].getState() == 2) { //if diagonal from top right to bottom left are all circles...

               //Circle win diagonal [/]
               winner = 2;
               gameover = true;
    }
  }
  
    if (full == 9) { //if full = 9, ie: all cells have been filled...
      gameover = true; //end the game in a tie.
    }
  
  }
  
  /*
  
  the big reveal! yes! i did go off and code an AI.
  it is of course, the legendary third player that i have spoke of.
  mind you, she is quite smart, but not perfect in any sense of the word.
  so please do not blame me if she misses an easy win. thank you.
  
  please look forward to it.
  
  */
  void AI() { //I documented this as i went... because if i did not, i would be very, very lost.
    if (player == 2) { //if it is the AI's turn...
    
      for (int i = 0; i < cols; i++) { //initialize for loop central
        for (int j = 0; j < rows; j++) { //this one is only used @ the end
                       
          //===============[ VERTICAL, HORIZONTAL CHECKS BEGIN HERE ]===============//
                       
                       //vertical, row 1 check
                       
                   if (board[i][0].getState() != 2 && //is not circle
                       board[i][1].getState() == 1 &&
                       board[i][2].getState() == 1) { //checks if the bottom 2 rows are crosses and the top row is not a circle.
              
                       board[i][0].click(width/3*i + width/6, height/3*0 + width/6); //clicks accordingly in that position. This repeats further below.
                       
                       if (debug) {println("hit top row");}
                       
                       /* i made all these grids to remind myself where I was
                       
                       [o][o][o] <-- hit this line
                       [x][x][x]
                       [x][x][x]
                       
                       */
                       
                       //vertical, row 2 check
              
            } else if (board[i][0].getState() == 1 &&
                       board[i][1].getState() != 2 &&
                       board[i][2].getState() == 1) { //checks if the top and bottom rows are crosses and the middle row is not a circle.
              
                       board[i][1].click(width/3*i + width/6,height/3*1 + width/6);
                       
                       if (debug) {println("hit middle row");}
                       
                       /*
                       
                       [x][x][x]
                       [o][o][o] <-- hit this line
                       [x][x][x]
                       
                       */
                       
                       //vertical, row 3 check
              
            } else if (board[i][0].getState() == 1 &&
                       board[i][1].getState() == 1 &&
                       board[i][2].getState() != 2) { //checks if the top 2 rows are crosses and bottom is not a circle.
                       
                       board[i][2].click(width/3*i + width/6,height/3*2 + width/6);
                       
                       if (debug) {println("hit bot row");}
                       
                       /*
                       
                       [x][x][x]
                       [x][x][x]
                       [o][o][o] <-- hit this line
                       
                       */
                       
                       //horizontal, column 1 check
                       
            } else if (board[0][i].getState() != 2 &&
                       board[1][i].getState() == 1 &&
                       board[2][i].getState() == 1) { //checks if the right 2 columns are crosses and left is not a circle.
              
                       board[0][i].click(width/3*0 + width/6,height/3*i + width/6);
                       
                       if (debug) {println("hit left col");}
                       
                       /*
                       
                       [o][x][x]
                       [o][x][x]
                       [o][x][x]
                        ^-- hit this line
                       
                       */
                       
                       //horizontal, column 2 check
              
            } else if (board[0][i].getState() == 1 &&
                       board[1][i].getState() != 2 &&
                       board[2][i].getState() == 1) { //checks if the left and right columns are crosses and middle is not a circle.
              
                       board[1][i].click(width/3*1 + width/6,height/3*i + width/6);
                       
                       if (debug) {println("hit mid col");}
                       
                       /*
                       
                       [x][o][x]
                       [x][o][x]
                       [x][o][x]
                           ^-- hit this line
                       
                       */
                       
                       //horizontal, column 3 check
              
            } else if (board[0][i].getState() == 1 &&
                       board[1][i].getState() == 1 &&
                       board[2][i].getState() != 2) { //checks if the left 2 columns are crosses and right is not a circle.
              
                       board[2][i].click(width/3*2 + width/6,height/3*i + width/6);
                       
                       if (debug) {println("hit right col");}
                       
                       /*
                       
                       [x][x][o]
                       [x][x][o]
                       [x][x][o]
                              ^-- hit this line
                       
                       */
                       
            //===============[ DIAGONAL CHECKS BEGIN HERE ]===============//
              
            } else if (board[0][0].getState() != 2 &&
                       board[1][1].getState() == 1 &&
                       board[2][2].getState() == 1) { //I can't really explain these well in text... just look at my diagrams below.
              
                       board[0][0].click(width/3*0 + width/6,height/3*0 + width/6);
                       
                       if (debug) {println("hit diag 1");}
                       
                       /*
                       
                       [o][-][-]
                       [-][x][-]
                       [-][-][x]
                        ^-- hit this spot (designated by circle)
                       
                       */
              
            } else if (board[0][0].getState() == 1 &&
                       board[1][1].getState() != 2 &&
                       board[2][2].getState() == 1) {
              
                       board[1][1].click(width/3*1 + width/6,height/3*1 + width/6);
                       
                       if (debug) {println("hit diag 2");}
                       
                       /*
                       
                       [x][-][-]
                       [-][o][-]
                       [-][-][x]
                           ^-- hit this spot
                       
                       */
              
            } else if (board[0][0].getState() == 1 &&
                       board[1][1].getState() == 1 &&
                       board[2][2].getState() != 2) {
              
                       board[2][2].click(width/3*2 + width/6,height/3*2 + width/6);
                       
                       if (debug) {println("hit diag 3");}
                       
                       /*
                       
                       [x][-][-]
                       [-][x][-]
                       [-][-][o]
                              ^-- hit this spot
                       
                       */
              
            } else if (board[0][2].getState() != 2 &&
                       board[1][1].getState() == 1 &&
                       board[2][0].getState() == 1) {
              
                       board[0][2].click(width/3*0 + width/6,height/3*2 + width/6);
                       
                       if (debug) {println("hit diag 4");}
                       
                       /*
                       
                       [-][-][x]
                       [-][x][-]
                       [o][-][-]
                        ^-- hit this spot
                       
                       */
              
            } else if (board[0][2].getState() == 1 &&
                       board[1][1].getState() != 2 &&
                       board[2][0].getState() == 1) {
              
                       board[1][1].click(width/3*1 + width/6,height/3*1 + width/6);
                       
                       if (debug) {println("hit diag 5");}
                       
                       /*
                       
                       [-][-][x]
                       [-][o][-]
                       [x][-][-]
                           ^-- hit this spot
                       
                       */
              
            } else if (board[0][2].getState() == 1 &&
                       board[1][1].getState() == 1 &&
                       board[2][0].getState() != 2) {
              
                       board[2][0].click(width/3*2 + width/6,height/3*0 + width/6);
                       
                       if (debug) {println("hit diag 6");}
                       
                       /*
                       
                       [-][-][o]
                       [-][x][-]
                       [x][-][-]
                              ^-- hit this spot
                       
                       */
              
            } else { //if the AI cannot find any suitable moves, just do a random one!
                       board[i][j].click(width/3*random(3) + 50,height/3*random(3) + 50);
                       //println("hit random");
          }
        }
      }
    }
  }
}
read-only archive source from /2017/Assignments/A06 - Tic Tac Toe/Assignment_06/Assignment_06.pde