Codemaxxers / Issues

0 stars 0 forks source link

Issue #43

Open F1nnC opened 9 months ago

F1nnC commented 9 months ago

FRQ 1 - Arrays and ArrayLists

This FRQ was focused on ArrayLists, 1D arrays, and 2D arrays. In our project, we use many arrays in many different places for our project to function. We use 2D arrays in our project to keep track of health and damage in our game.

In Person.java

public static Person[] init() {
        int[][] baseStatsArray = {{100, 0}, {100, 0}}; // <--
        ArrayList<Integer> baseInventory = new ArrayList<>();

Here, we use a 2D array to store our character's base stats. As a sidenote, we also use an ArrayList to keep and maintain a base inventory.

In PersonApiController.java

// START OF LEVEL STATS CALCULATION
        int[] baseStats = {100,107,114,121,128,135,141,148,155,162,169,176,183,190,197,204,211,218,225,232,239,246,253,260,267,274,281,288,295,300};
        int accountLevelMatchingStats = newLevel - 1;
        int[][] statsArray = person.getStatsArray();
        statsArray[0][0] = baseStats[accountLevelMatchingStats];
        statsArray[1][0] = baseStats[accountLevelMatchingStats];
        person.setStatsArray(statsArray);
// END OF LEVEL STATS CALCULATION

Here, we use our 2D array to calculate the Level Stats based on the 2D array. Using this array, we are able to determine the base stats and determine the matching account level from them.

Our use of ArrayLists is similar to the FRQ in the sense that it uses integers and it has a 2D array, as well as including an ArrayList, and we have a lot of 1D arrays in our project.

Arrays and ArrayLists are both extremely important aspects of Java that we need to learn how to use, since it comes up multiple times in many situations. We have many more examples of Arrays and ArrayLists, however, for brevity, we have decided to showcase one. We use Arrays and ArrayLists all the time, and this FRQ as well as our integration into our project demonstrates how essential these aspects are to our success not only in Java, but in many other aspects of programming where similar ideas can be taken up.

FRQ 2 - Classes

This problem asked us to create a word guessing game, similar to the Wordle game from the New York Times. The player was given a word and then asked to guess it, using key symbols to determine what they had to do next. This was accomplished using classes to give the different hints, which is what we used in our project. Here is an example of our Question class:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@NamedNativeQuery(name = "Question.findByCourse", query = "SELECT * FROM ?1", resultClass = Question.class)
public class Question {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "Question", nullable = false)
    private String question;

    @Column(name = "Answer 1", nullable = false)
    private String answer1;

    @Column(name = "Answer 2", nullable = false)
    private String answer2;

    @Column(name = "Answer 3", nullable = false)
    private String answer3;

    @Column(name = "Answer 4", nullable = false)
    private String answer4;

    @Column(name = "Correct Answer", nullable = false)
    private Integer correctAnswer;

    @Column(name = "Difficulty", nullable = false)
    private Integer difficulty;

    @Column(name = "Unit", nullable = false)
    private Integer unit;

    @Column(name = "Points", nullable = false)
    private Integer points;
}

This class in our project is similar to the one in the FRQ in which we use a class to get and set variables (the @Column allows us to set the variables from the SQLite table that we load), which is important to our project. Moreover, we have our Entity setter class:

// Parent class for all character classes
public class Entity {
    public int x, y;  // position
    public int speed;  // speed 

    public String direction; 
}

This class in our project does something similar to the above class, but for our entities in our game when we developed it on the backend. Overall, our class structure is extremely important to the success of our project.

FRQ 3 - 2D Arrays + Method and Control Structures

This FRQ asked about 2D arrays, and then went into specifics about sparse arrays. While we do not use sparse arrays in our project, we use many principles talked about arrays and we use 2D arrays in our project, as showcased by FRQ 1:

In Person.java

