Blog Improvements

While the blog styling is still clearly a work in progress, as I’ve been learning Java, I haven’t forgotten to decorate my blog.

Bullet Points

Check these out.

  • There are little SpongeBob cloud bullet points.
  • They vary in color, which is cool.
  • Try reloading the page…

Woah…they’re all different.

Pair Styling Discussion

I used the experience I gained with this more randomized bullet system to help Jishnu change his bullet points. You should see them. They’re really cool.

He also changed the mouse cursor for his whole site, which, whenever I find the mouse icon I’m looking for, I’m planning on doing the same. If possible, I would love opening the possibility of having multiple cursor options for the user.

Lab Notebook Organization

If you click on the Lab Notebook tab on the header, you’ll see that I’ve used the CSA table settings for my own purposes. I’m planning on going further than this by styling the table. I’m still trying to figure out where each week is starting and ending.

Weekly Plans

I summarized what I did on Weeks 0 and 1 and put them on the schedule page for consistency’s sake, as well as an active planning blog for this week.

Java Hello

Below is my work on the hacks from the Java Hello blog.

Hacks

  • Explain Anatomy of a Class in comments of a program (Diagram key parts of the class).
  • Comment in code where there is a definition of a Class and an instance of a Class (ie object)
  • Comment in code where there are constructors and highlight the signature difference in the signature
  • Call an object method with parameter (ie setters).

These can all be seen in the provided Person object.

Additional requirements

  1. Go through code progression of understanding Class usage and generating an Instance of a Class (Object). a. Build a purposeful dynamic Class, using an Object, generate multiple instances: - Person: Name and Age - Dessert: Type and Cost - Location: City, State, Zip b. Create a static void main tester method to generate objects of the class. c. In tester method, show how setters/mutators can be used to make the data in the Object dynamically change

I did this by having users initially created in a Person database that can be modified.

  1. Go through progression of understanding a Static Class. Build a purposeful static Class, no Objects.
    • Calculate common operations on a Date field, age since date, older of two dates, number of seconds since date
    • Calculate stats functions on an array of values: mean, median, mode.

I did this a ton with my updated console games hacks, but I decided to also make an object that

Dynamic Person Class

I created a dynamic class for Person. A database of three of them can be edited using the main method provided.

