Skip to content

What happend when I asked ChatGPT to code simple video games.

License

Notifications You must be signed in to change notification settings

seanbutler/ChatGPTGameDev

Repository files navigation

ChatGPTGameDev

Prompt01

Given

"generate a c++ program for a simple video game"

ChatGPT responded as follows...

Sure, here is an example C++ program for a simple video game using the ncurses library:

#include <iostream>
#include <ncurses.h>

using namespace std;

int main()
{
    // Initialize ncurses
    initscr();
    noecho();
    curs_set(0);

    // Set up game variables
    int x = 0, y = 0;
    int max_x = 0, max_y = 0;
    int ch = 0;

    // Get screen size
    getmaxyx(stdscr, max_y, max_x);

    // Main game loop
    while (ch != 'q')
    {
        // Clear the screen
        clear();

        // Draw the player character
        mvprintw(y, x, "O");

        // Move the player character based on user input
        switch (ch)
        {
            case KEY_UP:
                if (y > 0)
                    y--;
                break;
            case KEY_DOWN:
                if (y < max_y - 1)
                    y++;
                break;
            case KEY_LEFT:
                if (x > 0)
                    x--;
                break;
            case KEY_RIGHT:
                if (x < max_x - 1)
                    x++;
                break;
        }

        // Refresh the screen
        refresh();

        // Get user input
        ch = getch();
    }

    // Clean up ncurses
    endwin();

    return 0;
}

This program uses the ncurses library to create a simple game where the player can move a character around the screen using the arrow keys. The game loop clears the screen, draws the player character at the current position, moves the player character based on user input, and refreshes the screen. The loop continues until the user presses the 'q' key. This is just a simple example, but it could be expanded to include obstacles, enemies, and other game mechanics.

it worked but its not a video game. apart from one line of code missing which was necessary to make ncurses read the arrow keys properly. added necessary code. its almost as if its the starting code a course might give students to work from an initial shell to get them going.

IMG

Prompt 02

prompt

"generate a c++ program for a simple video game including obstacles and enemies"

result

Here is an example C++ program for a simple video game that includes obstacles and enemies, using the ncurses library

#include <iostream>
#include <vector>
#include <ncurses.h>

using namespace std;

// Structs for game objects
struct GameObject
{
    int x, y;
    char symbol;
};

struct Obstacle : public GameObject
{
    Obstacle(int x, int y) { this->x = x; this->y = y; this->symbol = '#'; }
};

struct Enemy : public GameObject
{
    Enemy(int x, int y) { this->x = x; this->y = y; this->symbol = 'X'; }
};

// Function to check for collisions
bool checkCollision(int x1, int y1, int x2, int y2)
{
    return x1 == x2 && y1 == y2;
}

int main()
{
    // Initialize ncurses
    initscr();
    noecho();
    curs_set(0);

    // Set up game variables
    int player_x = 0, player_y = 0;
    int max_x = 0, max_y = 0;
    int ch = 0;

    // Set up obstacles and enemies
    vector<Obstacle> obstacles = { Obstacle(5, 5), Obstacle(10, 10), Obstacle(15, 15) };
    vector<Enemy> enemies = { Enemy(20, 20), Enemy(25, 25), Enemy(30, 30) };

    // Main game loop
    while (ch != 'q')
    {
        // Clear the screen
        clear();

        // Draw the player character
        mvprintw(player_y, player_x, "O");

        // Draw the obstacles
        for (Obstacle obstacle : obstacles)
        {
            mvprintw(obstacle.y, obstacle.x, "#");
            if (checkCollision(player_x, player_y, obstacle.x, obstacle.y))
            {
                // Game over
                mvprintw(max_y/2, max_x/2 - 5, "GAME OVER");
                refresh();
                getch();
                endwin();
                return 0;
            }
        }

        // Draw the enemies
        for (Enemy enemy : enemies)
        {
            mvprintw(enemy.y, enemy.x, "X");
            if (checkCollision(player_x, player_y, enemy.x, enemy.y))
            {
                // Game over
                mvprintw(max_y/2, max_x/2 - 5, "GAME OVER");
                refresh();
                getch();
                endwin();
                return 0;
            }
        }

        // Move the player character based on user input
        switch (ch)
        {
            case KEY_UP:
                if (player_y > 0)
                    player_y--;
                break;
            case KEY_DOWN:
                if (player_y < max_y - 1)
                    player_y++;
                break;
            case KEY_LEFT:
                if (player_x > 0)
                    player_x--;
                break;
            case KEY_RIGHT:
                if (player_x < max_x - 1)
                    player_x++;
                break;
        }

        // Get screen size
        getmaxyx(stdscr, max_y, max_x);

        // Refresh the screen
        refresh();

        // Get user input
        ch = getch();
    }

    // Clean up ncurses
    endwin();

    return 0;
}



