added "real ai" Ai snake
This commit is contained in:
@@ -98,18 +98,28 @@ function buttonUpgradeAIPressed(){
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "wallDetection":
|
case "wallDetection":
|
||||||
|
AItype = "nearApple";
|
||||||
|
UpgradeAIPrice = 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "nearApple":
|
||||||
AItype = "appleBias";
|
AItype = "appleBias";
|
||||||
UpgradeAIPrice = 15;
|
UpgradeAIPrice = 25;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "appleBias":
|
case "appleBias":
|
||||||
AItype = "snakeDetection";
|
AItype = "snakeDetection";
|
||||||
UpgradeAIPrice = 35;
|
UpgradeAIPrice = 50;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "snakeDetection":
|
case "snakeDetection":
|
||||||
AItype = "smart";
|
AItype = "smart";
|
||||||
UpgradeAIPrice = 100;
|
UpgradeAIPrice = 120;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "smart":
|
||||||
|
AItype = "survival";
|
||||||
|
UpgradeAIPrice = 300;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,15 +130,15 @@ function buttonAddMoreApplesPressed(){
|
|||||||
}
|
}
|
||||||
eatenApples -= AddMoreApplesPrice;
|
eatenApples -= AddMoreApplesPrice;
|
||||||
if (appleAmount < 5){
|
if (appleAmount < 5){
|
||||||
AddMoreApplesPrice = 1;
|
AddMoreApplesPrice += 1;
|
||||||
}else if (appleAmount < 10){
|
}else if (appleAmount < 10){
|
||||||
AddMoreApplesPrice = 2;
|
AddMoreApplesPrice += 2;
|
||||||
}else if (appleAmount < 20){
|
}else if (appleAmount < 20){
|
||||||
AddMoreApplesPrice = 3;
|
AddMoreApplesPrice += 3;
|
||||||
}else if (appleAmount < 50){
|
}else if (appleAmount < 50){
|
||||||
AddMoreApplesPrice = 4;
|
AddMoreApplesPrice += 4;
|
||||||
}else{
|
}else{
|
||||||
AddMoreApplesPrice = ceil(AddMoreApplesPrice*0.15);
|
AddMoreApplesPrice += ceil(AddMoreApplesPrice*0.15);
|
||||||
}
|
}
|
||||||
summonApple();
|
summonApple();
|
||||||
appleAmount++;
|
appleAmount++;
|
||||||
@@ -339,6 +349,10 @@ function snakeAI(){
|
|||||||
snakeAIwallDetection();
|
snakeAIwallDetection();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "nearApple":
|
||||||
|
snakeAInearApple();
|
||||||
|
break;
|
||||||
|
|
||||||
case "appleBias":
|
case "appleBias":
|
||||||
snakeAIappleBias();
|
snakeAIappleBias();
|
||||||
break;
|
break;
|
||||||
@@ -350,9 +364,28 @@ function snakeAI(){
|
|||||||
case "smart":
|
case "smart":
|
||||||
snakeAIsmart();
|
snakeAIsmart();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "survival":
|
||||||
|
snakeAIsurvival();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAppleVisionDistance(){
|
||||||
|
|
||||||
|
if (appleAmount < 5){
|
||||||
|
return 2;
|
||||||
|
}else if (appleAmount < 15){
|
||||||
|
return 3;
|
||||||
|
}else if (appleAmount < 30){
|
||||||
|
return 5;
|
||||||
|
}else if (appleAmount < 60){
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
function directionToVector(direction){
|
function directionToVector(direction){
|
||||||
|
|
||||||
switch(direction){
|
switch(direction){
|
||||||
@@ -418,6 +451,36 @@ function getClosestApple(){
|
|||||||
return bestApple;
|
return bestApple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function countFreeNeighbors(x, y){
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
let dirs = [
|
||||||
|
[1,0],
|
||||||
|
[0,1],
|
||||||
|
[-1,0],
|
||||||
|
[0,-1]
|
||||||
|
];
|
||||||
|
|
||||||
|
for (let i = 0; i < dirs.length; i++) {
|
||||||
|
|
||||||
|
let nx = x + dirs[i][0];
|
||||||
|
let ny = y + dirs[i][1];
|
||||||
|
|
||||||
|
if (
|
||||||
|
nx >= 0 &&
|
||||||
|
ny >= 0 &&
|
||||||
|
nx < grid.length &&
|
||||||
|
ny < grid[0].length &&
|
||||||
|
grid[nx][ny] != 2
|
||||||
|
){
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
function snakeAIrandom() {
|
function snakeAIrandom() {
|
||||||
snakeDirection = floor(random(0, 4));
|
snakeDirection = floor(random(0, 4));
|
||||||
}
|
}
|
||||||
@@ -439,6 +502,59 @@ function snakeAIwallDetection(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function snakeAInearApple(){
|
||||||
|
|
||||||
|
let visionDistance = getAppleVisionDistance();
|
||||||
|
|
||||||
|
for (let i = 0; i < grid.length; i++) {
|
||||||
|
for (let j = 0; j < grid[0].length; j++) {
|
||||||
|
|
||||||
|
if (grid[i][j] != 1){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let distance =
|
||||||
|
abs(snake[0][0] - i) +
|
||||||
|
abs(snake[0][1] - j);
|
||||||
|
|
||||||
|
if (distance <= visionDistance){
|
||||||
|
|
||||||
|
let possibleDirections = [];
|
||||||
|
|
||||||
|
if (i > snake[0][0]){
|
||||||
|
possibleDirections.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j > snake[0][1]){
|
||||||
|
possibleDirections.push(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < snake[0][0]){
|
||||||
|
possibleDirections.push(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < snake[0][1]){
|
||||||
|
possibleDirections.push(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let k = 0; k < possibleDirections.length; k++) {
|
||||||
|
|
||||||
|
if (isDirectionSafe(possibleDirections[k])){
|
||||||
|
|
||||||
|
// 70% chance to follow apple
|
||||||
|
if (random() < 0.7){
|
||||||
|
snakeDirection = possibleDirections[k];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
snakeAIwallDetection();
|
||||||
|
}
|
||||||
|
|
||||||
function snakeAIappleBias(){
|
function snakeAIappleBias(){
|
||||||
|
|
||||||
let apple = getClosestApple();
|
let apple = getClosestApple();
|
||||||
@@ -448,28 +564,37 @@ function snakeAIappleBias(){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let possibleDirections = [];
|
let preferredDirections = [];
|
||||||
|
|
||||||
if (apple[0] > snake[0][0]){
|
if (apple[0] > snake[0][0]){
|
||||||
possibleDirections.push(0);
|
preferredDirections.push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apple[1] > snake[0][1]){
|
if (apple[1] > snake[0][1]){
|
||||||
possibleDirections.push(1);
|
preferredDirections.push(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apple[0] < snake[0][0]){
|
if (apple[0] < snake[0][0]){
|
||||||
possibleDirections.push(2);
|
preferredDirections.push(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apple[1] < snake[0][1]){
|
if (apple[1] < snake[0][1]){
|
||||||
possibleDirections.push(3);
|
preferredDirections.push(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < possibleDirections.length; i++) {
|
// 65% chance to go toward apple
|
||||||
|
if (
|
||||||
|
preferredDirections.length > 0 &&
|
||||||
|
random() < 0.65
|
||||||
|
){
|
||||||
|
|
||||||
if (isDirectionSafe(possibleDirections[i])){
|
let direction =
|
||||||
snakeDirection = possibleDirections[i];
|
preferredDirections[
|
||||||
|
floor(random(preferredDirections.length))
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isDirectionSafe(direction)){
|
||||||
|
snakeDirection = direction;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -508,7 +633,7 @@ function snakeAIsmart(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
let bestDirection = snakeDirection;
|
let bestDirection = snakeDirection;
|
||||||
let bestDistance = Infinity;
|
let bestScore = -999999;
|
||||||
|
|
||||||
for (let i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
|
|
||||||
@@ -525,9 +650,16 @@ function snakeAIsmart(){
|
|||||||
abs(newX - apple[0]) +
|
abs(newX - apple[0]) +
|
||||||
abs(newY - apple[1]);
|
abs(newY - apple[1]);
|
||||||
|
|
||||||
if (distance < bestDistance){
|
let freeNeighbors =
|
||||||
|
countFreeNeighbors(newX, newY);
|
||||||
|
|
||||||
bestDistance = distance;
|
let score =
|
||||||
|
(-distance * 3) +
|
||||||
|
(freeNeighbors * 8);
|
||||||
|
|
||||||
|
if (score > bestScore){
|
||||||
|
|
||||||
|
bestScore = score;
|
||||||
bestDirection = i;
|
bestDirection = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,6 +667,52 @@ function snakeAIsmart(){
|
|||||||
snakeDirection = bestDirection;
|
snakeDirection = bestDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
function snakeAIrandomNowallHit(){
|
function snakeAIsurvival(){
|
||||||
snakeDirection = floor(random(0, 4));
|
|
||||||
|
let bestDirection = snakeDirection;
|
||||||
|
let bestScore = -999999;
|
||||||
|
|
||||||
|
let apple = getClosestApple();
|
||||||
|
|
||||||
|
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 freeNeighbors =
|
||||||
|
countFreeNeighbors(newX, newY);
|
||||||
|
|
||||||
|
let score = freeNeighbors * 20;
|
||||||
|
|
||||||
|
if (apple != null){
|
||||||
|
|
||||||
|
let distance =
|
||||||
|
abs(newX - apple[0]) +
|
||||||
|
abs(newY - apple[1]);
|
||||||
|
|
||||||
|
score -= distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// avoid tunnels
|
||||||
|
if (freeNeighbors <= 1){
|
||||||
|
score -= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// slight randomness
|
||||||
|
score += random(-3, 3);
|
||||||
|
|
||||||
|
if (score > bestScore){
|
||||||
|
|
||||||
|
bestScore = score;
|
||||||
|
bestDirection = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
snakeDirection = bestDirection;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user