diff --git a/sketches/snake.js b/sketches/snake.js index 698331c..188f28c 100644 --- a/sketches/snake.js +++ b/sketches/snake.js @@ -83,11 +83,35 @@ function buttonAddRowsPressed(){ } } function buttonUpgradeAIPressed(){ + if (eatenApples < UpgradeAIPrice) { return; } + eatenApples -= UpgradeAIPrice; - AItype = "smart"; + + switch (AItype) { + + case "random": + AItype = "wallDetection"; + UpgradeAIPrice = 5; + break; + + case "wallDetection": + AItype = "appleBias"; + UpgradeAIPrice = 15; + break; + + case "appleBias": + AItype = "snakeDetection"; + UpgradeAIPrice = 35; + break; + + case "snakeDetection": + AItype = "smart"; + UpgradeAIPrice = 100; + break; + } } function buttonAddMoreApplesPressed(){ @@ -95,6 +119,17 @@ function buttonAddMoreApplesPressed(){ return; } eatenApples -= AddMoreApplesPrice; + if (appleAmount < 5){ + AddMoreApplesPrice = 1; + }else if (appleAmount < 10){ + AddMoreApplesPrice = 2; + }else if (appleAmount < 20){ + AddMoreApplesPrice = 3; + }else if (appleAmount < 50){ + AddMoreApplesPrice = 4; + }else{ + AddMoreApplesPrice = ceil(AddMoreApplesPrice*0.15); + } summonApple(); appleAmount++; } @@ -270,7 +305,7 @@ function draw() { text("AI: " + AItype, gridColumns * gridSize + gridSize, _textSize * 3); buttonUpgradeAI.html("Upgrade AI ₴ " + UpgradeAIPrice); - buttonUpgradeAI.position(gridColumns * gridSize + gridSize + _textSize*6, _textSize * 2.5); + buttonUpgradeAI.position(gridColumns * gridSize + gridSize + _textSize*((4+AItype.length)*0.6), _textSize * 2.5); text("Coloums: " + gridColumns, gridColumns * gridSize + gridSize, _textSize * 4); @@ -293,17 +328,213 @@ function mousePressed() { } function snakeAI(){ + switch (AItype) { + case "random": snakeAIrandom(); break; + + case "wallDetection": + snakeAIwallDetection(); + break; + + case "appleBias": + snakeAIappleBias(); + break; + + case "snakeDetection": + snakeAIsnakeDetection(); + break; + + case "smart": + snakeAIsmart(); + break; } } +function directionToVector(direction){ + + switch(direction){ + case 0: + return [1, 0]; + + case 1: + return [0, 1]; + + case 2: + return [-1, 0]; + + case 3: + return [0, -1]; + } +} + +function isDirectionSafe(direction){ + + let vec = directionToVector(direction); + + let newX = snake[0][0] + vec[0]; + let newY = snake[0][1] + vec[1]; + + if ( + newX < 0 || + newY < 0 || + newX >= grid.length || + newY >= grid[0].length + ){ + return false; + } + + if (grid[newX][newY] == 2){ + return false; + } + + return true; +} + +function getClosestApple(){ + + let bestApple = null; + let bestDistance = Infinity; + + for (let i = 0; i < grid.length; i++) { + for (let j = 0; j < grid[0].length; j++) { + + if (grid[i][j] == 1){ + + let distance = + abs(snake[0][0] - i) + + abs(snake[0][1] - j); + + if (distance < bestDistance){ + bestDistance = distance; + bestApple = [i, j]; + } + } + } + } + + return bestApple; +} + function snakeAIrandom() { snakeDirection = floor(random(0, 4)); } +function snakeAIwallDetection(){ + + let tries = 0; + + while (tries < 20){ + + let direction = floor(random(0, 4)); + + if (isDirectionSafe(direction)){ + snakeDirection = direction; + return; + } + + tries++; + } +} + +function snakeAIappleBias(){ + + let apple = getClosestApple(); + + if (apple == null){ + snakeAIwallDetection(); + return; + } + + let possibleDirections = []; + + if (apple[0] > snake[0][0]){ + possibleDirections.push(0); + } + + if (apple[1] > snake[0][1]){ + possibleDirections.push(1); + } + + if (apple[0] < snake[0][0]){ + possibleDirections.push(2); + } + + if (apple[1] < snake[0][1]){ + possibleDirections.push(3); + } + + for (let i = 0; i < possibleDirections.length; i++) { + + if (isDirectionSafe(possibleDirections[i])){ + snakeDirection = possibleDirections[i]; + return; + } + } + + snakeAIwallDetection(); +} + +function snakeAIsnakeDetection(){ + + let safeDirections = []; + + for (let i = 0; i < 4; i++) { + + if (isDirectionSafe(i)){ + safeDirections.push(i); + } + } + + if (safeDirections.length <= 0){ + return; + } + + snakeDirection = + safeDirections[ + floor(random(0, safeDirections.length)) + ]; +} + +function snakeAIsmart(){ + + let apple = getClosestApple(); + + if (apple == null){ + snakeAIsnakeDetection(); + return; + } + + let bestDirection = snakeDirection; + let bestDistance = Infinity; + + for (let i = 0; i < 4; i++) { + + if (!isDirectionSafe(i)){ + continue; + } + + let vec = directionToVector(i); + + let newX = snake[0][0] + vec[0]; + let newY = snake[0][1] + vec[1]; + + let distance = + abs(newX - apple[0]) + + abs(newY - apple[1]); + + if (distance < bestDistance){ + + bestDistance = distance; + bestDirection = i; + } + } + + snakeDirection = bestDirection; +} + function snakeAIrandomNowallHit(){ snakeDirection = floor(random(0, 4)); } \ No newline at end of file