This program builds on the previous example, adding obstacles and enemies to the game. The obstacles and enemies are stored in vectors of Obstacle and Enemy objects, respectively. The game loop draws the obstacles and enemies on the screen, checks for

( i think maybe it got a bit bored at this point as the text just stopped.)

Prompt 03

prompt

"can you make the enemies move please?"

result

#include <iostream>
#include <vector>
#include <ncurses.h>
#include <cstdlib>
#include <ctime>

using namespace std;

// Structs for game objects
struct GameObject
{
    int x, y;
    char symbol;
};

struct Obstacle : public GameObject
{
    Obstacle(int x, int y) { this->x = x; this->y = y; this->symbol = '#'; }
};

struct Enemy : public GameObject
{
    Enemy(int x, int y) { this->x = x; this->y = y; this->symbol = 'X'; }
};

// Function to check for collisions
bool checkCollision(int x1, int y1, int x2, int y2)
{
    return x1 == x2 && y1 == y2;
}

// Function to move enemies randomly
void moveEnemies(vector<Enemy>& enemies, int max_x, int max_y)
{
    for (Enemy& enemy : enemies)
    {
        int dx = rand() % 3 - 1;
        int dy = rand() % 3 - 1;
        if (enemy.x + dx >= 0 && enemy.x + dx < max_x)
            enemy.x += dx;
        if (enemy.y + dy >= 0 && enemy.y + dy < max_y)
            enemy.y += dy;
    }
}

