added "real ai" Ai snake
This commit is contained in:
@@ -98,18 +98,28 @@ function buttonUpgradeAIPressed(){
|
||||
break;
|
||||
|
||||
case "wallDetection":
|
||||
AItype = "nearApple";
|
||||
UpgradeAIPrice = 12;
|
||||
break;
|
||||
|
||||
case "nearApple":
|
||||
AItype = "appleBias";
|
||||
UpgradeAIPrice = 15;
|
||||
UpgradeAIPrice = 25;
|
||||
break;
|
||||
|
||||
case "appleBias":
|
||||
AItype = "snakeDetection";
|
||||
UpgradeAIPrice = 35;
|
||||
UpgradeAIPrice = 50;
|
||||
break;
|
||||
|
||||
case "snakeDetection":
|
||||
AItype = "smart";
|
||||
UpgradeAIPrice = 100;
|
||||
UpgradeAIPrice = 120;
|
||||
break;
|
||||
|
||||
case "smart":
|
||||
AItype = "survival";
|
||||
UpgradeAIPrice = 300;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -120,15 +130,15 @@ function buttonAddMoreApplesPressed(){
|
||||
}
|
||||
eatenApples -= AddMoreApplesPrice;
|
||||
if (appleAmount < 5){
|
||||
AddMoreApplesPrice = 1;
|
||||
AddMoreApplesPrice += 1;
|
||||
}else if (appleAmount < 10){
|
||||
AddMoreApplesPrice = 2;
|
||||
AddMoreApplesPrice += 2;
|
||||
}else if (appleAmount < 20){
|
||||
AddMoreApplesPrice = 3;
|
||||
AddMoreApplesPrice += 3;
|
||||
}else if (appleAmount < 50){
|
||||
AddMoreApplesPrice = 4;
|
||||
AddMoreApplesPrice += 4;
|
||||
}else{
|
||||
AddMoreApplesPrice = ceil(AddMoreApplesPrice*0.15);
|
||||
AddMoreApplesPrice += ceil(AddMoreApplesPrice*0.15);
|
||||
}
|
||||
summonApple();
|
||||
appleAmount++;
|
||||
@@ -339,6 +349,10 @@ function snakeAI(){
|
||||
snakeAIwallDetection();
|
||||
break;
|
||||
|
||||
case "nearApple":
|
||||
snakeAInearApple();
|
||||
break;
|
||||
|
||||
case "appleBias":
|
||||
snakeAIappleBias();
|
||||
break;
|
||||
@@ -350,9 +364,28 @@ function snakeAI(){
|
||||
case "smart":
|
||||
snakeAIsmart();
|
||||
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){
|
||||
|
||||
switch(direction){
|
||||
@@ -418,6 +451,36 @@ function getClosestApple(){
|
||||
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() {
|
||||
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(){
|
||||
|
||||
let apple = getClosestApple();
|
||||
@@ -448,28 +564,37 @@ function snakeAIappleBias(){
|
||||
return;
|
||||
}
|
||||
|
||||
let possibleDirections = [];
|
||||
let preferredDirections = [];
|
||||
|
||||
if (apple[0] > snake[0][0]){
|
||||
possibleDirections.push(0);
|
||||
preferredDirections.push(0);
|
||||
}
|
||||
|
||||
if (apple[1] > snake[0][1]){
|
||||
possibleDirections.push(1);
|
||||
preferredDirections.push(1);
|
||||
}
|
||||
|
||||
if (apple[0] < snake[0][0]){
|
||||
possibleDirections.push(2);
|
||||
preferredDirections.push(2);
|
||||
}
|
||||
|
||||
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])){
|
||||
snakeDirection = possibleDirections[i];
|
||||
let direction =
|
||||
preferredDirections[
|
||||
floor(random(preferredDirections.length))
|
||||
];
|
||||
|
||||
if (isDirectionSafe(direction)){
|
||||
snakeDirection = direction;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -508,7 +633,7 @@ function snakeAIsmart(){
|
||||
}
|
||||
|
||||
let bestDirection = snakeDirection;
|
||||
let bestDistance = Infinity;
|
||||
let bestScore = -999999;
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
|
||||
@@ -525,9 +650,16 @@ function snakeAIsmart(){
|
||||
abs(newX - apple[0]) +
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -535,6 +667,52 @@ function snakeAIsmart(){
|
||||
snakeDirection = bestDirection;
|
||||
}
|
||||
|
||||
function snakeAIrandomNowallHit(){
|
||||
snakeDirection = floor(random(0, 4));
|
||||
function snakeAIsurvival(){
|
||||
|
||||
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