Stworzyłem grę za pomocą ChatGPT. Ty też możesz!

Stworzyłem grę za pomocą ChatGPT. Ty też możesz!
Dall-e. Prompt: Cartoon Kid's film scene illustration, an man in front of a desktop computer in a sunny room, old pixel game visible on screen, pixelart style,oc render,best quality,8k,fine luster,ultra detailed,vivid

Nie umiejąc programować, w około pięć minut stworzyłem prostą webową gierkę w javascript'cie. Wszystko dzięki ChatGPT. Czy rola programisty jest zagrożona?

Setup

Nie umiem programować ale znam HTML/CSS i mniej więcej rozumiem Javascript choć nigdy nic w nim nie napisałem. Dlatego wybrałem tę technologie do stworzenia mini gry - internetowego węża (Snake). Ogólne zrozumienie frameworku w którym się tworzy pomaga - gdy starałem się stworzyć coś w Next.JS czy react'cie byłem jakby bardziej bezradny.

W programowaniu przerastało mnie wszystko ale najbardziej osłabiało mnie tworzenie tego środowiska, pobieranie pakietów etc. Dlatego bardzo ucieszyłem się gdy dowiedziałem się o replit.com - to chmurowe środowisko developerskie z automatycznym deployem aplikacji do chmury. Super.

Po założeniu konta na replit najważniejszą rzeczą było przygotowanie dobrego opisu gry. Jestem super leniwy, więc udałem się na wikipedie i skopiowałem kawałek opisu gry Snake.

Koniec końców moje polecenie do ChatGPT brzmiało tak:

hi, i want to make simple web application game on replit. game should be single player, controlled by keyboard arrows. game description:  action video games where the player maneuvers the end of a growing line, often themed as a snake. The player must keep the snake from colliding with both other obstacles and itself, which gets harder as the snake lengthens.

AI jak dobry nauczyciel najpierw przedstawił mi instrukcje, a ja jak typowy uczeń ominąłem je i przeszedłem do snippetów z kodem. Ale dla kronikarskiej dokładności wkleję screen odpowiedzi.

Wygenerowana wartość pliku index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Snake Game</title>
  </head>
  <body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <script src="script.js"></script>
  </body>
</html>

Nothing too fancy.

No ale jedziemy dalej. Teraz javascriptowy plik z samą aplikacją:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const blockSize = 10;
let snake = [{x: 50, y: 50}, {x: 40, y: 50}, {x: 30, y: 50}];
let dx = blockSize;
let dy = 0;
let food = {x: 0, y: 0};

function drawSnake() {
  for (let i = 0; i < snake.length; i++) {
    ctx.fillRect(snake[i].x, snake[i].y, blockSize, blockSize);
  }
}

function drawFood() {
  ctx.fillRect(food.x, food.y, blockSize, blockSize);
}

function moveSnake() {
  const head = {x: snake[0].x + dx, y: snake[0].y + dy};
  snake.unshift(head);
  if (head.x === food.x && head.y === food.y) {
    createFood();
  } else {
    snake.pop();
  }
}

function createFood() {
  const maxX = canvas.width / blockSize - 1;
  const maxY = canvas.height / blockSize - 1;
  food.x = Math.floor(Math.random() * maxX) * blockSize;
  food.y = Math.floor(Math.random() * maxY) * blockSize;
}

function checkCollision() {
  const head = snake[0];
  if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height) {
    return true;
  }
  for (let i = 1; i < snake.length; i++) {
    if (head.x === snake[i].x && head.y === snake[i].y) {
      return true;
    }
  }
  return false;
}

