Friday, March 8, 2024

#chatgpt - an adventure; with codereview!

 So there's alot of fuss around AI lately; it's been stirring my curiosity for a while - it's been a long time since playing with it in chess games at university.

For fun, and to explore; i deciced to want to make a "maze" game. A very simple game in which you have to figure out how to get out of a maze, while avoiding enemies.

Nothing fancy, very basic prototype level stuff. Only one requirement: let chatgpt do all the work!


So far, I have:

- a maze

- a player

- two enemies

- a rendering loop

- collision engine

- and some stats

The first funny thing; it calls python "pseudo-code" (i.e. it coded it in python from the beginning). There was a bit a hassle with setting up the dependencies for the OpenGL piping (on Debian), but otherwise it runs. I had a few iterations on it; code restructuring was particularly painful (apparently class structure context is something that gets easily lost when extrapolating from a single file to individual ones - i.e. one per class); when I decided to move the maze code into it's own class, the references to it woule have been still "maze", but it didnt acknowledge the actual maze data present within the maze class (as in maze.maze was missing from the other classes using it).
Most of the logic is then also glued into the rendering class, for some reason - I wonder if  the notion of the inversion of control pattern is tricky for it.

So after this output, we get this:

 

quite an open maze, I must say.  I will try to solve this problem later on.

The stats also do not show, despite being there (there should be a header with a life counter).

The whole process of prompt "engineering" (or whatever it is heretically called) is just brain dumb. Telling chatgpt what is needed is actually _very_ tedious, and can easily lead to errors. Another thing : chatgpt _cannot_ commit to github. Now that's quite the deal; yes of course chatgpt is storing every change for you, and it can revert to any of them at any point; but if you'd want the flexibility of git in it, it'all download/add/commit/push/merge cycles. Unhandy to say the least.
Also, when you ask it for a change, chatgpt will stay specific, i.e. it will prefer to output a short part of the code you are asking changes for, instead (for example) of the whole file with the new changes in it (this makes copy pasting tedious too). It's also "missing out" on some module imports for constants (mainly DOUBLEBUF, OPENGL, which come from the pygame module). As well the font initialization part was missing.

Now lets say I want to add some extra logic (If I click on a wall, I want to be able to "move" the brick by one cell forward or backwards). This is the changeset chatgpt proposes:

48a49,50
>         self.dragging_wall = False
>         self.dragging_wall_pos = None
72a75,78
>     def handle_mouse_down(self, x, y):
>         x = max(0, min(x // 20, self.maze_width - 1))
>         y = max(0, min((y - 50) // 20, self.maze_height - 1))
>         if self.maze.maze[y][x] == 1:
>             self.dragging_wall = True
>             self.dragging_wall_pos = (x, y)
>
82a89,97
>     def handle_mouse_up(self):
>         self.dragging_wall = False
>         self.dragging_wall_pos = None
>
87,89d101
<         # Handle dragging wall
<         if self.dragging_wall and self.dragging_wall_pos is not None:
<             x, y = pygame.mouse.get_pos()
94,107d105
<                 x = max(0, min(x // cell_size, self.maze_width - 1))
<                 y = max(0, min((y - header_height) // cell_size, self.maze_height - 1))
<                 if self.maze.maze[y][x] == 0:
<                     self.maze.maze[self.dragging_wall_pos[1]][self.dragging_wall_pos[0]] = 0
<                     self.maze.maze[y][x] = 1
<                     self.dragging_wall_pos = (x, y)
<
95a108
>     def draw(self):
102a116,119
>             elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
>                 self.handle_mouse_down(*event.pos)
>             elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
>                 self.handle_mouse_up()
108,109c125,126
<                 glVertex2f(x * cell_size, y * cell_size + header_height)
<                 glVertex2f((x + 1) * cell_size, y * cell_size + header_height)
---
>                 glVertex2f(x * cell_size, y * cell_size + header_height)
>                 glVertex2f((x + 1) * cell_size, y * cell_size + header_height)
111,112c128,129
<                 glVertex2f((x + 1) * cell_size, (y + 1) * cell_size + header_height)
<                 glVertex2f(x * cell_size, (y + 1) * cell_size + header_height)
---
>                 glVertex2f((x + 1) * cell_size, (y + 1) * cell_size + header_height)
>                 glVertex2f(x * cell_size, (y + 1) * cell_size + header_height)

But hey it's been one hour tops, and I am this far! The enemies move, adn the player is controllable. Impressive. The same game took me about 6 hours to code a few years back (mainly the maze algorithm was a bit cumbersome).