mirror of
				https://github.com/flynx/Slang.git
				synced 2025-10-31 03:20:09 +00:00 
			
		
		
		
	initial commit...
This commit is contained in:
		
						commit
						1cf7e1d69a
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | .* | ||||||
|  | *.sp[pow] | ||||||
							
								
								
									
										144
									
								
								jsssnake-test.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										144
									
								
								jsssnake-test.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,144 @@ | |||||||
|  | function test(){ | ||||||
|  | 	var field = Field("field") | ||||||
|  | 
 | ||||||
|  | 	// TODO UI...
 | ||||||
|  | 
 | ||||||
|  | 	// setup a wall...
 | ||||||
|  | 	for(var i=8; i < 20; i++){ | ||||||
|  | 		field.Wall(field.cell(12, i)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// apple and apple creation on callback...
 | ||||||
|  | 	field.Apple(field.cell(10, 4)) | ||||||
|  | 	field.on_apple_eaten = function(){ | ||||||
|  | 		field.Apple(field.cell(13, 6)) | ||||||
|  | 		// remove the event handler...
 | ||||||
|  | 		field.on_apple_eaten = null | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// snake 0 script...
 | ||||||
|  | 	// test general control and being killed...
 | ||||||
|  | 	var s0 = field.Snake('black', field.cell(2, 2), 's', 3) | ||||||
|  | 	setTimeout(function(){s0.left()}, 3000) | ||||||
|  | 	setTimeout(function(){s0.right()}, 6000) | ||||||
|  | 
 | ||||||
|  | 	// snake 1 script...
 | ||||||
|  | 	// test general controls and killing...
 | ||||||
|  | 	var s1 = field.Snake('blue', field.cell(6, 2), 's', 5) | ||||||
|  | 	setTimeout(function(){s1.right()}, 6000) | ||||||
|  | 
 | ||||||
|  | 	// snake 2 script...
 | ||||||
|  | 	// test apple eating...
 | ||||||
|  | 	var s2 = field.Snake('silver', field.cell(7, 4), 'e', 2) | ||||||
|  | 	setTimeout(function(){s2.right()}, 5000) | ||||||
|  | 	setTimeout(function(){s2.right()}, 6000) | ||||||
|  | 
 | ||||||
|  | 	// snake 3 script...
 | ||||||
|  | 	// test n/s wall traversal...
 | ||||||
|  | 	var s3 = field.Snake('green', field.cell(15, 2), 'n', 4) | ||||||
|  | 	setTimeout(function(){s3.right()}, 2000) | ||||||
|  | 	setTimeout(function(){s3.right()}, 3000) | ||||||
|  | 
 | ||||||
|  | 	// snake 4 script...
 | ||||||
|  | 	// test l/r wall traversal...
 | ||||||
|  | 	var s4 = field.Snake('gold', field.cell(2, 15), 'w', 4) | ||||||
|  | 	setTimeout(function(){s4.right()}, 2500) | ||||||
|  | 	setTimeout(function(){s4.right()}, 3500) | ||||||
|  | 	setTimeout(function(){s4.right()}, 5000) | ||||||
|  | 
 | ||||||
|  | 	// general game commands...
 | ||||||
|  | 	field.start(500) | ||||||
|  | 	setTimeout(function(){field.stop()}, 28000) | ||||||
|  | 	setTimeout(function(){field.reset()}, 30000) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	// test the Game object...
 | ||||||
|  | 	setTimeout(function(){ | ||||||
|  | 		var game = JSSnakeGame(field) | ||||||
|  | 
 | ||||||
|  | 		game.Wall() | ||||||
|  | 		game.Wall() | ||||||
|  | 		game.Wall() | ||||||
|  | 		game.Wall() | ||||||
|  | 
 | ||||||
|  | 		game.Apple() | ||||||
|  | 		game.Apple() | ||||||
|  | 		game.Apple() | ||||||
|  | 		game.Apple() | ||||||
|  | 	}, 8000) | ||||||
|  | 
 | ||||||
|  | 	// test for special cases...
 | ||||||
|  | 	setTimeout(function(){ | ||||||
|  | 		var game = JSSnakeGame(field) | ||||||
|  | 
 | ||||||
|  | 		game.field.reset() | ||||||
|  | 		for(var i=0; i < game.field.cells.length; i++) | ||||||
|  | 			game.Wall(game.field.Cell(i), 3, 'n') | ||||||
|  | 		game.field.reset() | ||||||
|  | 		for(var i=0; i < game.field.cells.length; i++) | ||||||
|  | 			game.Wall(game.field.Cell(i), 3, 's') | ||||||
|  | 		game.field.reset() | ||||||
|  | 		for(var i=0; i < game.field.cells.length; i++) | ||||||
|  | 			game.Wall(game.field.Cell(i), 3, 'e') | ||||||
|  | 		game.field.reset() | ||||||
|  | 		for(var i=0; i < game.field.cells.length; i++) | ||||||
|  | 			game.Wall(game.field.Cell(i), 3, 'w') | ||||||
|  | 	}, 21000) | ||||||
|  | 
 | ||||||
|  | 	setTimeout(function(){ | ||||||
|  | 		var game = JSSnakeGame(field) | ||||||
|  | 
 | ||||||
|  | 		game.field.reset() | ||||||
|  | 		for(var i=0; i < game.field.cells.length; i++) | ||||||
|  | 			game.Apple(game.field.Cell(i)) | ||||||
|  | 	}, 22000) | ||||||
|  | 
 | ||||||
|  | 	setTimeout(function(){ | ||||||
|  | 		setTimeout(function(){ | ||||||
|  | 			var game = JSSnakeGame(Field("field")) | ||||||
|  | 			game.field.reset() | ||||||
|  | 			game.levels.sand() | ||||||
|  | 		}, 100) | ||||||
|  | 
 | ||||||
|  | 		setTimeout(function(){ | ||||||
|  | 			var game = JSSnakeGame(Field("field")) | ||||||
|  | 			game.field.reset() | ||||||
|  | 			game.levels.walls() | ||||||
|  | 		}, 2000) | ||||||
|  | 
 | ||||||
|  | 		setTimeout(function(){ | ||||||
|  | 			var game = JSSnakeGame(Field("field")) | ||||||
|  | 			game.field.reset() | ||||||
|  | 			game.levels.dashed(20, 2) | ||||||
|  | 		}, 4000) | ||||||
|  | 
 | ||||||
|  | 		setTimeout(function(){ | ||||||
|  | 			var game = JSSnakeGame(Field("field")) | ||||||
|  | 			game.field.reset() | ||||||
|  | 			game.levels.dashed(15) | ||||||
|  | 		}, 6000) | ||||||
|  | 
 | ||||||
|  | 		setTimeout(function(){ | ||||||
|  | 			var game = JSSnakeGame(Field("field")) | ||||||
|  | 			game.field.reset() | ||||||
|  | 			game.levels.dashed(5, 18) | ||||||
|  | 		}, 8000) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		setTimeout(function(){ | ||||||
|  | 			var game = JSSnakeGame(Field("field")) | ||||||
|  | 			game.field.reset() | ||||||
|  | 			setInterval(function(){ | ||||||
|  | 				game.field.reset() | ||||||
|  | 				game.levels.walls() | ||||||
|  | 
 | ||||||
|  | 				var APPLES = 4 | ||||||
|  | 
 | ||||||
|  | 				for(var i=0; i < APPLES; i++) | ||||||
|  | 					game.Apple() | ||||||
|  | 			}, 1000) | ||||||
|  | 		}, 10000) | ||||||
|  | 	}, 24000) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // vim:set ts=4 sw=4 spell :
 | ||||||
							
								
								
									
										549
									
								
								jsssnake.html
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										549
									
								
								jsssnake.html
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,549 @@ | |||||||
|  | <script language="javascript" src="jsssnake.js"></script> | ||||||
|  | <script language="javascript" src="jsssnake-test.js"></script> | ||||||
|  | <script language="javascript"> | ||||||
|  | 
 | ||||||
|  | function start(){ | ||||||
|  | 	var game = JSSnakeGame(Field("field")) | ||||||
|  | 
 | ||||||
|  | 	game.field.reset() | ||||||
|  | 
 | ||||||
|  | 	game.levels.walls() | ||||||
|  | 
 | ||||||
|  | 	var APPLES = 4 | ||||||
|  | 
 | ||||||
|  | 	for(var i=0; i < APPLES; i++) | ||||||
|  | 		game.Apple() | ||||||
|  | 
 | ||||||
|  | 	// zombification... | ||||||
|  | 	/* | ||||||
|  | 	game.field.reset() | ||||||
|  | 	setInterval(function(){ | ||||||
|  | 		game.field.reset() | ||||||
|  | 		game.levels.walls() | ||||||
|  | 
 | ||||||
|  | 		var APPLES = 4 | ||||||
|  | 
 | ||||||
|  | 		for(var i=0; i < APPLES; i++) | ||||||
|  | 			game.Apple() | ||||||
|  | 	}, 1000) | ||||||
|  | 	*/ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DEBUG = false | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <style> | ||||||
|  | 	#field { | ||||||
|  | 		border: solid silver 5px | ||||||
|  | 	} | ||||||
|  | 	#field td { | ||||||
|  | 		border: none | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
|  | <body onload="DEBUG?test():start()"> | ||||||
|  | <table id="field" width="400" height="400" border="1" cellspacing="0" cellpadding="0"> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | 	<tr> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 
 | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 		<td> </td> | ||||||
|  | 	</tr> | ||||||
|  | </table> | ||||||
|  | <div id="log"></div> | ||||||
|  | </body> | ||||||
							
								
								
									
										366
									
								
								jsssnake.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										366
									
								
								jsssnake.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,366 @@ | |||||||
|  | var DEBUG = true | ||||||
|  | 
 | ||||||
|  | function log(text){ | ||||||
|  | 	document.getElementById('log').innerHTML += text + '<br>' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var Field = function(field_id){ | ||||||
|  | 	return ({ | ||||||
|  | 		// XXX HACK: get this from CSS...
 | ||||||
|  | 		APPLE_COLOR: 'red', | ||||||
|  | 		WALL_COLOR: 'gray', | ||||||
|  | 		FIELD_COLOR: 'white', | ||||||
|  | 		TICK: 200, | ||||||
|  | 
 | ||||||
|  | 		// interface...
 | ||||||
|  | 		init: function(field_id, on_kill, on_apple_eaten){ | ||||||
|  | 			this.field = document.getElementById(field_id) | ||||||
|  | 
 | ||||||
|  | 			// this depends on topology...
 | ||||||
|  | 			// NOTE: we consider that the field may not change during operation...
 | ||||||
|  | 			this.cells = this.field.getElementsByTagName("td") | ||||||
|  | 			this.height = this.field.getElementsByTagName("tr").length | ||||||
|  | 
 | ||||||
|  | 			this.cell_count = this.cells.length | ||||||
|  | 			this.width = this.cell_count / this.height | ||||||
|  | 
 | ||||||
|  | 			this.on_kill = on_kill | ||||||
|  | 			this.on_apple_eaten = on_apple_eaten | ||||||
|  | 
 | ||||||
|  | 			this._timer = null | ||||||
|  | 
 | ||||||
|  | 			this.reset() | ||||||
|  | 
 | ||||||
|  | 			// rotation tables...
 | ||||||
|  | 			this._cw = { | ||||||
|  | 				'n': 'e',  | ||||||
|  | 				's': 'w', | ||||||
|  | 				'e': 's', | ||||||
|  | 				'w': 'n' | ||||||
|  | 			} | ||||||
|  | 			this._ccw = { | ||||||
|  | 				'n': 'w',  | ||||||
|  | 				's': 'e', | ||||||
|  | 				'e': 'n', | ||||||
|  | 				'w': 's' | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return this | ||||||
|  | 		}, | ||||||
|  | 		// setup/reset the field to it's original state.
 | ||||||
|  | 		reset: function(){ | ||||||
|  | 			this._snakes = {} | ||||||
|  | 			this._tick = 0 | ||||||
|  | 			this.stop() | ||||||
|  | 			for(var i=0; i < this.cells.length; i++){ | ||||||
|  | 				var cell = this.Cell(i) | ||||||
|  | 				cell.o.style.backgroundColor = this.FIELD_COLOR | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		// do a single step...
 | ||||||
|  | 		step: function(){ | ||||||
|  | 			var cells = this.cells | ||||||
|  | 
 | ||||||
|  | 			for(var i=0; i < cells.length; i++){ | ||||||
|  | 				var cell = this.Cell(i) | ||||||
|  | 				// identify the object...
 | ||||||
|  | 				if(this.is_snake(cell)){ | ||||||
|  | 					this.Snake(cell.o.style.backgroundColor, cell).step() | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			this._tick += 1 | ||||||
|  | 		}, | ||||||
|  | 		start: function(tick){ | ||||||
|  | 			var that = this | ||||||
|  | 			if(tick === null){ | ||||||
|  | 				tick = this.TICK | ||||||
|  | 			} | ||||||
|  | 			if(this._timer === null){ | ||||||
|  | 				this._timer = setInterval(function(){that.step()}, tick) | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 		stop: function(){ | ||||||
|  | 			if(this._timer === null){ | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			clearInterval(this._timer) | ||||||
|  | 			this._timer = null | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		// get a cell helper...
 | ||||||
|  | 		Cell: function(n){ | ||||||
|  | 			var that = this | ||||||
|  | 			var cells = this.cells | ||||||
|  | 			return ({ | ||||||
|  | 				// NOTE: this will be null if a cell does not exist.
 | ||||||
|  | 				o: cells[n], | ||||||
|  | 				index: n, | ||||||
|  | 				// NOTE: these are cyclic...
 | ||||||
|  | 				n: function(){ | ||||||
|  | 					var t = n - that.width | ||||||
|  | 					if(t < 0) | ||||||
|  | 						t = that.cells.length + t | ||||||
|  | 					return that.Cell(t) | ||||||
|  | 				}, | ||||||
|  | 				s: function(){ | ||||||
|  | 					var t = n + that.width | ||||||
|  | 					if(t > that.cells.length-1) | ||||||
|  | 						t = t - that.cells.length | ||||||
|  | 					return that.Cell(t) | ||||||
|  | 				}, | ||||||
|  | 				e: function(){ | ||||||
|  | 					var t = n + 1 | ||||||
|  | 					if(Math.floor(t/that.width) > Math.floor(n/that.width)) | ||||||
|  | 						t = t - that.width | ||||||
|  | 					return that.Cell(t) | ||||||
|  | 				}, | ||||||
|  | 				w: function(){ | ||||||
|  | 					var t = n - 1 | ||||||
|  | 					if(Math.floor(t/that.width) < Math.floor(n/that.width)) | ||||||
|  | 						t = t + that.width | ||||||
|  | 					return that.Cell(t) | ||||||
|  | 				} | ||||||
|  | 			}) | ||||||
|  | 		}, | ||||||
|  | 		// get a cell by it's coordinates...
 | ||||||
|  | 		cell: function(x, y){ | ||||||
|  | 			return this.Cell(x + (y-1) * this.width) | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		// add a snake to the field...
 | ||||||
|  | 		// XXX BUG: size of 1 makes the snake endless...
 | ||||||
|  | 		Snake: function(color, cell, direction, size){ | ||||||
|  | 			var that = this | ||||||
|  | 
 | ||||||
|  | 			// draw the snake if it does not exist...
 | ||||||
|  | 			if(this._snakes[color] == null){ | ||||||
|  | 				cell.o.style.backgroundColor = color | ||||||
|  | 				cell.o.age = size | ||||||
|  | 				this._snakes[color] = { | ||||||
|  | 					'direction':direction, | ||||||
|  | 					'size': size | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// NOTE: the only things this uses from the above scope is color and that.
 | ||||||
|  | 			// NOTE: color is the onlu thing that can't change in a snake.
 | ||||||
|  | 			return ({ | ||||||
|  | 				// XXX BUG: the last cell of a dead snake lives an extra tick...
 | ||||||
|  | 				kill: function(){ | ||||||
|  | 					// this will disable moving and advancing the snake...
 | ||||||
|  | 					that._snakes[color].size = 0 | ||||||
|  | 					if(that.on_kill != null){ | ||||||
|  | 						that.on_kill(that) | ||||||
|  | 					} | ||||||
|  | 				}, | ||||||
|  | 				step: function(){ | ||||||
|  | 					var direction = that._snakes[color].direction | ||||||
|  | 					var size = that._snakes[color].size | ||||||
|  | 					var target = cell[direction]() | ||||||
|  | 
 | ||||||
|  | 					// skip a cell if it's already handled at this step.
 | ||||||
|  | 					if(cell.o.moved_at == that._tick){ | ||||||
|  | 						return | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					// do this only for the head...
 | ||||||
|  | 					if(parseInt(cell.o.age) == size){ | ||||||
|  | 						// handle field bounds...
 | ||||||
|  | 						if(target.o == null){ | ||||||
|  | 							alert('out of bounds!') | ||||||
|  | 							return | ||||||
|  | 						}  | ||||||
|  | 						// kill conditions: walls and other snakes...
 | ||||||
|  | 						if(that.is_snake(target) || that.is_wall(target)){ | ||||||
|  | 							// XXX move this to a separate action
 | ||||||
|  | 							this.kill() | ||||||
|  | 							return | ||||||
|  | 						} | ||||||
|  | 						// apple... 
 | ||||||
|  | 						if(that.is_apple(target)){ | ||||||
|  | 							// grow the snake by one...
 | ||||||
|  | 							// XXX move this to a separate action
 | ||||||
|  | 							that._snakes[color].size += 1 | ||||||
|  | 							size = that._snakes[color].size | ||||||
|  | 							if(that.on_apple_eaten != null){ | ||||||
|  | 								that.on_apple_eaten(that) | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 						// all clear, do the move...
 | ||||||
|  | 						target.o.style.backgroundColor = color | ||||||
|  | 						target.o.age = size | ||||||
|  | 						target.o.moved_at = that._tick | ||||||
|  | 						cell.o.age = size - 1 | ||||||
|  | 
 | ||||||
|  | 					} else {  | ||||||
|  | 						if(cell.o.age <= 1) { | ||||||
|  | 							cell.o.style.backgroundColor = that.FIELD_COLOR | ||||||
|  | 						} | ||||||
|  | 						cell.o.age = parseInt(cell.o.age) - 1 | ||||||
|  | 					} | ||||||
|  | 				}, | ||||||
|  | 
 | ||||||
|  | 				// user interface...
 | ||||||
|  | 				left: function(){ | ||||||
|  | 					that._snakes[color].direction = that._ccw[that._snakes[color].direction] | ||||||
|  | 				}, | ||||||
|  | 				right: function(){ | ||||||
|  | 					that._snakes[color].direction = that._cw[that._snakes[color].direction] | ||||||
|  | 				} | ||||||
|  | 			}) | ||||||
|  | 		}, | ||||||
|  | 		is_snake: function(cell){ | ||||||
|  | 			var snakes = this._snakes | ||||||
|  | 			var color = cell.o.style.backgroundColor | ||||||
|  | 
 | ||||||
|  | 			for(var c in snakes){ | ||||||
|  | 				if(c == color) | ||||||
|  | 					return true | ||||||
|  | 			} | ||||||
|  | 			return false | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		Apple: function(cell){ | ||||||
|  | 			cell.o.style.backgroundColor = this.APPLE_COLOR | ||||||
|  | 			return cell | ||||||
|  | 		}, | ||||||
|  | 		is_apple: function(cell){ | ||||||
|  | 			return cell.o.style.backgroundColor == this.APPLE_COLOR | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		Wall: function(cell){ | ||||||
|  | 			cell.o.style.backgroundColor = this.WALL_COLOR | ||||||
|  | 			return cell | ||||||
|  | 		}, | ||||||
|  | 		is_wall: function(cell){ | ||||||
|  | 			return cell.o.style.backgroundColor == this.WALL_COLOR | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		is_empty: function(cell){ | ||||||
|  | 			return cell.o.style.backgroundColor == this.FIELD_COLOR | ||||||
|  | 		} | ||||||
|  | 	}).init(field_id) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // this defines the basic game logic and controls the rules and levels...
 | ||||||
|  | /* | ||||||
|  | 	NOTE: it is recommended to create game objects in the folowing order: | ||||||
|  | 		1) walls | ||||||
|  | 		2) apples | ||||||
|  | 		3) players | ||||||
|  |  */ | ||||||
|  | function JSSnakeGame(field){ | ||||||
|  | 
 | ||||||
|  | 	var game = { | ||||||
|  | 		field: field, | ||||||
|  | 		TICK: 300, | ||||||
|  | 		// utility methods...
 | ||||||
|  | 		_random_empty_cell: function(){ | ||||||
|  | 			// NOTE: if we are really unlucky, this will take 
 | ||||||
|  | 			//       really long, worse, if we are infinitely unlucky
 | ||||||
|  | 			//       this will take an infinite amount of time... (almost)
 | ||||||
|  | 			var field = this.field | ||||||
|  | 			var i = field.cells.length-1 | ||||||
|  | 			var l = i | ||||||
|  | 			while(true){ | ||||||
|  | 				var c = field.Cell(Math.round(Math.random()*l)) | ||||||
|  | 				if(field.is_empty(c)) | ||||||
|  | 					return c | ||||||
|  | 				i-- | ||||||
|  | 				if(i == 0) | ||||||
|  | 					return null | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 		// create a new player...
 | ||||||
|  | 		// NOTE: direction and position are optional...
 | ||||||
|  | 		// XXX BUG: players should not get created facing a wall directly...
 | ||||||
|  | 		Player: function(name, ccw_button, cw_button, color, cell, direction, size){ | ||||||
|  | 			// XXX register controls...
 | ||||||
|  | 
 | ||||||
|  | 			if(direction == null){ | ||||||
|  | 				direction = ['n', 's', 'e', 'w'][Math.round(Math.random()*3)] | ||||||
|  | 			} | ||||||
|  | 			if(cell === null){ | ||||||
|  | 				cell = this._random_empty_cell() | ||||||
|  | 				if(cell === null) | ||||||
|  | 					return | ||||||
|  | 			} | ||||||
|  | 			// create a snake...
 | ||||||
|  | 			return this.field.Snake(color, cell, direction, size) | ||||||
|  | 		}, | ||||||
|  | 		// NOTE: position is optional...
 | ||||||
|  | 		Apple: function(cell){ | ||||||
|  | 			// place an apple at a random and not occupied position...
 | ||||||
|  | 			var c = this._random_empty_cell() | ||||||
|  | 			if(c === null) | ||||||
|  | 				return | ||||||
|  | 			return this.field.Apple(c) | ||||||
|  | 			 | ||||||
|  | 		}, | ||||||
|  | 		// NOTE: all arguments are optional...
 | ||||||
|  | 		Wall: function(cell, len, direction){ | ||||||
|  | 			// generate random data for arguments that are not given...
 | ||||||
|  | 			if(cell == null){ | ||||||
|  | 				cell = this._random_empty_cell() | ||||||
|  | 				if(cell === null) | ||||||
|  | 					return | ||||||
|  | 			} | ||||||
|  | 			if(direction == null){ | ||||||
|  | 				direction = ['n', 's', 'e', 'w'][Math.round(Math.random()*3)] | ||||||
|  | 			} | ||||||
|  | 			if(len == null){ | ||||||
|  | 				if(direction == 'n' || direction == 's') | ||||||
|  | 					var max = this.field.height  | ||||||
|  | 				else | ||||||
|  | 					var max = this.field.width  | ||||||
|  | 				len = Math.round(Math.random()*(max-1)) | ||||||
|  | 			} | ||||||
|  | 			// place a wall...
 | ||||||
|  | 			for(var i=0; i < len; i++){ | ||||||
|  | 				field.Wall(cell) | ||||||
|  | 				cell = cell[direction]() | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		// level generators and helpers...
 | ||||||
|  | 		levels: { | ||||||
|  | 			dotted: function(n){ | ||||||
|  | 				for(var i=0; i < n; i++) | ||||||
|  | 					game.Wall(null, 1, null) | ||||||
|  | 			}, | ||||||
|  | 			dashed: function(n, length){ | ||||||
|  | 				if(length == null) | ||||||
|  | 					length = 3 | ||||||
|  | 				for(var i=0; i < n; i++) | ||||||
|  | 					game.Wall(null, length, null) | ||||||
|  | 			}, | ||||||
|  | 			// specific level styles...
 | ||||||
|  | 			sand: function(){ | ||||||
|  | 				this.dotted(Math.round(game.field.cells.length/20)) | ||||||
|  | 			}, | ||||||
|  | 			walls: function(){ | ||||||
|  | 				this.dashed( | ||||||
|  | 					Math.round(game.field.cells.length/90),  | ||||||
|  | 					Math.min( | ||||||
|  | 						game.field.width,  | ||||||
|  | 						game.field.height)-2) | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		start: function(){ | ||||||
|  | 			// start the game...
 | ||||||
|  | 			field.start(this.TICK) | ||||||
|  | 		}, | ||||||
|  | 		stop: function(){ | ||||||
|  | 			field.stop() | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	field.on_apple_eaten = function(){game.Apple()} | ||||||
|  | 	//field.on_kill = null
 | ||||||
|  | 
 | ||||||
|  | 	return game | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // vim:set ts=4 sw=4 spell :
 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user