|  |  | @ -1,4 +1,4 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | const [EMPTY, FOOD, WALL, FIRE, HOLE, HOLE_S, SNAKE]=Array(7).keys(); |  |  |  | const [EMPTY, FOOD, SUPER_FOOD, WALL, FIRE, HOLE, HOLE_S, SNAKE]=Array(7).keys(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | class SnekGame { |  |  |  | class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	constructor(settings, canvas, rules) { |  |  |  | 	constructor(settings, canvas, rules) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -17,6 +17,7 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 						switch(settings.world[y][x]) { |  |  |  | 						switch(settings.world[y][x]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 							case ' ': return EMPTY; |  |  |  | 							case ' ': return EMPTY; | 
			
		
	
		
		
			
				
					
					|  |  |  | 							case 'f': return FOOD; |  |  |  | 							case 'f': return FOOD; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 							case 'F': return SUPER_FOOD; | 
			
		
	
		
		
			
				
					
					|  |  |  | 							case 'w': return WALL; |  |  |  | 							case 'w': return WALL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 							case 'o': return HOLE; |  |  |  | 							case 'o': return HOLE; | 
			
		
	
		
		
			
				
					
					|  |  |  | 							case 'i': return FIRE; |  |  |  | 							case 'i': return FIRE; | 
			
		
	
	
		
		
			
				
					|  |  | @ -60,6 +61,9 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 			// add the food
 |  |  |  | 			// add the food
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 			settings.food.forEach(([x, y]) => this.world[x][y]=FOOD); |  |  |  | 			settings.food.forEach(([x, y]) => this.world[x][y]=FOOD); | 
			
		
	
		
		
			
				
					
					|  |  |  | 			this.fruits=[...settings.food]; |  |  |  | 			this.fruits=[...settings.food]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			// add the super food
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			if(settings.superFood) settings.superFood.forEach(([x, y]) => this.world[x][y]=SUPER_FOOD); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// add the snake to the world
 |  |  |  | 		// add the snake to the world
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -88,6 +92,7 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		// load the custom rules
 |  |  |  | 		// load the custom rules
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		this.rules=Object.assign({ |  |  |  | 		this.rules=Object.assign({ | 
			
		
	
		
		
			
				
					
					|  |  |  | 			fruitRegrow: true, |  |  |  | 			fruitRegrow: true, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			superFruitGrow: false, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			speedIncrease: true, |  |  |  | 			speedIncrease: true, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			worldWrap: true, |  |  |  | 			worldWrap: true, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			winCondition: 'none', |  |  |  | 			winCondition: 'none', | 
			
		
	
	
		
		
			
				
					|  |  | @ -145,6 +150,7 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const wall=assets.get('wall'); |  |  |  | 		const wall=assets.get('wall'); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const hole=assets.get('hole'); |  |  |  | 		const hole=assets.get('hole'); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const fire=assets.get('fire'); |  |  |  | 		const fire=assets.get('fire'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		const superFruit=assets.get('superFruit'); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		const putTile=(x, y, tile) => this.ctx.drawImage( |  |  |  | 		const putTile=(x, y, tile) => this.ctx.drawImage( | 
			
		
	
		
		
			
				
					
					|  |  |  | 			tile, |  |  |  | 			tile, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			offsetX+cellSize*x, |  |  |  | 			offsetX+cellSize*x, | 
			
		
	
	
		
		
			
				
					|  |  | @ -190,6 +196,10 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 						// technically, this works for all shapes
 |  |  |  | 						// technically, this works for all shapes
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 						// however, the tileset only handles convex shapes
 |  |  |  | 						// however, the tileset only handles convex shapes
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 					} |  |  |  | 					} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					case SUPER_FOOD: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						putTileAnim(x, y, superFruit); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
	
		
		
			
				
					|  |  | @ -362,7 +372,12 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				) return this.die(); |  |  |  | 				) return this.die(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 				break; |  |  |  | 				break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 			// you eat, you don't die
 |  |  |  | 			// you eat, you get a massive score boost
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			case SUPER_FOOD: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				this.score+=10; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			// you eat, you grow
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 			case FOOD: |  |  |  | 			case FOOD: | 
			
		
	
		
		
			
				
					
					|  |  |  | 				// re-grow the snake
 |  |  |  | 				// re-grow the snake
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				this.snake.push(tail); |  |  |  | 				this.snake.push(tail); | 
			
		
	
	
		
		
			
				
					|  |  | @ -377,9 +392,9 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 				// increase score
 |  |  |  | 				// increase score
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				this.score++; |  |  |  | 				this.score++; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				// custom rules
 |  |  |  | 				// list empty cells
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 				if(this.rules.fruitRegrow) { |  |  |  | 				const getEmptyCells=() => | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 					const emptyCells=this.world |  |  |  | 					this.world | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 						.map( |  |  |  | 						.map( | 
			
		
	
		
		
			
				
					
					|  |  |  | 							(l, x) => l |  |  |  | 							(l, x) => l | 
			
		
	
		
		
			
				
					
					|  |  |  | 								.map( |  |  |  | 								.map( | 
			
		
	
	
		
		
			
				
					|  |  | @ -388,11 +403,24 @@ class SnekGame { | 
			
		
	
		
		
			
				
					
					|  |  |  | 									a => a |  |  |  | 									a => a | 
			
		
	
		
		
			
				
					
					|  |  |  | 								) |  |  |  | 								) | 
			
		
	
		
		
			
				
					
					|  |  |  | 						).flat(); |  |  |  | 						).flat(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				// custom rules
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				if(this.rules.fruitRegrow) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					const emptyCells=getEmptyCells(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 					const cell=emptyCells[Math.floor(Math.random()*emptyCells.length)]; |  |  |  | 					const cell=emptyCells[Math.floor(Math.random()*emptyCells.length)]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 					this.fruits.push(cell); |  |  |  | 					this.fruits.push(cell); | 
			
		
	
		
		
			
				
					
					|  |  |  | 					this.world[cell[0]][cell[1]]=FOOD; |  |  |  | 					this.world[cell[0]][cell[1]]=FOOD; | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				if(this.rules.superFruitGrow) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					if(Math.random()<.1) { // 10% chance
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						const emptyCells=getEmptyCells(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						const cell=emptyCells[Math.floor(Math.random()*emptyCells.length)]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 						this.world[cell[0]][cell[1]]=SUPER_FOOD; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 					} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				if(this.rules.speedIncrease) { |  |  |  | 				if(this.rules.speedIncrease) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 					this.delay*=this.rules.speedMultiplier; |  |  |  | 					this.delay*=this.rules.speedMultiplier; | 
			
		
	
		
		
			
				
					
					|  |  |  | 					if(this.delay<this.rules.speedCap) this.delay=this.rules.speedCap; |  |  |  | 					if(this.delay<this.rules.speedCap) this.delay=this.rules.speedCap; | 
			
		
	
	
		
		
			
				
					|  |  | 
 |