ChatGPT AI Building a Turn Based Strategy Game, Part 2

Today I am starting where I left off, with the intent to refactor the code. I suspect this is a big ask for ChatGPT.

The code is getting harder to manage. Can the functions be grouped into classes? Also, can hard-coded values be set globally and referenced by name throughout the code?

Like before, I asked this like I would to someone I would be working with on the code. Chat replied with the following.

Certainly! We can use classes to better organize the code and make it more maintainable. We can create classes for the Board, Tile, and Unit to group related functions together. Additionally, we can set global constants for hard-coded values and use them throughout the code.
Here's a reorganized version of the code using classes and global constants:

// Global constants
const TERRAIN = {
  NEUTRAL: 0,
  WATER: 1,
  PLAYER_OWNED: 2,
};

const COLORS = {
  NEUTRAL_DARK_GREY: [64, 64, 64],
  WATER_DARK_BLUE: [0, 0, 139],
};

const PLAYER_COLORS = [
  { r: 255, g: 0, b: 0 },
  { r: 0, g: 255, b: 0 },
  { r: 0, g: 0, b: 255 },
  { r: 255, g: 255, b: 0 },
  { r: 255, g: 0, b: 255 },
];

// Board class
class Board {
  constructor(gridSize, tileSize) {
    this.gridSize = gridSize;
    this.tileSize = tileSize;
    this.grid = [];
    this.initGrid();
  }

  initGrid() {
    // Initialize grid with Tile objects
  }

  draw() {
    // Draw the board and the units
  }
}

// Tile class
class Tile {
  constructor(x, y, terrain, player, unit) {
    this.x = x;
    this.y = y;
    this.terrain = terrain;
    this.player = player;
    this.unit = unit;
  }

  draw() {
    // Draw the tile
  }
}

// Unit class
class Unit {
  constructor(player, tile) {
    this.player = player;
    this.tile = tile;
  }

  draw() {
    // Draw the unit and its border
  }
}

// Initialize the board and other setup logic
// Replace hard-coded values with global constants

This created classes, which is what I wanted. It also made a big mess of the codebase. Simply stated, functions are not invoking class methods and there is ambiguity in the draw() functions in the classes from the previous versions. It is confusing.

At this point I am repeatedly giving ChatGPT the entire script content to find issues. I will skip sharing those steps as it is a series of long and messy code blocks with notes of what to replace. My objective is to get the application to work again, with better organized code.

Among the iterations, asking about specific errors creates specific responses. The following is a good example and is illustrative of the subtle learning opportunities. Notice the parenthetical comment “referred to as ‘this’ within the class”. ChatGPT explains ‘this’ is an instance of the Board class. Then finishes by explaining ‘this’ is a keyword, and the generateStartingPositions() method now accept a boardInstance as a parameter, which is the ‘this’ value passed to it.

I get an error "boardInstance is not defined at Board.generateStartingPositions"
Apologies for the oversight. The issue occurs because you are trying to access the ‘boardInstance’ variable before it is defined in the ‘setup()’ function. To resolve this issue, you can pass the ‘Board’ instance (referred to as ‘this’ within the class) to the ‘generateStartingPositions()’ method. Here's the updated code:

// Board class
class Board {
  constructor(gridSize, tileSize) {
    this.gridSize = gridSize;
    this.tileSize = tileSize;
    this.grid = this.initGrid();
  }

  initGrid() {
    let grid = [];
    for (let y = 0; y < this.gridSize; y++) {
      let row = [];
      for (let x = 0; x < this.gridSize; x++) {
        row.push(new Tile(x, y));
      }
      grid.push(row);
    }
    this.generateStartingPositions(this); // Pass 'this' as an argument
    return grid;
  }

  // ...

  generateStartingPositions(boardInstance) {
    // ... (the rest of the function remains the same)
  }
}

// ...

In the ‘initGrid()’ method, I have passed the ‘this’ keyword as an argument to the ‘generateStartingPositions()’ method. Then, I updated the ‘generateStartingPositions()’ method to accept the ‘boardInstance’ parameter. This will ensure that the correct ‘boardInstance’ is being used within the method.

This iterative process has been going on for a long time. Debugging has been rather tedious and slow. While I was starting to make progress again, ChatGPT 4 hit a capacity limit and gave me the option of taking up the tasks later or switching to ChatGPT 3.5.

Switching to version 3.5 gives faster responses, but also fewer code samples and simpler debugging steps. It is also unaware of what information was previously provided. Version 3.5 also does not apologize for causing confusion, which makes me miss it.

After about three hours of back-and-forth exchanges, I almost have the application working again. Asking for Chat to refactor the code into classes was a big ask.

While the switch to ChatGPT 3.5 was quicker to respond, it was less helpful to clarify code and lacked awareness of the previous suggestions and the state of the code as exchanged. I noticed this behavior before when I was experimenting with Version 3.5 to act as a Game Master while simulating Dungeons & Dragons with me as the player. It was creative, but forgetful and inaccurate.

My next step will be to start with ChatGPT 4 again, maybe with a new session and giving Chat the current copy of the code. I am not sure if the current session will allow me to go back to version 4 or remain using version 3.5. I have lots to play with.