changeset 39:9bccdb3ac979

Add priority queue implementation to lifter. Add methods for cloning playfield and determining valid moves.
author Mike Pavone <pavone@retrodev.com>
date Sun, 15 Jul 2012 14:27:21 -0700
parents cd3ec7d99330
children 20327ae2120b
files src/lifter.tp src/sim.tp
diffstat 2 files changed, 120 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/lifter.tp	Sun Jul 15 14:25:05 2012 -0700
+++ b/src/lifter.tp	Sun Jul 15 14:27:21 2012 -0700
@@ -1,4 +1,49 @@
 #{
+	pqueue <- {
+		normalnode <- :pri val {
+			#{
+				priority <- pri
+				value <- val
+				next <- false
+				higherPriority? <- :other {
+					priority > (other priority)
+				}
+				if:else <- :self trueblock :elseblock {
+					trueblock:
+				}
+			}
+		}
+		head <- #{
+			higherPriority? <- :other {false}
+			next <- { self }
+			value <- { false }
+		}
+		#{
+			take <- {
+				cur <- head
+				head <- cur next
+				cur value
+			}
+			insert:atPriority <- :val pri {
+				node <- normalnode: pri val
+				cur <- head
+				last <- false
+				while: {cur higherPriority?: node} do: {
+					last <- cur
+					cur <- cur next
+				}
+				if: last {
+					node next!: (last next)
+					last next!: node
+				} else: {
+					node next!: head
+					head <- node
+				}
+				self
+			}
+		}
+	}
+	
 	abs <- :val {
 		if: val < 0 { 0 - val } else: { val }
 	}
@@ -13,5 +58,14 @@
 		os write: 2 text
 		os write: 2 "width: " . (string: (playfield width)) . "\n"
 		os write: 2 "height: " . (string: (playfield height)) . "\n"
+		me <-playfield getRobot
+		os write: 2 "robot x: " . (me x) . " y: " . (me y) . "\n"
+		neighbors <- playfield validMoves: (me x) (me y)
+		foreach: neighbors :idx move {
+			os write: 2 "move: " . move . "\n"
+			curfield <- playfield clone
+			curfield advance: (move cmd)
+			curfield printGrid
+		}
 	}
 }
--- a/src/sim.tp	Sun Jul 15 14:25:05 2012 -0700
+++ b/src/sim.tp	Sun Jul 15 14:27:21 2012 -0700
@@ -14,6 +14,10 @@
 	debugLog <- :str {
 		os write: 2 str
 	}
+	
+	abs <- :val {
+		if: val < 0 { 0 - val } else: { val }
+	}
 
 	makeCellTypes <- {
 		typedict <- dict linear
@@ -114,7 +118,7 @@
 	state <- #{
 		new <- :in_grid in_width in_height { 
 			nextGrid <- #[]
-			robot <- null
+			_robot <- null
 			endreached <- false
 			ret <- #{
 				grid <- in_grid
@@ -129,6 +133,47 @@
 				getCell <- :x y {
 					grid get: (calcIndex: x y)
 				}
+				validDest?:from <- :index :fromIndex {
+					cell <- (grid get: index)
+					if: (cell navigable) {true} else: {
+						if: (cell eq: (cellTypes rock)) {
+							diff <- index - fromIndex
+							//make sure movement was horizontal
+							if: (abs: diff) = 1 {
+								rockdest <- index + diff
+								if: ((grid get: rockdest) eq: (cellTypes empty)) {
+									//make sure rock destination doesn't wrap
+									(calcY: rockdest) = (calcY: index)
+								}
+							}
+						}
+					}
+				}
+				validMoves <- :x y {
+					
+					amove <- :idx name {#{
+						index <- idx
+						cmd <- name
+						string <- {
+							name . "(" . idx . ")"
+						} 
+					}}
+					here <- calcIndex: x y
+					//TODO: Add wait move when rocks are in motion
+					//(amove: here "W") 
+					cur <- #[(amove: here "A")]
+					up <- amove: (calcIndex: x y + 1) "U"
+					down <- amove: (calcIndex: x y - 1) "D"
+					left <- amove: (calcIndex: x - 1 y) "L"
+					right <- amove: (calcIndex: x + 1 y) "R"
+					foreach: #[up down left right] :idx el {
+						if: (validDest?: (el index) from: here) {
+							cur append: el
+						}
+					}
+					cur
+				}
+				getRobot <- { _robot }
 				updatePos <- :obj Index {
 					obj x!: (calcX: Index)
 					obj y!: (calcY: Index)
@@ -145,7 +190,7 @@
 				advance <- :roboCmd {
 					endreached <- roboCmd = "A"
 					if: (not: endreached) {
-						robot doCmd: roboCmd
+						_robot doCmd: roboCmd
 						moves <- moves + 1
 						doUpdate:
 					}
@@ -165,13 +210,29 @@
 						}
 					}
 				}
+				clone <- {
+					cgrid <- #[]
+					foreach: grid :idx el {
+						if: (el isrobot) {
+							cgrid append: (cellTypes robot)
+						} else: {
+							cgrid append: el
+						}
+					}
+					myclone <- state new: cgrid width height
+					myclone water!: water
+					myclone flooding!: flooding
+					myclone waterproof!: waterproof
+					myclone moves!: moves
+					myclone
+				}
 			}
 			foreach: in_grid :index el{
 				nextGrid append: el
 				if: (el isrobot) {
-					robot <- el
-					robot mine!: ret
-					ret updatePos: robot index
+					_robot <- el
+					_robot mine!: ret
+					ret updatePos: _robot index
 				}