// Copyright (C) 2008 Robert W. Clarke Consulting, all rights reserved.// do not remove this copyright notice// Global vars ----------------------------------------------------------------------------------var ary_state_status = new Array();var ary_unclicked_states = new Array();var current_state;var game_status = "init";var game_level;// Map XML --------------------------------------------------------------------------------------function updateMap(){ // called by selectState function every time user clicks on a state	// this function generates the xml to configure the map based the array of selected states	var ary_colors = new Array();	ary_colors['correct'] = "00FF00"; // green	ary_colors['wrong'] = "FF0000"; // red	ary_colors['noclick'] = "FFFFFF"; // white	ary_colors['roll'] = "666666"; // gray		var state_code, xml_state, re, color, rcolor, ncolor, state_status, state_action;	var xml_state_tmpl = '<state id="_ID_" ncolor="_NCOLOR_" rcolor="_RCOLOR_" action="_ACTION_" />';	var action_template = "javascript:selectState(\'_ID_\')";		// start the xml	var xml = '<?xml version="1.0" encoding="iso-8859-1" ?><MT1022>'; // start the xml	xml += '<global state_initials="off" state_name="_SN_" action_target="_self" />';		// set state name visibility on mouseover based oneasy or difficult level	var sn_visibility = "off";	if(game_level == "easy"){		sn_visibility = "on";	}	if(game_status == "end"){		sn_visibility = "off";	}	re = /_SN_/;	xml = xml.replace(re,sn_visibility);		for(state_code in ary_state_name){ // loop through each state		xml_state = xml_state_tmpl; // set to state template xml				// set the ID		re = /_ID_/g;		xml_state = xml_state.replace(re,state_code); // replace id			// get the status of the state		state_status = ary_state_status[state_code]; // -1 for wrong, 0 for noclick, 1 for correct				// make the state action		if(state_status == 0){ // never clicked			re = /_ID_/;			state_action = action_template.replace(re,state_code);		} else { // already clicked no further clicks on the state			state_action = "";		}		if(game_status == "end"){  // game has ended, no rollovers, no further clicking			state_action = "";		}		re = /_ACTION_/g;		xml_state = xml_state.replace(re,state_action); // replace ACTION						// set state normal and roll colors		if(state_status == 0){ // never clicked			if(game_status == "end"){ // game has ended, no rollovers, no further clicking				ncolor = ary_colors['noclick'];				rcolor = ncolor;			} else {				ncolor = ary_colors['noclick'];				rcolor = ary_colors['roll'];			}		} else { // already clicked			if(state_status > 0){ // correct				ncolor = ary_colors['correct'];			} else { // wrong				ncolor = ary_colors['wrong'];			}			rcolor = ncolor; // no longer rolls over		}		re = /_NCOLOR_/g;		xml_state = xml_state.replace(re,ncolor);		re = /_RCOLOR_/g;		xml_state = xml_state.replace(re,rcolor);				xml += xml_state; // append xml	}		xml += '</MT1022>'; // finish xml		// update the map	sendXML(xml);}function sendXML(xml){	// this function sends the xml to the map	// the map receives the xml and configures itself automatically	if(window.maptron){		window.document["maptron"].SetVariable("jxml", xml);	}	if(document.maptron){		document.maptron.SetVariable("jxml", xml);	}}// Game Control ----------------------------------------------------------------------------------function initGame(){	document.forms.gamecontrol.time.value = 0;	document.forms.gamecontrol.score.value = 0;	document.forms.gamecontrol.ss.value = "START";	document.forms.gamecontrol.state.value = "Click on START button";	document.forms.gamecontrol.correct.value = 0;	document.forms.gamecontrol.incorrect.value = 0;	disableLevelSelection(false);	document.forms.gamecontrol.level[0].checked = true;	game_status = "ready";}function resetUnclickedStates(){ // called by newGame()	var sc	for(sc in ary_state_name){		ary_unclicked_states.push(sc);	}	ary_unclicked_states = shuffleArray(ary_unclicked_states); // make random}function resetStateStatus(){ // called by newGame()	var sc	for(sc in ary_state_name){		ary_state_status[sc] = 0;	}}function disableLevelSelection(directive){	document.forms.gamecontrol.level[0].disabled = directive;	document.forms.gamecontrol.level[1].disabled = directive;}function newGame(){	// set the game level, either easy or difficult	game_level = getSelectedRadioValue(document.forms.gamecontrol.level);		// set game time	var game_time = 180;	if(game_level == "easy"){		game_time += 60;	}		// reset the controls	document.forms.gamecontrol.time.value = game_time;	document.forms.gamecontrol.score.value = 0;	document.forms.gamecontrol.correct.value = 0;	document.forms.gamecontrol.incorrect.value = 0;	document.forms.gamecontrol.ss.value = "NEXT";	disableLevelSelection(true);		// reset arrays	resetStateStatus();	resetUnclickedStates();	// update the map, activates the states	updateMap();	nextState();		interval_gametime = setInterval("updateTime()",1000); // call every second	game_status = "run";}function nextState(){ // called when NEXT button is clicked, map is clicked, or newGame()	if(ary_unclicked_states.length == 0){ // nothing left to click on		endGame();		return;	}	if(ary_unclicked_states.length > 1){ // circulate array		var sc = ary_unclicked_states.shift(); // remove first array element		ary_unclicked_states.push(sc); // place it at the end	}	current_state = ary_unclicked_states[0];	document.forms.gamecontrol.state.value = ary_state_name[current_state];}function removeUnclickedState(state_code){	// rebuild the ary_unclicked_states without the state_code	var i;	var ary = new Array();	ary = ary.concat(ary_unclicked_states);	ary_unclicked_states = new Array();	for(i=0;i<ary.length;i++){		if(ary[i] != state_code){			ary_unclicked_states.push(ary[i]);		}	}}function updateScore(points){	// update the score box	var current_score = Math.floor(document.forms.gamecontrol.score.value);	current_score += points;	if(current_score < 0){current_score=0;}	document.forms.gamecontrol.score.value = current_score;		// update the correct and incorrect click text fields	var correct_clicks = 0;	var incorrect_clicks = 0;	var sc	for(sc in ary_state_name){		if(ary_state_status[sc] < 0){			incorrect_clicks ++;		}		if(ary_state_status[sc] > 0){			correct_clicks ++;		}	}	document.forms.gamecontrol.correct.value = correct_clicks;	document.forms.gamecontrol.incorrect.value = incorrect_clicks;}function updateTime(){ // called by interval	// first check to see if there are any states left to click	if(ary_unclicked_states.length == 0){ // nothing left to click on		endGame();		return;	}	// update the time	var time = Math.floor(document.forms.gamecontrol.time.value);	time --;	document.forms.gamecontrol.time.value = time;		// check for timeout	if(time <= 0){		endGame();		return;	}}function endGame(){	clearInterval(interval_gametime); // stop the one second interval	game_status = "end";	updateMap();		// calculate extra points based on remaining time	var time_remaining = Math.floor(document.forms.gamecontrol.time.value);	if(time_remaining > 0){		// update the score with remaining time		var extra_points = 0;		for(sc in ary_state_name){			if(ary_state_status[sc] > 0){				extra_points ++; // one point per correct state			}			if(ary_state_status[sc] < 0){				extra_points --; // one point per correct state			}		}		if(extra_points == ary_state_name.length){ // all correct			extra_points += 100; // bonus 100 for all correct		}		if(extra_points > 0){			updateScore(extra_points * time_remaining);		}	}		disableLevelSelection(false);	document.forms.gamecontrol.ss.value = "START";	document.forms.gamecontrol.state.value = "Game over, click START for new game";	game_status = "ready";}var interval_gametime;function gameControl(btn_obj){ // called from the game START / NEXT button	if(btn_obj.value == "START"){		newGame();		return;	} 		if(btn_obj.value == "NEXT"){		updateScore(-25);		nextState();		return;	}}// General funcitons -------------------------------------------------------------------------------function shuffleArray(ary){	var numbers = "_";	var n;	var ary_shuffled = new Array();	while(ary_shuffled.length < ary.length){		n = randomNumber(0,ary.length-1);		if(numbers.indexOf("_" + n + "_") < 0){ // not already picked			numbers += n + "_";			ary_shuffled.push(ary[n]);		}	}	return ary_shuffled;}function randomNumber(nmin,nmax){	return nmin + Math.floor(Math.random() * (nmax - nmin + 1));}function getSelectedRadioValue(radio_obj){	var i;	for(i=0;i<radio_obj.length;i++){		if(radio_obj[i].checked){			return radio_obj[i].value;		}	}}// Selection --------------------------------------------------------------------------------------function selectState(state_code){ // called by map when user clicks on a state	// map clicks only apply if game is running	if(game_status != "run"){ return; }		// accept the click	if(state_code == current_state){ // correct		ary_state_status[state_code] = 1;		updateScore(100);		if(game_level == "difficult"){			updateScore(50);		}	} else { // wrong		ary_state_status[state_code] = -1;		updateScore(-50);	}	removeUnclickedState(state_code);	updateMap();	nextState();}// Data --------------------------------------------------------------------------------------// make array for state namesvar ary_state_name = new Array();ary_state_name['AL']="Alabama";ary_state_name['AK']="Alaska";ary_state_name['AZ']="Arizona";ary_state_name['AR']="Arkansas";ary_state_name['CA']="California";ary_state_name['CO']="Colorado";ary_state_name['CT']="Connecticut";ary_state_name['DE']="Delaware";ary_state_name['FL']="Florida";ary_state_name['GA']="Georgia";ary_state_name['HI']="Hawaii";ary_state_name['ID']="Idaho";ary_state_name['IL']="Illinois";ary_state_name['IN']="Indiana";ary_state_name['IA']="Iowa";ary_state_name['KS']="Kansas";ary_state_name['KY']="Kentucky";ary_state_name['LA']="Louisiana";ary_state_name['ME']="Maine";ary_state_name['MD']="Maryland";ary_state_name['MA']="Massachusetts";ary_state_name['MI']="Michigan";ary_state_name['MN']="Minnesota";ary_state_name['MS']="Mississippi";ary_state_name['MO']="Missouri";ary_state_name['MT']="Montana";ary_state_name['NE']="Nebraska";ary_state_name['NV']="Nevada";ary_state_name['NH']="New Hampshire";ary_state_name['NJ']="New Jersey";ary_state_name['NM']="New Mexico";ary_state_name['NY']="New York";ary_state_name['NC']="North Carolina";ary_state_name['ND']="North Dakota";ary_state_name['OH']="Ohio";ary_state_name['OK']="Oklahoma";ary_state_name['OR']="Oregon";ary_state_name['PA']="Pennsylvania";ary_state_name['RI']="Rhode Island";ary_state_name['SC']="South Carolina";ary_state_name['SD']="South Dakota";ary_state_name['TN']="Tennessee";ary_state_name['TX']="Texas";ary_state_name['UT']="Utah";ary_state_name['VT']="Vermont";ary_state_name['VA']="Virginia";ary_state_name['WA']="Washington";ary_state_name['WV']="West Virginia";ary_state_name['WI']="Wisconsin";ary_state_name['WY']="Wyoming";