// person Class
public class Person {
    // creating private object variables
    private String name;
    private int age;
    private String koubutsu;
    // private Object location;
    // THIS IS THE CONSTRUCTOR
    public Person(String name, int age, String koubutsu) {
        this.name = name;
        this.age = age;
        this.koubutsu = koubutsu;
    }
    // SETTERS AND GETTERS
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getKoubutsu() {
        return koubutsu;
    }
    public void setKoubutsu(String koubutsu) {
        this.koubutsu = koubutsu;
    }
    public static Person[] makePeople() {
        // create a new people in an array
        Person[] people = new Person[3];
        people[0] = new Person("John", 30, "Ice Cream");
        people[1] = new Person("Timothee", 25, "Chocolate");
        people[2] = new Person("Lebron", 38, "Crème brûlée");
        // return the people array
        return people;
    }
    // main method
    public static void main(String[] args) {
        // creating the people database
        Person[] database = makePeople();
        // making the system active baby woooooooo
        boolean active = true;
        // introduction text
        System.out.println("Welcome to the Rich People Luxury Paradise database!\nThere are already three people signed up for attendance this year.\nThis list is now set in stone. (Unless...)");
        Scanner input = new Scanner(System.in);  // create a Scanner object
        // to be repeated while active
        while (active) {
            System.out.println("\t1. See the list\n\t2. HACK THE DATABASE (CHOOSE THIS ONE)\n\t3. Hear a short description of Rich People Luxury Paradise\n\t4. Exit");
            String selection = input.nextLine();  // read user input
            if ("1".equals(selection)) {
                System.out.println("");
                for (int i = 0; i < database.length; i++) {
                    System.out.println("Attendee " + Integer.toString(i + 1) + ":");
                    System.out.println("\tName: " + database[i].getName());
                    System.out.println("\tAge: " + database[i].getAge());
                    System.out.println("\tFavorite Dessert: " + database[i].getKoubutsu());
                }
                System.out.println("");
            } else if ("2".equals(selection)) {
                System.out.println("\nWhich user would you like to hack? (Enter their attendee number as an integer.)");
                for (int i = 0; i < database.length; i++) {
                    System.out.println("\tAttendee " + Integer.toString(i + 1) + ": " + database[i].getName());
                }
                String hackee = input.nextLine(); // read user input again
                int dataIndex = Integer.parseInt(hackee) - 1; // turn the string into an integer
                Person selectedPerson = database[dataIndex];
                // options setup
                System.out.println("What would you like to do with this user?\n\t1. Change Name\n\t2. Change Age\n\t3. Change Favorite Desert\n\t4. Replace User");
                String hackSelection = input.nextLine(); // hack selection from input line
                if ("1".equals(hackSelection)) {
                    System.out.println("What would you like the new name to be?");
                    String nameSelection = input.nextLine();
                    selectedPerson.setName(nameSelection); // USING SETNAME
                    System.out.println("Excellent choice, hacker. This person's name is now " + nameSelection + ".");
                } else if ("2".equals(hackSelection)) {
                    System.out.println("What would you like the new age to be? (Input an integer, please.)");
                    String ageSelection = input.nextLine();
                    int newAge = Integer.parseInt(ageSelection);
                    selectedPerson.setAge(newAge); // USING SETAGE
                    System.out.println("Excellent choice, hacker. This person's age is now " + ageSelection + ".");
                } else if ("3".equals(hackSelection)) {
                    System.out.println("What would you like the new favorite dessert to be?");
                    String koubutsuSelection = input.nextLine();
                    selectedPerson.setKoubutsu(koubutsuSelection); // USING SETKOUBUTSU
                    System.out.println("Excellent choice, hacker. This person's favorite dessert is now " + koubutsuSelection + ".");
                } else if ("4".equals(hackSelection)) {
                    // combination of all other selections
                    System.out.println("What would you like the new name to be?");
                    String nameSelection = input.nextLine();
                    selectedPerson.setName(nameSelection); // USING SETNAME
                    System.out.println("What would you like the new age to be? (Input an integer, please.)");
                    String ageSelection = input.nextLine();
                    int newAge = Integer.parseInt(ageSelection);
                    selectedPerson.setAge(newAge); // USING SETAGE
                    System.out.println("What would you like the new favorite dessert to be?");
                    String koubutsuSelection = input.nextLine();
                    selectedPerson.setKoubutsu(koubutsuSelection); // USING SETKOUBUTSU
                    System.out.println("Excellent work, hacker. A new person can now attend the Rich People Luxury Paradise.");
                } else {
                    System.out.println("Invalid input. The system has crashed. Great, NOW look what you've done...\nERROR CODE 80085: IDIOT USING DATABASE");
                    input.close();
                    return;
                }
            } else if ("3".equals(selection)) {
                //describe the paradise yo
                System.out.println("\nThe Rich People Luxury Paradise is a luxury resort that can only be attended by three (incredibly) rich people per year.");
                System.out.println("Once the payment has been processed, the rich person is added to the database. This includes first name, age and favorite dessert.");
                System.out.println("The only way for this to change would be for someone to input someone else's information into the database by hacking...but that'll never happen!\n");
            } else if ("4".equals(selection)) {
                System.out.println("\nThank you for using the Rich People Luxury Paradise database!");
                input.close();
                return;
            } else {
                System.out.println("Invalid input. The system has crashed. Great, NOW look what you've done...\n\u001B[31mERROR CODE 80085: IDIOT USING DATABASE");
                input.close();
                return;
            }
        }
    }
}

Person.main(null)

Stat Function Calculator

This is a Static Object that can be used to find the mean, median, and mode of an array of data.

import java.util.*;

