// Player's snake and the AI snake class Snake{ static final int UP = 1; static final int RIGHT = 2; static final int DOWN = 4; static final int LEFT = 8; int [] x,y;//snake body array int d,len;//direction and length int col;//snake color int square_col; int path_col; boolean alive, AI; Vector path; Tile next; Snake(int d, int len, int col, int path_col, int square_col, int x_start, int y_start, boolean AI){ this.d = d; this.len = len; x = new int[len]; y = new int[len]; this.col = col; this.path_col = path_col; this.square_col = square_col; alive = true; this.AI = AI; path = new Vector(); for(int i = 0; i < len; i++){ x[i] = x_start; y[i] = y_start; } move(); } // Loop void main(){ move(); if(AI && alive){ AIEgg(); } else if(alive){ AIGuide(); } draw(); } // Read tin void move(){ //shift values along one grid[y[0]][x[0]].walkable = true; for (int i = 1; i < len; i++){ x[i-1] = x[i]; y[i-1] = y[i]; } switch(d){ case RIGHT: x[len-1]++; break; case DOWN: y[len-1]++; break; case LEFT: x[len-1]--; break; case UP: y[len-1]--; break; } //check for own body, walls and eggs if(x[len-1] < grid_size && x[len-1] > -1 && y[len-1] < grid_size && y[len-1] > -1){ // wall if(!grid[y[len-1]][x[len-1]].walkable){ alive = false; } else { // egg if(egg.x == x[len-1] && egg.y == y[len-1]){ for(int i = 0; i < random(1,6); i++){ x = append(x, x[len-1]); y = append(y, y[len-1]); ++len; } spawnEgg(); } // big egg if(big_egg != null){ if(big_egg.x == x[len-1] && big_egg.y == y[len-1]){ for(int i = 0; i < random(7,15); i++){ x = append(x, x[len-1]); y = append(y, y[len-1]); ++len; } big_egg = null; } } grid[y[len-1]][x[len-1]].walkable = false; } }else{ alive = false; } } // Read tin void draw(){ // draw body stroke(square_col); fill(col); for(int i = 0; i < len; i++){ rect(xc + x[i] * grid_unit, yc + y[i] * grid_unit, grid_unit, grid_unit); } // draw AI if(path != null){ if(path.size() > 0){ stroke(path_col); noFill(); for(int i = 0; i < path.size(); i++){ Tile temp = (Tile)path.elementAt(i); rect(1 + xc + temp.x * grid_unit, 1 + yc + temp.y * grid_unit, grid_unit-2, grid_unit-2); } } } } // Find a path to the egg and steer towards void AIEgg(){ if(big_egg != null){ path = astar.getPath(grid[y[len-1]][x[len-1]], big_egg.t); } else { path = astar.getPath(grid[y[len-1]][x[len-1]], egg.t); } if(path.size() > 0){ next = (Tile)path.elementAt(path.size()-1); //veer towards next node if(next.x > x[len-1] && d != LEFT) d = RIGHT; else if(next.y > y[len-1] && d != UP) d = DOWN; else if(next.x < x[len-1] && d != RIGHT) d = LEFT; else if(next.y < y[len-1] && d != DOWN) d = UP; } else { AIObject(); } } // AStar has failed, avoid walls and self void AIObject(){ boolean free = false; int deadmeat = 0; while(!free){ //veer away from wall switch(d){ case RIGHT: if(x[len-1] + 1 < grid_size) free = true; else{ d = random(2) == 1 ? DOWN : UP; free = false; } break; case DOWN: if(y[len-1] + 1 < grid_size) free = true; else{ d = random(2) == 1 ? LEFT : RIGHT; free = false; } break; case LEFT: if(x[len-1] - 1 > -1) free = true; else{ d = random(2) == 1 ? UP : DOWN; free = false; } break; case UP: if(y[len-1] - 1 > -1) free = true; else{ d = random(2) == 1 ? RIGHT : LEFT; free = false; } break; } //veer away from tail switch(d){ case RIGHT: if(x[len-1] + 1 < grid_size - 1){ if(grid[y[len-1]][x[len-1]+1].walkable) free = true; else{ free = false; d = random(2) == 1 ? DOWN : UP; } } break; case DOWN: if(y[len-1] + 1 < grid_size - 1){ if(grid[y[len-1]+1][x[len-1]].walkable) free = true; else{ free = false; d = random(2) == 1 ? LEFT : RIGHT; } } break; case LEFT: if(x[len-1] - 1 > -1){ if(grid[y[len-1]][x[len-1]-1].walkable) free = true; else{ free = false; d = random(2) == 1 ? UP : DOWN; } } break; case UP: if(y[len-1] - 1 > -1){ if(grid[y[len-1]-1][x[len-1]].walkable) free = true; else{ free = false; d = random(2) == 1 ? RIGHT : LEFT; } } break; } if(++deadmeat > 7) break; } } // Generate a guide for the player void AIGuide(){ if(big_egg != null){ path = astar.getPath(grid[y[len-1]][x[len-1]], big_egg.t); } else { path = astar.getPath(grid[y[len-1]][x[len-1]], egg.t); } } }