Tekoäly. Pelastaja vai tuho?

OpenAI julkaisi o3-minin. Tuli ilmeisesti hoppu, koska kiina.

Kokeilin, miten onnistuu koodin teko.

Tee matopeli. Madon pitää ohjata itse itseään. Koko koodi yhdelle html-sivulle.

Meni noin minuutti. Koko urakkaan.

Ensin äly kertoi, mitä aikoo tehdä:




Crafting the game

I’m tasked with creating an HTML page featuring a snake game where the snake autonomously navigates to food, eliminating user-directed movement.

Coining a plan

I'm thinking through a smart snake algorithm, possibly using A* pathfinding to navigate to food while avoiding collisions. This approach ensures autonomous movement to the target.

Calculating the course

I’m considering using BFS to determine and update the snake's path to food, ensuring it navigates around obstacles like its own body on every frame.

Charting the course

I’m leaning towards using a straightforward pathfinding method, like BFS or A*, to guide the snake towards food, considering the potential for the path to become invalid as the snake moves.

Charting the route

I’m working through calculating a BFS-based path for the snake to food, factoring in obstacles like its own body segments, and noting the potential for paths to become invalid as the snake moves.

Mapping the strategy

I’m considering BFS to chart the snake to food, factoring in obstacles like its body segments, while occasionally treating the tail as empty space for navigation.

Navigating the grid

I’m mapping out BFS on a grid to guide the snake to food, treating all body segments, except the head, as obstacles and defining a function to determine valid moves.

Charting the course

I’m detailing the BFS algorithm, using a queue to explore neighbors, checking grid boundaries and obstacles, and reconstructing the path to determine the snake's next move, with a fallback plan for uncharted conditions.

Mapping the journey

I’m thinking through the snake's next movement by recalculating the path every update tick, choosing the direction from the head to the first cell in the computed path, and reusing the previous path if still valid.

Advancing the game

I’m detailing the game update logic: calculating paths with BFS, setting the snake's velocity, checking for collisions, and updating the canvas with the snake and food positions.

Calculating optimal routes

I’m assessing BFS's efficiency in navigating the grid, considering obstacles, and ensuring backup plans are in place to avoid snake collisions and maintain smooth progress towards food.

Implementing autonomous logic

I'm enhancing the snake's movement by integrating BFS pathfinding, ensuring safety with fallback moves, and coding within the same HTML file for streamlined execution.

Techniques for game design

I’m focusing on autonomous movement and collision checks, ensuring new food placement after consumption, and embedding the code within a single HTML file for simplicity and ease of use.

Mapping out game dynamics

I’m detailing the game structure, including setting up the canvas, defining snake movements, handling collisions, and ensuring the food is placed randomly and safely.

Handling BFS specifics

OK, let me see. Whether the snake's head is an obstacle and the order of safe moves are minor. The update function includes preparing the BFS path and managing movements.

Updating and drawing

I’m setting velocities, adjusting the snake's head, ensuring collisions are checked, and drawing the game board each tick. If the snake depletes its length, the game over screen is triggered.



Sitten se esitteli tuotoksensa:

"Seuraavassa on esimerkki HTML-tiedostosta, joka sisältää itsenäisesti ohjautuvan (”älykkään”) matopelin. Tässä versiossa mato yrittää etsiä reitin ruoan luo käyttäen yksinkertaista BFS-reitinhakualgoritmia. Kopioi koodi uuteen tiedostoon (esim. alykka_matopeli.html) ja avaa se selaimessa – ei tarvita mitään palvelinpuolen teknologiaa."

Koodi:
<!DOCTYPE html>
<html lang="fi">
<head>
  <meta charset="UTF-8">
  <title>Älykäs Matopeli</title>
  <style>
    /* Sivun ja pelialueen tyylit */
    body {
      background-color: #222;
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      color: #fff;
      font-family: Arial, sans-serif;
    }
    canvas {
      background-color: #333;
      border: 2px solid #fff;
    }
  </style>
