
/* 
 *       A N T                \ /
 *                             o
 *        T H E F T           >O<
 *                            /0\
 *           A U T O
 *
 *   based on 'Boulder Dash', 'Rockford', C64 santa claus game etc.
 *   (c) Robin Johnson 2003
 *   Copy and distribute freely. Do not distribute modified copies.
 *
 */

/* 'constants'
 * Not that I intend to change the values, but it saves on magic numbers.
 */
MAP_ROWS = 16; // rows 0 to 15
MAP_COLS = 20; // cols 0 to 19

// images for things that can go on the map
// TODO: change these to gifs before going live
Im_blank=new Image(24,24);
Im_hero=new Image(24,24);
Im_hero2=new Image(24,24);
Im_junk = new Image(24,24);
Im_glass = new Image(24,24);
Im_boulder=new Image(24,24);
Im_anteater=new Image(24,24);
Im_sugar=new Image(24,24);
Im_glare=new Image(24,24);
Im_wall=new Image(24,24);

var TERRAINS = new Array(
'nest',
'toolshed',
'kitchen',
'sweets',
'scary',
'computer',
'space'
);

// load images for a certain terrain type
function set_terrain(t)
{

	t = TERRAINS[(level - 1) % TERRAINS.length] ;

	//alert('level is ' + level + '; t is ' + t);

	if(t=='nest')
	{
		Im_blank.src='space.jpg';
		Im_hero.src='ant.jpg';
		Im_hero2.src='ant2.jpg';
		Im_glass.src='glass.jpg';
		Im_anteater.src='anteater.jpg';
		Im_sugar.src='sugar.jpg';
		Im_junk.src='mud.jpg';
		Im_boulder.src='boulder.jpg';
		Im_wall.src='stone.jpg';
		Im_glare.src='glare.jpg';
	}
	else if(t=='toolshed')
	{
		Im_blank.src='space.jpg';
		Im_hero.src='ant.jpg';
		Im_hero2.src='ant2.jpg';
		Im_glass.src='glass.jpg';
		Im_anteater.src='anteater.jpg';
		Im_sugar.src='sugar.jpg';
		Im_junk.src='sawdust.jpg';
		Im_boulder.src='nut.jpg';
		Im_wall.src='wood.jpg';
		Im_glare.src='glare.jpg';
	}
	else if(t=='kitchen')
	{
		Im_blank.src='space.jpg';
		Im_hero.src='ant.jpg';
		Im_hero2.src='ant2.jpg';
		Im_glass.src='glass.jpg';
		Im_anteater.src='anteater.jpg';
		Im_sugar.src='sugar.jpg';
		Im_junk.src='butter.jpg';
		Im_boulder.src='pea.jpg';
		Im_wall.src='tile.jpg';
		Im_glare.src='glare.jpg';
	}
	else if(t=='space')
	{
		Im_blank.src='space.jpg';
		Im_hero.src='spaceant.jpg';
		Im_hero2.src='spaceant2.jpg';
		Im_glass.src='glass.jpg';
		Im_anteater.src='spaceanteater.jpg';
		Im_sugar.src='sugar.jpg';
		Im_junk.src='nebula.jpg';
		Im_boulder.src='planet.jpg';
		Im_wall.src='spacewall.jpg';
		Im_glare.src='glare.jpg';
	}
	else if(t=='sweets')
	{
		Im_blank.src='space.jpg';
		Im_hero.src='ant.jpg';
		Im_hero2.src='ant2.jpg';
		Im_glass.src='glass.jpg';
		Im_anteater.src='anteater.jpg';
		Im_sugar.src='sugar.jpg';
		Im_junk.src='eatsweet.jpg';
		Im_boulder.src='sweetie.jpg';
		Im_wall.src='chocolate.jpg';
		Im_glare.src='glare.jpg';
	}
	else if(t=='scary')
	{
		Im_blank.src='space.jpg';
		Im_hero.src='ant.jpg';
		Im_hero2.src='ant2.jpg';
		Im_glass.src='glass.jpg';
		Im_anteater.src='anteater.jpg';
		Im_sugar.src='sugar.jpg';
		Im_junk.src='blood.jpg';
		Im_boulder.src='skull.jpg';
		Im_wall.src='bones.jpg';
		Im_glare.src='glare.jpg';
	}
	else if(t=='computer')
	{
		Im_blank.src='space.jpg';
		Im_hero.src='ant.jpg';
		Im_hero2.src='ant2.jpg';
		Im_glass.src='glass.jpg';
		Im_anteater.src='anteater.jpg';
		Im_sugar.src='sugar.jpg';
		Im_junk.src='circuit.jpg';
		Im_boulder.src='led.jpg';
		Im_wall.src='case.jpg';
		Im_glare.src='glare.jpg';
	}
	else alert('Unrecognised terrain type: '+t);

	document.images.ant_key.src=Im_hero.src;
	document.images.glass_key.src=Im_glass.src;
	document.images.anteater_key.src=Im_anteater.src;
	document.images.sugar_key.src=Im_sugar.src;
	document.images.mud_key.src=Im_junk.src;
	document.images.boulder_key.src=Im_boulder.src;
	document.images.wall_key.src=Im_wall.src;
}
// terrain currently being used
var terrain='';

