func TileFind(start *TileWrapper, goal Status, tilestate *TileState) env.Direction { var pfstate t_pf_state var node *t_pathnode pfstate.init(env.MAX_SIZE * env.MAX_SIZE) pfstate.setTilestate(tilestate) pfstate.setStart(start, false) node = pfstate.startNode for len(pfstate.open) != 0 { // Find the node with the lowest value for f() // from the open list. As no heuristics are used, // f() effectively returns the value of g. node = pfstate.open[0] for i := 1; i < len(pfstate.open); i++ { if pfstate.open[i].f() < node.f() { node = pfstate.open[i] } } pfstate.addToClosed(node) for i := 0; i < 4; i++ { var dir env.Direction = env.Direction(i) var status Status = tilestate.GetTileStatus(node.tile.tile, dir) if status == goal { // We cannot use the undiscovered tile in pathfinding // because it hasn't been discovered yet. The link // between the TileWrapper and the env.ITile is nil. // However, if we started at a neighbouring tile, we // already know the direction. if start == node.tile { return dir } // Return A* to the closest neighbouring tile (node). return PathFind(start, node.tile, tilestate) } else if status == TILE_DISCOVERED { var wrapper *TileWrapper var neighbour *t_pathnode wrapper = tilestate.GetTile(node.tile, dir) neighbour = pfstate.getPathnode(wrapper) if pfstate.isOpen(neighbour) { neighbour.parent = node neighbour.g = node.g } else if !pfstate.isClosed(neighbour) { pfstate.addToOpen(neighbour) neighbour.parent = node neighbour.g = node.g } } } } return env.NONE }
func (a *Agent) performAction(action int, perf *util.SimPerf) { switch action { case NOOP: case SUCK: perf.AgentCleaned(a.currentTile.GetITile()) a.vacuumCurrent() case int(env.UP): fallthrough case int(env.RIGHT): fallthrough case int(env.DOWN): fallthrough case int(env.LEFT): var moved bool moved = a.moveInDirection(env.Direction(action)) // If the agent successfully moved in the direction, // notify the SimPerf of the dirt-status of the tile. if moved { tile := a.currentTile.GetITile() perf.AgentEnteredTile(tile.GetState() == env.DIRTY) perf.AgentMoved() } } }
/* Returns the direction the agent should take in order to * successfully arrive at the end-tile. */ func PathFind(start, end *TileWrapper, tilestate *TileState) env.Direction { var pfstate t_pf_state var node *t_pathnode var success bool pfstate.init(env.MAX_SIZE * env.MAX_SIZE) pfstate.setTilestate(tilestate) pfstate.setStart(start, true) node = pfstate.startNode for len(pfstate.open) != 0 { // Find the node with the lowest value for f() // from the open list node = pfstate.open[0] for i := 1; i < len(pfstate.open); i++ { if pfstate.open[i].f() < node.f() { node = pfstate.open[i] } } // Stop searching when we've added the destination // to the closed list pfstate.addToClosed(node) if node.tile == end { success = true break } for i := 0; i < 4; i++ { var dir env.Direction = env.Direction(i) var status Status = tilestate.GetTileStatus(node.tile.tile, dir) if status == TILE_DISCOVERED { var wrapper *TileWrapper var neighbour *t_pathnode wrapper = tilestate.GetTile(node.tile, dir) neighbour = pfstate.getPathnode(wrapper) if pfstate.isOpen(neighbour) { neighbour.parent = node neighbour.g = node.g } else if !pfstate.isClosed(neighbour) { pfstate.addToOpen(neighbour) neighbour.parent = node neighbour.g = node.g } } } } if success && node.parent != nil { for node.parent.parent != nil { node = node.parent } // Get the relative position x0, y0 := node.tile.tile.GetIndices() x1, y1 := node.parent.tile.tile.GetIndices() x := x0 - x1 y := y0 - y1 return env.GetDirection(x, y) } return env.NONE }