</head>
<body>
  <canvas id="gameCanvas" width="400" height="400"></canvas>
  <script>
    // Pelin perusasetukset
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const gridSize = 20; // Ruudun koko
    const tileCountX = canvas.width / gridSize;
    const tileCountY = canvas.height / gridSize;

    // Mato: aloituspaikka, pituus ja aloitussuunnan määrittely (ohjaus lasketaan automaattisesti)
    let snake = [{ x: 10, y: 10 }];
    let snakeLength = 5;
    let velocity = { x: 1, y: 0 }; // Alkuarvo, jota AI päivittää joka kierroksella

    // Ruoka
    let food = { x: 15, y: 15 };

    let gameOver = false;
    const fps = 10;

    // Reitinhaku (BFS, leveys ensin -hakualgoritmi)
    function findPath(start, goal) {
      let queue = [];
      let visited = new Set();
      // Jokainen solmu sisältää koordinaatit ja viittauksen edelliseen solmuun
      queue.push({ x: start.x, y: start.y, parent: null });
      visited.add(start.x + "," + start.y);

      let found = null;
      while (queue.length > 0) {
        let node = queue.shift();

        // Tarkista, onko tavoite saavutettu
        if (node.x === goal.x && node.y === goal.y) {
          found = node;
          break;
        }

        // Tutkitaan neljää mahdollista liikesuuntaa
        let neighbors = [
          { x: node.x + 1, y: node.y },
          { x: node.x - 1, y: node.y },
          { x: node.x, y: node.y + 1 },
          { x: node.x, y: node.y - 1 }
        ];

        for (let neighbor of neighbors) {
          // Varmistetaan, että liike pysyy kentän sisällä
          if (
            neighbor.x < 0 || neighbor.x >= tileCountX ||
            neighbor.y < 0 || neighbor.y >= tileCountY
          ) {
            continue;
          }
          // Estetään, että reitti kulkee madon läpi.
          // Huom! Tässä kaikki madon segmentit lasketaan esteiksi, vaikka käytännössä hännän tilalle saattaisi tulla vapaa ruutu.
          let collision = snake.some(segment => segment.x === neighbor.x && segment.y === neighbor.y);
          if (collision) continue;

          let key = neighbor.x + "," + neighbor.y;
          if (visited.has(key)) continue;

          visited.add(key);
          queue.push({ x: neighbor.x, y: neighbor.y, parent: node });
        }
      }

      if (!found) return null;

      // Rakennetaan reitti alusta loppuun käymällä "parent"-linkkien kautta
      let path = [];
      let cur = found;
      while (cur.parent !== null) {
        path.push({ x: cur.x, y: cur.y });
        cur = cur.parent;
      }
      path.reverse();
      return path;
    }

    // Jos ruutua ruokaan johtavaa reittiä ei löydy, etsitään jokin turvallinen liikesuunta
    function getSafeMove(head) {
      const directions = [
        { x: 0, y: -1 }, // ylös
        { x: 1, y: 0 },  // oikealle
        { x: 0, y: 1 },  // alas
        { x: -1, y: 0 }  // vasemmalle
      ];
      for (let dir of directions) {
        let nextX = head.x + dir.x;
        let nextY = head.y + dir.y;
        if (nextX < 0 || nextX >= tileCountX || nextY < 0 || nextY >= tileCountY) continue;
        let collision = snake.some(segment => segment.x === nextX && segment.y === nextY);
        if (!collision) return dir;
      }
      return null;
    }

    // Päivitetään pelitilanne
    function update() {
      if (gameOver) return;

      let head = snake[0];

      // Lasketaan reitti madon pään ja ruoan välille
      let path = findPath(head, food);
      if (path && path.length > 0) {
        // Asetetaan liikesuunta niin, että mato siirtyy kohti reitin ensimmäistä askelta
        let nextStep = path[0];
        velocity = { x: nextStep.x - head.x, y: nextStep.y - head.y };
      } else {
        // Jos reittiä ei löydy, kokeillaan löytää jokin turvallinen liike
        let safeDir = getSafeMove(head);
        if (safeDir) {
          velocity = safeDir;
        } else {
          // Jos yksikään liike ei ole turvallinen, peli päättyy
          gameOver = true;
          return;
        }
      }

      // Lasketaan uuden pään sijainti
      let newHead = { x: head.x + velocity.x, y: head.y + velocity.y };

      // Tarkistetaan törmäykset reunaan
      if (
        newHead.x < 0 || newHead.x >= tileCountX ||
        newHead.y < 0 || newHead.y >= tileCountY
      ) {
        gameOver = true;
        return;
      }
      // Tarkistetaan törmäys omaan kehoon
      for (let segment of snake) {
        if (segment.x === newHead.x && segment.y === newHead.y) {
          gameOver = true;
          return;
        }
      }

      // Lisätään uusi pää madon eteen
      snake.unshift(newHead);

      // Jos ruoka on syöty, kasvatetaan matoa ja sijoitetaan uusi ruoka
      if (newHead.x === food.x && newHead.y === food.y) {
        snakeLength++;
        placeFood();
      }

      // Pidetään madon pituus halutun pituisena
      while (snake.length > snakeLength) {
        snake.pop();
      }
    }

    // Piirretään pelin elementit canvas-elementtiin
    function draw() {
      // Tyhjennetään pelialue
      ctx.fillStyle = '#333';
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // Piirretään ruoka
      ctx.fillStyle = 'red';
      ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize - 2, gridSize - 2);

      // Piirretään mato
      ctx.fillStyle = 'lime';
      for (let segment of snake) {
        ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 2, gridSize - 2);
      }
    }

    // Pelisilmukka
    function gameLoop() {
      if (gameOver) {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'red';
        ctx.font = '40px Arial';
        ctx.textAlign = 'center';
        ctx.fillText('Game Over', canvas.width / 2, canvas.height / 2);
        return;
      }
      update();
      draw();
    }

    // Uusi ruoka sijoitetaan aina satunnaiseen ruutuun, joka ei ole madon päällä
    function placeFood() {
      let valid = false;
      while (!valid) {
        food.x = Math.floor(Math.random() * tileCountX);
        food.y = Math.floor(Math.random() * tileCountY);
        valid = true;
        for (let segment of snake) {
          if (segment.x === food.x && segment.y === food.y) {
            valid = false;
            break;
          }
        }
      }
    }

    // Käynnistetään pelisilmukka
    setInterval(gameLoop, 1000 / fps);
  </script>
