<!DOCTYPE html>
<html>
	<head>
	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

        <link rel="stylesheet" href="style.css" />
        <script src='script.js'></script>
		<title>Tower of Hanoi</title>
	</head>
	<body>
		<div class="post_area">
			<div id="post_1" class="stick"></div>
		</div>
		<div class="post_area">
			<div id="post_2" class="stick"></div>
		</div>
		<div class="post_area">
			<div id="post_3" class="stick"></div>
		</div>
		<div class="base">
			<div class="error_msg"></div>
		</div>
		<div class="instructions">
			<h4>Tower of Hanoi Instructions:</h4>
			<div>
				Get all the discs from the 1st post to the
				3rd post. A larger disc cannot be placed on
				top of a smaller disc. Press '1', '2', or '3'
				to select the top disc of the specified post.
				Press '1', '2', or '3' to move the disc to
				the specified post or cancel movement if the
				post corresponds to the selected disc.
			</div>
		</div>
	</body>
</html>
/* Base */
.base{
	background-color: #554400;
	position: relative;
	top: 250px;
	width: 540px;
	height: 50px;
}
.error_msg{
	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
	position: absolute;
	top: 17px;
}
/* Posts */
.post_area{
	float: left;
	width: 180px;
}
.stick{
	background-color: #554400;
	position: relative;
	left: 80px;
	width: 20px;
	height: 250px;
}
/* Discs */
.disc{
	position: absolute;
	height: 20px;
}
.disc_9{
	background-color: #0000FF;
	left: -72px;
	width: 164px;
}
.disc_8{
	background-color: #00FF00;
	left: -64px;
	width: 148px;
}
.disc_7{
	background-color: #FF0000;
	left: -56px;
	width: 132px;
}
.disc_6{
	background-color: #00FFFF;
	left: -48px;
	width: 116px;
}
.disc_5{
	background-color: #FF00FF;
	left: -40px;
	width: 100px;
}
.disc_4{
	background-color: #888888;
	left: -32px;
	width: 84px;
}
.disc_3{
	background-color: #000088;
	left: -24px;
	width: 68px;
}
.disc_2{
	background-color: #008800;
	left: -16px;
	width: 52px;
}
.disc_1{
	background-color: #880000;
	left: -8px;
	width: 36px;
}
.level_9{
	top: 70px;
}
.level_8{
	top: 90px;
}
.level_7{
	top: 110px;
}
.level_6{
	top: 130px;
}
.level_5{
	top: 150px;
}
.level_4{
	top: 170px;
}
.level_3{
	top: 190px;
}
.level_2{
	top: 210px;
}
.level_1{
	top: 230px;
}
.selected{
	border: 1px solid #FFFF00;
}
/* Instructions */
.instructions{
	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
	text-align: center;
	position: relative;
	top: 58px;
	width: 540px;
}
h4{
	font-size: 24px;
	-webkit-margin-after: 3px;
}
// Constants
var INIT_POST = 1;
var FINAL_POST = 3;
var NUM_DISCS = 9;
var EMPTY_POST_TEXT = 'The selected post does not have any discs '+
						'on it.';
var INVALID_MOVE_HEADER = 'You cannot move this disc onto post ';
var INVALID_MOVE_FOOTER = ', because the top disc is too small!';
var GAME_COMPLETE_TEXT = 'Congratulations! You won!\n\n'+
						'Would you like to play again?';
// "Class" variables
var posts = [];
posts[0] = [];
posts[1] = [];
posts[2] = [];
var selection = 0;

$(document).ready(function(){
	if (NUM_DISCS > 9) { // Game does not work w/ more than 9 discs
		NUM_DISCS = 9;
	}else if(NUM_DISCS < 1){
		NUM_DISCS = 1;
	}
	createDiscs();
	$(document).keyup(function(event){
		var post_num = event.which-48;
		if (post_num < 1 || post_num > 3){ // Only accept valid keys
			return;
		}
		var post, disc_num, $disc_to_move;
		var finished = false;
		if (selection === 0){ // Initial selection
			if(isPostEmpty(post_num)){
				errorLog(EMPTY_POST_TEXT);
			}else{
				post = posts[post_num-1];
				disc_num = post[post.length-1];
				$disc_to_move = $('.disc_'+disc_num);
				$disc_to_move.addClass('selected');
				selection = post_num;
				errorLog();
			}
			return;
		}else{
			post = posts[selection-1];
			disc_num = post[post.length-1];
			$disc_to_move = $('.disc_'+disc_num);
			if(selection !== post_num){ // Move disc
				if(isValidMove(disc_num,post_num)){ 
					posts[post_num-1].push(post.pop());
					$disc_to_move = changeLevel($disc_to_move,post,
						posts[post_num-1]);
					$('#post_'+post_num).append($disc_to_move);
					finished = isPostFull(FINAL_POST);
					errorLog();
				}else{
					errorLog(INVALID_MOVE_HEADER+post_num+
						INVALID_MOVE_FOOTER);
				}
			}else{
				errorLog();
			}
			$disc_to_move.removeClass('selected');
			selection = 0;
			if (finished){
				if (confirm(GAME_COMPLETE_TEXT)){
					resetDiscs();
				}else{
					$(document).unbind('keyup');
				}
			}
		}
	});
});

function createDiscs(){
	var $post = $('#post_'+INIT_POST);
	for(var index=NUM_DISCS; index>=1; index--){
		posts[INIT_POST-1].push(index);
		$('<div />').addClass('disc disc_'+index+' level_'+
			(NUM_DISCS-index+1)).appendTo($post);
	}
}

function isValidMove(disc_num,post_num){
	var post = posts[post_num-1];
	return isPostEmpty(post_num) || disc_num < post[post.length-1];
}

function isPostEmpty(post_num){
	return !posts[post_num-1].length;
}

function isPostFull(post_num){
	var post = posts[post_num-1];
	for (var index=0; index<post.length; index++){
		if(post[index] !== NUM_DISCS-index){
			return false;
		}
	}
	return post.length === NUM_DISCS;
}

function changeLevel($disc,oldPost,newPost){
	return $disc.removeClass('level_'+(oldPost.length+1)).
		addClass('level_'+newPost.length);
}

function resetDiscs(){
	posts[FINAL_POST-1] = [];
	var $post = $('#post_'+INIT_POST);
	$('#post_'+FINAL_POST).children('.disc').
		each(function(index,value){
		posts[INIT_POST-1].push(NUM_DISCS-index);
		$(value).appendTo($post);
	});
}

function errorLog(error_text){
	error_text = error_text || "";
	$('.error_msg').text(error_text);
}
Created from scratch
782 forks
40118 views

Browse more Codebits