public class StatCalculator {
    // mean calculator
    public static double calculateMean(double[] numbers) {
        // calculate number sum
        double sum = 0.0;
        for (double num : numbers) { // this is a for each loop that i learned about
            sum += num;
        }

        // Calculate the mean
        if (numbers.length > 0) {
            return sum / numbers.length;
        } else {
            // if the list is empty
            return 0.0;
        }
    }
    // median calculator
    public static double calculateMedian(double[] numbers) {
        // uses the Arrays util
        Arrays.sort(numbers);
        // finding length and using it to find the middle value(s)
        int n = numbers.length;
        if (n % 2 == 0) {
            // even number of elements means middle two values need to be averaged
            int middle1 = n / 2;
            int middle2 = middle1 - 1;
            return (numbers[middle1] + numbers[middle2]) / 2.0;
        } else {
            // odd number of elements means the midpoint of the dataset
            int middle = n / 2;
            return numbers[middle];
        }
    }
    // mode calculator
    public static List<Double> calculateMode(double[] numbers) {
        Map<Double, Integer> frequencyMap = new HashMap<>(); //using hashmaps babyyyyyyy
        // iterating through numbers and adding to the HM value of each double key
        for (double num : numbers) { // another for each loop
            frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); //getting the original value and adding 1
        }
        // find the number(s) with the most frequency
        int maxFrequency = Collections.max(frequencyMap.values());
        List<Double> modes = new ArrayList<>();
        // iterating through the frequency map entries and comparing to the maxiumum frequency
        // this determines which of the potentially multiple keys is a/the mode
        for (Map.Entry<Double, Integer> entry : frequencyMap.entrySet()) {
            if (entry.getValue() == maxFrequency) {
                modes.add(entry.getKey());
            }
        }
        return modes; //all done
    }

    public static void main(String[] args) {
        // create user input scanner
        Scanner statInput = new Scanner(System.in);
        // create new ArrayList object for user to fill
        ArrayList<Double> statList = new ArrayList<>();
        boolean dataAdding = true;
        System.out.println("Please enter some numbers to use for data proofs.");
        while (dataAdding) {
            System.out.println("What number should be added? It can be any real number, including decimals.");
            String newNumber = statInput.nextLine();
            statList.add(Double.parseDouble(newNumber));
            System.out.println("Continue adding data? (Enter y or n.)");
            String continueResponse = statInput.nextLine();
            if ("n".equals(continueResponse)) {dataAdding = false;}
        }
        // close scanner
        statInput.close();
        // converting to double[]
        double[] doubleArray = new double[statList.size()];
        for (int i = 0; i < statList.size(); i++) {
            doubleArray[i] = statList.get(i);
        }
        System.out.println("Running stats methods now...");
        System.out.println("\tMean: " + Double.toString(calculateMean(doubleArray)));
        System.out.println("\tMedian: " + Double.toString(calculateMedian(doubleArray)));
        String modesText = "";
        for (double num : calculateMode(doubleArray)) {
            modesText = modesText + Double.toString(num) + " ";
        }
        System.out.println("\tMode(s): " + modesText);
    }
}

StatCalculator.main(null);

Java Console Games

Hacks

To start the year, I want you to consider a simple Java console game or improve on the games listed.

  • Make RPS, Tic-Tack-Toe, and Higher Lower into different objects. Answer why you think this is important?

Making them different objects is important for a bunch of reasons, including ease of testing, modularity, encapsulation (and private class variables that are relevant to the given game), and the scalability of this games console.

  • Simplify logic, particularly T-T-T. What could you do to make this more simple? Java has HashMap (like Python Dictionary), Arrays (fixed size), ArraLists (Dynamic Size).
  • Run the menu using recursion versus while loop.

For my hacks, I improved all of these games’ functionality and made them their own separate objects. I then made a separate object that would run each of the games when selected. I also did the recursion thing.

Rock Paper Scissors

I optimized the win-lose-tie system with a single array in a separate rpsWinCheck function and created an option to play again using a while loop.

import java.util.Random;

public class RockPaperScissors {
    // win check method; returns "win", "lose" or "tie"
    private static String rpsWinCheck(int playerChoice, int computerChoice) {
        // array representing win conditions
        String[][] outcomeArray = {
            {"tie", "lose", "win"},
            {"win", "tie", "lose"},
            {"lose", "win", "tie"}
        };
        // selecting outcome
        String outcome = outcomeArray[playerChoice][computerChoice];
        // return the outcome as a string
        return outcome;
    }

    // main game start method
    public static void main(String[] args) {
        // used for game text
        String[] choices = {"rock", "paper", "scissors"};
        // new random object
        Random random = new Random();
        // random rps selection
        int compChoice = random.nextInt(3);

        // user stuff yo yo yo
        Scanner rpsInput = new Scanner(System.in);  // create a Scanner object
        try {
            boolean playing = true;
            while (playing) {
                System.out.println("It's Rock Paper Scissors time! What do you choose? (Input an integer option below.)\n\t1. Rock\n\t2. Paper\n\t3. Scissors");
                String rpsSelection = rpsInput.nextLine();
                int pChoice = Integer.parseInt(rpsSelection) - 1; String result = rpsWinCheck(pChoice, compChoice);
                System.out.println("You chose " + choices[pChoice] + " and the opponent chose " + choices[compChoice] + ", so you " + result + "!");
                System.out.println("Would you like to play again? (Input 'y' or 'n', please.)");
                String playAgain = rpsInput.nextLine();
                if ("n".equals(playAgain)) {playing = false;}
            }
            rpsInput.close();
            return;
        } catch (Exception e) {
            System.out.println("You had three clearly-defined options to pick from, and you failed. How shameful.");
            return;
        } finally {rpsInput.close();}
    }
}

