// Cloned by Aniket Lilwani on 10 Nov 2024 from World "A star" by "Coding Train" project
// Please leave this clone trail here.
// This Program is Solely Completed by Aniket Lilwani Individually without any group.
function removeFromArray(arr, elt) {
for (var i = arr.length - 1; i >= 0; i--) {
if (arr[i] == elt) {
arr.splice(i, 1);
}
}
}
function heuristic(a,b){
// return dist(a.i, a.j, b.i, b.j);
return abs(a.i-b.i) + abs(a.j-b.j);
}
var isReachable = true;
let cars = [];
var cols = 25;
var rows = 25;
var grid = new Array(cols);
var openSets = [[],[],[],[]];
var closedSets = [[],[],[],[]];
var openSet = [];
var closedSet = [];
var count = 0;
const carsStart = [];
const carsEnd = [];
var counter = 0;
var w,h; //
var allCompleted = false;
var countRound = [0,0,0,0];
var storedPath = [];
var paths = [];
var path = [];
var temppath = [];
var start;
var end;
var ind = 0;
var currentCompletion = [false,false,false,false];
var notFinished = [true,true,true,true];
var blocked = [false,false,false,false]; // Blocked Array to check if the Cars are colliding.
/*
Pre-Loading of the images visible in the grid with proper dimensions.
this was learnt from https://editor.p5js.org/xinxin/sketches/nC-CYIRGt
*/
function preload(){
img = loadImage('uploads/sleepyaniket/grassback.jpg');
img1 = loadImage('uploads/sleepyaniket/mud.jpg');
img2 = loadImage('uploads/sleepyaniket/homenew.png')
cars[0] = loadImage('uploads/sleepyaniket/car1.png');
cars[1] = loadImage('uploads/sleepyaniket/car2.png');
cars[2] = loadImage('uploads/sleepyaniket/car3.png');
cars[3] = loadImage('uploads/sleepyaniket/car4.png');
}
/*
Function to create Randomized Obstacles including grass mud and houses at random
This Code was written by Me but it was inspired by the following tutorial https://happycoding.io/tutorials/p5js/creating-functions/town
*/
function createObstacle(grid,img,choice){
var height = int(cols/5);
var width = int(random(5,8));
var randomX = int(random(1,rows-1));
var randomY = int(random(1,cols-1));
for(var i = randomX;i<randomX+width;i++){
for(var j = randomY;j<randomY+height;j++){
if(i < rows && j < cols ){
if(choice == 1)
grid[i][j].showImage(img);
else
var ans = int(random(0,50));
if(ans % 5 == 0)
grid[i][j].showImage(img2);
else
grid[i][j].showImage(img);
grid[i][j].wall = true;
}
}
}
}
function Cell(i,j){
this.i = i;
this.j = j;
this.f = 0;
this.g = 0;
this.h = 0;
this.car = false;
this.neighbors = [];
this.wall = false;
this.showImage = function(img){
image(img, this.i*w,this.j*h,w,h);
};
this.show = function(col){
fill(col);
noStroke();
rect(this.i*w,this.j*h,w-1,h-1);
};
this.addNeighbors = function(grid){
if(i < cols-1)
this.neighbors.push(grid[this.i+1][j]);
if(i > 0)
this.neighbors.push(grid[this.i-1][j]);
if(j < rows-1)
this.neighbors.push(grid[this.i][j+1]);
if(j > 0)
this.neighbors.push(grid[this.i][j-1]);
}
}
function setup(){
createCanvas(700,700);
colorArray = [color('#E56399'),color('#3a86ff'), color('#a8dadc'), color('#ffbe0b'),color('#E56399')];
w = width / cols;
h = height/ rows;
for(var i =0;i<cols;i++){
grid[i]= new Array(rows);
}
for(i = 0;i<cols;i++){
for(var j =0;j<rows;j++){
grid[i][j] = new Cell(i,j);
}
}
for ( i = 0; i < cols; i++) {
for ( j = 0; j < rows; j++) {
grid[i][j].addNeighbors(grid);
}
}
for(i = 0;i < int(random(6,9));i++){
if(i % 2 == 0)
createObstacle(grid,img,0);
else
createObstacle(grid,img1,1);
}
/*Random Starts for Cars
This was solely Written by Me only
*/
for( i = 0;i < 4;i++){
randX = Math.ceil(random(0,rows-1));
randY = Math.ceil(random(0,rows-1));
grid[randX][randY].car = true;
while((grid[randX][randY].wall)){
randX = Math.ceil(random(0,cols-1));
randY = Math.ceil(random(0,cols-1));
}
grid[randX][randY].wall = true;
grid[randX][randY].car = true;
carsStart[i] = [randX,randY];
}
for( i = 0;i < cols;i++){
for( j = 0; j < rows;j++){
if(!grid[i][j].wall)
grid[i][j].show(color(128,126,120));
}
}
for( i= 0;i<carsStart.length;i++){
var arrStart = carsStart[i];
grid[arrStart[0]][arrStart[1]].show(colorArray[i]);
grid[arrStart[0]][arrStart[1]].showImage(cars[i]);
}
/*Randomized ends for cars*/
for( i = 0;i < 4;i++){
randX = Math.ceil(random(0,rows-1));
randY = Math.ceil(random(0,rows-1));
while((grid[randX][randY].wall)){
randX = Math.ceil(random(0,cols-1));
randY = Math.ceil(random(0,cols-1));
}
grid[randX][randY].show(colorArray[i]);
carsEnd[i] = [randX,randY];
}
for(i = 0;i<4;i++){
var strt = carsStart[i];
openSets[i].push(grid[strt[0]][strt[1]]);
}
strt = carsStart[0];
start = grid[strt[0]][strt[1]];
strt = carsEnd[0];
end = grid[strt[0]][strt[1]];
openSet.push(start);
}
function aStar(index){
if(openSet.length > 0){
var winner = 0;
for(var i = 0;i<openSet.length;i++){
if(openSet[i].f < openSet[winner].f){
winner = i;
}
}
var current = openSet[winner];
if(current === end){
start.wall = false;
start.car = false;
path.pop();
paths.push(path);
storedPath.push(temppath);
currentCompletion[index] = true;
}
removeFromArray(openSet, current);
closedSet.push(current);
var neighbors = current.neighbors;
for (i = 0; i < neighbors.length; i++) {
var neighbor = neighbors[i];
if (!closedSet.includes(neighbor) && !neighbor.wall && !neighbor.car) {
var tempG = current.g + heuristic(neighbor, current);
var newPath = false;
if (openSet.includes(neighbor)) {
if (tempG < neighbor.g) {
neighbor.g = tempG;
newPath = true;
}
} else {
neighbor.g = tempG;
newPath = true;
openSet.push(neighbor);
}
if(newPath) {
neighbor.h = heuristic(neighbor, end);
neighbor.f = neighbor.g + neighbor.h;
neighbor.previous = current;
}
}
}
}
else{
currentCompletion[index] = true;
path = [start];
paths.push(path);
return;
}
path = [];
temppath = [];
var temp = current;
path.push(temp);
temppath.push(temp);
let count = 0;
while (temp.previous) {
count++;
if(count > 1000){
isAllowed = false;
index ++;
break;
}
path.push(temp.previous);
temppath.push(temp.previous);
var c = temp.previous;
temp = temp.previous;
}
}
function draw(){
/*Code by Aniket Lilwani*/
if(!allCompleted && ind < 4){
aStar(ind);
if(currentCompletion[ind]){
ind++;
if(ind < 4){
openSet = [];
closedSet = [];
var startV = carsStart[ind];
var endV = carsEnd[ind];
start = grid[startV[0]][startV[1]];
end = grid[endV[0]][endV[1]];
openSet.push(start);
}
}
}
if(ind > 3){
allCompleted = false;
setInterval(() => {
showPaths(paths);
}, 250);
/*
Seconds displaying cars can be increased and decreased by the above setIntervals function . NOTE Time is in milliseconds.
Code by Aniket Lilwani*/
noLoop();
}
}
function recalculatePath(index){
var startV = carsStart[index];
var endV = carsEnd[index];
start = grid[startV[0]][startV[1]];
end = grid[endV[0]][endV[1]];
start.wall = false;
end.wall = false;
openSet.push(start);
}
function resetBlocked(){
for(var i = 0;i< 4;i++){
if(blocked[i]){
blocked[i] = false;
var path = paths[i];
for(var i = path.length-1;i >= 1;i--){
if(path[i].car){
path.pop();
continue;
}else{
path[i].show(colorArray[i]);
path[i].showImage(cars[i]);
}
}
}
}
}
function showPaths(paths){
/*Code by Aniket Lilwani*/
for(var i = 0;i<4;i++){
if(paths[i].length == 1){
counter++;
var path = paths[i];
path[0].car = true;
path[0].wall = true;
path[0].show(colorArray[i]);
var pth = carsEnd[i];
grid[pth[0]][pth[1]].showImage(cars[i]);
path.pop();
notFinished[i] = false;
}
if(notFinished[i] && paths[i].length > 1 && !blocked[i]){
var len = paths[i].length-1;
var path = paths[i];
path[len].car = false;
path[len].show(colorArray[i]);
len--;
if(!path[len].car){
path[len].show(colorArray[i]);
path[len].showImage(cars[i]);
path.pop();
path[len].car = true;
}else{
len++;
path[len].show(colorArray[i]);
path[len].car = false;
blocked[i] = true;
}
}
}
}