var GRAVITATING = false;

// the map, all squares initialised to blanks
map_square = new Object;
for (r=0;r<MAP_ROWS;++r)
	for(c=0;c<MAP_COLS;++c)
		map_square[MAP_COLS*r+c] = 'blank';

// 'flipper' for whether stacked boulders should fall to left or right
stackfall_p = true;

// where the hero is
hero_r = 0;
hero_c = 0;

// whether the anteater exists, and where it is if it does
anteater_exists = false;
anteater_r = 0;
anteater_c = 0;

// game level
level = 1;

// your score
var score = 0;
var level_start_score = 0;

// high score table, just for fun
/*
 * deferred - where does the game end, if you don't complete it?
 *
var high_score = new Array;
var high_scorer = new Array;
high_scorer[1] = 'Emmanuel K-ant';			high_score[1] = 5000;
high_scorer[2] = 'Chris Tarr-ant';			high_score[2] = 4500;
high_scorer[3] = 'Ant-hea Turner';			high_score[3] = 3500;
high_scorer[4] = 'Mark Ant-hony';			high_score[4] = 3000;
high_scorer[5] = 'George Rembr-ant';		high_score[5] = 2500;
high_scorer[6] = 'Quentin Tar-ant-ino';		high_score[6] = 2000;
high_scorer[7] = 'Ant-oine de Caunes';		high_score[7] = 1500;
high_scorer[8] = 'The Ant-ichrist';			high_score[10] =   0;
high_scorer[9] = 'Ariel, the Little Mermex';	high_score[9] =  500;
high_scorer[10] = 'Dec';				high_score[9] =  500;
 *
 */

/*
 * Functions follow
 */

// put the hero somewhere
function put_hero(r,c)
{
	if (r < 0 || r >= MAP_ROWS || c < 0 || c >= MAP_COLS)
		alert('Tried to put hero on nonexistent square.')
	// decide whether ant should face right or left
	var th = '';
	if(c>hero_c)	th = 'hero'
	else if(c<hero_c)	th = 'hero2'
	else th = thing_at(hero_r,hero_c);
	if(th=='')	th = 'hero'; // shouldn't happen
	put_thing('blank',hero_r,hero_c);
	put_thing(th,hero_r=r,hero_c=c);

	check_fried();
}

function check_fried()
{

	// check if you're in line with a magnifying glass
	if(hero_r > 0) // up
		for(var r=hero_r-1;r>=0;--r)
		{
			if(thing_at(r,hero_c) == 'glass')
				fry(r,hero_c)
			else if(thing_at(r,hero_c) != 'blank')
				break;
		}
	if(hero_r<MAP_ROWS-1) // down
		for(var r=hero_r+1;r<MAP_ROWS;++r)
		{
			if(thing_at(r,hero_c) == 'glass')
				fry(r,hero_c)
			else if(thing_at(r,hero_c) != 'blank')
				break;
		}
	if(hero_c>0) // left
		for(var c=hero_c-1;c>=0;--c)
		{
			if(thing_at(hero_r,c) == 'glass')
				fry(hero_r,c)
			else if(thing_at(hero_r,c) != 'blank')
				break;
		}
	if(hero_c<MAP_COLS-1) // right
		for(var c=hero_c+1;c<MAP_COLS;++c)
		{
			if(thing_at(hero_r,c) == 'glass')
				fry(hero_r,c)
			else if(thing_at(hero_r,c) != 'blank')
				break;
		}
}

