	var numcards = 20;
	var numrows = 4;
	var numcols = 5;
	var card = new Array(numcards);
	var position = new Array(numrows * numcols);
	var image_pointers = new Array(numrows * numcols);
	var card_images = new Array(numcards);
	var cnt = 0;
	var rowcnt = 0;
	var colcnt = 0;
	var tempstring = new String("");
	var position_index = 0;
	var card_width = 75;
	var card_height = 122;
	var previous_index = -1;																			// storage for the last card that was flipped
	var numtries = 1;																						// number of tries a player takes
	var nummatched = 0;																					// number of pairs matched
	var gameover = false;																				// flag for when the game is finished
	var gameover_image = new Image();
	var done_loading = false;	
	var tries_digit1_image = "";	
																			// trap any clicks until done loading game
	
	function Card(source) {																				// set up card object to store the source file of the image
		this.src = source;
	}
	
	function Slot() {																						// set up a slot position on a board
		this.cardindex = 0;																				// which images is displayed in the slot
		this.state = 0;																					// state of the slot; hidden, card temporarily turned over, or card found
	}

	function fillBoard() {																				// fill up the board with two of each card
		position_index = 0;
		for (rowcnt = 0; rowcnt < numrows; rowcnt++) 
			for (colcnt = 0; colcnt < numcols; colcnt++) {										// repeat cards after we are half way through the board
				if (position_index >= numcards / 2) position[position_index].cardindex = position_index - (numcards / 2);
					else position[position_index].cardindex = position_index;
				position[position_index].state = 0;													// set every slot to hidden
				position_index += 1;
			}
	}
	
	function shuffleBoard() {																			// shuffle the board after it has been filled
		var cnt = 0;
		var p_i = Math.round(Math.random() * numcards);
		var p_o = Math.round(Math.random() * numcards);
		var temp = 0;
		for (cnt = 0; cnt < numcards * numcards; cnt++) {										// go through a number of times to make sure the board is random
			p_i = Math.floor(Math.random() * numcards);											// select the first position
			p_o = Math.floor(Math.random() * numcards);											// select the second position
			temp = position[p_i].cardindex;															// now swap the cards
			position[p_i].cardindex = position[p_o].cardindex;									// store the second card in the first position
			position[p_o].cardindex = temp;															// store the first card in the second postion			
		}
	}

	function tryCard(p_index) {																		// player clicks on a card and puts it into play
		var tempstring = new String();
		if ((position[p_index].state == 0) && !gameover) {
			numtries += 1;
			position[p_index].state = 1;
			if (previous_index >= 0) {																	// not the first card to be clicked on and different from previous card
				if (position[p_index].cardindex != position[previous_index].cardindex) {
					if (position[previous_index].state != -1) {
						image_pointers[previous_index].src = "Images/hidden.gif";
						position[previous_index].state = 0;
					}
				} else {
					position[previous_index].state = -1;
					position[p_index].state = -1;
					nummatched += 1;
					tempstring = new String(nummatched);											// update number of matches graphic
					if (tempstring.length == 2) {
						matches_digit1_image.src = "Images/numbers_f" + tempstring.charAt(0) + ".gif";
						matches_digit2_image.src = "Images/numbers_f" + tempstring.charAt(1) + ".gif";
					} else if (tempstring.length == 1) {
						matches_digit1_image.src = "Images/numbers_fblank.gif";
						matches_digit2_image.src = "Images/numbers_f" + tempstring.charAt(0) + ".gif";
					}	if (tempstring.length > 3) {
						matches_digit1_image.src = "Images/numbers_fdash.gif";
						matches_digit2_image.src = "Images/numbers_fdash.gif";
					}
				}
			}
			previous_index = p_index;
			tempstring = new String(numtries);														// update number of tries graphic
			if (tempstring.length == 3) {
				tries_digit1_image.src = "Images/numbers_f" + tempstring.charAt(0) + ".gif";
				tries_digit2_image.src = "Images/numbers_f" + tempstring.charAt(1) + ".gif";
				tries_digit3_image.src = "Images/numbers_f" + tempstring.charAt(2) + ".gif";
			} else if (tempstring.length == 2) {
				tries_digit1_image.src = "Images/numbers_fblank.gif";
				tries_digit2_image.src = "Images/numbers_f" + tempstring.charAt(0) + ".gif";
				tries_digit3_image.src = "Images/numbers_f" + tempstring.charAt(1) + ".gif";
			} else if (tempstring.length == 1) {
				tries_digit1_image.src = "Images/numbers_fblank.gif";
				tries_digit2_image.src = "Images/numbers_fblank.gif";
				tries_digit3_image.src = "Images/numbers_f" + tempstring.charAt(0) + ".gif";
			}	if (tempstring.length > 3) {
				tries_digit1_image.src = "Images/numbers_fdash.gif";
				tries_digit2_image.src = "Images/numbers_fdash.gif";
				tries_digit3_image.src = "Images/numbers_fdash.gif";
			}
		}
		image_pointers[p_index].src = card[position[p_index].cardindex].src;
		if (nummatched == numcards / 2) {															// game is over
			gameover = true;																				// stop the game
			gameover_image.src = "Images/gameover.gif";											// tell player how well they did
			if (numtries == 20){ response_image.src = "Images/r20.gif"; playsound(20);}
			else if (numtries < 30){ response_image.src = "Images/r30.gif"; playsound(30);}
				else if (numtries < 40){ response_image.src = "Images/r40.gif"; playsound(40);}
					else if (numtries < 50){ response_image.src = "Images/r50.gif"; playsound(50);}
						else if (numtries < 70){ response_image.src = "Images/r70.gif"; playsound(70);}
							else if (numtries < 90){ response_image.src = "Images/r90.gif"; playsound(90);}
								else if (numtries < 110){ response_image.src = "Images/r110.gif"; playsound(110);}
		}
	}
	
	function newGame() {
		for (cnt = 0; cnt < numcards / 2; cnt++) {												// create cards and point to image files
			tempstring = new String("Images/" + (cnt + 1) + ".gif");
			card[cnt] = new Card(tempstring);
		}
		position_index = 0;																				// create the board with a card in each position
		for (rowcnt = 0; rowcnt < numrows; rowcnt++) 
			for (colcnt = 0; colcnt < numcols; colcnt++) {
				position[position_index] = new Slot();
				position_index += 1;
			}
		fillBoard();																						// fill the board
		shuffleBoard();																					// randomly shuffle the board
		position_index = 0;
		for (rowcnt = 0; rowcnt < numrows; rowcnt++) 
			for (colcnt = 0; colcnt < numcols; colcnt++) {
				image_pointers[position_index].src = "Images/" + "hidden.gif";
				position_index += 1;
			}
		numtries = 0;
		nummatched = 0;
		gameover = false;
		tries_digit1_image.src = "Images/numbers_fblank.gif";
		tries_digit2_image.src = "Images/numbers_fblank.gif";
		tries_digit3_image.src = "Images/numbers_f0.gif";
		matches_digit1_image.src = "Images/numbers_fblank.gif";
		matches_digit2_image.src = "Images/numbers_f0.gif";
		gameover_image.src = "Images/whitedot.gif";
		response_image.src = "Images/rblank.gif";
		done_loading = true;
	}
	
	function loadImages() {
		for (cnt = 0; cnt < numcards / 2; cnt++) {												// preload card image files
			card_images[cnt] = new Image();
			card_images[cnt].src = "Images/" + (cnt + 1) + ".gif";
		}
	}

