Facebook
From tisI, 1 Week ago, written in JavaScript.
Embed
Download Paste or View Raw
Hits: 91
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" c initial-scale=1.0">
  6.   <title>Snake Game with RL</title>
  7.   <style>
  8.     canvas {
  9.       border: 1px solid #000;
  10.       display: block;
  11.       margin: 0 auto;
  12.     }
  13.   </style>
  14. </head>
  15. <body>
  16.   <canvas id="gameCanvas" width="400" height="400"></canvas>
  17.  
  18.   [removed]
  19.     // Game variables
  20.     const canvas = document.getElementById("gameCanvas");
  21.     const ctx = canvas.getContext("2d");
  22.     const scale = 20;
  23.     const rows = canvas.height / scale;
  24.     const columns = canvas.width / scale;
  25.     let snake;
  26.     let fruit;
  27.  
  28.     // Snake object
  29.     class Snake {
  30.       constructor() {
  31.         this.x = 0;
  32.         this.y = 0;
  33.         this.xSpeed = scale * 1;
  34.         this.ySpeed = 0;
  35.         this.total = 0;
  36.         this.tail = [];
  37.       }
  38.  
  39.       draw() {
  40.         ctx.fillStyle = "#FFFFFF";
  41.         for (let i = 0; i < this.tail.length; i++) {
  42.           ctx.fillRect(this.tail[i].x, this.tail[i].y, scale, scale);
  43.         }
  44.         ctx.fillRect(this.x, this.y, scale, scale);
  45.       }
  46.  
  47.       update() {
  48.         for (let i = 0; i < this.tail.length - 1; i++) {
  49.           this.tail[i] = this.tail[i + 1];
  50.         }
  51.         this.tail[this.total - 1] = { x: this.x, y: this.y };
  52.  
  53.         this.x += this.xSpeed;
  54.         this.y += this.ySpeed;
  55.  
  56.         if (this.x >= canvas.width) {
  57.           this.x = 0;
  58.         } else if (this.x < 0) {
  59.           this.x = canvas.width - scale;
  60.         }
  61.  
  62.         if (this.y >= canvas.height) {
  63.           this.y = 0;
  64.         } else if (this.y < 0) {
  65.           this.y = canvas.height - scale;
  66.         }
  67.       }
  68.  
  69.       changeDirection(direction) {
  70.         switch(direction) {
  71.           case 'Up':
  72.             if (this.ySpeed !== scale * 1) {
  73.               this.xSpeed = 0;
  74.               this.ySpeed = -scale * 1;
  75.             }
  76.             break;
  77.           case 'Down':
  78.             if (this.ySpeed !== -scale * 1) {
  79.               this.xSpeed = 0;
  80.               this.ySpeed = scale * 1;
  81.             }
  82.             break;
  83.           case 'Left':
  84.             if (this.xSpeed !== scale * 1) {
  85.               this.xSpeed = -scale * 1;
  86.               this.ySpeed = 0;
  87.             }
  88.             break;
  89.           case 'Right':
  90.             if (this.xSpeed !== -scale * 1) {
  91.               this.xSpeed = scale * 1;
  92.               this.ySpeed = 0;
  93.             }
  94.             break;
  95.         }
  96.       }
  97.  
  98.       eat(fruit) {
  99.         if (this.x === fruit.x && this.y === fruit.y) {
  100.           this.total++;
  101.           return true;
  102.         }
  103.         return false;
  104.       }
  105.  
  106.       collision() {
  107.         for (let i = 0; i < this.tail.length; i++) {
  108.           if (this.x === this.tail[i].x && this.y === this.tail[i].y) {
  109.             return true;
  110.           }
  111.         }
  112.         return false;
  113.       }
  114.  
  115.       getHeadPosition() {
  116.         return { x: this.x, y: this.y };
  117.       }
  118.     }
  119.  
  120.     // Fruit object
  121.     class Fruit {
  122.       constructor() {
  123.         this.x = (Math.floor(Math.random() * rows)) * scale;
  124.         this.y = (Math.floor(Math.random() * columns)) * scale;
  125.       }
  126.  
  127.       draw() {
  128.          ctx.fill
  129.         ctx.fillRect(this.x, this.y, scale, scale);
  130.       }
  131.     }
  132.  
  133.     // Q-learning RL agent
  134.     class QAgent {
  135.       constructor() {
  136.         this.qTable = {};
  137.         this.alpha = 0.1;
  138.         this.gamma = 0.9;
  139.          this.epsil
  140.         this.lastState = null;
  141.          this.lastActi
  142.       }
  143.  
  144.       getStateKey(state) {
  145.         return `${state.x},${state.y}`;
  146.       }
  147.  
  148.       chooseAction(state) {
  149.         if (Math.random() < this.epsilon || !(this.getStateKey(state) in this.qTable)) {
  150.            const acti 'Down', 'Left', 'Right'];
  151.           return actions[Math.floor(Math.random() * actions.length)];
  152.         } else {
  153.           const stateKey = this.getStateKey(state);
  154.            const acti
  155.            const maxActi b) => actionValues[a] > actionValues[b] ? a : b);
  156.           return maxAction;
  157.         }
  158.       }
  159.  
  160.       learn(state, action, reward, nextState) {
  161.         const stateKey = this.getStateKey(state);
  162.         const nextStateKey = this.getStateKey(nextState);
  163.  
  164.         if (!(stateKey in this.qTable)) {
  165.           this.qTable[stateKey] = { Up: 0, Down: 0, Left: 0, Right: 0 };
  166.         }
  167.  
  168.         if (!(nextStateKey in this.qTable)) {
  169.           this.qTable[nextStateKey] = { Up: 0, Down: 0, Left: 0, Right: 0 };
  170.         }
  171.  
  172.         const oldQValue = this.qTable[stateKey][action];
  173.         const maxNextQValue = Math.max(...Object.values(this.qTable[nextStateKey]));
  174.  
  175.         this.qTable[stateKey][action] += this.alpha * (reward + this.gamma * maxNextQValue - oldQValue);
  176.       }
  177.     }
  178.  
  179.     // Game initialization
  180.     let qAgent = new QAgent();
  181.     function init() {
  182.       snake = new Snake();
  183.       fruit = new Fruit();
  184.  
  185.       window.setInterval(() => {
  186.         ctx.clearRect(0, 0, canvas.width, canvas.height);
  187.         fruit.draw();
  188.         snake.update();
  189.         snake.draw();
  190.  
  191.         const state = snake.getHeadPosition();
  192.         const action = qAgent.chooseAction(state);
  193.         snake.changeDirection(action);
  194.  
  195.         const nextState = snake.getHeadPosition();
  196.         const reward = snake.eat(fruit) ? 1 : 0;
  197.  
  198.         qAgent.learn(state, action, reward, nextState);
  199.  
  200.         if (snake.collision()) {
  201.           alert("Game Over!");
  202.           snake = new Snake();
  203.           fruit = new Fruit();
  204.         }
  205.       }, 100);
  206.     }
  207.  
  208.     // Start the game
  209.     init();
  210.   [removed]
  211. </body>
  212. </html>
  213.