Introduction to Computer Science
ICS3UR: Introduction to Computer Science

Sarveshwar Senthil Kumar -

Mind Map

Course Mind Map

Course Projects

Processing(Java): Rendering a Smiley Face with Realistic Eyes and Brow

Code File

Processing(Java): Rendering a Circle to Follow the Cursor

Code File

Processing(Java): Rendering a Car that Can Be Scaled by Modifying the Width and Height of a Screen, Added Background Image for Car

Code File

Processing(Java): Practice Lab for Math Operations, Functions, and Programs

Tasks completed in this project:

  • Task 1. Calculate the area and perimeter of a rectangle
  • Task 2. Practice using the power function (pow) by writing different expressions
  • Task 3. Practice using the square root (sqrt) function by writing different expressions
  • Task 4. Calculate the temperature in Fahrenheit given Celsius
  • Task 5. Calculate the temperature in Celsius given Fahrenheit (Inverse of Task 4)
  • Task 6: Write a program that outputs a person's age given their birth year
Code File

Processing(Java): Rendering a Car Using a Scale Variable as Well as Vertexes Instead of a Rectangle Function

Code File

Processing(Java): Rendering Different Stars Using Scale and Position Variables as Well as Connecting Vertexes

Code File

Processing(Java): Rendering the Environment of the Car World by Importing Values to Scale

Code File

Processing(Java): Rendering a Nameplate Using a Sketch as an Initial Idea (Unit 2 Assessment)

Nameplate Project Code File

Processing(Java): Using an IntDict (Dictionary or Hash Map) in Processing to Store Grade Values for Letter Grades and Process Number Grades to Letter Grades

Code File

Processing(Java): Collision Detection Algorithm to Detect Overlap of Two Circles Using the dist (Distance Function)

Code File

Processing(Java): Utilized Two Car Images to Display Two Cars Driving Across a Road; They Turn Back When the Other Side is Reached, If One Car is Faster Than the Other, the Car Slows Down Using Collision Detection. (Last Lesson of Selection)

Processing(Java): Practice Lab for For Loops

Tasks completed in this project:

  • Task 1. Drawing a Grid Pattern Across the Canvas
  • Task 2. Drawing Imitation Raindrops Across the Screen
  • Task 3. A Bouncing Ball
Code File

Processing(Java): Practice Lab for While Loops

Tasks completed in this project:

  • Task 1. Starry Night: Render more than 10 stars on the screen using a loop
  • Task 2. Drawing Imitation Raindrops Across the Screen with a While Loop
Code File

Java: Practice Lab for String Manipulation

Code File

Java: Practice Lab for String Manipulation with additional input via Scanner

Code File

Java: Practice Lab for Reading and Writing to Files using BufferedReader and PrintWriter respectively

Code File

Java: Practice Lab for Reading and Writing to Files, replace every other character with a +

Code File

Java: Practice Lab for Developing a Rock Paper Scissors game

Code File

Java: Practice Lab for Arrays

Code File

Processing(Java): Reviewing Processing Basics: Built a Fruit Clicker Game with Dynamic Score Counter and Rounds

Code File

Processing(Java): Culminating Prep; Avoid the falling objects game

Code File

Processing(Java): Game Demo Video

Video demonstration of the Unit 4 Culminating game project, and finals prep:

Culminating Project Progress

Journal Entry

Today was the day I started to work on the actual codebase for the game.

  • Worked on the GUI for the main start menu
  • Figured out the logistics to toggle music in the app
  • Still working on the actual click interpretation for the buttons

Thoughts: I believe that today was a productive day however, it was quite tedious working with the graphical rendering and menial changing the different pixel values to make everything look better, I would like to move on to the true backend of the game tomorrow. I hope the music works each time, I watched a tutorial to figure out how to toggle the music.

Code