int main()
{
    // Initialize ncurses
    initscr();
    noecho();
    curs_set(0);

    // Set up game variables
    int player_x = 0, player_y = 0;
    int max_x = 0, max_y = 0;
    int ch = 0;
    srand(time(NULL));  // Seed the random number generator

    // Set up obstacles and enemies
    vector<Obstacle> obstacles = { Obstacle(5, 5), Obstacle(10, 10), Obstacle(15, 15) };
    vector<Enemy> enemies = { Enemy(20, 20), Enemy(25, 25), Enemy(30, 30) };

    // Main game loop
    while (ch != 'q')
    {
        // Clear the screen
        clear();

        // Draw the player character
        mvprintw(player_y, player_x, "O");

        // Draw the obstacles
        for (Obstacle obstacle : obstacles)
        {
            mvprintw(obstacle.y, obstacle.x, "#");
            if (checkCollision(player_x, player_y, obstacle.x, obstacle.y))
            {
                // Game over
                mvprintw(max_y/2, max_x/2 - 5, "GAME OVER");
                refresh();
                getch();
                endwin();
                return 0;
            }
        }

        // Draw the enemies and move them randomly
        moveEnemies(enemies, max_x, max_y);
        for (Enemy enemy : enemies)
        {
            mvprintw(enemy.y, enemy.x, "X");
            if (checkCollision(player_x, player_y, enemy.x, enemy.y))
            {
                // Game over
                mvprintw(max_y/2, max_x/2 - 5, "GAME OVER");
                refresh();
                getch();
                endwin();
                return 0;
            }
        }

        // Move the player character based on user input
        switch (ch)
        {
            case KEY_UP:
                if (player_y > 0)
                    player_y--;
                break;
            case KEY_DOWN:
                if (player_y < max_y - 1)
                    player_y++;
                break;

at this point ChatGPT stopped. unsure what to do next I remembered its a chat bot, so gave a new prompt...

"continue please"

ChatGPT continued as follows...

Here's the second half of the modified C++ program:

        case KEY_LEFT:
            if (player_x > 0)
                player_x--;
            break;
        case KEY_RIGHT:
            if (player_x < max_x - 1)
                player_x++;
            break;
    }

    // Refresh the screen
    refresh();

    // Get the maximum x and y coordinates of the screen
    getmaxyx(stdscr, max_y, max_x);

    // Wait for user input or a short time delay
    ch = getch();
    napms(50);
}

// Clean up ncurses
endwin();

return 0;

discussion

Followed by this text, which seems like it comes from some kind of explanation or tutorial.

In this version, the moveEnemies function randomly moves the enemy objects on the screen. The dx and dy variables determine the direction of the movement, and are set to random values between -1 and 1. The if statements ensure that the enemies don't move off the screen.

Note that the movement of the enemies in this version is quite simple and not very challenging. You can modify the moveEnemies function to make the movement more complex and interesting if you like.

As before the line was necessary to make it read the keyboard properly plus for unknown reasons the code was missing the fina bracket which was outside the code block of the chatGPT webpage and the accompanying descriptive text was in a code block. Ho Hum.

with the necessary changes it worked a bit more like a video game now. though it really feels like im working through the exercises from gamedev101.

IMG

Prompt 04

Given the prompt...

"can you make the enemies chase the player please?"

ChatGPT responded differently.

Yes, I can modify the C++ program to make the enemies chase the player. Here's a possible modification to the moveEnemies function that implements this behavior:

void moveEnemies(Enemy enemies[], int num_enemies, int player_x, int player_y) {
    for (int i = 0; i < num_enemies; i++) {
        // Calculate the distance between the enemy and the player
        int dist_x = player_x - enemies[i].x;
        int dist_y = player_y - enemies[i].y;
        int dist = sqrt(dist_x * dist_x + dist_y * dist_y);

        // If the enemy is close to the player, move towards the player
        if (dist < 10) {
            int dx = (dist_x > 0) - (dist_x < 0);
            int dy = (dist_y > 0) - (dist_y < 0);

            // Check if the new position is valid
            if (enemies[i].x + dx >= 0 && enemies[i].x + dx < max_x && 
                enemies[i].y + dy >= 0 && enemies[i].y + dy < max_y) {
                // Update the enemy position
                enemies[i].x += dx;
                enemies[i].y += dy;
            }
        } else {
            // Otherwise, move randomly
            int dx = rand() % 3 - 1;
            int dy = rand() % 3 - 1;

            // Check if the new position is valid
            if (enemies[i].x + dx >= 0 && enemies[i].x + dx < max_x && 
                enemies[i].y + dy >= 0 && enemies[i].y + dy < max_y) {
                // Update the enemy position
                enemies[i].x += dx;
                enemies[i].y += dy;
            }
        }
    }
}

Rather than generating the entire program again from scratch it has given me an edit to the previous programme. Again however its giving me a litle tutorial on the code generated. We didnt ask for this though so im guessing its generated from text surrounding the code examples it found on the internet.

In this version, if the distance between an enemy and the player is less than 10 units, the enemy moves towards the player's position. Otherwise, the enemy moves randomly as before. The dx and dy variables are calculated based on the distance between the enemy and the player, and are used to update the enemy's position.

Note that the chasing behavior implemented here is very simple and can be improved upon. For example, you can add more sophisticated algorithms that take into account obstacles on the screen, or implement different movement patterns for the enemies.

OK, so ive copied the supplied function in and commented out the previous version.

A small but relavent number of errors have been generated and output by the compiler.

/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp: In function ‘void moveEnemies(Enemy*, int, int, int)’:
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp:60:20: error: ‘sqrt’ was not declared in this scope
   60 |         int dist = sqrt(dist_x * dist_x + dist_y * dist_y);
      |                    ^~~~
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp:68:63: error: ‘max_x’ was not declared in this scope
   68 |             if (enemies[i].x + dx >= 0 && enemies[i].x + dx < max_x &&
      |                                                               ^~~~~
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp:69:63: error: ‘max_y’ was not declared in this scope
   69 |                 enemies[i].y + dy >= 0 && enemies[i].y + dy < max_y) {
      |                                                               ^~~~~
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp:80:63: error: ‘max_x’ was not declared in this scope
   80 |             if (enemies[i].x + dx >= 0 && enemies[i].x + dx < max_x &&
      |                                                               ^~~~~
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp:81:63: error: ‘max_y’ was not declared in this scope
   81 |                 enemies[i].y + dy >= 0 && enemies[i].y + dy < max_y) {
      |                                                               ^~~~~
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp: In function ‘int main()’:
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp:139:21: error: cannot convert ‘std::vector<Enemy>’ to ‘Enemy*’
  139 |         moveEnemies(enemies, max_x, max_y);
      |                     ^~~~~~~
      |                     |
      |                     std::vector<Enemy>
/home/sean/Projects/ChatGPTGameDev/Prompt04/main.cpp:55:24: note:   initializing argument 1 of ‘void moveEnemies(Enemy*, int, int, int)’
   55 | void moveEnemies(Enemy enemies[], int num_enemies, int player_x, int player_y) {
      |                  ~~~~~~^~~~~~~~~

C++ programmers will understand and be able to resolve these errors easily, the 1st is related to an absence of the maths code necessary to calculate distances in 2nd the square root. The others are related to the generated code itself and about how it doesnt quite integrate with the existing code so some of the variable need to be tweaked.

The code itself cant refer the limits of movement from these contexts and its using the array of enemies in a new/different way.

We will have to make some minor tweaks. First to add in a reference to the maths code (its pretty standard in all dev environment) and Second to expand the visability of the limits of movement (the max_ variables so they can be seen at this point) and Third patch up the array.

IMG

Prompt 05

Given the prompt...

"can you please make the enemies red??"

ChatGPT responded with a correct piece of code. Instead of offering an addition to the existing code it completed a new answer.

The enemies have changed color! Also so has the player. In addition the choice of characters has changed. Neither of these were asked form.

Take a look at the code in the Prompt05 for the complete code, its growing in lenght and there isnt much to be gained by pasting it here.

Prompt05 main.cpp

What is interesting from my perspective is the drift that has happend. The initial code responces generatd appear to have come from one set of examples and the later from another.

In c++ coding its possible to solve the same problem in many differrent ways, in early versions of the code we had a vector for the container of enemies and obstacles, in the later version the code used an array to hold them. A similar though less flexible but faster container type.

At the stage where the code generated was as as addendum to the earlier result the generator also appears to have changed from one choice of container to the other. In successive generations (05) its settled on the array container. I doubt this was because of it being an addendum but instead because its referring to different example code to achice the requested functionality.

In part I suspect this is occuring due to the similarity between the two concepts in a c++ context and the abundance of examples of introduction coding samples attempting the same thing in different ways so the ChatGPT infers they are equivalent.

English and other Natural languages have this kind of flexibility but programing languages having a more formal syntax and being interpreted by the more literal and less flexible compilers do not. These similar parts cannot be exchanged / substituted.

Prompt 06

Given the prompt...

"can you please put the player and enemies inside a cave?"

and we are beginning to see the limits of its understanding the relationship between english and the code necessary. (more on ths in due course)

About

What happend when I asked ChatGPT to code simple video games.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published