// die due to magnifying glass at specified co-ordinates
function fry(glass_r,glass_c)
{
	// show the zap
	if(glass_c > hero_c) // zap left
		for(var c=glass_c-1;c>hero_c;--c)
			put_thing('glare',hero_r,c);
	else if(glass_c < hero_c) // zap right
		for(var c=glass_c+1;c<hero_c;++c)
			put_thing('glare',hero_r,c);
	else if(glass_r > hero_r) // zap up
		for(var r=glass_r-1;r>hero_r;--r)
			put_thing('glare',r,hero_c);
	else if(glass_r < hero_r) // zap down
		for(var r=glass_r+1;r<hero_r;++r)
			put_thing('glare',r,hero_c);

	ant_dies('You fried!');
}

// die due to anteater
function be_eaten()
{
	if(hero_r != anteater_r || hero_c != anteater_c)
	{
		put_thing('blank',anteater_r,anteater_c);
		put_thing('anteater',hero_r,hero_c);
	}

	ant_dies('The anteater got you!');
}

// die
function ant_dies(epitaph)
{
	alert(epitaph + '\nFortunately, you belong to a large family...');
//	do_high_scores();
	level_start_score*=.9;
	restart_level();
}

// move the hero
// d is a number 2 4 8 or 6 for a keypad direction
function move(d)
{
	// NB
	// gravitate() and move_anteater() must be called at the end
	// of this function, so DO NOT return unless neither will be necessary

	if(d > 9 || d < 0 || Math.floor(d)!= d)
		alert('bad input to move(): '+d);
	var target_r = hero_r;
	var target_c = hero_c;
	if(d==8)		--target_r
	else if(d==2)	++target_r;
	else if(d==4)	--target_c;
	else if(d==6)	++target_c;
	if(target_c<0||target_c>=MAP_COLS||target_r<0||target_r>MAP_ROWS)
		return;

	var target = thing_at(target_r,target_c);

/*
 * old code in case I ever add doors to the anthills -
 * will probably need revising if it goes back in
 *	
	// handle doors specially
	if(thing_at(target_r,target_c)=='door')
	{
		if(d==8)		--target_r
		else if(d==4)	--target_c
		else if(d==6)	++target_c
		else if(d==2)	++target_r;
		if(thing_at(target_r,target_c) != 'blank')
			return;
		put_hero(target_r,target_c);
	}
 *
 */

	// handle the 'move' based on what is at the target square
	// blank or junk - move hero or/and destroy junk
	if(target=='blank'||target=='junk')
	{
		put_hero(target_r,target_c);
		if(target=='junk')
			add_score(1);
	}
	// boulder - can be pushed left or right if there is space
	else if(target=='boulder' && (d==4 || d==6))
	{
		var pusht_c = target_c;
		if(d==4)
			--pusht_c
		else
			++pusht_c;
		if(thing_at(target_r,pusht_c)=='blank' &&
		   pusht_c>=0 && pusht_c<MAP_COLS)
		{
			put_thing('blank',target_r,target_c);
			put_thing('boulder',target_r,pusht_c);
			put_hero(target_r,target_c);
		}
	}
	// sugar - move hero and check if level is finished
	else if(target=='sugar')
	{
		put_hero(target_r,target_c);
		// fudge to disallow if anteater is next to you
		if(anteater_exists &&
		   Math.abs(anteater_r-hero_r)<=1 &&
		   Math.abs(anteater_c-hero_c)<=1)
			move_anteater();
		add_score(10);
		var won_p = true;
		for(var r=0;r<MAP_ROWS;++r)
			for(var c=0;c<MAP_COLS;++c)
				if(thing_at(r,c)=='sugar')
				{
					won_p = false;
					break;
				}
		if(won_p)
		{
			var time_bonus = Math.floor(2000000 / (new Date() - level_started));
			alert('Level ' + level + ' completed\nTime bonus: ' + time_bonus);
			add_score(time_bonus);
			build_level(++level);
		}
	}
	// anteater - that was a stupid move...
	else if(target=='anteater')
	{
		// fudge to stop the anteater tile moving
		put_thing('blank',hero_r,hero_c);
		hero_r=anteater_r;
		hero_c=anteater_c; // actually this should only be possible from above
		be_eaten();
	}
	if (anteater_exists)
		move_anteater();
	gravitate();
}