public static Person[] init() {
        int[][] baseStatsArray = {{100, 0}, {100, 0}}; // <--
        ArrayList<Integer> baseInventory = new ArrayList<>();

Here, we use a 2D array to store our character's base stats. As a sidenote, we also use an ArrayList to keep and maintain a base inventory.

In PersonApiController.java

// START OF LEVEL STATS CALCULATION
        int[] baseStats = {100,107,114,121,128,135,141,148,155,162,169,176,183,190,197,204,211,218,225,232,239,246,253,260,267,274,281,288,295,300};
        int accountLevelMatchingStats = newLevel - 1;
        int[][] statsArray = person.getStatsArray();
        statsArray[0][0] = baseStats[accountLevelMatchingStats];
        statsArray[1][0] = baseStats[accountLevelMatchingStats];
        person.setStatsArray(statsArray);
// END OF LEVEL STATS CALCULATION

While we do not use sparse arrays, we use a lot of the same principles that we need from 2D arrays, such as value retrieval and decisions based on the value, which can be shown by our implementation of our 2D statsArray into our 1D baseStats, and then forwarding that to the actual person object.

2D arrays are efficient ways to store data, however, with a game structure like ours, we seldom see the chance to use them, as most of our data is more efficiently used in 1D arrays or ArrayLists. Although this may be the case, we still see the use for them and incorporate them into our project, and we use the principles we learn from this FRQ to improve the efficiency and scalability of our project.

FRQ 4 - Methods and Control Structures

This FRQ talks about the creation of interfaces and how to apply them to certain classes. These interfaces have certain methods that we need to use in our classes. In our project, we use a lot of inheritance to make sure that we can scale our project, as was the intended goal. We know that we are going to have to create multiple instances of the same format of game, so we need to use a lot of class extension. Here are a couple examples:

public class GamePanel extends JPanel implements Runnable {

    //Screen Settings
    final int originalTileSize = 16;  // 16x16 default tile/character size
    // scaling
    final int scale = 3;

    public final int tileSize = originalTileSize * scale;
    // 16 x 12 map
    final int maxScreenCol = 16;
    final int maxScreenRow = 12;

    final int screenWidth = tileSize * maxScreenCol;  // 768 pixels
    final int screenHeight = tileSize * maxScreenRow;  // 576 pixels

    KeyHandler keyH = new KeyHandler();
    Thread gameThread;
    Player player = new Player(this, keyH);

    // Setting player default position
    int playerX = 100;
    int playerY = 100;
    int playerSpeed = 4;

    // NPC 

    // FPS
    int FPS = 50;

    private Image backgroundImage;

    public GamePanel() {
        Npc npc = new Npc(200, 200, "Hello, I am an NPC!", this);
        this.setPreferredSize(new Dimension(screenWidth, screenHeight));
        this.addMouseListener(npc);

        // Load your background image
        this.backgroundImage = new ImageIcon(getClass().getResource("/com/nighthawk/spring_portfolio/mvc/collision/sprites/gamemap.png")).getImage();

        this.setDoubleBuffered(true);
        this.addKeyListener(keyH);
        this.setFocusable(true);
    }

    public void startGameThread() {
        gameThread = new Thread(this);
        gameThread.start();
    }

    @Override
    public void run() {
        double drawInterval = 1000000000 / FPS; // screen is redrawn 60 times per sec
        double nextDrawTime = System.nanoTime() + drawInterval;
        while (gameThread != null) {

            // 1- UPDATE character info like position
            update();
            // 2 - DRAW Screen with updated information
            repaint();

            try {
                double remainingTime = nextDrawTime - System.nanoTime();
                // convert nano to milli
                remainingTime = remainingTime / 1000000;

                if (remainingTime < 0) {
                    remainingTime = 0;
                }

                Thread.sleep((long) remainingTime);

                nextDrawTime += drawInterval;

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void update() { // player position updating
        player.update();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;

        // Draw the background image
        g2.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this);

        // Draw the player on top of the background
        player.draw(g2);
        g2.dispose();
    }
}

This code runs our gamepanel by implementing certain classes that allow our gamepanel to have different properties that are pulled through inheritance from different classes. Another example is our PersonJPA repository:

public interface PersonJpaRepository extends JpaRepository<Person, Long> {
    Person findByEmail(String email);

    Person findByName(String name);

    List<Person> findAllByOrderByNameAsc();

    // JPA query, findBy does JPA magic with "Name", "Containing", "Or", "Email", "IgnoreCase"
    List<Person> findByNameContainingIgnoreCaseOrEmailContainingIgnoreCase(String name, String email);

    /* Custom JPA query articles, there are articles that show custom SQL as well
       https://springframework.guru/spring-data-jpa-query/
       https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
    */
    Person findByEmailAndPassword(String email, String password);

    // Custom JPA query
    @Query(
            value = "SELECT * FROM Person p WHERE p.name LIKE ?1 or p.email LIKE ?1",
            nativeQuery = true)
    List<Person> findByLikeTermNative(String term);
    /*
      https://www.baeldung.com/spring-data-jpa-query
    */

    List<Person> findTop5ByOrderByCspPointsDesc();

    List<Person> findTop5ByOrderByCsaPointsDesc();

    // You can use no query or query

    @Query("SELECT p FROM Person p ORDER BY p.cspPoints DESC")
    List<Person> findTop5ByCspPoints();

    @Query("SELECT p FROM Person p ORDER BY p.csaPoints DESC")
    List<Person> findTop5ByCsaPoints();

}

This query allows us to get all the information about the person that we need, and we set up each person through this query that pulls methods from other classes to be more efficient and effective. Either way, both examples showcase the importance of streamlining code through inheritance, which allows our code to be more cohesive, efficient, and unified.

emmaxshen commented 9 months ago

3.8/3.6