</body>
</html>



Lopuksi vielä selvensi toimintaperiaatetta:

Miten koodi toimii​

  1. Pelin alustus ja asetukset:
    • Canvas-alkio toimii pelialueena.
    • Ruudukon koko on määritelty (gridSize) ja ruudut lasketaan canvaan sopiviksi.
  2. Maton ja ruoan tilat:
    • Mato tallennetaan taulukkoon, jossa ensimmäinen alkio on pään sijainti.
    • Ruoka sijoitetaan aluksi kiinteään kohtaan, ja syömisen jälkeen satunnaiseen paikkaan, joka ei ole madon päällä.
  3. Reitinhaku (findPath):
    • Käytetään BFS-algoritmia etsimään reitti madon pään ja ruoan välillä ottaen huomioon madon kehon esteenä.
    • Jos reitti löytyy, mato asettaa liikesuunnakseen ensimmäisen askeleen kohti ruokaa.
  4. Päivitys- ja piirtofunktiot:
    • update() laskee madon uuden pään paikan, tarkistaa törmäykset ja kasvattaa matoa, jos ruoka on syöty.
    • draw() piirtää ruoan ja madon pelialueelle.
    • gameLoop() kutsuu päivitys- ja piirtofunktioita säännöllisin väliajoin.
  5. Turvallinen liike (fallback):
    • Jos reittiä ruokaan ei löydy, funktio getSafeMove() etsii turvallisen suunnan, jottei mato törmää seinään tai itseensä.
Kopioi yllä oleva koodi omaan HTML-tiedostoosi, avaa se selaimessa ja seuraa, kuinka älykäs mato yrittää ohjata itseään ruoan luo!

:shokki:

Toimi laakista.
 
https://www.minnalearn.com/tekoalytalkoot/
tollanen tekoälykurssi for dummies ois tarjolla ilmaisella, perustuu aallon tekoäly mooc kurssiin mut taso ei juuri päätä huimaa... Ei toi tosin paljon aikaakaan vie mutta voi tuollakin jotain oppia. Jos tietää AI:sta jottain, niin ehkä en suosittelis tota, jos ei tiiä niin hyvä paikka vähän tutustua.
Tuolla on ryhmiä näille aloille:
  • Matkailu- ja ravintola-ala
  • Ajoneuvoala
  • Kuljetusala
  • Maatalousala
  • Puhtaus-, kiinteistöpalvelu- ja isännöintialat
 

Luo tili tai kirjaudu sisään kommentoidaksesi

Sinun täytyy olla jäsen voidaksesi jättää kommentin.

Luo käyttäjätili

Liity Konekansalaiseksi. Se on helppoa ja ilmaista!

Kirjaudu sisään

Oletko jo Konekansan jäsen? Kirjaudu sisään tästä.

Takaisin
Ylös