// move an anteater at (from) the specified co-ordinates, if necessary
// gravitate() should be called afterwards
function move_anteater()
{
	if(anteater_c < hero_c &&
	   (thing_at(anteater_r,anteater_c+1) == 'blank' ||
	    thing_at(anteater_r,anteater_c+1) == 'hero' ||
	    thing_at(anteater_r,anteater_c+1) == 'hero2'))
	{
		put_thing('blank',anteater_r,anteater_c);
		put_thing('anteater',anteater_r,++anteater_c);
	}
	if(anteater_c > hero_c &&
	   (thing_at(anteater_r,anteater_c-1) == 'blank' ||
	    thing_at(anteater_r,anteater_c-1) == 'hero' ||
	    thing_at(anteater_r,anteater_c-1) == 'hero2'))
	{
		put_thing('blank',anteater_r,anteater_c);
		put_thing('anteater',anteater_r,--anteater_c);
	}
	if(anteater_c == hero_c &&
	   (anteater_r==hero_r || anteater_r == hero_r-1))
		be_eaten();
}

// make things fall - recursive
function gravitate()
{
	if(GRAVITATING)
		return
	else
	{
		GRAVITATING = true;
		regravitate();
		GRAVITATING = false;
		check_fried(); // here, not at end of regravitate() - good enough.
	}
}

function regravitate()
{
	var changes_p = false;

	// Work up from bottom (makes a difference in some cases)
	// Don't check bottom row.
	for(var r=MAP_ROWS-2;r>=0;--r)
		for(var c=0;c<MAP_COLS;++c)
		{
			var th = thing_at(r,c)

			// sugar and anteaters fall straight down only
			if((th=='sugar'||th=='anteater') && thing_at(r+1,c) == 'blank')
			{
				changes_p = true;
				put_thing('blank',r,c);
				put_thing(th,r+1,c);
				if(th=='anteater')
					++anteater_r;
				// die if the anteater fell on the hero
				if(th=='anteater' &&
				   (thing_at(r+2,c) == 'hero' ||
				    thing_at(r+2,c) == 'hero2'))
					be_eaten();
			}
			// boulders fall straight down or roll
			else if(th == 'boulder')
			{
				var target_r=r;
				var target_c=c;
				if(thing_at(r+1,c) == 'blank')
				{
					++target_r;
					// if the anteater is on the next row, kill it now
					// (so only boulders dropped from a height are fatal)
					/*
					 * let's not make falling boulders fatal to the ant though
					 * (doing so would make level design very difficult)
					 *
					if(target_r+1==hero_r && c==hero_c)
					{
						put_thing('blank',r,c);
						put_thing('boulder',hero_r,c);
						ant_dies('Squish!');
						return;
					}
					else
					 *
					 */
					if(thing_at(target_r+1,c)=='anteater')
					{
						put_thing('blank',target_r+1,c);
						anteater_exists=false;
						add_score(200);
					}
				}
				else if(thing_at(r+1,c) == 'boulder')
				{
					var clear_r = false;
					var clear_l = false;
					if(c>0 && thing_at(r,c-1) == 'blank' &&
					   thing_at(r+1,c-1) == 'blank')
						clear_l = true;
					if(c<MAP_COLS-1 && thing_at(r,c+1) == 'blank' &&
					   thing_at(r+1,c+1) == 'blank')
						clear_r = true;
					if(clear_l && clear_r)
					{
						// check and toggle
						if(stackfall_p=!stackfall_p)
							clear_r = false
						else
							clear_l = false;
					}

					if(clear_r)
						++target_c
					else if(clear_l)
						--target_c;
				}

				if(target_r != r || target_c != c)
				{
					put_thing('blank',r,c);
					put_thing('boulder',target_r,target_c);
					changes_p = true;
				}
			}
		}

	// recur if anything has changed			
	// TODO: let the player see what is happening in more
	// detail, by means of some short delay here?
	if(changes_p)
	{
		setTimeout('regravitate();', 50);
	}
}