Higher or Lower

Once again, I added a “Play Again” option after the round. I made it more efficient.

public class HigherOrLower {
    private static boolean horlWinCheck(int playerChoice, int computerChoice) {
        String result = "DIFFERENT"; //if, for some reason, the comparison doesn't work
        if (playerChoice > 10 || playerChoice < 1) {
            System.out.println("Please guess a number between 1 and 10.");
            return false;
        }
        if (playerChoice == computerChoice) {
            System.out.println("Congratulations! You've successfully guessed the number!");
            return true;
        } else {
            if (playerChoice > computerChoice) {result = "LOWER";} else {result = "HIGHER";}
            System.out.println("The opponent's number is " + result + " than your guess.");
            return false;
        }
    }
    public static void main(String[] args) {
        // new random object
        Random random = new Random();
        // user stuff yo yo yo
        Scanner horlInput = new Scanner(System.in);  // create a Scanner object
        try {
            boolean playing = true;
            while (playing) {
                // random rps selection
                int compChoice = random.nextInt(10) + 1;
                // resetting to the first turn
                int turn = 1;
                System.out.println("Your opponent has chosen a number. You have 3 tries to guess it!");
                while (turn < 4) {
                    System.out.println("TURN " + Integer.toString(turn) + ": Guess a number between 1 and 10.");
                    String horlSelection = horlInput.nextLine();
                    if (horlWinCheck(Integer.parseInt(horlSelection), compChoice)) {
                        turn = 4;
                    } else {
                        if (turn == 3) {
                            System.out.println("Oh no! You weren't able to guess the number.");
                        }
                        turn += 1;
                    }
                }
                // play again?
                System.out.println("Would you like to play again? (Input 'y' or 'n', please.)\n");
                String playAgain = horlInput.nextLine();
                if ("n".equals(playAgain)) {playing = false;}
            }
            horlInput.close();
            return;
        } catch (Exception e) {
            System.out.println("You literally just pick a number from 1 to 10. It's so easy. I'm disappointed in you.");
            return;
        } finally {horlInput.close();}
    }
}

Tic-Tac-Toe

Rather than replay functionality, I mainly optimized this game by making the AI more efficient (and actually functional) and I made the checks for wins clearer.