import ddf.minim.*;

            AudioPlayer player;
            Minim minim;

            String text;
            String musicStatus = "ON";
            String currentStage = "start";

            void setup(){
            // Creating the basic canvas
            size(1000, 1000);
            background(#e6dfd0);
            
            // Setting up the music player
            minim = new Minim(this);
            player = minim.loadFile("music.mp3");
            player.loop();
            
            // Creating the basic title page
            setupTitlePage();
            }

            void draw(){
            if (currentStage == "start"){
                // Rendering the music settings dynamically
                fill(#cdbea1);
                rect(150, 400, width-300, 100);
                textSize(80);
                fill(0);
                text("MUSIC: " + musicStatus , (150+width-300)/2, 450);
                fill(#d6c9b1);
                rect(150+width-400, 400, 100, 100);
                fill(0);
                if (musicStatus == "ON"){
                fill(0);
                textSize(200);
                text("-" , 800, 435);
                }
                else if (musicStatus == "OFF"){
                fill(0);
                textSize(170);
                text("+" , 800, 445);
                }
            }
            }

            void keyPressed(){
            if (currentStage == "start"){
                // Checks for mute and unmute key presses and plays music accordingly
                if (key == 'm' || key == 'M'){
                if (musicStatus == "ON"){
                    musicStatus = "OFF";
                    player.close();
                    minim.stop();
                }
                else if (musicStatus == "OFF"){
                    musicStatus = "ON";
                    minim = new Minim(this);
                    player = minim.loadFile("music.mp3");
                    player.loop();
                }
                }
            }
            }

            void setupTitlePage(){
            // Set up basic title page
            textSize(150);
            fill(0);
            textAlign(CENTER, CENTER);
            text("2048:", width/2, 100);
            textSize(160);
            text("POWER", width/2, 250);
            currentStage = "start";
            
            // Rendering the Toggle Map Settings button
            fill(#cdbea1);
            rect(150, 520, width-300, 100);
            textSize(60);
            fill(0);
            text("Toggle Map Settings" , (width)/2, 570);
            
            // Rendering the Start Game button
            fill(#cdbea1);
            rect(150, 670, width-300, 100);
            textSize(60);
            fill(0);
            text("START GAME" , (width)/2, 720);

            // Printed instructions for menu selection
            textSize(50);
            fill(0);
            textAlign(CENTER, CENTER);
            text("Press M to mute/unmute", width/2, 850);
            textSize(50);
            text("Use mouse to select menu", width/2, 900);
            }
Download Code File

Journal Entry

Today I made progress on several aspects of the game:

  • Fixed the UI and made the buttons responsive
  • Worked on calculations and UI and backend of the adjust grid size feature
  • Thought about the integration of different themes using a colors array
  • Implemented carousel type theme selector (without colors)
  • Thought about logic for figuring out game characteristics

Thoughts: Today was semi-productive, in retrospect looking at the accomplishments on paper, seems like I did not do much today, I will need to save time thinking about the implementation at home and convert it to code for next time, however today was quite profound in figuring out the basic logistics of the idea.

Code

import ddf.minim.*;

                    AudioPlayer player;
                    Minim minim;

                    String text;
                    String musicStatus = "ON";
                    String currentStage = "start";
                    String theme = "desert";
                    int grid = 4;

                    color[] desertColors = [];

                    void setup() {
                    // Creating the basic canvas
                    size(1000, 1000);

                    // Setting up the music player
                    minim = new Minim(this);
                    player = minim.loadFile("music.mp3");
                    player.loop();

                    // Creating the basic title page
                    setupTitlePage();
                    }

                    void draw() {
                    if (currentStage == "start") {
                        // Rendering the music settings dynamically
                        fill(#cdbea1);
                        rect(150, 400, width-300, 100);
                        textSize(80);
                        fill(0);
                        text("MUSIC: " + musicStatus, (150+width-300)/2, 450);
                        fill(#d6c9b1);
                        rect(150+width-400, 400, 100, 100);
                        fill(0);
                        if (musicStatus == "ON") {
                        fill(0);
                        textSize(200);
                        text("-", 800, 435);
                        } else if (musicStatus == "OFF") {
                        fill(0);
                        textSize(170);
                        text("+", 800, 445);
                        }
                    } 
                    else if (currentStage == "selectingmaps") {
                        setupMapsPage();
                    }
                    else if (currentStage == "adjustinggrid") {
                        setupGridAdjust();
                    }
                    }

                    void keyPressed() {
                    if (currentStage == "start") {
                        // Checks for mute and unmute key presses and plays music accordingly
                        if (key == 'm' || key == 'M') {
                        toggleMusic();
                        }
                    }
                    
                    else if (currentStage == "adjustinggrid"){
                        if (keyCode == UP){
                        if (grid < 10){
                            grid+=1;
                        }
                        }
                        else if (keyCode == DOWN){
                        if (grid > 4){
                            grid-=1;
                        }
                        }
                    }
                    }

                    void mouseClicked() {
                    if (currentStage == "start") {
                        //Check for Start Menu Buttons
                        if (mouseX >= 150 && mouseX <= 150+width-300) {

                        //Check for Music Toggle
                        if (mouseY >= 400 && mouseY <= 500) {
                            toggleMusic();
                        }

                        // Check for Toggle Map Settings Button
                        else if (mouseY >= 520 && mouseY <= 620) {
                            setupMapsPage();
                        }
                        }
                    } 
                    else if (currentStage == "selectingmaps") {
                        // Check for Back Button
                        if (mouseX >= 10 && mouseX <= 70) {
                        if (mouseY >= 10 && mouseY <= 70) {
                            setupTitlePage();
                        }
                        }

                        if (theme == "desert") {
                        if (mouseX > width/2 - 110 && mouseX < (width/2 - 110) + 220) {
                            if (mouseY > 170 && mouseY < 170 + 220) {
                            theme = "desert";
                            }
                        }
                        if (mouseX >= 200 && mouseX <= 200 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "forest";
                            }
                        }
                        if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                            if (mouseY >= 190 && mouseY < 190 + 170) {
                            theme = "space";
                            }
                        }
                        } else if (theme == "forest") {
                        if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                            if (mouseY >= 170 && mouseY <= 170 + 220) {
                            theme = "forest";
                            }
                        }
                        if (mouseX >= 200 && mouseX <= 200 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "space";
                            }
                        }
                        if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "desert";
                            }
                        }
                        } else if (theme == "space") {
                        if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                            if (mouseY >= 170 && mouseY <= 170 + 220) {
                            theme = "space";
                            }
                        }
                        if (mouseX >= 200 && mouseX <= 200 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "desert";
                            }
                        }
                        if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "forest";
                            }
                        }
                        }
                        // Check for adjust grid size button click
                        if (mouseX >= 150 && mouseX <= 150+width-300) {
                        if (mouseY >= 520 && mouseY <= 620) {
                            setupGridAdjust();
                        }
                        }
                    }
                    else if (currentStage == "adjustinggrid"){
                        // Check for button to go back to the theme menu
                        if (mouseX >= 10 && mouseX <= 70) {
                        if (mouseY >= 10 && mouseY <= 70) {
                            setupMapsPage();
                        }
                        }
                        rect(width/2+10, 850, 100, 100);
                        rect(width/2-110, 850, 100, 100);
                    
                        if (mouseY >= 850 && mouseY <= 950){
                        if (mouseX >= width/2+10 && mouseX <= width/2+110){
                            if (grid > 4){
                            grid-=1;
                            }
                        }
                        else if (mouseX >= width/2-110 && mouseX <= width/2-10){
                            if (grid < 10){
                            grid+=1;
                            }
                        }
                        }
                    }
                    }

                    void setupGridAdjust(){
                    background(#e6dfd0);
                    currentStage = "adjustinggrid";
                    // Draw button background (rectangle)
                    fill(200);
                    rect(10, 10, 60, 60, 10);  // rounded corners

                    // Draw left-pointing arrow
                    fill(0);
                    beginShape();
                    vertex(20, 40);
                    vertex(60, 20);
                    vertex(60, 60);
                    endShape(CLOSE);
                    
                    text("Adjust Grid Size", (width)/2, 70);
                    
                    // Showing Main Grid 
                    fill(#ded4c0);
                    rect(200, 200, 600, 600, 50);
                    
                    fill(#c5b391);
                    for (int rows = 0; rows < grid; rows++){
                        for (int columns = 0; columns < grid; columns++){
                        rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                        }
                    }
                    
                    rect(width/2+10, 850, 100, 100);
                    rect(width/2-110, 850, 100, 100);
                    
                    // Draw the Up arrow inside the left rectangle
                    fill(0); // Set color to black
                    beginShape();
                    vertex(width/2-110+50, 850+25);  
                    vertex(width/2-110+10, 850+75); 
                    vertex(width/2-110+90, 850+75);  
                    endShape(CLOSE);
                    
                    // Draw the Down arrow inside the right rectangle
                    beginShape();
                    vertex(width/2+10+50, 850+75);  
                    vertex(width/2+10+10, 850+25);  
                    vertex(width/2+10+90, 850+25);  
                    endShape(CLOSE);

                    }

                    void setupMapsPage() {
                    background(#e6dfd0);
                    currentStage = "selectingmaps";
                    // Draw button background (rectangle)
                    fill(200);
                    rect(10, 10, 60, 60, 10);  // rounded corners

                    // Draw left-pointing arrow
                    fill(0);
                    beginShape();
                    vertex(20, 40);
                    vertex(60, 20);
                    vertex(60, 60);
                    endShape(CLOSE);

                    textSize(80);
                    text("Select Your Map", (width)/2, 70);

                    if (theme == "desert") {
                        fill(#c5b391);
                        rect(width/2-110, 170, 220, 220);
                        textSize(60);
                        fill(0);
                        text("Desert", (width)/2, 270);

                        fill(#ded4c0);
                        rect(200, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Forest", 285, 270);

                        fill(#ded4c0);
                        rect((width/2-110)+240, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Space", (width/2-110)+240+85, 270);
                    } else if (theme == "forest") {
                        fill(#c5b391);
                        rect(width/2-110, 170, 220, 220);
                        textSize(60);
                        fill(0);
                        text("Forest", (width)/2, 270);

                        fill(#ded4c0);
                        rect(200, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Space", 285, 270);

                        fill(#ded4c0);
                        rect((width/2-110)+240, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Desert", (width/2-110)+240+85, 270);
                    } else if (theme == "space") {
                        fill(#c5b391);
                        rect(width/2-110, 170, 220, 220);
                        textSize(60);
                        fill(0);
                        text("Space", (width)/2, 270);

                        fill(#ded4c0);
                        rect(200, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Desert", 285, 270);

                        fill(#ded4c0);
                        rect((width/2-110)+240, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Forest", (width/2-110)+240+85, 270);
                    }
                    
                    // Rendering the Change Map Dimensions button
                    fill(#cdbea1);
                    rect(150, 520, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("Adjust Grid Size", (width)/2, 570);

                    // Rendering the Start Game button
                    fill(#cdbea1);
                    rect(150, 670, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("START GAME", (width)/2, 720);
                    }

                    void toggleMusic() {
                    // Method to toggle music depending on current status
                    if (musicStatus == "ON") {
                        musicStatus = "OFF";
                        player.close();
                        minim.stop();
                    } else if (musicStatus == "OFF") {
                        musicStatus = "ON";
                        minim = new Minim(this);
                        player = minim.loadFile("music.mp3");
                        player.loop();
                    }
                    }

                    void setupTitlePage() {
                    // Set up basic title page

                    background(#e6dfd0);

                    textSize(150);
                    fill(0);
                    textAlign(CENTER, CENTER);
                    text("2048:", width/2, 100);
                    textSize(160);
                    text("POWER", width/2, 250);
                    currentStage = "start";

                    // Rendering the Toggle Map Settings button
                    fill(#cdbea1);
                    rect(150, 520, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("Toggle Map Settings", (width)/2, 570);

                    // Rendering the Start Game button
                    fill(#cdbea1);
                    rect(150, 670, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("START GAME", (width)/2, 720);

                    // Printed instructions for menu selection
                    textSize(50);
                    fill(0);
                    textAlign(CENTER, CENTER);
                    text("Press M to mute/unmute", width/2, 850);
                    textSize(50);
                    text("Use mouse to select menu", width/2, 900);
                    }
Download Code File

Journal Entry

Today was a highly productive day where I implemented the core game mechanics:

  • Implemented button logic for start game buttons across all menus
  • Fully implemented the theme selection system with three distinct color schemes
  • Created the grid generation system with random tile spawning
  • Developed slide functionality for the grid in all four directions (up, down, left, right)
  • Implemented collision detection between tiles
  • Built the game end checker to determine when no moves remain
  • Created the end game screen showing final stats
  • Implemented a score counter that tracks player progress

Thoughts: Today was the most productive day of the week where I got the majority of work done. While the work today wasn't as technically intensive as I expected, implementing all the core game mechanics was crucial. The stress of completing the project on time has been relieved as the remaining work consists of optional custom features to enhance the main game. The collision detection and grid shifting logic required careful testing but works reliably now.

Code

import ddf.minim.*;

                    AudioPlayer player;
                    Minim minim;

                    String text;
                    String musicStatus = "ON";
                    String currentStage = "start";
                    String theme = "desert";
                    int grid = 4;

                    int currentScore = 0;
                    int currentMoves = 0;

                    int[][] currentGrid;

                    color[] desertColors = {#e6dfd0, #ded4c0, #d6c9b1, #cdbea1, #c5b391, #bda981, #b49e72};
                    color[] spaceColors = {#cccccc, #c0c0c0, #b3b3b3, #a6a6a6, #999999, #8d8d8d, #808080};
                    color[] forestColors = {#99c199, #80b280, #66a266, #4d934d, #338333, #197419, #006400};

                    color[] colors = desertColors;

                    void setup() {
                    // Creating the basic canvas
                    size(1000, 1000);

                    // Setting up the music player
                    minim = new Minim(this);
                    player = minim.loadFile("music.mp3");
                    player.loop();

                    // Creating the basic title page
                    setupTitlePage();
                    }

                    void draw() {
                    if (currentStage == "start") {
                        // Rendering the music settings dynamically
                        fill(colors[3]);
                        rect(150, 400, width-300, 100);
                        textSize(80);
                        fill(0);
                        text("MUSIC: " + musicStatus, (150+width-300)/2, 450);
                        fill(colors[2]);
                        rect(150+width-400, 400, 100, 100);
                        fill(0);
                        if (musicStatus == "ON") {
                        fill(0);
                        textSize(200);
                        text("-", 800, 435);
                        } else if (musicStatus == "OFF") {
                        fill(0);
                        textSize(170);
                        text("+", 800, 445);
                        }
                    } 
                    else if (currentStage == "selectingmaps") {
                        setupMapsPage();
                    }
                    else if (currentStage == "adjustinggrid") {
                        setupGridAdjust();
                    }
                    else if (currentStage == "playinggame") {
                        playGame();
                    }
                    }

                    void keyPressed() {
                    if (currentStage == "start") {
                        // Checks for mute and unmute key presses and plays music accordingly
                        if (key == 'm' || key == 'M') {
                        toggleMusic();
                        }
                    }
                    
                    else if (currentStage == "adjustinggrid"){
                        if (keyCode == UP){
                        if (grid < 10){
                            grid+=1;
                        }
                        }
                        else if (keyCode == DOWN){
                        if (grid > 4){
                            grid-=1;
                        }
                        }
                    }
                    
                    else if (currentStage == "playinggame"){
                        if (keyCode == UP){
                        currentGrid = shiftGrid(currentGrid, "up");
                        currentMoves += 1;
                        
                        int[][] freeSpots = new int[grid*grid][2];
                        int totalFree = 0;
                        for (int rows = 0; rows < grid; rows++){
                            for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                freeSpots[totalFree][0] = rows;
                                freeSpots[totalFree][1] = columns;
                                totalFree += 1;
                                }
                            }
                        }
                        
                        if (totalFree == 0 && checkPossibleCollisions(currentGrid) == 0){
                            currentStage = "finishedgame";
                            setupFinishedGamePage();
                        }
                        
                        int randomAddition = (int)(Math.random()*totalFree);
                        int randomNum = (int)(Math.random()*10);
                        
                        if (randomNum == 9){
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                        }
                        else{
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                        }
                        
                        }
                        else if (keyCode == DOWN){
                        currentGrid = shiftGrid(currentGrid, "down");
                        currentMoves += 1;
                        
                        int[][] freeSpots = new int[grid*grid][2];
                        int totalFree = 0;
                        for (int rows = 0; rows < grid; rows++){
                            for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                freeSpots[totalFree][0] = rows;
                                freeSpots[totalFree][1] = columns;
                                totalFree += 1;
                                }
                            }
                        }
                        
                        if (totalFree == 0 && checkPossibleCollisions(currentGrid) == 0){
                            currentStage = "finishedgame";
                            setupFinishedGamePage();
                        }
                        
                        int randomAddition = (int)(Math.random()*totalFree);
                        int randomNum = (int)(Math.random()*10);
                        
                        if (randomNum == 9){
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                        }
                        else{
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                        }
                        
                        }
                        else if (keyCode == LEFT){
                        currentGrid = shiftGrid(currentGrid, "left");
                        currentMoves += 1;
                        
                        int[][] freeSpots = new int[grid*grid][2];
                        int totalFree = 0;
                        for (int rows = 0; rows < grid; rows++){
                            for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                freeSpots[totalFree][0] = rows;
                                freeSpots[totalFree][1] = columns;
                                totalFree += 1;
                                }
                            }
                        }
                        
                        if (totalFree == 0 && checkPossibleCollisions(currentGrid) == 0){
                            currentStage = "finishedgame";
                            setupFinishedGamePage();
                        }
                        
                        int randomAddition = (int)(Math.random()*totalFree);
                        int randomNum = (int)(Math.random()*10);
                        
                        if (randomNum == 9){
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                        }
                        else{
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                        }
                        
                        }
                        else if (keyCode == RIGHT){
                        currentGrid = shiftGrid(currentGrid, "right");
                        currentMoves += 1;
                        
                        int[][] freeSpots = new int[grid*grid][2];
                        int totalFree = 0;
                        for (int rows = 0; rows < grid; rows++){
                            for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                freeSpots[totalFree][0] = rows;
                                freeSpots[totalFree][1] = columns;
                                totalFree += 1;
                                }
                            }
                        }
                        
                        if (totalFree == 0 && checkPossibleCollisions(currentGrid) == 0){
                            currentStage = "finishedgame";
                            setupFinishedGamePage();
                        }
                        
                        int randomAddition = (int)(Math.random()*totalFree);
                        int randomNum = (int)(Math.random()*10);
                        
                        if (randomNum == 9){
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                        }
                        else{
                            currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                        }
                        
                        }
                    }
                    
                    else if (currentStage == "finishedgame"){
                        if (key == ' '){
                        setupTitlePage();
                        }
                    }
                    }

                    void mouseClicked() {
                    if (currentStage == "start") {
                        //Check for Start Menu Buttons
                        if (mouseX >= 150 && mouseX <= 150+width-300) {
                        //Check for Music Toggle
                        if (mouseY >= 400 && mouseY <= 500) {
                            toggleMusic();
                        }

                        // Check for Toggle Map Settings Button
                        else if (mouseY >= 520 && mouseY <= 620) {
                            setupMapsPage();
                        }
                        
                        // Check for Start Game Button
                        else if (mouseY >= 670 && mouseY <= 770) {
                            currentStage = "playinggame";

                            currentScore = 0;
                            currentMoves = 0;
                            currentGrid = new int[grid][grid];
                            for (int rows = 0; rows < grid; rows++){
                            for (int columns = 0; columns < grid; columns++){
                                currentGrid[rows][columns] = 0;
                            }
                            }
                            
                            currentGrid[(int)(Math.random()*grid-1)][(int)(Math.random()*grid-1)] = 2;
                            playGame();
                        }
                        }
                    } 
                    else if (currentStage == "selectingmaps") {
                        // Check for Back Button
                        if (mouseX >= 10 && mouseX <= 70) {
                        if (mouseY >= 10 && mouseY <= 70) {
                            setupTitlePage();
                        }
                        }

                        if (theme == "desert") {
                        if (mouseX > width/2 - 110 && mouseX < (width/2 - 110) + 220) {
                            if (mouseY > 170 && mouseY < 170 + 220) {
                            theme = "desert";
                            colors = desertColors;
                            }
                        }
                        if (mouseX >= 200 && mouseX <= 200 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "forest";
                            colors = forestColors;
                            }
                        }
                        if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                            if (mouseY >= 190 && mouseY < 190 + 170) {
                            theme = "space";
                            colors = spaceColors;
                            }
                        }
                        } else if (theme == "forest") {
                        if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                            if (mouseY >= 170 && mouseY <= 170 + 220) {
                            theme = "forest";
                            colors = forestColors;
                            }
                        }
                        if (mouseX >= 200 && mouseX <= 200 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "space";
                            colors = spaceColors;
                            }
                        }
                        if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "desert";
                            colors = desertColors;
                            }
                        }
                        } else if (theme == "space") {
                        if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                            if (mouseY >= 170 && mouseY <= 170 + 220) {
                            theme = "space";
                            colors = spaceColors;
                            }
                        }
                        if (mouseX >= 200 && mouseX <= 200 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "desert";
                            colors = desertColors;
                            }
                        }
                        if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                            if (mouseY >= 190 && mouseY <= 190 + 170) {
                            theme = "forest";
                            colors = forestColors;
                            }
                        }
                        }
                        
                        // Check for adjust grid size button click
                        if (mouseX >= 150 && mouseX <= 150+width-300) {
                        if (mouseY >= 520 && mouseY <= 620) {
                            setupGridAdjust();
                        }
                        // Check for Start Game Button
                        else if (mouseY >= 670 && mouseY <= 770) {
                            currentStage = "playinggame";
                            currentScore = 0;
                            currentMoves = 0;
                            currentGrid = new int[grid][grid];
                            for (int rows = 0; rows < grid; rows++){
                                for (int columns = 0; columns < grid; columns++){
                                currentGrid[rows][columns] = 0;
                                }
                            }
                            
                            currentGrid[(int)(Math.random()*grid)][(int)(Math.random()*grid)] = 2;
                            playGame();
                            }
                        }
                    }
                    else if (currentStage == "adjustinggrid"){
                        // Check for button to go back to the theme menu
                        if (mouseX >= 10 && mouseX <= 70) {
                        if (mouseY >= 10 && mouseY <= 70) {
                            setupMapsPage();
                        }
                        }
                        rect(width/2+10, 850, 100, 100);
                        rect(width/2-110, 850, 100, 100);
                    
                        if (mouseY >= 850 && mouseY <= 950){
                        if (mouseX >= width/2+10 && mouseX <= width/2+110){
                            if (grid > 4){
                            grid-=1;
                            }
                        }
                        else if (mouseX >= width/2-110 && mouseX <= width/2-10){
                            if (grid < 10){
                            grid+=1;
                            }
                        }
                        }
                    }
                    else if (currentStage == "playinggame"){
                        if (mouseX >= 10 && mouseX <= 70) {
                        if (mouseY >= 10 && mouseY <= 70) {
                            setupTitlePage();
                        }
                        }
                    }
                    }

                    void setupFinishedGamePage(){
                    background(colors[0]);
                        
                    fill(0);
                    textSize(60);
                    
                    text("Game Over!", width/2, 50);
                    // Displaying the number of moves
                    text("Number of Moves: " + currentMoves, width/2, 110);
                    
                    // Displaying the score of the user
                    text("Total Score: " + currentScore, width/2, 170);
                    
                    text("Final Grid", width/2, 270);
                    
                    // Displaying the Grid
                    for (int rows = 0; rows < grid; rows++){
                        for (int columns = 0; columns < grid; columns++){
                        fill(colors[4]);
                        rect(225+rows*(525/grid+4), 320+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                        
                        if (currentGrid[rows][columns] != 0){
                            fill(colors[((powerOfTwo(currentGrid[rows][columns])%colors.length))]);
                            rect(225+rows*(525/grid+4), 320+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                            
                            fill(0);
                            textSize(30);
                            text(currentGrid[rows][columns], (225+rows*(525/grid+4)+(530/grid-4)/2), (320+columns*(525/grid+4)+(530/grid-4)/2));
                        }
                        }
                    }
                    
                    text("Press SPACE to Continue", width/2, height-100);
                        
                    }

                    int checkPossibleCollisions(int[][] currentGrid){
                    int possibleCollisions = 0;
                    int[][] newGrid = currentGrid;
                    
                    for (int row=1; row0; row--){
                        for (int column=0; column0; column--){
                        if (newGrid[row][column]==newGrid[row][column-1] && newGrid[row][column]!=0){
                            possibleCollisions++;
                        }
                        }
                    }
                    
                    return possibleCollisions;
                    }

                    int[][] checkCollisions(int[][] currentGrid, String direction){
                    int[][] newGrid = currentGrid;
                    
                    switch (direction) {
                        case "left":
                        for (int row=1; row0; row--){
                            for (int column=0; column0; column--){
                            if (newGrid[row][column]==newGrid[row][column-1] && newGrid[row][column]!=0){
                                newGrid[row][column] = newGrid[row][column]+newGrid[row][column-1];
                                newGrid[row][column-1] = 0;
                                currentScore+=newGrid[row][column]+newGrid[row][column-1];
                            }
                            }
                        }
                        break;
                    }
                    
                    return newGrid;
                    }

                    int[][] shiftGrid(int[][] currentGrid, String direction) {
                    
                    int[][] newGrid = new int[grid][grid];
                    currentGrid = checkCollisions(currentGrid, direction);
                    
                    switch (direction) {
                        case "up":
                        for (int i=0; i0; x--){
                            filled[filledCount+x-1] = 0;
                            }
                            newGrid[i] = filled;
                        }
                        break;
                        
                        case "down":
                        for (int i = 0; i < grid; i++) {
                            int[] filled = new int[grid];
                            int filledCount = 0;
                        
                            for (int x = grid - 1; x >= 0; x--) {
                            if (currentGrid[i][x] != 0) {
                                filled[filledCount] = currentGrid[i][x];
                                filledCount++;
                            }
                            }
                        
                            for (int x = 0; x < filledCount; x++) {
                            newGrid[i][grid - 1 - x] = filled[x];
                            }

                            for (int x = 0; x < grid - filledCount; x++) {
                            newGrid[i][x] = 0;
                            }
                        }
                        break;
                        
                        case "left":
                        for (int i = 0; i < grid; i++) {
                            int[] filled = new int[grid];
                            int filledCount = 0;
                    
                            for (int x = 0; x < grid; x++) {
                            if (currentGrid[x][i] != 0) {
                                filled[filledCount] = currentGrid[x][i];
                                filledCount++;
                            }
                            }
                    
                            int y = grid - 1;
                            for (int x = grid-filledCount - 1; x >= 0; x--) {
                            newGrid[y][i] = 0;
                            y--;
                            }
                            while (y >= 0) {
                            newGrid[y][i] = filled[y];
                            y--;
                            }
                        }
                        break;
                        
                        case "right":
                        for (int i = 0; i < grid; i++) {
                            int[] filled = new int[grid];
                            int filledCount = 0;
                    
                            for (int x = 0; x < grid; x++) {
                            if (currentGrid[x][i] != 0) {
                                filled[filledCount] = currentGrid[x][i];
                                filledCount++;
                            }
                            }
                    
                            int y = grid - 1;
                            for (int x = filledCount - 1; x >= 0; x--) {
                            newGrid[y][i] = filled[x];
                            y--;
                            }
                    
                            while (y >= 0) {
                            newGrid[y][i] = 0;
                            y--;
                            }
                        }
                        break;
                    }
                    
                    return checkCollisions(newGrid, direction);
                    }

                    int powerOfTwo(int n) {
                    int power = 0;
                    while (n > 1) {
                        n /= 2;
                        power++;
                    }
                    return power;
                    }

                    void playGame(){
                    currentStage = "playinggame";
                    
                    background(colors[0]);
                    
                    // Draw button background (rectangle)
                    fill(200);
                    rect(10, 10, 60, 60, 10);  // rounded corners

                    // Draw left-pointing arrow
                    fill(0);
                    beginShape();
                    vertex(20, 40);
                    vertex(60, 20);
                    vertex(60, 60);
                    endShape(CLOSE);
                    
                    textSize(60);
                    // Displaying the number of moves
                    text("Number of Moves: " + currentMoves, width/2, 100);
                    
                    // Displaying the score of the user
                    text("Total Score: " + currentScore, width/2, 160);
                    
                    // Displaying the Grid
                    for (int rows = 0; rows < grid; rows++){
                        for (int columns = 0; columns < grid; columns++){
                        fill(colors[4]);
                        rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                        
                        if (currentGrid[rows][columns] != 0){
                            fill(colors[((powerOfTwo(currentGrid[rows][columns])%colors.length))]);
                            rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                            
                            fill(0);
                            textSize(30);
                            text(currentGrid[rows][columns], (225+rows*(525/grid+4)+(530/grid-4)/2), (225+columns*(525/grid+4)+(530/grid-4)/2));
                        }
                        }
                    }
                    }

                    void setupGridAdjust(){
                    background(colors[0]);
                    currentStage = "adjustinggrid";
                    // Draw button background (rectangle)
                    fill(200);
                    rect(10, 10, 60, 60, 10);  // rounded corners

                    // Draw left-pointing arrow
                    fill(0);
                    beginShape();
                    vertex(20, 40);
                    vertex(60, 20);
                    vertex(60, 60);
                    endShape(CLOSE);
                    
                    text("Adjust Grid Size", (width)/2, 70);
                    
                    // Showing Main Grid 
                    fill(colors[1]);
                    rect(200, 200, 600, 600, 50);
                    
                    currentGrid = new int[grid][grid];
                    
                    fill(colors[4]);
                    for (int rows = 0; rows < grid; rows++){
                        for (int columns = 0; columns < grid; columns++){
                        rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                        currentGrid[rows][columns] = 0;
                        }
                    }
                    
                    rect(width/2+10, 850, 100, 100);
                    rect(width/2-110, 850, 100, 100);
                    
                    // Draw the Up arrow inside the left rectangle
                    fill(0); // Set color to black
                    beginShape();
                    vertex(width/2-110+50, 850+25);  
                    vertex(width/2-110+10, 850+75); 
                    vertex(width/2-110+90, 850+75);  
                    endShape(CLOSE);
                    
                    // Draw the Down arrow inside the right rectangle
                    beginShape();
                    vertex(width/2+10+50, 850+75);  
                    vertex(width/2+10+10, 850+25);  
                    vertex(width/2+10+90, 850+25);  
                    endShape(CLOSE);

                    }

                    void setupMapsPage() {
                    background(colors[0]);
                    currentStage = "selectingmaps";
                    // Draw button background (rectangle)
                    fill(200);
                    rect(10, 10, 60, 60, 10);  // rounded corners

                    // Draw left-pointing arrow
                    fill(0);
                    beginShape();
                    vertex(20, 40);
                    vertex(60, 20);
                    vertex(60, 60);
                    endShape(CLOSE);

                    textSize(80);
                    text("Select Your Map", (width)/2, 70);

                    if (theme == "desert") {
                        fill(colors[4]);
                        rect(width/2-110, 170, 220, 220);
                        textSize(60);
                        fill(0);
                        text("Desert", (width)/2, 270);

                        fill(colors[1]);
                        rect(200, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Forest", 285, 270);

                        fill(colors[1]);
                        rect((width/2-110)+240, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Space", (width/2-110)+240+85, 270);
                    } else if (theme == "forest") {
                        fill(colors[4]);
                        rect(width/2-110, 170, 220, 220);
                        textSize(60);
                        fill(0);
                        text("Forest", (width)/2, 270);

                        fill(colors[1]);
                        rect(200, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Space", 285, 270);

                        fill(colors[1]);
                        rect((width/2-110)+240, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Desert", (width/2-110)+240+85, 270);
                    } else if (theme == "space") {
                        fill(colors[4]);
                        rect(width/2-110, 170, 220, 220);
                        textSize(60);
                        fill(0);
                        text("Space", (width)/2, 270);

                        fill(colors[1]);
                        rect(200, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Desert", 285, 270);

                        fill(colors[1]);
                        rect((width/2-110)+240, 190, 170, 170);
                        textSize(40);
                        fill(0);
                        text("Forest", (width/2-110)+240+85, 270);
                    }
                    
                    // Rendering the Change Map Dimensions button
                    fill(colors[3]);
                    rect(150, 520, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("Adjust Grid Size", (width)/2, 570);

                    // Rendering the Start Game button
                    fill(colors[3]);
                    rect(150, 670, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("START GAME", (width)/2, 720);
                    }

                    void toggleMusic() {
                    // Method to toggle music depending on current status
                    if (musicStatus == "ON") {
                        musicStatus = "OFF";
                        player.close();
                        minim.stop();
                    } else if (musicStatus == "OFF") {
                        musicStatus = "ON";
                        minim = new Minim(this);
                        player = minim.loadFile("music.mp3");
                        player.loop();
                    }
                    }

                    void setupTitlePage() {
                    // Set up basic title page

                    background(colors[0]);

                    textSize(150);
                    fill(0);
                    textAlign(CENTER, CENTER);
                    text("2048:", width/2, 100);
                    textSize(160);
                    text("POWER", width/2, 250);
                    currentStage = "start";

                    // Rendering the Toggle Map Settings button
                    fill(colors[3]);
                    rect(150, 520, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("Toggle Map Settings", (width)/2, 570);

                    // Rendering the Start Game button
                    fill(colors[3]);
                    rect(150, 670, width-300, 100);
                    textSize(60);
                    fill(0);
                    text("START GAME", (width)/2, 720);

                    // Printed instructions for menu selection
                    textSize(50);
                    fill(0);
                    textAlign(CENTER, CENTER);
                    text("Press M to mute/unmute", width/2, 850);
                    textSize(50);
                    text("Use mouse to select menu", width/2, 900);
                    }
Download Code File

Journal Entry

Today was a highly productive day where I implemented the core game mechanics:

  • Fixed a corner tile bug
  • Checked for useless moves and made sure they did not count
  • Added 5 power ups for various different purposes
  • Created a view instructions page

Thoughts: While on paper, it may look like not much was done today, that may have been true due to me being distracted however today was a solid day where I developed several monumental features of the game. I finished the basic functionality of the game as normal 2048, all that is left to do is to integrate my twist on things, add finishing touches, and go back and comment on the code. With that being said, due to the fact that I only have two days left to finish this project, the pressure is rising and it is turning into more of a race against time.

Code


                                        import ddf.minim.*;

                                        AudioPlayer player;
                                        Minim minim;

                                        PImage lightning;
                                        PImage undo;
                                        PImage hammer;

                                        String text;
                                        String musicStatus = "ON";
                                        String currentStage = "start";
                                        String theme = "desert";
                                        int grid = 4;

                                        String warning = "Welcome to the Game! Make your first move!";

                                        int currentScore = 0;
                                        int currentMoves = 0;

                                        boolean foursOnly = false;
                                        int fours = 0;

                                        boolean doubleMode = false;
                                        int doubles = 0;

                                        int[][] currentGrid;
                                        int[][] lastGrid;

                                        color[] desertColors = {#e6dfd0, #ded4c0, #d6c9b1, #cdbea1, #c5b391, #bda981, #b49e72};
                                        color[] spaceColors = {#cccccc, #c0c0c0, #b3b3b3, #a6a6a6, #999999, #8d8d8d, #808080};
                                        color[] forestColors = {#99c199, #80b280, #66a266, #4d934d, #338333, #197419, #006400};

                                        color[] colors = desertColors;

                                        void setup() {
                                        // Creating the basic canvas
                                        size(1000, 1000);
                                        
                                        // Holding lightning powerup image
                                        lightning = loadImage("lightningbolt.png");
                                        lightning.resize(80,80);
                                        
                                        undo = loadImage("undoicon.png");
                                        undo.resize(70,70);
                                        
                                        hammer = loadImage("hammer.png");
                                        hammer.resize(70,70);

                                        // Setting up the music player
                                        minim = new Minim(this);
                                        player = minim.loadFile("music.mp3");
                                        player.loop();

                                        // Creating the basic title page
                                        setupTitlePage();
                                        }

                                        void draw() {
                                        if (currentStage == "start") {
                                            // Rendering the music settings dynamically
                                            fill(colors[3]);
                                            rect(150, 400, width-300, 100);
                                            textSize(80);
                                            fill(0);
                                            text("MUSIC: " + musicStatus, (150+width-300)/2, 450);
                                            fill(colors[2]);
                                            rect(150+width-400, 400, 100, 100);
                                            fill(0);
                                            if (musicStatus == "ON") {
                                            fill(0);
                                            textSize(200);
                                            text("-", 800, 435);
                                            } else if (musicStatus == "OFF") {
                                            fill(0);
                                            textSize(170);
                                            text("+", 800, 445);
                                            }
                                        } 
                                        else if (currentStage == "selectingmaps") {
                                            setupMapsPage();
                                        }
                                        else if (currentStage == "adjustinggrid") {
                                            setupGridAdjust();
                                        }
                                        else if (currentStage == "playinggame") {
                                            playGame();
                                        }
                                        }

                                        void keyPressed() {
                                        if (currentStage == "start") {
                                            // Checks for mute and unmute key presses and plays music accordingly
                                            if (key == 'm' || key == 'M') {
                                            toggleMusic();
                                            }
                                        }
                                        
                                        else if (currentStage == "adjustinggrid"){
                                            if (keyCode == UP){
                                            if (grid < 10){
                                                grid+=1;
                                            }
                                            }
                                            else if (keyCode == DOWN){
                                            if (grid > 4){
                                                grid-=1;
                                            }
                                            }
                                        }
                                        
                                        else if (currentStage == "playinggame"){
                                            if (keyCode == UP){
                                            warning = "";
                                            int[][] tempGrid = shiftGrid(currentGrid, "up");
                                            int changes = 0;
                                            boolean trigger = true;
                                            
                                            for (int row=0; row= 150 && mouseX <= 150+width-300) {
                                            //Check for Music Toggle
                                            if (mouseY >= 400 && mouseY <= 500) {
                                                toggleMusic();
                                            }

                                            // Check for Toggle Map Settings Button
                                            else if (mouseY >= 520 && mouseY <= 620) {
                                                setupMapsPage();
                                            }
                                            
                                            // Check for Start Game Button
                                            else if (mouseY >= 670 && mouseY <= 770) {
                                                currentStage = "playinggame";

                                                currentScore = 0;
                                                currentMoves = 0;
                                                currentGrid = new int[grid][grid];
                                                for (int rows = 0; rows < grid; rows++){
                                                for (int columns = 0; columns < grid; columns++){
                                                    currentGrid[rows][columns] = 0;
                                                }
                                                }
                                                
                                                currentGrid[(int)(Math.random()*grid-1)][(int)(Math.random()*grid-1)] = 2;
                                                playGame();
                                            }
                                            }
                                        } 
                                        else if (currentStage == "selectingmaps") {
                                            // Check for Back Button
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupTitlePage();
                                            }
                                            }

                                            if (theme == "desert") {
                                            if (mouseX > width/2 - 110 && mouseX < (width/2 - 110) + 220) {
                                                if (mouseY > 170 && mouseY < 170 + 220) {
                                                theme = "desert";
                                                colors = desertColors;
                                                }
                                            }
                                            if (mouseX >= 200 && mouseX <= 200 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "forest";
                                                colors = forestColors;
                                                }
                                            }
                                            if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                                                if (mouseY >= 190 && mouseY < 190 + 170) {
                                                theme = "space";
                                                colors = spaceColors;
                                                }
                                            }
                                            } else if (theme == "forest") {
                                            if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                                                if (mouseY >= 170 && mouseY <= 170 + 220) {
                                                theme = "forest";
                                                colors = forestColors;
                                                }
                                            }
                                            if (mouseX >= 200 && mouseX <= 200 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "space";
                                                colors = spaceColors;
                                                }
                                            }
                                            if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "desert";
                                                colors = desertColors;
                                                }
                                            }
                                            } else if (theme == "space") {
                                            if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                                                if (mouseY >= 170 && mouseY <= 170 + 220) {
                                                theme = "space";
                                                colors = spaceColors;
                                                }
                                            }
                                            if (mouseX >= 200 && mouseX <= 200 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "desert";
                                                colors = desertColors;
                                                }
                                            }
                                            if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "forest";
                                                colors = forestColors;
                                                }
                                            }
                                            }
                                            
                                            // Check for adjust grid size button click
                                            if (mouseX >= 150 && mouseX <= 150+width-300) {
                                            if (mouseY >= 520 && mouseY <= 620) {
                                                setupGridAdjust();
                                            }
                                            // Check for Start Game Button
                                            else if (mouseY >= 670 && mouseY <= 770) {
                                                currentStage = "playinggame";
                                                currentScore = 0;
                                                currentMoves = 0;
                                                currentGrid = new int[grid][grid];
                                                for (int rows = 0; rows < grid; rows++){
                                                    for (int columns = 0; columns < grid; columns++){
                                                    currentGrid[rows][columns] = 0;
                                                    }
                                                }
                                                
                                                currentGrid[(int)(Math.random()*grid)][(int)(Math.random()*grid)] = 2;
                                                playGame();
                                                }
                                            
                                            // Check for View Instructions Button
                                            else if  (mouseY >= 780 && mouseY <= 880){
                                                currentStage = "viewinstructions";
                                                viewInstructions(); 
                                            }
                                            
                                            // Check for View Previous Scores Button
                                            else if  (mouseY >= 890 && mouseY <= 990){
                                                currentStage = "viewingprevious";
                                                viewPrevious(); 
                                            }
                                            }
                                        }
                                        else if (currentStage == "adjustinggrid"){
                                            // Check for button to go back to the theme menu
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupMapsPage();
                                            }
                                            }
                                            rect(width/2+10, 850, 100, 100);
                                            rect(width/2-110, 850, 100, 100);
                                        
                                            if (mouseY >= 850 && mouseY <= 950){
                                            if (mouseX >= width/2+10 && mouseX <= width/2+110){
                                                if (grid > 4){
                                                grid-=1;
                                                }
                                            }
                                            else if (mouseX >= width/2-110 && mouseX <= width/2-10){
                                                if (grid < 10){
                                                grid+=1;
                                                }
                                            }
                                            }
                                        }
                                        else if (currentStage == "playinggame"){
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupTitlePage();
                                            }
                                            }
                                            
                                            if (mouseX >= 225 && mouseX <= 325){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                combineAllPowerup();
                                            }
                                            }
                                            
                                            if (mouseX >= 335 && mouseX <= 435){
                                            if (mouseY >= 800 && mouseY <= 900){
                                            if (currentScore>=100*grid){
                                                currentScore -= 100*grid;
                                                foursOnly = true;
                                                }
                                                else{
                                                warning = "You need " + (100*grid-currentScore) + " more score!";
                                                }
                                            }
                                            }
                                            
                                            if (mouseX >= 445 && mouseX <= 545){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                if (currentScore>=50*grid){
                                                currentScore -= 50*grid;
                                                currentGrid = lastGrid;
                                                warning = "The last move has been undone";
                                                }
                                                else{
                                                warning = "You need " + (50*grid-currentScore) + " more score!";
                                                }
                                            }
                                            }
                                            
                                            if (mouseX >= 555 && mouseX <= 655){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                randomTileBreak();
                                            }
                                            }
                                            
                                            if (mouseX >= 665 && mouseX <= 765){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                if (currentScore>=200*grid){
                                                currentScore -= 200*grid;
                                                doubleMode = true;
                                                }
                                                else{
                                                warning = "You need " + (200*grid-currentScore) + " more score!";
                                                }
                                            }
                                            }
                                        }
                                        else if (currentStage == "viewinstructions"){
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupMapsPage();
                                            }
                                            }
                                            
                                            //Check for Start Menu Buttons
                                            if (mouseX >= 150 && mouseX <= 150+width-300) {
                                            
                                            // Check for Start Game Button
                                            if (mouseY >= 670 && mouseY <= 770) {
                                                currentStage = "playinggame";

                                                currentScore = 0;
                                                currentMoves = 0;
                                                currentGrid = new int[grid][grid];
                                                for (int rows = 0; rows < grid; rows++){
                                                for (int columns = 0; columns < grid; columns++){
                                                    currentGrid[rows][columns] = 0;
                                                }
                                                }
                                                
                                                currentGrid[(int)(Math.random()*grid-1)][(int)(Math.random()*grid-1)] = 2;
                                                playGame();
                                            }
                                            }
                                        }
                                        }

                                        void randomTileBreak(){
                                        int filledSquare = 0;
                                        int[][] filledGrid = new int[grid*grid][2];
                                        
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            if (currentGrid[rows][columns] != 0 && currentGrid[rows][columns] != 2){
                                                filledGrid[filledSquare][0] = rows;
                                                filledGrid[filledSquare][1] = columns;
                                                filledSquare++;
                                            }
                                            }
                                        }
                                        
                                        if (filledSquare > 0){
                                            if (currentScore>=25*grid){
                                            currentScore -= 25*grid;
                                            
                                            int randomIndex = (int)(Math.random()*(filledSquare));
                                            int[] randomSquare = filledGrid[randomIndex];
                                            
                                            currentGrid[randomSquare[0]][randomSquare[1]] = 0;
                                            }
                                            else{
                                            warning = "You need " + 25*grid + " more score!";
                                            }
                                        }
                                        else {
                                            warning = "You need more than 1 filled non-two tile!";
                                        }
                                        }

                                        void combineAllPowerup(){
                                        
                                        int filledSquare = 0;
                                        
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            if (currentGrid[rows][columns] != 0 && currentGrid[rows][columns] != 2){
                                                filledSquare++;
                                            }
                                            }
                                        }
                                        
                                        if (filledSquare > 0){
                                            int newSquare = closestTwoPower(currentScore/2);
                                            currentScore /= 4;
                                            
                                            currentGrid = new int[grid][grid];
                                            for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                                currentGrid[rows][columns] = 0;
                                            }
                                            }
                                                    
                                            currentGrid[(int)(Math.random()*grid)][(int)(Math.random()*grid)] = newSquare;
                                        }
                                        else {
                                            warning = "You need more than 1 filled non-two tile!";
                                        }
                                        }

                                        int closestTwoPower(int num){
                                        
                                        int counter = 1;
                                        
                                        //ArrayList powersOfTwo = new ArrayList<>();
                                        
                                        while (num > counter){
                                            counter*=2;
                                            //powersOfTwo.add(counter);
                                        }
                                        
                                        if (abs(num-counter)>=abs(num-counter/2)){
                                            counter/=2;
                                        }
                                        
                                        return counter;
                                        
                                        }

                                        void viewPrevious(){
                                        background(colors[0]);
                                        
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);
                                        
                                        try{
                                            BufferedReader sentenceReader = new BufferedReader(new java.io.FileReader("scores.txt"));
                                            String currentLine = sentenceReader.readLine();
                                            int numberOfScores = 0;
                                            textSize(40);
                                            while (currentLine != null) {
                                                text(currentLine, width/2, 100+numberOfScores*40);
                                                numberOfScores++;
                                                currentLine = sentenceReader.readLine();
                                            }
                                            sentenceReader.close();
                                        }
                                        catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                        }


                                        void viewInstructions(){
                                        background(colors[0]);

                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);

                                        // Display main instructions
                                        textSize(70);
                                        textAlign(CENTER, CENTER);
                                        text("Use ← ↑ ↓ → keys to move tiles", width/2, 150);

                                        textSize(40);
                                        text("Combine Like Tiles to Create a Larger Tile", width/2, 250);

                                        textSize(60);
                                        text("Goal: Reach the 2048 tile!", width/2, 310);
                                        text("Example: 2 + 2 → 4, 4 + 4 → 8", width/2, 370);

                                        // Rendering the Start Game button
                                        fill(colors[3]);
                                        rect(150, 670, width - 300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("START GAME", (width) / 2, 720);

                                        // Power-Up Button Layout
                                        // Lightning Power-Up Button
                                        fill(colors[1]);
                                        rect(225, 800, 100, 100, 10);
                                        image(lightning, 233, 810);
                                        
                                        // 444 Power-Up Button
                                        fill(colors[1]);
                                        rect(335, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("444", 385, 850);
                                        
                                        // Undo Power-Up Button
                                        fill(colors[1]);
                                        rect(445, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(undo, 460, 815);
                                        
                                        // Hammer Power-Up Button
                                        fill(colors[1]);
                                        rect(555, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(hammer, 570, 815);
                                        
                                        // 2x Power-Up Button
                                        fill(colors[1]);
                                        rect(665, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("2x", 715, 850);

                                        // Power-Up Descriptions (Make sure they fit between height 420 and 670)
                                        textSize(20);  // Smaller font size
                                        fill(0);
                                        textAlign(LEFT, TOP);

                                        // Lightning Power-Up Description
                                        text("Lightning: Clears the board, leaves 1 tile (closest power of 2 to score/2), costs current score/4", 100, 450);

                                        // 444 Power-Up Description
                                        text("444: Spawns 10 '4' tiles in a row, costs 100 per grid size", 100, 480);

                                        // Undo Power-Up Description
                                        text("Undo: Reverts last move, costs 50 per grid size", 100, 510);

                                        // Hammer Power-Up Description
                                        text("Hammer: Breaks a random tile, costs 25 per grid size", 100, 540);

                                        // 2x Power-Up Description
                                        text("2x: Doubles collisions for 10 moves, costs 200 per grid size", 100, 570);
                                        }

                                        void setupFinishedGamePage(){
                                        background(colors[0]);
                                            
                                        fill(0);
                                        textSize(60);
                                        
                                        text("Game Over!", width/2, 50);
                                        // Displaying the number of moves
                                        text("Number of Moves: " + currentMoves, width/2, 110);
                                        
                                        // Displaying the score of the user
                                        text("Total Score: " + currentScore, width/2, 170);
                                        
                                        text("Final Grid", width/2, 270);
                                        
                                        // Displaying the Grid
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            fill(colors[4]);
                                            rect(225+rows*(525/grid+4), 320+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                            
                                            if (currentGrid[rows][columns] != 0){
                                                fill(colors[((powerOfTwo(currentGrid[rows][columns])%colors.length))]);
                                                rect(225+rows*(525/grid+4), 320+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                                
                                                fill(0);
                                                textSize(30);
                                                text(currentGrid[rows][columns], (225+rows*(525/grid+4)+(530/grid-4)/2), (320+columns*(525/grid+4)+(530/grid-4)/2));
                                            }
                                            }
                                        }
                                        try {
                                            PrintWriter sentenceWriter = new PrintWriter(new java.io.FileWriter("scores.txt", true));
                                            sentenceWriter.println("Score: " + currentScore + " in " + currentMoves + " moves of grid size " + grid + "x" + grid);
                                            sentenceWriter.close(); 
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                        
                                        text("Press SPACE to Continue", width/2, height-100);
                                            
                                        }

                                        int checkPossibleCollisions(int[][] currentGrid){
                                        int possibleCollisions = 0;
                                        int[][] newGrid = currentGrid;
                                        
                                        for (int row=1; row0; row--){
                                            for (int column=0; column0; column--){
                                            if (newGrid[row][column]==newGrid[row][column-1] && newGrid[row][column]!=0){
                                                possibleCollisions++;
                                            }
                                            }
                                        }
                                        
                                        return possibleCollisions;
                                        }

                                        int[][] checkCollisions(int[][] currentGrid, String direction){
                                        int[][] newGrid = currentGrid;
                                        
                                        switch (direction) {
                                            case "left":
                                            for (int row=1; row0; row--){
                                                for (int column=0; column0; column--){
                                                if (newGrid[row][column]==newGrid[row][column-1] && newGrid[row][column]!=0){
                                                    if (doubleMode){
                                                    newGrid[row][column] = (newGrid[row][column]+newGrid[row][column-1])*2;
                                                    newGrid[row][column-1] = 0;
                                                    currentScore+=(newGrid[row][column]+newGrid[row][column-1]*2);
                                                    }
                                                    else{ 
                                                    newGrid[row][column] = newGrid[row][column]+newGrid[row][column-1];
                                                    newGrid[row][column-1] = 0;
                                                    currentScore+=newGrid[row][column]+newGrid[row][column-1];
                                                    }
                                                }
                                                }
                                            }
                                            break;
                                        }
                                        
                                        return newGrid;
                                        }

                                        int[][] shiftGrid(int[][] currentGrid, String direction) {
                                        
                                        int[][] newGrid = new int[grid][grid];
                                        currentGrid = checkCollisions(currentGrid, direction);
                                        
                                        switch (direction) {
                                            case "up":
                                            for (int i=0; i0; x--){
                                                filled[filledCount+x-1] = 0;
                                                }
                                                newGrid[i] = filled;
                                            }
                                            break;
                                            
                                            case "down":
                                            for (int i = 0; i < grid; i++) {
                                                int[] filled = new int[grid];
                                                int filledCount = 0;
                                            
                                                for (int x = grid - 1; x >= 0; x--) {
                                                if (currentGrid[i][x] != 0) {
                                                    filled[filledCount] = currentGrid[i][x];
                                                    filledCount++;
                                                }
                                                }
                                            
                                                for (int x = 0; x < filledCount; x++) {
                                                newGrid[i][grid - 1 - x] = filled[x];
                                                }

                                                for (int x = 0; x < grid - filledCount; x++) {
                                                newGrid[i][x] = 0;
                                                }
                                            }
                                            break;
                                            
                                            case "left":
                                            for (int i = 0; i < grid; i++) {
                                                int[] filled = new int[grid];
                                                int filledCount = 0;
                                        
                                                for (int x = 0; x < grid; x++) {
                                                if (currentGrid[x][i] != 0) {
                                                    filled[filledCount] = currentGrid[x][i];
                                                    filledCount++;
                                                }
                                                }
                                        
                                                int y = grid - 1;
                                                for (int x = grid-filledCount - 1; x >= 0; x--) {
                                                newGrid[y][i] = 0;
                                                y--;
                                                }
                                                while (y >= 0) {
                                                newGrid[y][i] = filled[y];
                                                y--;
                                                }
                                            }
                                            break;
                                            
                                            case "right":
                                            for (int i = 0; i < grid; i++) {
                                                int[] filled = new int[grid];
                                                int filledCount = 0;
                                        
                                                for (int x = 0; x < grid; x++) {
                                                if (currentGrid[x][i] != 0) {
                                                    filled[filledCount] = currentGrid[x][i];
                                                    filledCount++;
                                                }
                                                }
                                        
                                                int y = grid - 1;
                                                for (int x = filledCount - 1; x >= 0; x--) {
                                                newGrid[y][i] = filled[x];
                                                y--;
                                                }
                                        
                                                while (y >= 0) {
                                                newGrid[y][i] = 0;
                                                y--;
                                                }
                                            }
                                            break;
                                        }
                                        
                                        return checkCollisions(newGrid, direction);
                                        }

                                        int powerOfTwo(int n) {
                                        int power = 0;
                                        while (n > 1) {
                                            n /= 2;
                                            power++;
                                        }
                                        return power;
                                        }

                                        void playGame(){
                                        currentStage = "playinggame";
                                        
                                        background(colors[0]);
                                        
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);
                                        
                                        textSize(60);
                                        // Displaying the number of moves
                                        text("Number of Moves: " + currentMoves, width/2, 100);
                                        
                                        // Displaying the score of the user
                                        text("Total Score: " + currentScore, width/2, 160);
                                        
                                        // Displaying the Grid
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            fill(colors[4]);
                                            rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                            
                                            if (currentGrid[rows][columns] != 0){
                                                fill(colors[((powerOfTwo(currentGrid[rows][columns])%colors.length))]);
                                                rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                                
                                                fill(0);
                                                textSize(160/grid);
                                                text(currentGrid[rows][columns], (225+rows*(525/grid+4)+(530/grid-4)/2), (225+columns*(525/grid+4)+(530/grid-4)/2));
                                            }
                                            }
                                        }
                                        
                                        fill(colors[1]);
                                        rect(225, 800, 100, 100, 10);
                                        image(lightning, 233, 810);
                                        
                                        fill(colors[1]);
                                        rect(335, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("444", 385, 850);
                                        
                                        fill(colors[1]);
                                        rect(445, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(undo, 460, 815);
                                        
                                        fill(colors[1]);
                                        rect(555, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(hammer, 570, 815);
                                        
                                        fill(colors[1]);
                                        rect(665, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("2x", 715, 850);
                                        
                                        if (foursOnly){
                                            warning = "You have " + (10-fours) + " 4s left in a row!";
                                        }
                                        text(warning, width/2, 950);
                                        }

                                        void setupGridAdjust(){
                                        background(colors[0]);
                                        currentStage = "adjustinggrid";
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);
                                        
                                        text("Adjust Grid Size", (width)/2, 70);
                                        
                                        // Showing Main Grid 
                                        fill(colors[1]);
                                        rect(200, 200, 600, 600, 50);
                                        
                                        currentGrid = new int[grid][grid];
                                        
                                        fill(colors[4]);
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                            currentGrid[rows][columns] = 0;
                                            }
                                        }
                                        
                                        rect(width/2+10, 850, 100, 100);
                                        rect(width/2-110, 850, 100, 100);
                                        
                                        // Draw the Up arrow inside the left rectangle
                                        fill(0); // Set color to black
                                        beginShape();
                                        vertex(width/2-110+50, 850+25);  
                                        vertex(width/2-110+10, 850+75); 
                                        vertex(width/2-110+90, 850+75);  
                                        endShape(CLOSE);
                                        
                                        // Draw the Down arrow inside the right rectangle
                                        beginShape();
                                        vertex(width/2+10+50, 850+75);  
                                        vertex(width/2+10+10, 850+25);  
                                        vertex(width/2+10+90, 850+25);  
                                        endShape(CLOSE);

                                        }

                                        void setupMapsPage() {
                                        setupTitlePage();
                                        background(colors[0]);
                                        currentStage = "selectingmaps";
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);

                                        textSize(80);
                                        text("Select Your Map", (width)/2, 70);

                                        if (theme == "desert") {
                                            fill(colors[4]);
                                            rect(width/2-110, 170, 220, 220);
                                            textSize(60);
                                            fill(0);
                                            text("Desert", (width)/2, 270);

                                            fill(colors[1]);
                                            rect(200, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Forest", 285, 270);

                                            fill(colors[1]);
                                            rect((width/2-110)+240, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Space", (width/2-110)+240+85, 270);
                                        } else if (theme == "forest") {
                                            fill(colors[4]);
                                            rect(width/2-110, 170, 220, 220);
                                            textSize(60);
                                            fill(0);
                                            text("Forest", (width)/2, 270);

                                            fill(colors[1]);
                                            rect(200, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Space", 285, 270);

                                            fill(colors[1]);
                                            rect((width/2-110)+240, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Desert", (width/2-110)+240+85, 270);
                                        } else if (theme == "space") {
                                            fill(colors[4]);
                                            rect(width/2-110, 170, 220, 220);
                                            textSize(60);
                                            fill(0);
                                            text("Space", (width)/2, 270);

                                            fill(colors[1]);
                                            rect(200, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Desert", 285, 270);

                                            fill(colors[1]);
                                            rect((width/2-110)+240, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Forest", (width/2-110)+240+85, 270);
                                        }
                                        
                                        // Rendering the Change Map Dimensions button
                                        fill(colors[3]);
                                        rect(150, 520, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("Adjust Grid Size", (width)/2, 570);

                                        // Rendering the Start Game button
                                        fill(colors[3]);
                                        rect(150, 670, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("START GAME", (width)/2, 720);
                                        
                                        fill(colors[3]);
                                        rect(150, 780, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("View Instructions", (width)/2, 830);
                                        
                                        fill(colors[3]);
                                        rect(150, 890, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("View Previous Scores", (width)/2, 940);
                                        }

                                        void toggleMusic() {
                                        // Method to toggle music depending on current status
                                        if (musicStatus == "ON") {
                                            musicStatus = "OFF";
                                            player.close();
                                            minim.stop();
                                        } else if (musicStatus == "OFF") {
                                            musicStatus = "ON";
                                            minim = new Minim(this);
                                            player = minim.loadFile("music.mp3");
                                            player.loop();
                                        }
                                        }

                                        void setupTitlePage() {
                                        // Set up basic title page
                                        background(colors[0]);
                                        fill(colors[0]);
                                        rect(0, 0, 1000, 1000);

                                        textSize(150);
                                        
                                        fill(0);
                                        textAlign(CENTER, CENTER);
                                        text("2048:", width/2, 100);
                                        textSize(160);
                                        text("POWER", width/2, 250);
                                        currentStage = "start";

                                        // Rendering the Toggle Map Settings button
                                        fill(colors[3]);
                                        rect(150, 520, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("Toggle Map Settings", (width)/2, 570);

                                        // Rendering the Start Game button
                                        fill(colors[3]);
                                        rect(150, 670, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("START GAME", (width)/2, 720);

                                        // Printed instructions for menu selection
                                        textSize(50);
                                        fill(0);
                                        textAlign(CENTER, CENTER);
                                        text("Press M to mute/unmute", width/2, 850);
                                        textSize(50);
                                        text("Use mouse to select menu", width/2, 900);
                                        }
Download Code File

Journal Entry

Today was the final development day where I completed all major features:

  • Added score-based power-up system
  • Implemented special Lock tiles that stay in place for 8 moves
  • Created Bomb tiles that destroy surrounding tiles when matched
  • Built the view scores page to show previous game results
  • Added 9 additional music tracks across different genres
  • Completed the view instructions page with full game documentation
  • Added keyboard shortcuts (1-9) for quick music selection

Thoughts: This was by far the most productive day as today was when I completed all core game features. While all required features have been implemented, I still have ideas for additional enhancements I'd like to add throughout the summer. The remaining work is primarily code documentation and comments.

Code

import ddf.minim.*;

                    AudioPlayer player;
                    Minim minim;

                    PImage lightning;
                    PImage undo;
                    PImage hammer;
                    PImage lock;
                    PImage bomb;

                    String text;
                    String musicStatus = "ON";
                    String currentStage = "start";
                    String theme = "desert";
                    int grid = 4;

                    String warning = "Welcome to the Game! Make your first move!";

                    int currentScore = 0;
                    int currentMoves = 0;

                    boolean foursOnly = false;
                    int fours = 0;

                    boolean doubleMode = false;
                    int doubles = 0;

                    String currentMusic = "basiclofi";

                    int[][] currentGrid;
                    int[][] lastGrid;

                    color[] desertColors = {#e6dfd0, #ded4c0, #d6c9b1, #cdbea1, #c5b391, #bda981, #b49e72};
                    color[] spaceColors = {#cccccc, #c0c0c0, #b3b3b3, #a6a6a6, #999999, #8d8d8d, #808080};
                    color[] forestColors = {#99c199, #80b280, #66a266, #4d934d, #338333, #197419, #006400};

                    color[] colors = desertColors;

                    void setup() {
                    // Creating the basic canvas
                    size(1000, 1000);
                    
                    // Holding lightning powerup image
                    lightning = loadImage("lightningbolt.png");
                    lightning.resize(80,80);
                    
                    undo = loadImage("undoicon.png");
                    undo.resize(70,70);
                    
                    hammer = loadImage("hammer.png");
                    hammer.resize(70,70);
                    
                    lock = loadImage("lock.png");
                    lock.resize(50,50);
                    
                    bomb = loadImage("bomb.png");
                    bomb.resize(50,50);

                    // Setting up the music player
                    minim = new Minim(this);
                    player = minim.loadFile("music.mp3");
                    player.loop();

                    // Creating the basic title page
                    setupTitlePage();
                    }

                    void draw() {
                    if (currentStage == "start") {
                        // Rendering the music settings dynamically
                        fill(colors[3]);
                        rect(150, 400, width-300, 100);
                        textSize(80);
                        fill(0);
                        text("MUSIC: " + musicStatus, (150+width-300)/2, 450);
                        fill(colors[2]);
                        rect(150+width-400, 400, 100, 100);
                        fill(0);
                        if (musicStatus == "ON") {
                        fill(0);
                        textSize(200);
                        text("-", 800, 435);
                        } else if (musicStatus == "OFF") {
                        fill(0);
                        textSize(170);
                        text("+", 800, 445);
                        }
                    } 
                    else if (currentStage == "selectingmaps") {
                        setupMapsPage();
                    }
                    else if (currentStage == "adjustinggrid") {
                        setupGridAdjust();
                    }
                    else if (currentStage == "playinggame") {
                        playGame();
                    }
                    }

                    void keyPressed() {
                    // Checks for mute and unmute key presses and plays music accordingly
                    if (key == 'm' || key == 'M') {
                        toggleMusic();
                    }
                    if (key == 't' || key == 'T'){
                        if (currentMusic == "basiclofi"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "baby";
                            minim = new Minim(this);
                            player = minim.loadFile("baby.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "baby"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "espresso";
                            minim = new Minim(this);
                            player = minim.loadFile("espresso.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "espresso"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "party";
                            minim = new Minim(this);
                            player = minim.loadFile("party.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "party"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "wmyb";
                            minim = new Minim(this);
                            player = minim.loadFile("wmyb.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "wmyb"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "shakeitoff";
                            minim = new Minim(this);
                            player = minim.loadFile("shakeitoff.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "shakeitoff"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "wonderwall";
                            minim = new Minim(this);
                            player = minim.loadFile("wonderwall.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "wonderwall"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "carelesswhisper";
                            minim = new Minim(this);
                            player = minim.loadFile("carelesswhisper.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "carelesswhisper"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "apt";
                            minim = new Minim(this);
                            player = minim.loadFile("apt.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "apt"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "fein";
                            minim = new Minim(this);
                            player = minim.loadFile("fein.mp3");
                            player.loop();
                        }
                        else if (currentMusic == "fein"){
                            toggleMusic();
                            musicStatus = "ON";
                            currentMusic = "basiclofi";
                            minim = new Minim(this);
                            player = minim.loadFile("music.mp3");
                            player.loop();
                        }
                    }
                    
                    else if (currentStage == "adjustinggrid"){
                        if (keyCode == UP){
                        if (grid < 10){
                            grid+=1;
                        }
                        }
                        else if (keyCode == DOWN){
                        if (grid > 4){
                            grid-=1;
                        }
                        }
                    }
                    
                    else if (currentStage == "playinggame"){
                        if (keyCode == UP){
                        warning = "";
                        int[][] tempGrid = shiftGrid(currentGrid, "up");
                        int changes = 0;
                        boolean trigger = true;
                        
                        for (int row=0; row 0){
                            currentMoves += 1;
                            }
                            
                            int[][] freeSpots = new int[grid*grid][2];
                            int totalFree = 0;
                            for (int rows = 0; rows < grid; rows++){
                                for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                    freeSpots[totalFree][0] = rows;
                                    freeSpots[totalFree][1] = columns;
                                    totalFree += 1;
                                }
                                if (changes>0){
                                    if (currentGrid[rows][columns]%2!=0){
                                    if (currentGrid[rows][columns] == 17){
                                        currentGrid[rows][columns] = 0;
                                    }
                                    else{
                                        currentGrid[rows][columns]+=2;
                                    }
                                    }
                                }
                                }
                            }
                            
                            int randomAddition = (int)(Math.random()*totalFree);
                            int randomNum = (int)(Math.random()*101);
                            
                            if (totalFree != 0 && changes != 0){
                                if (doubles == 10){
                                doubleMode = false;
                                doubles = 0;
                                }
                                if (doubleMode){
                                doubles+=1;
                                }
                                
                                if (fours == 10){
                                foursOnly = false;
                                fours = 0;
                                }
                                if (foursOnly){
                                currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                fours+=1;
                                }
                                else if (totalFree >= 4){
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else if (randomNum >= 98){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                    while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0){
                                    randomAddition = (int)(Math.random()*totalFree);
                                    }
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                                else{
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                            }
                            }
                            }
                        else if (keyCode == DOWN){
                        warning = "";
                        int[][] tempGrid = shiftGrid(currentGrid, "down");
                        int changes = 0;
                        boolean trigger = true;
                        
                        for (int row=0; row 0){
                            currentMoves += 1;
                            }
                            
                            int[][] freeSpots = new int[grid*grid][2];
                            int totalFree = 0;
                            for (int rows = 0; rows < grid; rows++){
                                for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                    freeSpots[totalFree][0] = rows;
                                    freeSpots[totalFree][1] = columns;
                                    totalFree += 1;
                                }
                                if (changes>0){
                                    if (currentGrid[rows][columns]%2!=0){
                                    if (currentGrid[rows][columns] == 17){
                                        currentGrid[rows][columns] = 0;
                                    }
                                    else{
                                        currentGrid[rows][columns]+=2;
                                    }
                                    }
                                }
                                }
                            }
                            
                            int randomAddition = (int)(Math.random()*totalFree);
                            int randomNum = (int)(Math.random()*101);
                            
                            if (totalFree != 0 && changes != 0){
                                if (doubles == 10){
                                doubleMode = false;
                                doubles = 0;
                                }
                                if (doubleMode){
                                doubles+=1;
                                }
                                
                                if (fours == 10){
                                foursOnly = false;
                                fours = 0;
                                }
                                if (foursOnly){
                                currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                fours+=1;
                                }
                                else if (totalFree >= 4){
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else if (randomNum >= 98){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                    while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0){
                                    randomAddition = (int)(Math.random()*totalFree);
                                    }
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                                else{
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                            }
                        }
                        
                        }
                        else if (keyCode == LEFT){
                        warning = "";
                        int[][] tempGrid = shiftGrid(currentGrid, "left");
                        int changes = 0;
                        boolean trigger = true;
                        
                        for (int row=0; row 0){
                            currentMoves += 1;
                            }
                            
                            int[][] freeSpots = new int[grid*grid][2];
                            int totalFree = 0;
                            for (int rows = 0; rows < grid; rows++){
                                for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                    freeSpots[totalFree][0] = rows;
                                    freeSpots[totalFree][1] = columns;
                                    totalFree += 1;
                                }
                                if (changes>0){
                                    if (currentGrid[rows][columns]%2!=0){
                                    if (currentGrid[rows][columns] == 17){
                                        currentGrid[rows][columns] = 0;
                                    }
                                    else{
                                        currentGrid[rows][columns]+=2;
                                    }
                                    }
                                }
                                }
                            }
                            
                            int randomAddition = (int)(Math.random()*totalFree);
                            int randomNum = (int)(Math.random()*101);
                            
                            if (totalFree != 0 && changes != 0){
                                if (doubles == 10){
                                doubleMode = false;
                                doubles = 0;
                                }
                                if (doubleMode){
                                doubles+=1;
                                }
                                
                                if (fours == 10){
                                foursOnly = false;
                                fours = 0;
                                }
                                if (foursOnly){
                                currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                fours+=1;
                                }
                                else if (totalFree >= 4){
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else if (randomNum >= 98){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                    while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0){
                                    randomAddition = (int)(Math.random()*totalFree);
                                    }
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                                else{
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                            }
                            }
                        }
                        else if (keyCode == RIGHT){
                        warning = "";
                        int[][] tempGrid = shiftGrid(currentGrid, "right");
                        int changes = 0;
                        boolean trigger = true;
                        
                        for (int row=0; row 0){
                            currentMoves += 1;
                            }
                            
                            int[][] freeSpots = new int[grid*grid][2];
                            int totalFree = 0;
                            for (int rows = 0; rows < grid; rows++){
                                for (int columns = 0; columns < grid; columns++){
                                if (currentGrid[rows][columns] == 0){
                                    freeSpots[totalFree][0] = rows;
                                    freeSpots[totalFree][1] = columns;
                                    totalFree += 1;
                                }
                                if (changes>0){
                                    if (currentGrid[rows][columns]%2!=0){
                                    if (currentGrid[rows][columns] == 17){
                                        currentGrid[rows][columns] = 0;
                                    }
                                    else{
                                        currentGrid[rows][columns]+=2;
                                    }
                                    }
                                }
                                }
                            }
                            
                            int randomAddition = (int)(Math.random()*totalFree);
                            int randomNum = (int)(Math.random()*101);
                            
                            if (totalFree != 0 && changes != 0){
                                if (doubles == 10){
                                doubleMode = false;
                                doubles = 0;
                                }
                                if (doubleMode){
                                doubles+=1;
                                }
                                
                                if (fours == 10){
                                foursOnly = false;
                                fours = 0;
                                }
                                if (foursOnly){
                                currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                fours+=1;
                                }
                                else if (totalFree >= 4){
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else if (randomNum >= 98){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                    while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0){
                                    randomAddition = (int)(Math.random()*totalFree);
                                    }
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                                else{
                                if (randomNum >= 85 && randomNum <= 92){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                }
                                else if (randomNum >= 93 && randomNum <= 97){
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                }
                                else{
                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                }
                                }
                            }
                            }
                        }
                    }
                    else if (currentStage == "finishedgame"){
                        if (key == ' '){
                        setupTitlePage();
                        }
                    }
                    
                    if (key == '1'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "basiclofi";
                        minim = new Minim(this);
                        player = minim.loadFile("music.mp3");
                        player.loop();
                    }
                    else if (key == '2'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "baby";
                        minim = new Minim(this);
                        player = minim.loadFile("baby.mp3");
                        player.loop();
                    }
                    else if (key == '3'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "espresso";
                        minim = new Minim(this);
                        player = minim.loadFile("espresso.mp3");
                        player.loop();
                    }
                    else if (key == '4'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "party";
                        minim = new Minim(this);
                        player = minim.loadFile("party.mp3");
                        player.loop();
                    }
                    else if (key == '5'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "wmyb";
                        minim = new Minim(this);
                        player = minim.loadFile("wmyb.mp3");
                        player.loop();
                    }
                    else if (key == '6'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "shakeitoff";
                        minim = new Minim(this);
                        player = minim.loadFile("shakeitoff.mp3");
                        player.loop();
                    }
                    else if (key == '7'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "wonderwall";
                        minim = new Minim(this);
                        player = minim.loadFile("wonderwall.mp3");
                        player.loop();
                    }
                    else if (key == '8'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "carelesswhisper";
                        minim = new Minim(this);
                        player = minim.loadFile("carelesswhisper.mp3");
                        player.loop();
                    }
                    else if (key == '9'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "apt";
                        minim = new Minim(this);
                        player = minim.loadFile("apt.mp3");
                        player.loop();
                    }
                    else if (key == '0'){
                        toggleMusic();
                        musicStatus = "ON";
                        currentMusic = "fein";
                        minim = new Minim(this);
                        player = minim.loadFile("fein.mp3");
                        player.loop();
                    }
                    }
Download Code File

Journal Entry

Today was the final development day where I completed all major features:

  • Went through the entire codebase and added comments and documentation to make it more readable
  • Created GitHub repository for the code at https://github.com/SarveshwarSenthilKumar/2048-Power
  • Created website for the game at https://sarveshwarsenthilkumar.github.io/2048-Power/

Thoughts: While it was quite tedious to go through the entire codebase and comment on the thought process behind the different functions and why the algorithms are the way they are. It also highlighted some inefficiencies which I fixed which helped me optimize my code.

Code


                                        /*
                                        * Title: 2048-Power
                                        * Author: Sarveshwar Senthil Kumar
                                        * Date: June 17th, 2025
                                        * Description of the program: This is a template
                                        */

                                        import ddf.minim.*;

                                        // Initializing classes for Audio
                                        AudioPlayer player;
                                        Minim minim;

                                        // Initializing classes for images
                                        PImage lightning;
                                        PImage undo;
                                        PImage hammer;
                                        PImage lock;
                                        PImage bomb;

                                        String text;
                                        String musicStatus = "ON";
                                        String currentStage = "start";
                                        String theme = "desert";
                                        int grid = 4;

                                        // Display text for the first move
                                        String warning = "Welcome to the Game! Make your first move!";

                                        int currentScore = 0;
                                        int currentMoves = 0;

                                        // Powerup Toggle Variables
                                        boolean foursOnly = false;
                                        int fours = 0;

                                        boolean doubleMode = false;
                                        int doubles = 0;

                                        String currentMusic = "basiclofi";

                                        int[][] currentGrid;
                                        int[][] lastGrid;

                                        // Initializing arrays for special themes
                                        color[] desertColors = {#e6dfd0, #ded4c0, #d6c9b1, #cdbea1, #c5b391, #bda981, #b49e72};
                                        color[] spaceColors = {#cccccc, #c0c0c0, #b3b3b3, #a6a6a6, #999999, #8d8d8d, #808080};
                                        color[] forestColors = {#99c199, #80b280, #66a266, #4d934d, #338333, #197419, #006400};

                                        color[] colors = desertColors;

                                        void setup() {
                                        // Creating the basic canvas
                                        size(1000, 1000);
                                        
                                        // Image to hold Lightning Powerup image
                                        lightning = loadImage("lightningbolt.png");
                                        lightning.resize(80,80);
                                        
                                        // Image to hold Undo Powerup Image
                                        undo = loadImage("undoicon.png");
                                        undo.resize(70,70);
                                        
                                        // Image to hold Hammer Powerup Image
                                        hammer = loadImage("hammer.png");
                                        hammer.resize(70,70);
                                        
                                        // Image to hold Lock Powerup Image
                                        lock = loadImage("lock.png");
                                        lock.resize(50,50);
                                        
                                        // Image to hold Bomb Powerup Image
                                        bomb = loadImage("bomb.png");
                                        bomb.resize(50,50);

                                        // Setting up the music player
                                        minim = new Minim(this);
                                        player = minim.loadFile("music.mp3");
                                        player.loop();

                                        // Creating the basic title page
                                        setupTitlePage();
                                        }

                                        void draw() {
                                        if (currentStage == "start") {
                                            // Rendering the music settings dynamically
                                            fill(colors[3]);
                                            rect(150, 400, width-300, 100);
                                            textSize(80);
                                            fill(0);
                                            text("MUSIC: " + musicStatus, (150+width-300)/2, 450);
                                            fill(colors[2]);
                                            rect(150+width-400, 400, 100, 100);
                                            fill(0);
                                            
                                            // Conditional to Toggle Music + or - depending on ON or OFF
                                            if (musicStatus == "ON") {
                                            fill(0);
                                            textSize(200);
                                            text("-", 800, 435);
                                            } else if (musicStatus == "OFF") {
                                            fill(0);
                                            textSize(170);
                                            text("+", 800, 445);
                                            }
                                        } 
                                        else if (currentStage == "selectingmaps") {
                                            setupMapsPage();
                                        }
                                        else if (currentStage == "adjustinggrid") {
                                            setupGridAdjust();
                                        }
                                        else if (currentStage == "playinggame") {
                                            playGame();
                                        }
                                        }

                                        void keyPressed() {
                                        // Checks for mute and unmute key presses and plays music accordingly
                                        if (key == 'm' || key == 'M') {
                                            toggleMusic();
                                        }
                                        
                                        // Checks for toggle track key press
                                        if (key == 't' || key == 'T'){
                                            
                                            // Conditional to update track based on current track
                                            if (currentMusic == "basiclofi"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "baby";
                                                minim = new Minim(this);
                                                player = minim.loadFile("baby.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "baby"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "espresso";
                                                minim = new Minim(this);
                                                player = minim.loadFile("espresso.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "espresso"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "party";
                                                minim = new Minim(this);
                                                player = minim.loadFile("party.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "party"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "wmyb";
                                                minim = new Minim(this);
                                                player = minim.loadFile("wmyb.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "wmyb"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "shakeitoff";
                                                minim = new Minim(this);
                                                player = minim.loadFile("shakeitoff.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "shakeitoff"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "wonderwall";
                                                minim = new Minim(this);
                                                player = minim.loadFile("wonderwall.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "wonderwall"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "carelesswhisper";
                                                minim = new Minim(this);
                                                player = minim.loadFile("carelesswhisper.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "carelesswhisper"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "apt";
                                                minim = new Minim(this);
                                                player = minim.loadFile("apt.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "apt"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "fein";
                                                minim = new Minim(this);
                                                player = minim.loadFile("fein.mp3");
                                                player.loop();
                                            }
                                            else if (currentMusic == "fein"){
                                                toggleMusic();
                                                musicStatus = "ON";
                                                currentMusic = "basiclofi";
                                                minim = new Minim(this);
                                                player = minim.loadFile("music.mp3");
                                                player.loop();
                                            }
                                        }
                                        
                                        else if (currentStage == "adjustinggrid"){
                                            // Checking for arrow clicks to increase or decrease size of grid
                                            if (keyCode == UP){
                                            if (grid < 10){
                                                grid+=1;
                                            }
                                            }
                                            else if (keyCode == DOWN){
                                            if (grid > 4){
                                                grid-=1;
                                            }
                                            }
                                        }
                                        
                                        else if (currentStage == "playinggame"){
                                            // Checking for moves in-game using arrow keys
                                            if (keyCode == UP){
                                            warning = "";
                                            int[][] tempGrid = shiftGrid(currentGrid, "up");
                                            int changes = 0;
                                            boolean trigger = true;
                                            
                                            // Loop to check for the number of changes in upcoming turn
                                            for (int row=0; row 0){
                                                currentMoves += 1;
                                                }
                                                
                                                // Array to store the coordinates of the free spots
                                                int[][] freeSpots = new int[grid*grid][2];
                                                int totalFree = 0;
                                                
                                                // Loop to iterate through every square and check the value
                                                for (int rows = 0; rows < grid; rows++){
                                                    for (int columns = 0; columns < grid; columns++){
                                                    // If the value is 0 in the square, the coordinate will be added to freeSpots array and increase the totalFree ticker
                                                    if (currentGrid[rows][columns] == 0){
                                                        freeSpots[totalFree][0] = rows;
                                                        freeSpots[totalFree][1] = columns;
                                                        totalFree += 1;
                                                    }
                                                    if (changes>0){
                                                        // Conditional to account for lock tiles, add a move to their timer
                                                        if (currentGrid[rows][columns]%2!=0){
                                                        // If 8 moves has passed, the lock tile will be set to a empty tile
                                                        if (currentGrid[rows][columns] == 17){
                                                            currentGrid[rows][columns] = 0;
                                                        }
                                                        else{
                                                            currentGrid[rows][columns]+=2;
                                                        }
                                                        }
                                                    }
                                                    }
                                                }
                                                
                                                // Generate a random index in the freeSpots array to generate a square
                                                int randomAddition = (int)(Math.random()*totalFree);
                                                // Generate a number for probabilities from 0 to 100
                                                int randomNum = (int)(Math.random()*101);
                                                
                                                /*
                                                Probabilities Table:
                                                2: 0-84 85%
                                                4: 85-92 8%
                                                Lock: 93-97 5%
                                                Bomb: 98-100 2%
                                                */
                                                
                                                if (totalFree != 0 && changes != 0){
                                                    // Check if doubles is activated, if 10 moves have passed deactivate double powerup
                                                    if (doubles == 10){
                                                    doubleMode = false;
                                                    doubles = 0;
                                                    }
                                                    // If double powerup is activated, add a move to the counter
                                                    if (doubleMode){
                                                    doubles+=1;
                                                    }
                                                    
                                                    // Check if fours only powerup is activated, if 10 moves have passed deactivate fours powerup
                                                    if (fours == 10){
                                                    foursOnly = false;
                                                    fours = 0;
                                                    }
                                                    // If fours only powerup is activated, add a move to the counter and generate a 4
                                                    if (foursOnly){
                                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    fours+=1;
                                                    }
                                                    // If there are more than 4 squares free in the grid, allow probability for bomb tile
                                                    else if (totalFree >= 4){
                                                    // If random number is between 85 and 92: generate a 4 in a random free square
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    // If random number is between 93 and 97: generate a lock tile in a random free square
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    // If random number is between 98 and 100: generate two bomb tiles in two random free squares
                                                    else if (randomNum >= 98){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                        // Loop to keep iterating until two bomb tiles are placed in individual open tiles
                                                        do {
                                                        randomAddition = (int)(Math.random()*totalFree);
                                                        } while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0);
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                    }
                                                    // If random number is between 85 and 92: generate a 2 in a random free square
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                    // If there are less than 4 squares, the probabilities for bomb tile switch to a 2 tile
                                                    else{
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                }
                                                }
                                                }
                                            else if (keyCode == DOWN){
                                            warning = "";
                                            int[][] tempGrid = shiftGrid(currentGrid, "down");
                                            int changes = 0;
                                            boolean trigger = true;
                                            
                                            // Loop to check for the number of changes in upcoming turn
                                            for (int row=0; row 0){
                                                currentMoves += 1;
                                                }
                                                
                                                // Array to store the coordinates of the free spots
                                                int[][] freeSpots = new int[grid*grid][2];
                                                int totalFree = 0;
                                                
                                                // Loop to iterate through every square and check the value
                                                for (int rows = 0; rows < grid; rows++){
                                                    for (int columns = 0; columns < grid; columns++){
                                                    // If the value is 0 in the square, the coordinate will be added to freeSpots array and increase the totalFree ticker
                                                    if (currentGrid[rows][columns] == 0){
                                                        freeSpots[totalFree][0] = rows;
                                                        freeSpots[totalFree][1] = columns;
                                                        totalFree += 1;
                                                    }
                                                    if (changes>0){
                                                        // Conditional to account for lock tiles, add a move to their timer
                                                        if (currentGrid[rows][columns]%2!=0){
                                                        // If 8 moves has passed, the lock tile will be set to a empty tile
                                                        if (currentGrid[rows][columns] == 17){
                                                            currentGrid[rows][columns] = 0;
                                                        }
                                                        else{
                                                            currentGrid[rows][columns]+=2;
                                                        }
                                                        }
                                                    }
                                                    }
                                                }
                                                
                                                // Generate a random index in the freeSpots array to generate a square
                                                int randomAddition = (int)(Math.random()*totalFree);
                                                // Generate a number for probabilities from 0 to 100
                                                int randomNum = (int)(Math.random()*101);
                                                
                                                /*
                                                Probabilities Table:
                                                2: 0-84 85%
                                                4: 85-92 8%
                                                Lock: 93-97 5%
                                                Bomb: 98-100 2%
                                                */
                                                
                                                if (totalFree != 0 && changes != 0){
                                                    // Check if doubles is activated, if 10 moves have passed deactivate double powerup
                                                    if (doubles == 10){
                                                    doubleMode = false;
                                                    }
                                                    // If double powerup is activated, add a move to the counter
                                                    if (doubleMode){
                                                    doubles+=1;
                                                    }
                                                    
                                                    // Check if fours only powerup is activated, if 10 moves have passed deactivate fours powerup
                                                    if (fours == 10){
                                                    foursOnly = false;
                                                    fours = 0;
                                                    }
                                                    // If fours only powerup is activated, add a move to the counter and generate a 4
                                                    if (foursOnly){
                                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    fours+=1;
                                                    }
                                                    // If there are more than 4 squares free in the grid, allow probability for bomb tile
                                                    else if (totalFree >= 4){
                                                    // If random number is between 85 and 92: generate a 4 in a random free square
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    // If random number is between 93 and 97: generate a lock tile in a random free square
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    // If random number is between 98 and 100: generate two bomb tiles in two random free squares
                                                    else if (randomNum >= 98){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                        // Loop to keep iterating until two bomb tiles are placed in individual open tiles
                                                        do {
                                                        randomAddition = (int)(Math.random()*totalFree);
                                                        } while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0);
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                    }
                                                    // If random number is between 85 and 92: generate a 2 in a random free square
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                    // If there are less than 4 squares, the probabilities for bomb tile switch to a 2 tile
                                                    else{
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                }
                                            }
                                            
                                            }
                                            else if (keyCode == LEFT){
                                            warning = "";
                                            int[][] tempGrid = shiftGrid(currentGrid, "left");
                                            int changes = 0;
                                            boolean trigger = true;
                                            
                                            // Loop to check for the number of changes in upcoming turn
                                            for (int row=0; row 0){
                                                currentMoves += 1;
                                                }
                                                
                                                // Array to store the coordinates of the free spots
                                                int[][] freeSpots = new int[grid*grid][2];
                                                int totalFree = 0;
                                                
                                                // Loop to iterate through every square and check the value
                                                for (int rows = 0; rows < grid; rows++){
                                                    for (int columns = 0; columns < grid; columns++){
                                                    // If the value is 0 in the square, the coordinate will be added to freeSpots array and increase the totalFree ticker
                                                    if (currentGrid[rows][columns] == 0){
                                                        freeSpots[totalFree][0] = rows;
                                                        freeSpots[totalFree][1] = columns;
                                                        totalFree += 1;
                                                    }
                                                    if (changes>0){
                                                        // Conditional to account for lock tiles, add a move to their timer
                                                        if (currentGrid[rows][columns]%2!=0){
                                                        // If 8 moves has passed, the lock tile will be set to a empty tile
                                                        if (currentGrid[rows][columns] == 17){
                                                            currentGrid[rows][columns] = 0;
                                                        }
                                                        else{
                                                            currentGrid[rows][columns]+=2;
                                                        }
                                                        }
                                                    }
                                                    }
                                                }
                                                
                                                // Generate a random index in the freeSpots array to generate a square
                                                int randomAddition = (int)(Math.random()*totalFree);
                                                // Generate a number for probabilities from 0 to 100
                                                int randomNum = (int)(Math.random()*101);
                                                
                                                /*
                                                Probabilities Table:
                                                2: 0-84 85%
                                                4: 85-92 8%
                                                Lock: 93-97 5%
                                                Bomb: 98-100 2%
                                                */
                                                
                                                if (totalFree != 0 && changes != 0){
                                                    // Check if doubles is activated, if 10 moves have passed deactivate double powerup
                                                    if (doubles == 10){
                                                    doubleMode = false;
                                                    }
                                                    // If double powerup is activated, add a move to the counter
                                                    if (doubleMode){
                                                    doubles+=1;
                                                    }
                                                    
                                                    // Check if fours only powerup is activated, if 10 moves have passed deactivate fours powerup
                                                    if (fours == 10){
                                                    foursOnly = false;
                                                    fours = 0;
                                                    }
                                                    // If fours only powerup is activated, add a move to the counter and generate a 4
                                                    if (foursOnly){
                                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    fours+=1;
                                                    }
                                                    // If there are more than 4 squares free in the grid, allow probability for bomb tile
                                                    else if (totalFree >= 4){
                                                    // If random number is between 85 and 92: generate a 4 in a random free square
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    // If random number is between 93 and 97: generate a lock tile in a random free square
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    // If random number is between 98 and 100: generate two bomb tiles in two random free squares
                                                    else if (randomNum >= 98){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                        // Loop to keep iterating until two bomb tiles are placed in individual open tiles
                                                        do {
                                                        randomAddition = (int)(Math.random()*totalFree);
                                                        } while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0);
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                    }
                                                    // If random number is between 85 and 92: generate a 2 in a random free square
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                    // If there are less than 4 squares, the probabilities for bomb tile switch to a 2 tile
                                                    else{
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                }
                                                }
                                            }
                                            else if (keyCode == RIGHT){
                                            warning = "";
                                            int[][] tempGrid = shiftGrid(currentGrid, "right");
                                            int changes = 0;
                                            boolean trigger = true;
                                            
                                            // Loop to check for the number of changes in upcoming turn
                                            for (int row=0; row 0){
                                                currentMoves += 1;
                                                }
                                                
                                                // Array to store the coordinates of the free spots
                                                int[][] freeSpots = new int[grid*grid][2];
                                                int totalFree = 0;
                                                
                                                // Loop to iterate through every square and check the value
                                                for (int rows = 0; rows < grid; rows++){
                                                    for (int columns = 0; columns < grid; columns++){
                                                    // If the value is 0 in the square, the coordinate will be added to freeSpots array and increase the totalFree ticker
                                                    if (currentGrid[rows][columns] == 0){
                                                        freeSpots[totalFree][0] = rows;
                                                        freeSpots[totalFree][1] = columns;
                                                        totalFree += 1;
                                                    }
                                                    if (changes>0){
                                                        // Conditional to account for lock tiles, add a move to their timer
                                                        if (currentGrid[rows][columns]%2!=0){
                                                        // If 8 moves has passed, the lock tile will be set to a empty tile
                                                        if (currentGrid[rows][columns] == 17){
                                                            currentGrid[rows][columns] = 0;
                                                        }
                                                        else{
                                                            currentGrid[rows][columns]+=2;
                                                        }
                                                        }
                                                    }
                                                    }
                                                }
                                                
                                                // Generate a random index in the freeSpots array to generate a square
                                                int randomAddition = (int)(Math.random()*totalFree);
                                                // Generate a number for probabilities from 0 to 100
                                                int randomNum = (int)(Math.random()*101);
                                                
                                                /*
                                                Probabilities Table:
                                                2: 0-84 85%
                                                4: 85-92 8%
                                                Lock: 93-97 5%
                                                Bomb: 98-100 2%
                                                */
                                                
                                                if (totalFree != 0 && changes != 0){
                                                    // Check if doubles is activated, if 10 moves have passed deactivate double powerup
                                                    if (doubles == 10){
                                                    doubleMode = false;
                                                    }
                                                    // If double powerup is activated, add a move to the counter
                                                    if (doubleMode){
                                                    doubles+=1;
                                                    }
                                                    
                                                    // Check if fours only powerup is activated, if 10 moves have passed deactivate fours powerup
                                                    if (fours == 10){
                                                    foursOnly = false;
                                                    fours = 0;
                                                    }
                                                    // If fours only powerup is activated, add a move to the counter and generate a 4
                                                    if (foursOnly){
                                                    currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    fours+=1;
                                                    }
                                                    // If there are more than 4 squares free in the grid, allow probability for bomb tile
                                                    else if (totalFree >= 4){
                                                    // If random number is between 85 and 92: generate a 4 in a random free square
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    // If random number is between 93 and 97: generate a lock tile in a random free square
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    // If random number is between 98 and 100: generate two bomb tiles in two random free squares
                                                    else if (randomNum >= 98){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                        // Loop to keep iterating until two bomb tiles are placed in individual open tiles
                                                        do {
                                                        randomAddition = (int)(Math.random()*totalFree);
                                                        } while (currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] != 0);
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 6;
                                                    }
                                                    // If random number is between 85 and 92: generate a 2 in a random free square
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                    // If there are less than 4 squares, the probabilities for bomb tile switch to a 2 tile
                                                    else{
                                                    if (randomNum >= 85 && randomNum <= 92){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 4;
                                                    }
                                                    else if (randomNum >= 93 && randomNum <= 97){
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 1;
                                                    }
                                                    else{
                                                        currentGrid[freeSpots[randomAddition][0]][freeSpots[randomAddition][1]] = 2;
                                                    }
                                                    }
                                                }
                                                }
                                            }
                                        }
                                        else if (currentStage == "finishedgame"){
                                            // Toggle the title page if the user presses space after game is over
                                            if (key == ' '){
                                            setupTitlePage();
                                            }
                                        }
                                        
                                        // Toggle different music tracks depending on the number which the user presses
                                        if (key == '1'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "basiclofi";
                                            minim = new Minim(this);
                                            player = minim.loadFile("music.mp3");
                                            player.loop();
                                        }
                                        else if (key == '2'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "baby";
                                            minim = new Minim(this);
                                            player = minim.loadFile("baby.mp3");
                                            player.loop();
                                        }
                                        else if (key == '3'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "espresso";
                                            minim = new Minim(this);
                                            player = minim.loadFile("espresso.mp3");
                                            player.loop();
                                        }
                                        else if (key == '4'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "party";
                                            minim = new Minim(this);
                                            player = minim.loadFile("party.mp3");
                                            player.loop();
                                        }
                                        else if (key == '5'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "wmyb";
                                            minim = new Minim(this);
                                            player = minim.loadFile("wmyb.mp3");
                                            player.loop();
                                        }
                                        else if (key == '6'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "shakeitoff";
                                            minim = new Minim(this);
                                            player = minim.loadFile("shakeitoff.mp3");
                                            player.loop();
                                        }
                                        else if (key == '7'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "wonderwall";
                                            minim = new Minim(this);
                                            player = minim.loadFile("wonderwall.mp3");
                                            player.loop();
                                        }
                                        else if (key == '8'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "carelesswhisper";
                                            minim = new Minim(this);
                                            player = minim.loadFile("carelesswhisper.mp3");
                                            player.loop();
                                        }
                                        else if (key == '9'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "apt";
                                            minim = new Minim(this);
                                            player = minim.loadFile("apt.mp3");
                                            player.loop();
                                        }
                                        else if (key == '0'){
                                            toggleMusic();
                                            musicStatus = "ON";
                                            currentMusic = "fein";
                                            minim = new Minim(this);
                                            player = minim.loadFile("fein.mp3");
                                            player.loop();
                                        }
                                        }

                                        void mouseClicked() {
                                        if (currentStage == "start") {
                                            //Check for Start Menu Buttons
                                            if (mouseX >= 150 && mouseX <= 150+width-300) {
                                            //Check for Music Toggle
                                            if (mouseY >= 400 && mouseY <= 500) {
                                                toggleMusic();
                                            }

                                            // Check for Toggle Map Settings Button
                                            else if (mouseY >= 520 && mouseY <= 620) {
                                                setupMapsPage();
                                            }
                                            
                                            // Check for Start Game Button
                                            else if (mouseY >= 670 && mouseY <= 770) {
                                                currentStage = "playinggame";

                                                // Reset the score count, the number of moves, and the grid
                                                currentScore = 0;
                                                currentMoves = 0;
                                                currentGrid = new int[grid][grid];
                                                for (int rows = 0; rows < grid; rows++){
                                                for (int columns = 0; columns < grid; columns++){
                                                    currentGrid[rows][columns] = 0;
                                                }
                                                }
                                                
                                                // Set a random square to 2 to start the game
                                                currentGrid[(int)(Math.random()*grid-1)][(int)(Math.random()*grid-1)] = 2;
                                                playGame();
                                            }
                                            }
                                        } 
                                        else if (currentStage == "selectingmaps") {
                                            // Check for Back Button
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupTitlePage();
                                            }
                                            }

                                            // Check for change theme clicks depending on current theme
                                            if (theme == "desert") {
                                            if (mouseX > width/2 - 110 && mouseX < (width/2 - 110) + 220) {
                                                if (mouseY > 170 && mouseY < 170 + 220) {
                                                theme = "desert";
                                                colors = desertColors;
                                                }
                                            }
                                            if (mouseX >= 200 && mouseX <= 200 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "forest";
                                                colors = forestColors;
                                                }
                                            }
                                            if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                                                if (mouseY >= 190 && mouseY < 190 + 170) {
                                                theme = "space";
                                                colors = spaceColors;
                                                }
                                            }
                                            } else if (theme == "forest") {
                                            if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                                                if (mouseY >= 170 && mouseY <= 170 + 220) {
                                                theme = "forest";
                                                colors = forestColors;
                                                }
                                            }
                                            if (mouseX >= 200 && mouseX <= 200 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "space";
                                                colors = spaceColors;
                                                }
                                            }
                                            if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "desert";
                                                colors = desertColors;
                                                }
                                            }
                                            } else if (theme == "space") {
                                            if (mouseX >= width/2 - 110 && mouseX <= (width/2 - 110) + 220) {
                                                if (mouseY >= 170 && mouseY <= 170 + 220) {
                                                theme = "space";
                                                colors = spaceColors;
                                                }
                                            }
                                            if (mouseX >= 200 && mouseX <= 200 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "desert";
                                                colors = desertColors;
                                                }
                                            }
                                            if (mouseX >= (width/2 - 110) + 240 && mouseX <= (width/2 - 110) + 240 + 170) {
                                                if (mouseY >= 190 && mouseY <= 190 + 170) {
                                                theme = "forest";
                                                colors = forestColors;
                                                }
                                            }
                                            }
                                            
                                            // Check for adjust grid size button click
                                            if (mouseX >= 150 && mouseX <= 150+width-300) {
                                            if (mouseY >= 520 && mouseY <= 620) {
                                                setupGridAdjust();
                                            }
                                            // Check for Start Game Button
                                            else if (mouseY >= 670 && mouseY <= 770) {
                                                currentStage = "playinggame";
                                                
                                                // Reset the score count, the number of moves, and the grid
                                                currentScore = 0;
                                                currentMoves = 0;
                                                currentGrid = new int[grid][grid];
                                                for (int rows = 0; rows < grid; rows++){
                                                    for (int columns = 0; columns < grid; columns++){
                                                    currentGrid[rows][columns] = 0;
                                                    }
                                                }
                                                
                                                // Set a random square to 2 to start the game
                                                currentGrid[(int)(Math.random()*grid)][(int)(Math.random()*grid)] = 2;
                                                playGame();
                                                }
                                            
                                            // Check for View Instructions Button
                                            else if  (mouseY >= 780 && mouseY <= 880){
                                                currentStage = "viewinstructions";
                                                viewInstructions(); 
                                            }
                                            
                                            // Check for View Previous Scores Button
                                            else if  (mouseY >= 890 && mouseY <= 990){
                                                currentStage = "viewingprevious";
                                                viewPrevious(); 
                                            }
                                            }
                                        }
                                        else if (currentStage == "viewingprevious"){
                                            // Check for back button in view previous scores page
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupMapsPage();
                                            }
                                            }
                                        }
                                        else if (currentStage == "adjustinggrid"){
                                            // Check for button to go back to the theme menu
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupMapsPage();
                                            }
                                            }
                                            rect(width/2+10, 850, 100, 100);
                                            rect(width/2-110, 850, 100, 100);
                                        
                                            // Check for arrow button clicks to adjust grid size
                                            if (mouseY >= 850 && mouseY <= 950){
                                            if (mouseX >= width/2+10 && mouseX <= width/2+110){
                                                if (grid > 4){
                                                grid-=1;
                                                }
                                            }
                                            else if (mouseX >= width/2-110 && mouseX <= width/2-10){
                                                if (grid < 10){
                                                grid+=1;
                                                }
                                            }
                                            }
                                        }
                                        else if (currentStage == "playinggame"){
                                            // Check for button to go back in the actual game screen
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupTitlePage();
                                            }
                                            }
                                            
                                            // Check if first powerup to combine all tiles is pressed
                                            if (mouseX >= 225 && mouseX <= 325){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                combineAllPowerup();
                                            }
                                            }
                                            
                                            // Check if second powerup to spawn only fours is pressed
                                            if (mouseX >= 335 && mouseX <= 435){
                                            if (mouseY >= 800 && mouseY <= 900){
                                            // Check if the user has enough score to toggle this powerup which costs 100 points per grid size
                                            if (currentScore>=100*grid){
                                                currentScore -= 100*grid;
                                                foursOnly = true;
                                                }
                                                else{
                                                warning = "You need " + (100*grid-currentScore) + " more score!";
                                                }
                                            }
                                            }
                                            
                                            // Check if third powerup to undo the last move is pressed
                                            if (mouseX >= 445 && mouseX <= 545){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                // Check if the user has enough score to toggle this powerup which costs 50 points per grid size
                                                if (currentScore>=50*grid){
                                                currentScore -= 50*grid;
                                                currentGrid = lastGrid;
                                                warning = "The last move has been undone";
                                                }
                                                else{
                                                warning = "You need " + (50*grid-currentScore) + " more score!";
                                                }
                                            }
                                            }
                                            
                                            // Check if the fourth powerup to break a random tile is pressed - this powerup costs only 25 points per grid size
                                            if (mouseX >= 555 && mouseX <= 655){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                randomTileBreak();
                                            }
                                            }
                                            
                                            // Check if the fifth powerup to double the next 10 collisions is pressed
                                            if (mouseX >= 665 && mouseX <= 765){
                                            if (mouseY >= 800 && mouseY <= 900){
                                                // Check if the user has enough score to toggle this powerup which costs 200 points per grid size
                                                if (currentScore>=200*grid){
                                                currentScore -= 200*grid;
                                                doubleMode = true;
                                                }
                                                else{
                                                warning = "You need " + (200*grid-currentScore) + " more score!";
                                                }
                                            }
                                            }
                                        }
                                        else if (currentStage == "viewinstructions"){
                                            // Check if the user clicks the back button
                                            if (mouseX >= 10 && mouseX <= 70) {
                                            if (mouseY >= 10 && mouseY <= 70) {
                                                setupTitlePage();
                                                setupMapsPage();
                                            }
                                            }
                                            
                                            //Check for Start Menu Buttons
                                            if (mouseX >= 150 && mouseX <= 150+width-300) {
                                            
                                            // Check for Start Game Button
                                            if (mouseY >= 670 && mouseY <= 770) {
                                                setupTitlePage();
                                                currentStage = "playinggame";
                                                
                                                // Reset the score count, the number of moves, and the grid
                                                currentScore = 0;
                                                currentMoves = 0;
                                                currentGrid = new int[grid][grid];
                                                for (int rows = 0; rows < grid; rows++){
                                                for (int columns = 0; columns < grid; columns++){
                                                    currentGrid[rows][columns] = 0;
                                                }
                                                }
                                                
                                                // Set a random square to 2 to start
                                                currentGrid[(int)(Math.random()*grid-1)][(int)(Math.random()*grid-1)] = 2;
                                                playGame();
                                            }
                                            }
                                        }
                                        }

                                        // Method for the powerup to break a random tile
                                        void randomTileBreak(){
                                        
                                        //Checking for the number of filled squares and adding the coordinates to the filledGrid array
                                        int filledSquare = 0;
                                        int[][] filledGrid = new int[grid*grid][2];
                                        
                                        
                                        // Iterating through each square in the array and updating the counter and array respectively
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            if (currentGrid[rows][columns] != 0 && currentGrid[rows][columns] != 2){
                                                filledGrid[filledSquare][0] = rows;
                                                filledGrid[filledSquare][1] = columns;
                                                filledSquare++;
                                            }
                                            }
                                        }
                                        
                                        // If there are any filled squares that are not 2s
                                        if (filledSquare > 0){
                                            // Make sure that the user can afford this powerup, else display a warning for such
                                            if (currentScore>=25*grid){
                                            // Deduct the cost of the powerup
                                            currentScore -= 25*grid;
                                            
                                            // Choose a random square from the filled grid and set that square equal to 0 meaning a free square
                                            int randomIndex = (int)(Math.random()*(filledSquare));
                                            int[] randomSquare = filledGrid[randomIndex];
                                            
                                            currentGrid[randomSquare[0]][randomSquare[1]] = 0;
                                            }
                                            else{
                                            warning = "You need " + 25*grid + " more score!";
                                            }
                                        }
                                        // If there are no filled squares that are not 2s, displays a warning
                                        else {
                                            warning = "You need more than 1 filled non-two tile!";
                                        }
                                        }

                                        // Method for the powerup to essentially combine all tiles into one tile
                                        void combineAllPowerup(){
                                        
                                        int filledSquare = 0;
                                        
                                        // Iterate through each square and check for filled squares
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            if (currentGrid[rows][columns] != 0 && currentGrid[rows][columns] != 2){
                                                filledSquare++;
                                            }
                                            }
                                        }
                                        
                                        // If there are more than one filled tile which is not a two, continue with the powerup logic, else display a warning
                                        if (filledSquare > 0){
                                            // The new square is calculated as the closest power of two to the currentScore divided by 2
                                            int newSquare = closestTwoPower(currentScore/2);
                                            
                                            // Divide the current score by 4 as a punishment
                                            currentScore /= 4;
                                            
                                            // Set the entire grid equal to empty squares
                                            currentGrid = new int[grid][grid];
                                            for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                                currentGrid[rows][columns] = 0;
                                            }
                                            }
                                                    
                                            // Choose a random square to house to new square
                                            currentGrid[(int)(Math.random()*grid)][(int)(Math.random()*grid)] = newSquare;
                                        }
                                        else {
                                            warning = "You need more than 1 filled non-two tile!";
                                        }
                                        }

                                        // Method used in the combineAllPowerup to find the closest power of two
                                        int closestTwoPower(int num){
                                        int counter = 1;
                                        
                                        // Future addition to the function to return a list of powers below the number
                                        //ArrayList powersOfTwo = new ArrayList<>();
                                        
                                        // While the number is higher than the counter, the number gets multiplied by 2
                                        while (num > counter){
                                            counter*=2;
                                            // Future addition with the list
                                            //powersOfTwo.add(counter);
                                        }
                                        
                                        // If the previous power of two is closer to the number, the counter is divided by 2
                                        if (abs(num-counter)>=abs(num-counter/2)){
                                            counter/=2;
                                        }
                                        
                                        return counter;
                                        }

                                        // Function to toggle the View Previous Scores Page
                                        void viewPrevious(){
                                        background(colors[0]);
                                        
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);
                                        
                                        try{
                                            // Declaring a new instance of the BufferedReader class to read the lines of scores.txt
                                            String path = sketchPath("scores.txt");
                                            BufferedReader sentenceReader = new BufferedReader(new java.io.FileReader(path));
                                            String currentLine = sentenceReader.readLine();
                                            
                                            // Initualizing an integer variable to hold the number of scores, as well as an strings ArrayList to hold the scores and other information
                                            int numberOfScores = 0;
                                            textSize(40);
                                            ArrayList scores = new ArrayList<>();
                                            
                                            // Iterates through the file until the last line and adds the scores to the ArrayList and the counter respectively
                                            while (currentLine != null) {
                                                scores.add(currentLine);
                                                numberOfScores++;
                                                currentLine = sentenceReader.readLine();
                                            }
                                            
                                            numberOfScores-=1;
                                            
                                            // Loop to display the scores line by line with a buffer of 40 pixels
                                            for (; numberOfScores>0; numberOfScores--){
                                            text(scores.get(numberOfScores), width/2, 100+(scores.size()-numberOfScores)*40);
                                            if (scores.size()-numberOfScores==20){
                                                break;
                                            }
                                            }
                                            sentenceReader.close();
                                        }
                                        catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                        }

                                        // Method to render the View Instructions Page
                                        void viewInstructions(){
                                        background(colors[0]);

                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);

                                        // Display main instructions
                                        textSize(70);
                                        textAlign(CENTER, CENTER);
                                        text("Use ← ↑ ↓ → keys to move tiles", width/2, 150);

                                        textSize(40);
                                        text("Combine Like Tiles to Create a Larger Tile", width/2, 250);

                                        textSize(60);
                                        text("Goal: Achieve the highest score!", width/2, 310);
                                        text("Example: 2 + 2 → 4, 4 + 4 → 8", width/2, 370);

                                        // Rendering the Start Game button
                                        fill(colors[3]);
                                        rect(150, 670, width - 300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("START GAME", (width) / 2, 720);

                                        // Power-Up Button Layout
                                        // Lightning Power-Up Button
                                        fill(colors[1]);
                                        rect(225, 800, 100, 100, 10);
                                        image(lightning, 233, 810);
                                        
                                        // 444 Power-Up Button
                                        fill(colors[1]);
                                        rect(335, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("444", 385, 850);
                                        
                                        // Undo Power-Up Button
                                        fill(colors[1]);
                                        rect(445, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(undo, 460, 815);
                                        
                                        // Hammer Power-Up Button
                                        fill(colors[1]);
                                        rect(555, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(hammer, 570, 815);
                                        
                                        // 2x Power-Up Button
                                        fill(colors[1]);
                                        rect(665, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("2x", 715, 850);

                                        // Power-Up Descriptions (Make sure they fit between height 420 and 670)
                                        textSize(20);  // Smaller font size
                                        fill(0);
                                        textAlign(LEFT, TOP);

                                        // Lightning Power-Up Description
                                        text("Lightning: Clears the board, leaves 1 tile (closest power of 2 to score/2), costs current score/4", 100, 450);

                                        // 444 Power-Up Description
                                        text("444: Spawns 10 '4' tiles in a row, costs 100 per grid size", 100, 480);

                                        // Undo Power-Up Description
                                        text("Undo: Reverts last move, costs 50 per grid size", 100, 510);

                                        // Hammer Power-Up Description
                                        text("Hammer: Breaks a random tile, costs 25 per grid size", 100, 540);

                                        // 2x Power-Up Description
                                        text("2x: Doubles collisions for 10 moves, costs 200 per grid size", 100, 570);
                                        
                                        // Lock Description
                                        text("Locked blocks cannot be broken and disappear after 8 moves", 100, 610);
                                        
                                        // Exploding Blocks Description
                                        text("Exploding blocks do not disappear unless broken in which case, they will destroy the blocks around them", 100, 640);
                                        }

                                        // Method to display the End Screen after the user loses the current game
                                        void setupFinishedGamePage(){
                                        background(colors[0]);
                                            
                                        fill(0);
                                        textSize(60);
                                        
                                        text("Game Over!", width/2, 50);
                                        // Displaying the number of moves
                                        text("Number of Moves: " + currentMoves, width/2, 110);
                                        
                                        // Displaying the score of the user
                                        text("Total Score: " + currentScore, width/2, 170);
                                        
                                        text("Final Grid", width/2, 270);
                                        
                                        // Displaying the Grid
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){

                                            // Draw a square which is the total width divided by the grid size and total height divided by the grid size
                                            fill(colors[((powerOfTwo(currentGrid[rows][columns])%colors.length))]);
                                            rect(225+rows*(525/grid+4), 320+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                            
                                            // If the square is a 6, it is a bomb square, in which case the bomb image will be rendered
                                            if (currentGrid[rows][columns] == 6){
                                                bomb.resize((int)((500/grid)),(int)((500/grid)));
                                                image(bomb, (225+rows*(525/grid+4)), (320+columns*(525/grid+4)));
                                            }
                                            // Render the text number of the square if the square is not a 0
                                            else if (currentGrid[rows][columns]%2 == 0){
                                                fill(0);
                                                textSize(160/grid);
                                                text(currentGrid[rows][columns], (225+rows*(525/grid+4)+(530/grid-4)/2), (320+columns*(525/grid+4)+(530/grid-4)/2));
                                            }
                                            // If the square is not divisible by 2, it is a lock square, in which case the lock image will be rendered
                                            else {
                                                lock.resize((int)((500/grid)),(int)((500/grid)));
                                                image(lock, (225+rows*(525/grid+4)), (320+columns*(525/grid+4)));
                                            }
                                            }
                                        }
                                        try {
                                            // Write the score to the scores.txt file for future reference where the current score, the number of moves, and the grid size are mentioned.
                                            String path = sketchPath("scores.txt");
                                            PrintWriter sentenceWriter = new PrintWriter(new java.io.FileWriter(path, true));
                                            sentenceWriter.println("Score: " + currentScore + " in " + currentMoves + " moves of grid size " + grid + "x" + grid);
                                            sentenceWriter.close(); 
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                        
                                        // Display instructions for the user to move on to the next stage
                                        text("Press SPACE to Continue", width/2, height-100);
                                            
                                        }

                                        // Method to check the number of possible collisions in a grid
                                        int checkPossibleCollisions(int[][] currentGrid){
                                        // Initialize variable for possible collisionss
                                        int possibleCollisions = 0;
                                        int[][] newGrid = currentGrid;
                                        
                                        // Check for left swipe collisions
                                        for (int row=1; row0; row--){
                                            for (int column=0; column0; column--){
                                            if (newGrid[row][column]==newGrid[row][column-1] && newGrid[row][column]!=0){
                                                possibleCollisions++;
                                            }
                                            }
                                        }
                                        
                                        return possibleCollisions;
                                        }

                                        // Method to combine squares before the grid is shifted
                                        int[][] checkCollisions(int[][] currentGrid, String direction){
                                        int[][] newGrid = currentGrid;
                                        
                                        switch (direction) {
                                            case "left":
                                            // Iterates through every square in the grid
                                            for (int row=1; row0; row--){
                                                for (int column=0; column0; column--){
                                                // Checks if the square above is the same as the current square
                                                if (newGrid[row][column]==newGrid[row][column-1] && newGrid[row][column]!=0){
                                                    // If the double powerup is on, the value of the new square is doubled
                                                    if (doubleMode){
                                                    newGrid[row][column] = (newGrid[row][column]+newGrid[row][column-1])*2;
                                                    newGrid[row][column-1] = 0;
                                                    currentScore+=(newGrid[row][column]+newGrid[row][column-1]*2);
                                                    }
                                                    else{ 
                                                    newGrid[row][column] = newGrid[row][column]+newGrid[row][column-1];
                                                    newGrid[row][column-1] = 0;
                                                    currentScore+=newGrid[row][column]+newGrid[row][column-1];
                                                    }
                                                }
                                                }
                                            }
                                            break;
                                        }

                                        // Checking for Bomb Tile
                                        // Iterate through every tile
                                        for (int row=0; row0){
                                                    // Sets the square directly above to blank
                                                    newGrid[row-1][column] = 0;
                                                    
                                                    // Checks for column to the left
                                                    if (column>0){
                                                    // Sets the square in the top left to blank
                                                    newGrid[row-1][column-1] = 0;
                                                    }
                                                    
                                                    // Checks for column to the right
                                                    if (column0){
                                                    // Sets the square at the bottom left to blank
                                                    newGrid[row+1][column-1] = 0;
                                                    }
                                                    
                                                    // Checks for column to the right
                                                    if (column0){
                                                    // Sets the square directly to the left to blank
                                                    newGrid[row][column-1] = 0;
                                                }
                                                
                                                // Checks for the column to the right
                                                if (column0; x--){
                                                filled[filledCount+x-1] = 0;
                                                }
                                                newGrid[i] = filled;
                                            }
                                            break;
                                            
                                            case "down":
                                            for (int i = 0; i < grid; i++) {
                                                // Initializes an empty array to store the coordinates of the filled tiles
                                                int[] filled = new int[grid];
                                                int filledCount = 0;
                                            
                                                // Loop to iterate through each square in the current column and add filled squares to the array
                                                for (int x = grid - 1; x >= 0; x--) {
                                                if (currentGrid[i][x] != 0) {
                                                    filled[filledCount] = currentGrid[i][x];
                                                    filledCount++;
                                                }
                                                }
                                            
                                                // Due to the direction of down, the filled squares fill up at the bottom
                                                for (int x = 0; x < filledCount; x++) {
                                                newGrid[i][grid - 1 - x] = filled[x];
                                                }

                                                // Due to the direction of down, the empty spaces fill up from the top
                                                for (int x = 0; x < grid - filledCount; x++) {
                                                newGrid[i][x] = 0;
                                                }
                                            }
                                            break;
                                            
                                            case "left":
                                            for (int i = 0; i < grid; i++) {
                                                // Initializes an empty array to store the coordinates of the filled tiles
                                                int[] filled = new int[grid];
                                                int filledCount = 0;
                                        
                                                // Loop to iterate through each square in the current row and add filled squares to the array
                                                for (int x = 0; x < grid; x++) {
                                                if (currentGrid[x][i] != 0) {
                                                    filled[filledCount] = currentGrid[x][i];
                                                    filledCount++;
                                                }
                                                }
                                        
                                                
                                                int y = grid - 1;
                                                // Iterate through each row and set the right most squares to the number of blank squares
                                                for (int x = grid-filledCount - 1; x >= 0; x--) {
                                                newGrid[y][i] = 0;
                                                y--;
                                                }
                                                
                                                // Iterate through each row and set the left most squares to the filled squares
                                                while (y >= 0) {
                                                newGrid[y][i] = filled[y];
                                                y--;
                                                }
                                            }
                                            break;
                                            
                                            case "right":
                                            for (int i = 0; i < grid; i++) {
                                                // Initializes an empty array to store the coordinates of the filled tiles
                                                int[] filled = new int[grid];
                                                int filledCount = 0;
                                        
                                                // Loop to iterate through each square in the current row and add filled squares to the array
                                                for (int x = 0; x < grid; x++) {
                                                if (currentGrid[x][i] != 0) {
                                                    filled[filledCount] = currentGrid[x][i];
                                                    filledCount++;
                                                }
                                                }
                                        
                                                int y = grid - 1;
                                                // Iterate through each row and set the left most squares to the number of blank squares
                                                for (int x = filledCount - 1; x >= 0; x--) {
                                                newGrid[y][i] = filled[x];
                                                y--;
                                                }
                                        
                                                // Iterate through each row and set the right most squares to the filled squares
                                                while (y >= 0) {
                                                newGrid[y][i] = 0;
                                                y--;
                                                }
                                            }
                                            break;
                                        }
                                        
                                        return checkCollisions(newGrid, direction);
                                        }

                                        // Method to find how many times two has to be multipled to reach a number
                                        int powerOfTwo(int n) {
                                        // Initialize the variable to keep track of how many times the number has been divided
                                        int power = 0;
                                        
                                        // While the number is greater than 2 to the power of 0, the number keeps getting divided by 2
                                        while (n > 1) {
                                            n /= 2;
                                            power++;
                                        }
                                        return power;
                                        }

                                        // Method for the actual game screen
                                        void playGame(){
                                        currentStage = "playinggame";
                                        
                                        background(colors[0]);
                                        
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);
                                        
                                        textSize(30);
                                        // Displaying the Current Song
                                        if (currentMusic == "basiclofi"){
                                            text("Currently Playing: Lofi (Worst Choice)", width/2, 50);
                                        }
                                        else if (currentMusic == "baby"){
                                            text("Currently Playing: Baby - Justin Bieber, Ludacris", width/2, 50);
                                        }
                                        else if (currentMusic == "espresso"){
                                            text("Currently Playing: Espresso - Sabrina Carpenter", width/2, 50);
                                        }
                                        else if (currentMusic == "party"){
                                            text("Currently Playing: Party in the USA - Miley Cyrus", width/2, 50);
                                        }
                                        else if (currentMusic == "wmyb"){
                                            text("Currently Playing: What Makes You Beautiful - One Direction", width/2, 50);
                                        }
                                        else if (currentMusic == "shakeitoff"){
                                            text("Currently Playing: Shake It Off - Taylor Swift", width/2, 50);
                                        }
                                        else if (currentMusic == "wonderwall"){
                                            text("Currently Playing: Wonderwall - Oasis (Developer's Pick)", width/2, 50);
                                        }
                                        else if (currentMusic == "carelesswhisper"){
                                            text("Currently Playing: Careless Whisper - George Michael", width/2, 50);
                                        }
                                        else if (currentMusic == "apt"){
                                            text("Currently Playing: A.P.T. - Bruno Mars & Rose", width/2, 50);
                                        }
                                        else if (currentMusic == "fein"){
                                            text("Currently Playing: FEIN - Travis Scott", width/2, 50);
                                        }
                                        
                                        textSize(60);
                                        // Displaying the number of moves
                                        text("Number of Moves: " + currentMoves, width/2, 100);
                                        
                                        // Displaying the score of the user
                                        text("Total Score: " + currentScore, width/2, 160);
                                        
                                        // Displaying the Grid
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            fill(colors[4]);
                                            rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                            
                                            if (currentGrid[rows][columns] != 0){
                                                fill(colors[((powerOfTwo(currentGrid[rows][columns])%colors.length))]);
                                                rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                                
                                                // If the current square is a bomb, render bomb image
                                                if (currentGrid[rows][columns] == 6){
                                                bomb.resize((int)((500/grid)),(int)((500/grid)));
                                                image(bomb, (225+rows*(525/grid+4)), (225+columns*(525/grid+4)));
                                                }
                                                // Display the number as text if it is a number block
                                                else if (currentGrid[rows][columns]%2 == 0){
                                                fill(0);
                                                textSize(160/grid);
                                                text(currentGrid[rows][columns], (225+rows*(525/grid+4)+(530/grid-4)/2), (225+columns*(525/grid+4)+(530/grid-4)/2));
                                                }
                                                // If the current square is a lock, render lock image
                                                else {
                                                lock.resize((int)((500/grid)),(int)((500/grid)));
                                                image(lock, (225+rows*(525/grid+4)), (225+columns*(525/grid+4)));
                                                }
                                            }
                                            }
                                        }
                                        
                                        // Display Powerup Squares
                                        // Display combine all powerup
                                        fill(colors[1]);
                                        rect(225, 800, 100, 100, 10);
                                        image(lightning, 233, 810);
                                        
                                        // Display only spawn 4s powerup
                                        fill(colors[1]);
                                        rect(335, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("444", 385, 850);
                                        
                                        // Display undo last move powerup
                                        fill(colors[1]);
                                        rect(445, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(undo, 460, 815);
                                        
                                        // Display destroy random block powerup
                                        fill(colors[1]);
                                        rect(555, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        image(hammer, 570, 815);
                                        
                                        // Display 2x combine powerup
                                        fill(colors[1]);
                                        rect(665, 800, 100, 100, 10);
                                        fill(0);
                                        textSize(40);
                                        text("2x", 715, 850);
                                        
                                        if (foursOnly){
                                            warning = "You have " + (10-fours) + " 4s left in a row!";
                                        }
                                        if (doubleMode){
                                            warning = "You have " + (10-doubles) + " more doubled moves left!";
                                        }
                                        
                                        // Display any warnings left behind
                                        text(warning, width/2, 950);
                                        }

                                        // Method to setup adjust grid size page
                                        void setupGridAdjust(){
                                        background(colors[0]);
                                        currentStage = "adjustinggrid";
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);
                                        
                                        text("Adjust Grid Size", (width)/2, 70);
                                        
                                        // Showing Main Grid 
                                        fill(colors[1]);
                                        rect(200, 200, 600, 600, 50);
                                        
                                        currentGrid = new int[grid][grid];
                                        
                                        fill(colors[4]);
                                        
                                        // Render grid using dynamic height and width using calculations
                                        for (int rows = 0; rows < grid; rows++){
                                            for (int columns = 0; columns < grid; columns++){
                                            rect(225+rows*(525/grid+4), 225+columns*(525/grid+4), (530/grid-4), (530/grid-4), 10);
                                            currentGrid[rows][columns] = 0;
                                            }
                                        }
                                        
                                        rect(width/2+10, 850, 100, 100);
                                        rect(width/2-110, 850, 100, 100);
                                        
                                        // Draw the Up arrow inside the left rectangle
                                        fill(0); // Set color to black
                                        beginShape();
                                        vertex(width/2-110+50, 850+25);  
                                        vertex(width/2-110+10, 850+75); 
                                        vertex(width/2-110+90, 850+75);  
                                        endShape(CLOSE);
                                        
                                        // Draw the Down arrow inside the right rectangle
                                        beginShape();
                                        vertex(width/2+10+50, 850+75);  
                                        vertex(width/2+10+10, 850+25);  
                                        vertex(width/2+10+90, 850+25);  
                                        endShape(CLOSE);

                                        }

                                        // Method to setup the select maps page
                                        void setupMapsPage() {
                                        background(colors[0]);
                                        currentStage = "selectingmaps";
                                        // Draw button background (rectangle)
                                        fill(200);
                                        rect(10, 10, 60, 60, 10);  // rounded corners

                                        // Draw left-pointing arrow
                                        fill(0);
                                        beginShape();
                                        vertex(20, 40);
                                        vertex(60, 20);
                                        vertex(60, 60);
                                        endShape(CLOSE);

                                        textSize(80);
                                        text("Select Your Map", (width)/2, 70);

                                        // Display the maps slider for size based on the current theme selected
                                        if (theme == "desert") {
                                            fill(colors[4]);
                                            rect(width/2-110, 170, 220, 220);
                                            textSize(60);
                                            fill(0);
                                            text("Desert", (width)/2, 270);

                                            fill(colors[1]);
                                            rect(200, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Forest", 285, 270);

                                            fill(colors[1]);
                                            rect((width/2-110)+240, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Space", (width/2-110)+240+85, 270);
                                        } else if (theme == "forest") {
                                            fill(colors[4]);
                                            rect(width/2-110, 170, 220, 220);
                                            textSize(60);
                                            fill(0);
                                            text("Forest", (width)/2, 270);

                                            fill(colors[1]);
                                            rect(200, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Space", 285, 270);

                                            fill(colors[1]);
                                            rect((width/2-110)+240, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Desert", (width/2-110)+240+85, 270);
                                        } else if (theme == "space") {
                                            fill(colors[4]);
                                            rect(width/2-110, 170, 220, 220);
                                            textSize(60);
                                            fill(0);
                                            text("Space", (width)/2, 270);

                                            fill(colors[1]);
                                            rect(200, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Desert", 285, 270);

                                            fill(colors[1]);
                                            rect((width/2-110)+240, 190, 170, 170);
                                            textSize(40);
                                            fill(0);
                                            text("Forest", (width/2-110)+240+85, 270);
                                        }
                                        
                                        // Rendering the Change Map Dimensions button
                                        fill(colors[3]);
                                        rect(150, 520, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("Adjust Grid Size", (width)/2, 570);

                                        // Rendering the Start Game button
                                        fill(colors[3]);
                                        rect(150, 670, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("START GAME", (width)/2, 720);
                                        
                                        // Rendering the View Instructions button
                                        fill(colors[3]);
                                        rect(150, 780, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("View Instructions", (width)/2, 830);
                                        
                                        // Rendering the View Previous Scores button
                                        fill(colors[3]);
                                        rect(150, 890, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("View Previous Scores", (width)/2, 940);
                                        }

                                        // Method to toggle music on and off
                                        void toggleMusic() {
                                        // Method to toggle music depending on current status
                                        if (musicStatus == "ON") {
                                            musicStatus = "OFF";
                                            player.close();
                                            minim.stop();
                                        } else if (musicStatus == "OFF") {
                                            if (currentMusic == "basiclofi"){
                                            musicStatus = "ON";
                                            minim = new Minim(this);
                                            player = minim.loadFile("music.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "baby"){
                                            musicStatus = "ON";
                                            currentMusic = "baby";
                                            minim = new Minim(this);
                                            player = minim.loadFile("baby.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "espresso"){
                                            musicStatus = "ON";
                                            currentMusic = "espresso";
                                            minim = new Minim(this);
                                            player = minim.loadFile("espresso.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "party"){
                                            musicStatus = "ON";
                                            currentMusic = "party";
                                            minim = new Minim(this);
                                            player = minim.loadFile("party");
                                            player.loop();
                                            }
                                            else if (currentMusic == "wmyb"){
                                            musicStatus = "ON";
                                            currentMusic = "wmyb";
                                            minim = new Minim(this);
                                            player = minim.loadFile("wmyb.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "shakeitoff"){
                                            musicStatus = "ON";
                                            currentMusic = "shakeitoff";
                                            minim = new Minim(this);
                                            player = minim.loadFile("shakeitoff.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "wonderwall"){
                                            musicStatus = "ON";
                                            currentMusic = "wonderwall";
                                            minim = new Minim(this);
                                            player = minim.loadFile("wonderwall.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "carelesswhisper"){
                                            musicStatus = "ON";
                                            currentMusic = "carelesswhisper";
                                            minim = new Minim(this);
                                            player = minim.loadFile("carelesswhisper.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "apt"){
                                            musicStatus = "ON";
                                            currentMusic = "apt";
                                            minim = new Minim(this);
                                            player = minim.loadFile("apt.mp3");
                                            player.loop();
                                            }
                                            else if (currentMusic == "fein"){
                                            musicStatus = "ON";
                                            currentMusic = "fein";
                                            minim = new Minim(this);
                                            player = minim.loadFile("fein.mp3");
                                            player.loop();
                                            }
                                        }
                                        }

                                        // Method to setup the title page for the user
                                        void setupTitlePage() {
                                        // Set up basic title page
                                        background(colors[0]);
                                        fill(colors[0]);
                                        rect(0, 0, 1000, 1000);

                                        textSize(150);  
                                        
                                        fill(0);
                                        textAlign(CENTER, CENTER);
                                        text("2048:", width/2, 100);
                                        textSize(160);
                                        text("POWER", width/2, 250);
                                        currentStage = "start";

                                        // Rendering the Toggle Map Settings button
                                        fill(colors[3]);
                                        rect(150, 520, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("Toggle Map Settings", (width)/2, 570);

                                        // Rendering the Start Game button
                                        fill(colors[3]);
                                        rect(150, 670, width-300, 100);
                                        textSize(60);
                                        fill(0);
                                        text("START GAME", (width)/2, 720);

                                        // Printed instructions for menu selection
                                        textSize(50);
                                        fill(0);
                                        textAlign(CENTER, CENTER);
                                        text("Press M to mute/unmute", width/2, 850);
                                        textSize(50);
                                        text("Use mouse to select menu", width/2, 900);
                                        textSize(50);
                                        text("Press T or use numbers to toggle tracks", width/2, 950);
                                        }
Download Code File