view code/gameState.lm @ 64:8f6ade456edf

bugfixes to runtime errors of gameState.lm
author William Morgan <billjunk@mrgn.org>
date Mon, 28 Jul 2014 03:14:50 -0700
parents c17380c8bac3
children
line wrap: on
line source

#{
	import: [
		length
		reverse
		split:at
		map
		fold:with
		filter
		flatten
	] from: (module: "ll.lm")
		
	import: [
		makeTree:size
		makeTree
		get:fromTree:size
		get:fromTree
		treeMap:size
		treeMap
		tree:size:update:with
		tree:update:with
		tree:set:to
	] from: (module: "tree.lm")

	import: [
		grid:get	
		grid:update:with
		grid:set:to
		gridMaxX
		gridMaxY
		gridArea
		grid:inBounds?
		grid:get:withDefault
		calcPos
	] from: (module: "grid.lm")

	myAnd <- :a b {
		// only ones and zeros
		(a + b) = 2
	}

	poorMod <- :input mod {
		ret <- input
		if: input >= mod {
			ret <- input - mod
		} else: {
			ret <- input 
		}
		ret
	}

	tupGet <- :cell idx size {
		ret <- 0
		if: idx = 0 {
			ret <- cell value
		} else: { 
	        if: size = 1 {
				ret <- cell tail
			} else: {  // warning, out-of-bounds idx will return a value!
				ret <- tupGet: (cell tail) (idx - 1) (size - 1)
			}
		}
		ret
	}

	tileWall <- 0
	tileEmpty <- 1
	tilePill <- 2
	tilePower <- 3
	tileFruit <- 4
	tileLm <- 5
	tileGhost <- 6

	dirUp <- 0
	dirRight <- 1
	dirDown <- 2
	dirLeft <- 3
	dirFlipped <- :dir {(dir + 2) poorMod: 4}

	makeTicker <- :mapGrid :ghosts{
		print: #[2 ghosts]
		lives <- 3
		lambdamanStartPos <- #[5 5] // TODO grab during parse or write {grid: mapGrid find: tileLm}
		lambdamanStartDir <- dirDown
		lambdamanPos <- lambdamanStartPos
		lambdamanDir <- lambdamanStartDir
		win <- 0
		pillCount <- 50 // TODO count pills during parse 

		isFood <- :tile { (2 <= tile) myAnd: (tile <= 4) }
		getLambdamanChoice <- {0} // TODO ai hookups

		print: 30
		ghostPopulation <- ghosts value
		ghostChoosers <- #[{0} {0} {0} {0}] // TODO ai hookups
		ghostChoice <- :ghostIdx{tupGet: ghostChoosers ghostIdx 4}
		ghostModeStandard <- 0
		ghostModeFright <- 1
		ghostModeinvisble <- 2
		ghostVitality <- :ghost {ghost value}
		ghostPos <- :ghost {(ghost tail) value}
		ghostSetPos <- :ghost pos { #[(ghost ghostVitality) pos (ghost ghostDir)] }
		ghostDir <- :ghost {(ghost tail) tail}
		ghostSetDir <- :ghost dir { #[(ghost ghostVitality) (ghost ghostPos) dir] }
		ghostGetLag <- :ghostType vitality{
			ticksPerMove <- 130 + 2 * ghostType 
			frightTicksPerMove <- ticksPerMove + 65 + ghostType 
			ret <- 0
			if: vitality = ghostModeFright {
				ret <- ticksPerMove
			} else: { 
				ret <- frightTicksPerMove
			}
			ret
		}


		makeEventType <- :lagTick isMovement behavior{
			print: 12
			:curTick {
				print: 11
				expireTick <- curTick + lagTick
				#[expireTick isMovement :events {behavior: expireTick events}]
			}
		}

		endOfLives <- makeEventType: (127 * (mapGrid gridArea) * 16) 0 :tick events {
			777 print
			lives <- 0
			events
		}

		/*
		TODO the rest of the easy action events
		frightModeDeactivate <- (127 * 20) 0

		// fruit must be a lambda that can be given a time
		fruit <- :tick { }
		fruit1Appears <- makeEventType: (127 * 200) 0 :events {
			fruit <- :tick{80}
			fruit1Expires | events
		}
		fruit2Appears <- (127 * 400) 0
		fruit1Expires <- (127 * 280) 0
		fruit2Expires <- (127 * 480) 0
		*/

		moveLambdaman <- makeEventType: 127 1 :tick events {
			print: 20
			move <- getLambdamanChoice: 
			newPos <- (calcPos: move lambdamanPos)
			newTile <- grid: mapGrid get: newPos withDefault: tileWall
			if: (not: (newTile = tileWall)) {
				lambdamanPos <- newPos
			} else: { }
			
			ret <- 0
			if: (newTile isFood) {
				ret <- (moveLambdaman: (tick + 10)) | events
			} else: {
				ret <-(moveLambdaman: tick) | events
			}
			ret
		}

		moveGhost <- :lagTick ghostIdx ghostType curTick {
			print: 21
			expireTick <- curTick + lagTick
			#[expireTick 1 :events {
				nextExpire <- 0
				tree: ghosts update: ghostIdx with: :ghost {
					dir <- ghostDir: ghost
					legalChoice <- dir
					choice <- ghostChoice: ghostIdx
					if: (not: (choice = (dir dirFlipped))) {
						legalChoice <- choice
					} else: { }

					attempts <- [legalChoice dirUp dirDown dirLeft dirRight]
					newDir <- 0
					newPos <- ghost ghostPos
					newTile <- 0
					while: {not: (attempts empty?:)} do:{
						newDir <- attempts value
						newPos <- (calcPos: newDir (ghost ghostPos))
						newTile <- grid: mapGrid get: newPos withDefault: tileWall
						if: (not: (newTile = tileWall)) {
							ghost ghostSetPos: newPos
							ghost ghostSetDir: newDir
							attempts <- []
						} else: {
							attempts <- attempts tail
						}
					}
					
					nextExpire <- ghostGetLag: ghostType (ghost ghostVitality)
					ghost
				}
				(moveGhost: nextExpire ghostIdx ghostType expireTick) | events
			}]
		}

		executeEvents <- :tick isMove events {
			print: #[23 tick isMove events]
			event <- 0
			eventTick <- 0
			eventIsMove <- 0
			eventLam <- 0

			unexpired <- []
			while: { not: (events empty?) } do: {
				event <- events value
				eventTick <- event value
				eventIsMove <- (event tail) value
				print: 17
				if: ( ( eventTick = tick ) myAnd: ( eventIsMove = isMove ) ) {
					eventLam <- ((event tail) tail)
					unexpired <- eventLam: unexpired
				} else: {
					unexpired <- event | unexpired
				}
				events <- events tail
			}
			print: 18
			unexpired
		}

		executeTick <- :tick events {
			print: 14
			// 1.) movement
			events <- executeEvents: tick 1 events

			print: 15
			// 2.) actions
			events <- executeEvents: tick 0 events
			
			print: 16
			// 3.) TODO collide pills powerpills fruit
			

			// 4.) TODO ghost collision

			ret <- 0
			if: pillCount = 0 {
				win <- 1
				ret <- []
			} else: {
				if: lives = 0 {
					ret <- []
				} else: {
					ret <- events
				}
			}
			ret
		}
	
		nextTick <- :events {
			print: 8
			fold: events 0x7FFFFFFF with: :curMin event {
				print: #[9 curMin event]
				eventTick <- event value
				print: 10
				if: eventTick < curMin {
					curMin <- eventTick
				} else: { }
				curMin
			}
		}

		print: 4
		:runUntil {
			tick <- 1
			events <- [
				endOfLives: 0
				moveLambdaman: 0
			]
			ghostIdx <- 0
			ghostType <- 0
			ghostTick <- 0
			while: {ghostIdx < ghostPopulation} do: {
				ghostTick <- ghostGetLag: ghostType ghostModeStandard
				print: 5
				events <- (moveGhost: 0 ghostIdx ghostType ghostTick) | events
				ghostIdx <- ghostIdx + 1
				ghostType <- (ghostType + 1) poorMod: 4
			}
			while: {(tick < runUntil) myAnd: (not: (events empty?))} do: {
				print: 6
				events <- executeTick: tick events
				print: 7
				tick <- events nextTick
			}
		}
	}

	step <- :myState world {
		print: 1
		grid <- makeTree: (map: (world value) :row { 
			makeTree: row 
		})

		world

		ghostsList <- ((world tail) tail) value
		ghosts <- makeTree: ghostsList
		ticker <- makeTicker: grid ghosts
		print: 3
		ticker: 1000

		#[0 0]
	}

	main <- :initWorld ghostCode{
		#[0 step]
	}
/*
	main <- {
		print: (step: 0 #[
			//grid
			[
				[0 0 0 0]
				[0 2 2 0]
				[0 1 0 0]
				[0 0 0 0]
			]
			//lmstate
			#[0 #[1 2] 2 3 0]
			//ghost state
			[]
			//fruit state
			0
		])
	}
*/
}