xxxxxxxxxx
612
//TODO
// Write a better shuffle function.
const DIM = 4;
var w,h;
var board=[]; // Array of cells;
var val=0;
var next=1;
var movecount=0;
var nextQ=1; // Next tile we need a queue for
var queue=[]; // Array containing moves for next tile
var highlight=false;
function setup() {
createCanvas(600, 600);
test = createP(movecount);
w=width/DIM;
h=height/DIM;
//frameRate(2);
for(var i=0; i< DIM; i++)
{
for(var j=0; j<DIM; j++)
{
val++;
board.push(new Cell(j*w, i*h, w, val));
}
}
board[board.length-1].value=0;
// Mix up the board
mixBoard();
//loadMoves(nextQ);
}
var highest=1;
var highIndex=0;
var search=false;
function draw() {
background(255);
// Find Next
highest=1;
highIndex=0;
search=true;
for(var i=0; i<board.length && search; i++)
{
if(board[i].value==highest)
{
highest++;
}
else
{
search=false;
}
}
for (var i=0; i<board.length; i++)
{
if(board[i].value==highest)
{
highIndex=i;
}
board[i].show();
}
{
//ellipseMode(CENTER);
if(highlight)
{
fill(0,255,0,50);
circle(board[highIndex].x+w/2, board[highIndex].y+h/2, w/2);
fill(0,0,255,50)
{
circle(board[highest-1].x+w/2, board[highest-1].y+h/2, w/2);
}
}
}
strokeWeight(2);
//line(0, height/2, width, height/2);
//line(width/2, 0, width/2, height);
strokeWeight(1);
//If we have moves in the queue
/* if(1==2)
//if(queue.length)
{
//console.log(queue.length);
nextM=queue[0];
queue.splice(0,1);
switch(nextM)
//switch(queue.pop())
{
case "UP": up();
break;
case "DOWN": down();
break;
case "LEFT": left();
break;
case "RIGHT": right();
break;
}
}
else // otherwise, load the next number's moves
{
//noLoop();
nextQ++;
loadMoves(nextQ);
}
*/
}
function mousePressed()
{
//swapCells(0, 8);
var test = coordToIndex(floor(mouseX/w), floor(mouseY/h));
moveCell(test);
//console.log(test);
var t2=rtnCoord(test);
//console.log(t2.x, t2.y);
//console.log(floor(mouseX/w), floor(mouseY/h));
}
// Takes two cells and swaps their positions
function swapCells(ind1, ind2)
{
//tempx=board[ind1].x;
//tempy=board[ind1].y;
tempv=board[ind1].value;
//temphx=board[ind1].homex;
//temphy=board[ind1].homey;
//board[ind1].x=board[ind2].x;
//board[ind1].y=board[ind2].y;
board[ind1].value=board[ind2].value;
//board[ind1].homex=board[ind2].homex;
//board[ind1].homey=board[ind2].homey;
//board[ind2].x=tempx;
//board[ind2].y=tempy;
board[ind2].value=tempv;
//board[ind2].homex=temphx;
//board[ind2].homey=temphy;
}
//Takes a row and column and returns
// the board index
function coordToIndex(c, r)
{
return(r*DIM)+c;
}
function rtnCoord(ind)
{
//console.log("IND: " +ind);
var cds=createVector(0,0);
cds.x=ind % DIM;
cds.y=floor(ind / DIM);
//console.log("COORDS: " + cds);
return cds;
}
// Checks click.
// if cell is next to a blank cell,
// moves that cell to the blank cell.
function moveCell(ind)
{
// First check all neighbors for a blank
var pos=rtnCoord(ind);
var coordx=pos.x; // My X Coord
var coordy=pos.y; // My Y Coord
var compind;
var compx; // X coord of cell i'm checking
var compy; // Y coord of cell I'm checking
var blankInd=-1;
// Left edge (but not corners)
//if((coordx==0) && (coordy!==0) && (coordy!==DIM-1))
{
compx=coordx;
compy=coordy-1;
compind=coordToIndex(compx, compy);
// Check above,
if(coordy!==0)
{
if(board[compind].value==0)
{
blankInd=compind;
//console.log("UP");
swapCells(compind, ind)
}
}
// Check right
if((blankInd<0) && (coordx<DIM-1))
{
compx=coordx+1;
compy=coordy;
compind=coordToIndex(compx, compy);
if(board[compind].value==0)
{
blankInd=compind;
swapCells(compind,ind)
}
}
// Check Down
if((blankInd<0) && (coordy<DIM-1))
{
compx=coordx;
compy=coordy+1;
compind=coordToIndex(compx, compy);
if(board[compind].value==0)
{
blankInd=compind;
//console.log("DOWN");
swapCells(compind, ind)
}
}
// Check Left
if((blankInd<0) && (coordx>0))
{
compx=coordx-1;
compy=coordy;
compind=coordToIndex(compx, compy);
if(board[compind].value==0)
{
blankInd=compind;
swapCells(compind, ind)
}
}
}
var correct=true;
for(var i=0; i<board.length-1 && correct; i++)
{
if(board[i].value!=i+1)
{
correct=false;
}
}
if(correct)
{
console.log("SOLVED!");
}
}
function mixBoard()
{
var blankInd;
var blank=false;
// Verify Where the blank tile is
for(var i=0; i<board.length && !blank; i++)
{
if(board[i].value==0)
{
blankInd=i;
blank=true;
}
}
var pos=rtnCoord(blankInd);
var blankx=pos.x;
var blanky=pos.y;
var swapx;
var swapy;
var swapind;
var choices=[];
// Make bout a thousand moves
// to mix up the board
for(var i=0; i<1000*DIM; i++)
{
choices.length=0;
pos=rtnCoord(blankInd);
blankx=pos.x;
blanky=pos.y
// Figure out legal directions for the
// blank to go
// Blank is not on the left side
// We can swap left
if(blankx>0)
{
choices.push("LEFT");
}
// Blank is not on the right side
if(blankx<DIM-1)
{
choices.push("RIGHT");
}
// Blank is not at the top
if(blanky>0)
{
choices.push("UP");
}
//Blank is not at the bottom
if(blanky<DIM-1)
{
choices.push("DOWN");
}
switch (random(choices))
{
case "LEFT": swapx=blankx-1;
swapy=blanky;
break;
case "RIGHT":swapx=blankx+1;
swapy=blanky;
break;
case "UP": swapx=blankx;
swapy=blanky-1;
break;
case "DOWN": swapx=blankx;
swapy=blanky+1;
break;
}
swapInd=coordToIndex(swapx, swapy);
moveCell(swapInd);
blankInd=swapInd;
}
}
// This is me starting to implement an autosolver
// Moves the tile that is to the right
// of the blank into the blank spot.
function left()
{
var blankInd=findBlank();
var pos=rtnCoord(blankInd);
var blankx=pos.x;
var blanky=pos.y;
var swapx;
var swapy;
var swapind;
if(blankx<DIM-1)
{
swapx=blankx+1;
swapy=blanky;
swapInd=coordToIndex(swapx, swapy);
moveCell(swapInd);
blankInd=swapInd;
}
}
function right()
{
var blankInd=findBlank();
var pos=rtnCoord(blankInd);
var blankx=pos.x;
var blanky=pos.y;
var swapx;
var swapy;
var swapind;
if(blankx>0)
{
swapx=blankx-1;
swapy=blanky;
swapInd=coordToIndex(swapx, swapy);
moveCell(swapInd);
blankInd=swapInd;
}
}
function down()
{
var blankInd=findBlank();
var pos=rtnCoord(blankInd);
var blankx=pos.x;
var blanky=pos.y;
var swapx;
var swapy;
var swapind;
if(blanky>0)
{
swapx=blankx;
swapy=blanky-1;
swapInd=coordToIndex(swapx, swapy);
moveCell(swapInd);
blankInd=swapInd;
}
}
function up()
{
var blankInd=findBlank();
var pos=rtnCoord(blankInd);
var blankx=pos.x;
var blanky=pos.y;
var swapx;
var swapy;
var swapind;
if(blanky<DIM-1)
{
swapx=blankx;
swapy=blanky+1;
swapInd=coordToIndex(swapx, swapy);
moveCell(swapInd);
blankInd=swapInd;
}
}
// Returns index of blank tile
function findBlank()
{
var blankInd;
var blank=false;
// Verify Where the blank tile is
for(var i=0; i<board.length && !blank; i++)
{
if(board[i].value==0)
{
blankInd=i;
blank=true;
}
}
return blankInd;
}
function keyPressed()
{
movecount++;
test.html(movecount);
// console.log(keyCode);
switch(keyCode)
{
case 37: right();
break;
case 39: left();
break;
case 40: up();
break;
case 38: down();
break;
case 72: highlight=!highlight;
}
}
// Try to create an autosolver
// This will load all of the moves
// required for the nextTile
function loadMoves(nt)
{
// Find where the blank tile is
var blankInd;
blankInd=findBlank();
var pos=rtnCoord(blankInd);
var blankx=pos.x;
var blanky=pos.y;
// Find where the next tile we are looking for is.
var nextInd=findNext(nt);
nextpos=rtnCoord(nextInd);
nextx=nextpos.x;
nexty=nextpos.y;
// Find where the next tile needs to go
var targetpos=rtnCoord(nt-1);
var targetx=targetpos.x
var targety=targetpos.y;
console.log("Current: " + nextx + "," + nexty);
console.log("Target: " + targetx + "," + targety);
console.log("Blank: " + blankx + "," + blanky);
// Verify that next tile passed in is
// not where it is supposed to be
// if it is, we don't do anything
if(board[nt-1].value!= nt)
{
//console.log(board[nt-1].value);
// This is where it gets kind of dirty
// There are all kinds of scenarios we have to
// account for like edges and such.
// Just for testing we are ignoring edge cases and trying to verify if our idea works first
if(blanky > nexty)
{
for(var i=0; i< (blanky-nexty)+1; i++)
{
queue.push("DOWN");
}
}
else if (blanky <nexty)
{
for(var i=0; i< (nexty-blanky)-1; i++)
{
queue.push("UP");
}
}
if(blankx>nextx)
{
for(var i=0; i<blankx-nextx; i++)
{
queue.push("RIGHT");
}
}
else if (blankx<nextx)
{
for(var i=0; i<nextx-blankx; i++)
{
queue.push("LEFT");
}
}
if(nextx<DIM-1)
{
for(var i=0; i<(nexty-targety)-1; i++)
{
queue.push("UP");
queue.push("LEFT");
queue.push("DOWN");
queue.push("DOWN");
queue.push("RIGHT");
}
queue.push("UP");
if(nextx>targetx)
{
queue.push("RIGHT");
queue.push("DOWN");
for(var i=0; i<(nextx-targetx)-1; i++)
{
queue.push("LEFT");
queue.push("UP");
queue.push("RIGHT");
queue.push("RIGHT");
queue.push("DOWN");
}
queue.push("LEFT");
}
}
}
//console.log(queue);
//noLoop();
}
function findNext(n)
{
var nxtInd;
var found=false;
// Verify Where the next tile is
for(var i=0; i<board.length && !found; i++)
{
if(board[i].value==n)
{
nxtInd=i;
found=true;
}
}
return nxtInd;
}