// put a thing on the map
function put_thing(thing, r, c)
{
	eval('document.images.c'+r+'_'+c+'.src = Im_' + thing + '.src');
	map_square[r*MAP_COLS+c] = thing;
}

function thing_at(r,c)
{
	return map_square[r*MAP_COLS+c];
}

// restart a level
function restart_level()
{
	//alert('level is '+ level);
	
	score = level_start_score;
	add_score(0);
	build_level(level);
}

// restart the game
function restart_game()
{
	add_score(score=0);
	build_level(1);
}

// add to (or update) score
function add_score(n)
{
	score += n;
	score=Math.floor(score);
	if(score<0)	// (careful)
		score=0;
	document.forms[0].score.value = score;
}

// show the level
function show_level()
{
	document.forms[0].level.value = '' + level ; // + ' ('  + terrain + ')';
}

/*
 * not used - doesn't behave well at all
 *
// delay for approximately t seconds
function delay(t)
{
	if(t==0)
		return;
	var startd = new Date();
	var starts = stard.getSeconds();
	var now = new Date();
	while(now.getSeconds() == starts)
	{
		now = new Date();
	}
	delay(t-1);
}
 *
 */

// handle keypress
function handle_keypress(e)
{
	var k;
	if(e.which)
		k = e.which	
	else
		k = e.keyCode ;

	//alert(k);

	// support HJKL. for Opera
	if (k=='104') k = 52;
	if (k=='106') k = 50;
	if (k=='107') k = 56;
	if (k=='108') k = 54;
	if (k=='46')  k = 53;
	
	if (k=='50'||k=='52'||k=='53'||k=='54'||k=='56')
		move(k-48);
}

/*
 * Levels follow
 *
 * When adding levels, remember to TEST THEM and prove they're possible.
 * Remember there IS a slight element of randomness in boulders falling
 * (if a boulder lands on top of a stack of boulders, does it go left or
 * right), which might make a difference sometimes.
 *
 */
 