function update() {
  if (checkCollision()) {
    clearInterval(gameLoop);
    alert('Game over!');
    return;
  }
  ctx.clearRect(0, 0

No i tu napotkałem pierwszy problem - prawdopodobnie gdybym był kompletnie zielony nie wiedziałbym co się dzieje i porzuciłbym próby. ChatGPT generując odpowiedzi czasami się zacina - nie wiem z czego to wynika - w imię nauki nawet zdecydowałem się kupić sobie abonament za 20 USD. Chat jakby działał szybciej, ale przy generowaniu dłuższych odpowiedzi często się zacinał. Rozwiązałem to następującym promptem:

your code snippet is incomplete, please continue from function update()
function update() {
  if (checkCollision()) {
    clearInterval(gameLoop);
    alert('Game over!');
    return;
  }
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  moveSnake();
  drawSnake();
  drawFood();
}

function handleKeyDown(e) {
  if (e.keyCode === 37 && dx !== blockSize) {
    dx = -blockSize;
    dy = 0;
  } else if (e.keyCode === 38 && dy !== blockSize) {
    dx = 0;
    dy = -blockSize;
  } else if (e.keyCode === 39 && dx !== -blockSize) {
    dx = blockSize;
    dy = 0;
  } else if (e.keyCode === 40 && dy !== -blockSize) {
    dx = 0;
    dy = blockSize;
  }
}

createFood();

const gameLoop = setInterval(update, 100);

document.addEventListener('keydown', handleKeyDown);

Dodatkowo otrzymałem krótki opis logiki którą ten kod wykonuje co jest fajne. Po przeklejeniu wszystkiego do replit z wypiekami na twarzy kliknąłem guzik RUN i... zadziałało!

Jeszcze tylko lekki lifting graficzny

awsome! can we style it like old nokia game?

Yes, we can definitely style the game to make it look like the classic Nokia Snake game. Here's an example of how you can style the canvas and the snake.

Otrzymałem instrukcje dodające odpowiednie CSSy i aktualizacje index.html oraz pliku z javascriptem. Ten ostatni wkleję bo kontekście zaczepnego pytania o przyszłość programistów z zajawki tekstu ma to dla mnie istotne znaczenie.

Otrzymałem kod wraz z instrukcją podmiany konkretnej funkcji

function drawSnake() {
  for (let i = 0; i < snake.length; i++) {
    ctx.fillStyle = '#4CAF50';
    ctx.fillRect(snake[i].x, snake[i].y, blockSize, blockSize);
    ctx.strokeStyle = '#2B2B2B';
    ctx.strokeRect(snake[i].x, snake[i].y, blockSize, blockSize);
  }
}

No i pyk.

Dojście do tego etapu zajęło mi 5  minut. Warto dodać, że wcześniej spędziłem z pół godziny na tworzeniu Tetrisa co zakończyło się fiaskiem. Kod węża ma około 80 linii, Tetrisa 320 - jak wspomniałem generowanie kodu często było przerywane i w wypadku Tetrisa musiałem sklejać plik z bodaj 4 odpowiedzi. Spodziewam się, że tam mogło się coś zgubić.

To jak to będzie z tymi programistami?

Należę do obozu "Technologia nie zabiera pracy, ona zwiększa produktywność" - dzięki czemu ludzi mogą robić mniej nużące, bardziej istotne zadania. I to jest super. To, że powstała koparka nie oznacza, że ludzie nie uczestniczą w procesie kopania - są dzięki koparce stukrotnie bardziej wydajni. Taka zmiana jednak wymaga przekwalifikowania się, więc gdy dzieje się bardzo szybko, to faktycznie jednostka może poczuć się wypchnięta poza nawias. A jak pisałem tutaj, uważam, że zmiany związane z AI będą błyskawiczne.

W kontekście zmian społecznych wprowadzanych przez AI uważałem, że programiści będą jeszcze bardziej potrzebni i jeszcze bardziej wydajni. Ale po tym eksperymencie zaczynam się zastanawiać. I zdaję sobie sprawę z tego, że to trywialna aplikacja, być może słabo napisana - nie potrafię tego nawet ocenić. Byłem mocno przekonany, że generowanie podstawowego kodu będzie świetnie wychodziło sztucznej inteligencji, tu nie ma zaskoczenia. AI-ową rewolucje w obszarze tworzenia oprogramowania bardziej pozycjonowałem w obszarze mocno dostosowywanych szablonów aplikacji a nie gotowych, produkcyjnych rozwiązań.

Ale dziś jestem coraz bardziej bullish, że AI za parę lat może być "partnerem" dla Product Ownera który dyktuje swoje oczekiwania. Nie do końca rozumiem, co developer może dodać w tej relacji - zakładając oczywiście dalszy rozwój modeli. Moją dużą obawą było późniejsze edytowanie kodu - zadbanie o wszystkie powiązania i aktualizacje w różnych miejscach w aplikacji. Prosty eksperyment z stylowaniem gry pokazał, że model rozumie o co mi chodzi i wie jakie elementy trzeba zmienić by osiągnąć ten cel.

Przyszłość widzę w wizualnych edytorach które generują kod - podobnie jak FlutterFlow czy Wappler. Chcę móc wklejać (lub generować z pomocą AI) kod i mieć ogólny pogląd co się dzieje - jak wyglądają zależności. Uważam, że taki krok pośredni będzie jeszcze długo potrzebny. Wiele pomysłów powstaje podczas tworzenia, korzystania z dzieła.