public class TicTacToe {
    // ttt player input for "X" and "O"
    public static String[][] tttMakeMove(String xoro, int gridIndex, String[][] boardData) {
        int converterCheck = 1;
        outerloop:
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) {
                if (converterCheck == gridIndex) {
                    boardData[j][k] = xoro;
                    break outerloop;
                }
                converterCheck++;
                if (converterCheck == 10) {
                    System.out.println("Invalid input.");
                }
            }
        }
        return boardData;
    }

    // win check function
    public static boolean tttWinCheck(String[][] board) {
        // check rows and columns
        for (int i = 0; i < 3; i++) {
            if (board[i][0].equals(board[i][1]) && board[i][1].equals(board[i][2])) {
                System.out.println("Three in a row! " + board[i][0] + " player wins.");
                return true; // row win
            }
            if (board[0][i].equals(board[1][i]) && board[1][i].equals(board[2][i])) {
                System.out.println("Three in a row! " + board[0][i] + " player wins.");
                return true; // column win
            }
        }
        // Check diagonals
        if (board[0][0].equals(board[1][1]) && board[1][1].equals(board[2][2])) {
            System.out.println("Three in a row! " + board[0][0] + " player wins.");
                return true; // top-left-to-right diagonal win
        }
        if (board[0][2].equals(board[1][1]) && board[1][1].equals(board[2][0])) {
            System.out.println("Three in a row! " + board[0][2] + " player wins.");
            return true; // top-right-to-left diagonal win
        }
        // test for tie
        int tieTest = 0;
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) {
                if ("X".equals(board[j][k]) || "O".equals(board[j][k])) {tieTest++;}
            }
        }
        if (tieTest >= 9) {
            System.out.println("It's a tie! Nobody wins.");
            return true; // tie ending
        }
        return false; // no win
    }

    // main game run
    public static void main(String[] args) {
        Scanner tttInput = new Scanner(System.in);  // create a Scanner object
        try {
            Random random = new Random(); //create random object
            boolean compGame = true;
            // player chooses mode
            System.out.println("Welcome to Tic-Tac-Toe! Please choose a mode.\n\t1. Player vs. Player\n\t2. Player vs. Computer");
            String modeChoice = tttInput.nextLine();
            if ("1".equals(modeChoice)) {compGame = false;}
            // create board with numbers
            String[][] board = {
                {"1", "2", "3"},
                {"4", "5", "6"},
                {"7", "8", "9"}
            };
            // repeat game loop while active
            boolean playing = true;
            while (playing) {
                for (int i = 0; i < 3; i++) {
                    System.out.println(board[i][0] + " | " + board[i][1] + " | " + board[i][2]);
                }
                System.out.println("Where would you like to place an X?");
                String tttSelection1 = tttInput.nextLine();
                int gridValue = Integer.parseInt(tttSelection1);
                board = tttMakeMove("X", gridValue, board);
                if (tttWinCheck(board)) {return;}
                if (compGame) {
                    boolean compChoosing = true;
                    while (compChoosing) {
                        int compChoiceRow = random.nextInt(3);
                        int compChoiceColumn = random.nextInt(3);
                        if (!("X".equals(board[compChoiceRow][compChoiceColumn])) && !("O".equals(board[compChoiceRow][compChoiceColumn]))) {
                            board[compChoiceRow][compChoiceColumn] = "O";
                            compChoosing = false;
                        }
                    }
                } else {
                    for (int i = 0; i < 3; i++) {
                        System.out.println(board[i][0] + " | " + board[i][1] + " | " + board[i][2]);
                    }
                    System.out.println("Other player, where would you like to place an O?");
                    String tttSelection2 = tttInput.nextLine();
                    int gridValue2 = Integer.parseInt(tttSelection2);
                    board = tttMakeMove("O", gridValue2, board);
                }
                if (tttWinCheck(board)) {return;}
            }
        } catch (Exception e) {
            System.out.println("You have a specific set of numerical choices and you messed it up. Wow.");
            return;
        } finally {tttInput.close();}
    }
}

Recursive Console Games Object

I created a new ConsoleGames object that allows for game selection and works recursively rather than with a while loop.

public class ConsoleGames {
    public static void main(String[] args) {
        Scanner consoleInput = new Scanner(System.in);
        playGames(consoleInput);
        consoleInput.close();
    }

    // the play games fun thing
    private static void playGames(Scanner consoleInput) {
        String menu = ""
                + "\u001B[31m____________________________\n"
                + "\u001B[31m|\t\t\u001B[35mGames Menu\t\t\t\u001B[31m|\n"
                + "\u001B[31m|\t\u001B[35m1. Rock Paper Scissors\t\t\u001B[31m|\n"
                + "\u001B[31m|\t\u001B[35m2. Higher or Lower\t\t\t\u001B[31m|\n"
                + "\u001B[31m|\t\u001B[35m3. Tic-Tac-Toe\t\t\t\t\u001B[31m|\n"
                + "\u001B[31m|\t\u001B[35m4. Exit\t\t\t\t\t\u001B[31m|\n"
                + "\u001B[31m____________________________\n"
                + "\n\u001B[37mChoose one of the games to play.";
        System.out.println(menu);

        String gameChoice = consoleInput.nextLine();

        switch (gameChoice) {
            case "1":
                RockPaperScissors.main(null);
                break;
            case "2":
                HigherOrLower.main(null);
                break;
            case "3":
                TicTacToe.main(null);
                break;
            case "4":
                System.out.println("Goodbye, World!");
                return; // terminate
            default:
                System.out.println("Invalid input. Try again.");
                break;
        }

        // RECURSION
        playGames(consoleInput);
    }
}

ConsoleGames.main(null);
____________________________
|		Games Menu			|
|	1. Rock Paper Scissors		|
|	2. Higher or Lower			|
|	3. Tic-Tac-Toe				|
|	4. Exit					|
____________________________

Choose one of the games to play.



|   ConsoleGames.main(null);

Evaluation interrupted.