LEVEL_MAPS = new Array(

// title level
'.....o......oo......' +
'.%%%.###.#.###......' +
'.%*%.#.#.#..#.......' +
'.%%%.#.#.#..#.......' +
'.%.%.#.###..#.......' +
'....................' +
'.###.#.#.###.##.###.' +
'..#..#.#.##..#...#..' +
'..#..###.#...##..#..' +
'..#..#.#.###.#...#..' +
'....................' +
'.###.#.#.###.o%%....' +
'.#*#.#.#..#..%.%....' +
'.#%#.#.#..#..%@%....' +
'.#.#.###..#..%%%....' +
'............X.......' ,

// introduction to anteaters and the squashing thereof

'A..##...............' +
'##..##..............' +
'.##..##...###.......' +
'..##..##..#*#.......' +
'...##..##.#o#.......' +
'....##..###o#.......' +
'.....##..##o#.......' +
'......##..#o#.......' +
'.......##..%#.......' +
'........##..##......' +
'.........##..##.....' +
'..........#%..##....' +
'..........#.#..##...' +
'..........#.##..##..' +
'..........#.###.@##.' +
'..........#.#.##..#.' ,

'***#................' +
'ooo%....####........' +
'ooo%..###..###......' +
'ooo%.##......##.....' +
'%%%%##..###A.*#.....' +
'....#..##.##.*##....' +
'....#..#*..##%%##...' +
'....#..##...#...#...' +
'....##..##..#...#...' +
'.....##....##...#...' +
'....#.######...##.##' +
'..............##..#*' +
'###.........###...#o' +
'..###########.....%o' +
'.@................%o' +
'...................o' ,


'.....#...*.#....A#..' +
'.....#...%.#....*#..' +
'..#..#..o..#..#*%#..' +
'o*#..#..#..#..#%%#..' +
'o*#..#..#*.#..#o*#..' +
'*o#..#..#%.#..#*%#..' +
'*o#..#..#..#..#%o#..' +
'o*#..#*.#..#..#%*#..' +
'o*#..#o%#..#..#*%#..' +
'*o#..#o%#..#..#%%#..' +
'*o#..#o%#..#..#o*#..' +
'o*#.*#o%#..#..#*%#..' +
'o*#.*Xo.#..#..#%o#..' +
'*o#.o.*.%%.#..#%*#..' +
'*o#.%%*.%#....#*%...' +
'@o#.%%*.%#...*#%o..*' ,

// advanced boulder dynamics

'..o.....o..o.....o..' +
'.#*o....*..*....o*#.' +
'..#*o...o..o...o*#..' +
'...#*o..#..#..o*#...' +
'....#*o......o*#....' +
'.....#*o....o*#.....' +
'......#*..@.*#......' +
'......o#....#o......' +
'.....o*#....#*o.....' +
'....o*#......#*o....' +
'...o*#..o..o..#*o...' +
'..o*#...*..*...#*o..' +
'.o*#....o..o....#*o.' +
'.*#.....#..#.....#*.' +
'.#................#.' +
'X....*...A....*....X' ,

// stars and stripes
'oooooooooooooooooooo' +
'oooooooooooooooooooo' +
'oooooooooooooooooooo' +
'oooooooooooooooooooo' +
'oooooooooooooooooooo' +
'oooooooooooooooooooo' +
'#########%##########' +
'.........A..........' +
'********************' +
'********************' +
'********************' +
'********************' +
'********************' +
'********************' +
'********************' +
'@*******************' ,

// 'kong' level

'........%ooo%.......' +
'........%ooo%.**...X' +
'........%ooo%.**####' +
'....######o######%o%' +
'..........%......%o%' +
'.................%o%' +
'.......*..A...#..%o%' +
'###############..%o%' +
'.#o#............#ooo' +
'.#o#............#o*o' +
'.#*#............#ooo' +
'.#*#...###########%#' +
'..*....#...#...#....' +
'X.*.................' +
'..*....#...#...#..@.' +
'################....' ,

// more ways to squash anteaters
'....................' +
'A.............#o%...' +
'#o............#o%...' +
'#o%o########..#o%...' +
'#o%o##.....#..#o%...' +
'#o%o##.....#oo#o%...' +
'#%.%##.....#%%#o%...' +
'.%.%.#.....#..#o%...' +
'.%.%.#.....#..#o%...' +
'.%.%.#.....#..#o%...' +
'.%.%.#.....#..#o%...' +
'.%.%###.......#o%...' +
'.%.%#X#.......##%...' +
'.%.%.....@....#X....' +
'.#*#..........##....' +
'.#*#*.............*.' ,

'..........#.........' +
'.@........#.........' +
'..........o.........' +
'.........o*o........' +
'........oo#oo.......' +
'.......ooo#ooo..*...' +
'......oooo#oooo.*...' +
'#####.#########.%###' +
'....X.....#.........' +
'..........#.........' +
'###o......#.........' +
'X*#oo....o..........' +
'X*#ooo..*oo.........' +
'X*#%%%..*ooo........' +
'#*#%##..oo#oo.......' +
'#*...*.ooo#oo*.A..**' ,

// gumball machine
'..X.#*ooooooooo*#...' +
'....#*ooooooooo*#...' +
'....#*ooooooooo*#...' +
'....##*ooooooo*##...' +
'.....##ooooooo##....' +
'......##ooooo##.....' +
'.......##ooo##......' +
'........##%##.......' +
'........%.A.%.......' +
'........%ooo%.......' +
'........%%%%%.......' +
'......o.......o.....' +
'.....ooo.....ooo....' +
'..*.oooo*.X.*oooo...' +
'..################..' +
'..........@.........' ,

// easter egg
'.......######.......' +
'.@...##......##.....' +
'...##%%%%%%%%%%##...' +
'..#oooooooooooooo#..' +
'.%%%%%%%%%%%%%%%%%#.' +
'.#................#.' +
'#..........X.......#' +
'#%%%%%%%%%%%%%%%%%%#' +
'#******************#' +
'#%%%%%%%%%%%%%%%%%%#' +
'.#X..............X#.' +
'.#.......A........#.' +
'..#%%%%%%%%%%%%%%#..' +
'...##**********##...' +
'.....##******##.....' +
'.......######.......' ,

// water pipe
'....*o...o*o....*...' +
'....#####o*o#.%%%...' +
'....#o.*.o*o#..A....' +
'..#######o*o#####...' +
'..#ooooo#o*o.*.o#...' +
'..#ooooo#o*o#####...' +
'..##oo###o*o#oooo...' +
'....%*.*.o*o###o%...' +
'....%####o*o.*.o%..*' +
'....%%###o*o###%%..%' +
'....%o.*.o*o#oooo...' +
'....%%###o*o####%...' +
'........#o*o.*..o...' +
'......###o*o###%%...' +
'...X..#@%%*o#.......' +
'......###ooo###...X.' ,

// oven
'..*******.X.******..' +
'..%%%%%%%.*.%%%%%%..' +
'..o%o%o%o.*.%%%%%%..' +
'..#######.%.######..' +
'..#..oooo...ooo..#..' +
'..#..%%%%o.o%%%..#..' +
'..#..%%%%%.%%%%..#..' +
'..#..#####.####..#..' +
'.##..#XXXX.XXX#..##.' +
'.#...#X......X#...#.' +
'.#.%X#X......X#X%.#.' +
'.#.%%#X...A..X#%%.#.' +
'.#***#X..***.X#***#.' +
'.#***#X..***.X#***#.' +
'.#########%########.' +
'..........@.........' ,

// Orbit One
'#........%%....oooo#' +
'.#.*.....##X..oooo#.' +
'..#%..@..##..oooo#..' +
'.*.#.....##..%%%#.*.' +
'.%..#....##....%..%.' +
'.....#..*##*..#.....' +
'......#.%%%%.#.....%' +
'%#######%**%#######%' +
'%#######%**%#######%' +
'......#..%%%........' +
'.....#...%%...#.....' +
'....#....##....#....' +
'.*.#.....##.....#.*.' +
'.%#......##......#%.' +
'.#.*....X##.....*.#.' +
'%..%.....%%.....%..%' ,

// moonbase alpha
'o****o#*.*...#......' +
'oooooo#%.%...#......' +
'%%%%%%%......%......' +
'......#......#......' +
'......#*..A.*#......' +
'##..#####%######%%##' +
'......#......#*o*o*o' +
'......#......#*o*o*o' +
'......#......#*o*o*o' +
'......#..o...#*o*o*o' +
'#%#######%%#####%###' +
'*o*o*o%.....*#......' +
'*o*o*o%.....*#......' +
'*o*o*o%.....*#...@..' +
'*o*o*o%.....*#......' +
'*%*%*o%...X.*#......' ,

// battlestar galactica
'..%.%o%..#X.o...#...' +
'@.#.*o...#..*...#.*.' +
'..#.*o%..#..*Ao.#.*.' +
'########%#o#*%#####%' +
'.*#......#%.*...#...' +
'.*#.*....#..*...#.*.' +
'.o%.*....#..*...#.*.' +
'.#######.######%###%' +
'............X%..#oo.' +
'..#....*.%..%%..#%%.' +
'..#....*.#......%%%.' +
'.#########%########.' +
'.X#......#......#...' +
'..#......#*.....#...' +
'..#......%*.....#...' +
'X.........*........X'
);





