//////////////////////////////////////////////////////////////////////////
function cmap(fn,c){
	return {x: fn(c.x), y: fn(c.y)};
}

function forRange(min,max,fn){
	for(var x=min;x<=max;x++){
		fn(x);
	}
}

function abs(x){return (x<0?-x:x);}

function whichWay(start, end){
	delta=cmap(abs, {x: end.x-start.x, y: end.y-start.y});

	if(delta.x>delta.y)return 'h-then-v';
	if(delta.y>delta.x)return 'v-then-h';
	return 'diag';
}

function copy(c){
	return {x:c.x,y:c.y};
}

function same(a,b){
	return (a.x==b.x && a.y==b.y);
}

function goH(curr,goal){
	if(curr.x<goal.x)curr.x++;
	else if(curr.x>goal.x)curr.x--;
}

function goV(curr,goal){
	if(curr.y<goal.y)curr.y++;
	else if(curr.y>goal.y)curr.y--;
}

function path(start, end){
	var way=whichWay(start,end);
	var curr={x:start.x, y:start.y};
	if(way=='diag'){
		return function(){
			if(same(curr,end))return null;
			goH(curr,end);
			goV(curr,end);
			return copy(curr);
		}
	} else if(way=='h-then-v'){
		return function(){
			if(same(curr,end))return null;
			if(curr.x!=end.x)goH(curr,end);
			else goV(curr,end);
			return copy(curr);
		}
	} else if(way=='v-then-h'){
		return function(){
			if(same(curr,end))return null;
			if(curr.y!=end.y)goV(curr,end);
			else goH(curr,end);
			return copy(curr);
		}
	}
}

function randomCoords(num,maxx,maxy){
	if(!maxx || !maxy){maxx=maxy=MAXX;}
	var used=[];
	var coords=[];
	var cnt=0;
	while(cnt<num){
		var x=rand(maxx);
		var y=rand(maxy);
		if(!used[x+y*maxx]){
			used[x+y*maxx]=true;
			coords[coords.length]={x:x,y:y};
			cnt++;
		}
	}
	return coords;
}


function distance(start,end){
	var p=path(start,end);
	var c=p();
	var cnt=0;
	
	while(c!=null){
		cnt++;
		if(!same(c,end) && isBlocked(c))return null;
		c=p();
	}
	return cnt;
}


function setupBlocks(){
	blocks=[];
	for(i in islands){
		var isle=islands[i];
		blocks[isle.coord.y*MAXX+isle.coord.x]=true;
	}
	for(i in mines){
		var m=mines[i];
		blocks[m.coord.y*MAXX+m.coord.x]=true;
	}
}


function isBlocked(c){
	if(blocks==null)setupBlocks();
	return blocks[c.y*MAXX+c.x]!=null;
}


function getReturns(c){
	var ret=[];
	for(i in mines){
		var m=mines[i];
		var d=distance(c,m.coord);
		if(d)ret[ret.length]=d;
	}
	return unique(ret).sort();
}

function unique(a){
	var r=[];
	for(i in a){
		var t=a[i];
		if(!contains(r,t))
			r[r.length]=t;
	}
	return r;
}

function contains(arr,n){
	for(i in arr)
		if(arr[i]==n)return true;
	return false;
}

function removeMineAt(coord){
	for(i in mines){
		var x=i;
		var m=mines[x];
		if(same(m.coord,coord)){
			mines[x]=mines[mines.length-1];
			mines.length--;
			break;
		}
	}
}
/////////////// RNG from andrew@hedges.name //////////////////////
rnd.today = new Date();
rnd.seed  = rnd.today.getTime();

function rnd() {
   rnd.seed = (rnd.seed*9301+49297) % 233280;
   return rnd.seed/(233280.0);
}

function rand(number) {
   return Math.floor(rnd()*number);
}
//////////////////////////////////////////////////////////////////

function makeIsland(){
	return {
		name: 'Images/island'+(rand(4)+1)+'.jpg',
		angle: 90*rand(4)
	}
}
//////////////////////////////////////////////////////////////////////////