// Initialise one of the game levels
// TODO: keep map data in external file
function build_level(n)
{
	level = n;
	level_start_score = score;
	anteater_exists = false;
	var map='';
	var ter='';

	if (LEVEL_MAPS.length > n)
	{
		map = LEVEL_MAPS[n - 1]
	}
	else
	{
		alert('You finished the game - well done!\nScore: '+score);
//		do_high_scores();
		restart_game();
		return;
	}

	set_terrain(ter); // now sets it according to n

	for(var r=0;r<MAP_ROWS;++r)
		for(var c=0;c<MAP_COLS;++c)
		{
			var ch = map.charAt(r*MAP_COLS+c);
			var th = '';
			if(ch=='.')		th='blank';
			else if(ch=='@')	th='hero';
			else if(ch=='#')	th='wall';
			else if(ch=='%')	th='junk';
			else if(ch=='*')	th='sugar';
			else if(ch=='o')	th='boulder';
			else if(ch=='X')	th='glass';
			else if(ch=='A')	th='anteater';
			else alert('unrecognised character in level map: '+ch);
			if(th=='hero')
			{
				// don't use put_hero or you get a blank at (0,0)
				hero_r=r;
				hero_c=c;
			}
			else if(th=='anteater')
			{
				anteater_exists = true;
				anteater_r=r;
				anteater_c=c;
			}
			put_thing(th,r,c);
		}
		show_level();
		level_started = new Date();
}

