Beispiel #1
0
    // Add state to open list. If it is alreay in closed, ignore.
    // If it is already in open, update parent and gCost (if shorter path found)
    // Otherwise add to open
    void AddToOpen(xyLoc s, float gCost, xyLoc parent)
    {
        // Write code here.
        if (!openClosed[s.x, s.y].open && openClosed[s.x, s.y].round == round)
        {
            return;
        }
        else if (openClosed[s.x, s.y].round != round)
        {
            openClosed[s.x, s.y].open = true;

            openClosed[s.x, s.y].parent = parent;

            openClosed[s.x, s.y].gCost = gCost;
            openClosed[s.x, s.y].hCost = h.HCost(s, g);

            openClosed[s.x, s.y].fCost = openClosed[s.x, s.y].gCost + openClosed[s.x, s.y].hCost;

            openClosed[s.x, s.y].round = round;
        }
        else if (openClosed[s.x, s.y].open && openClosed[s.x, s.y].round == round)
        {
            float fCos = gCost + openClosed[s.x, s.y].hCost;

            if (fCos < openClosed[s.x, s.y].fCost)
            {
                //Debug.Log("Previous gCost: " + openClosed[s.x,s.y].gCost + " vs. new gCost: " + gCost);
                openClosed[s.x, s.y].parent = parent;
                openClosed[s.x, s.y].fCost  = fCos;
                openClosed[s.x, s.y].gCost  = gCost;
            }
        }
    }
Beispiel #2
0
    // Update is called once per frame
    void Update()
    {
        // Left mouse is down in this frame
        if (Input.GetMouseButtonDown(0))
        {
            Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100))
            {
                startLoc = new xyLoc(Mathf.RoundToInt(hit.point.x), Mathf.RoundToInt(hit.point.z));
                endLoc   = startLoc;
            }
        }
        else if (Input.GetMouseButton(0) || Input.GetMouseButtonUp(0))
        {
            Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 100))
            {
                endLoc = new xyLoc(Mathf.RoundToInt(hit.point.x), Mathf.RoundToInt(hit.point.z));
            }
        }

        bool legal = false;

        if (LineOfSight(startLoc, endLoc))
        {
            legal = true;
        }
        Debug.DrawLine(new Vector3(startLoc.x, 0.5f, startLoc.y),
                       new Vector3(endLoc.x, 0.5f, endLoc.y),
                       legal ? Color.blue : Color.red);
    }
Beispiel #3
0
    void Expand(Map m, xyLoc s)
    {
        xyLoc tmp = new xyLoc();

        for (int x = -1; x <= 1; x++)
        {
            for (int y = -1; y <= 1; y++)
            {
                if (x == 0 && y == 0)
                {
                    continue;
                }
                float cost = 1.5f;
                if (x == 0 || y == 0)
                {
                    cost = 1.0f;
                }
                tmp.x = s.x + x;
                tmp.y = s.y + y;
                if (m.CanMove(s.x, s.y, s.x + x, s.y + y))
                {
                    AddToOpen(tmp, openClosed [s.x, s.y].gCost + cost, s);
                }
            }
        }
    }
Beispiel #4
0
    // Find the next best state to expand
    xyLoc GetNextToExpand()
    {
        xyLoc best  = new xyLoc(-1, -1);
        bool  valid = false;

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (openClosed [x, y].round == round && openClosed [x, y].open)
                {
                    if (valid == false)
                    {
                        best.x = x;
                        best.y = y;
                        valid  = true;
                    }
                    else if (openClosed [x, y].fCost < openClosed [best.x, best.y].fCost)
                    {
                        best.x = x;
                        best.y = y;
                    }
                    else if (openClosed [x, y].fCost == openClosed [best.x, best.y].fCost)
                    {
                        if (openClosed [x, y].gCost > openClosed [best.x, best.y].gCost)
                        {
                            best.x = x;
                            best.y = y;
                        }
                    }
                }
            }
        }
        return(best);
    }
Beispiel #5
0
    public float HCost(xyLoc s, xyLoc g)
    {
        float xDiff = Mathf.Abs(s.x - g.x);
        float yDiff = Mathf.Abs(s.y - g.y);

        return(Mathf.Max(xDiff, yDiff) + ((Mathf.Sqrt(2) - 1) * Mathf.Min(xDiff, yDiff)));
    }
Beispiel #6
0
 // Add state to open list. If it is alreay in closed, ignore.
 // If it is already in open, update parent and gCost (if shorter path found)
 // Otherwise add to open
 void AddToOpen(xyLoc s, float gCost, xyLoc parent)
 {
     // check if already here
     if (openClosed [s.x, s.y].round == round)
     {
         if (openClosed [s.x, s.y].open == false)
         {
             return;
         }
         if (openClosed [s.x, s.y].gCost <= gCost)
         {
             return;
         }
         openClosed [s.x, s.y].gCost  = gCost;
         openClosed [s.x, s.y].parent = parent;
         openClosed [s.x, s.y].fCost  = gCost + openClosed [s.x, s.y].hCost;
     }
     else
     {
         float hCost = h.HCost(s, g);
         openClosed [s.x, s.y].gCost  = gCost;
         openClosed [s.x, s.y].hCost  = hCost;
         openClosed [s.x, s.y].fCost  = gCost + hCost;
         openClosed [s.x, s.y].parent = parent;
         openClosed [s.x, s.y].round  = round;
         openClosed [s.x, s.y].open   = true;
     }
 }
Beispiel #7
0
    public float HCost(xyLoc s, xyLoc g)
    {
        int minv = Mathf.Min(Mathf.Abs(s.x - g.x), Mathf.Abs(s.y - g.y));
        int maxv = Mathf.Max(Mathf.Abs(s.x - g.x), Mathf.Abs(s.y - g.y));

        return(minv * 0.5f + maxv);
    }
Beispiel #8
0
    xyLoc GetClosestGhostLoc(GameController c, out float distance)
    {
        float minDist = Mathf.Infinity;
        xyLoc pacLoc = c.pacmanLoc;
        xyLoc returnLoc = new xyLoc();
        float pinkDist, clydeDist, inkDist, blinkDist;

        pinkDist  = distances[c.pinkyLoc.x / 8, c.pinkyLoc.y / 8];   //GhostController.Dist(pacLoc.x / 8, pacLoc.y / 8, c.pinkyLoc.x / 8, c.pinkyLoc.y / 8);
        clydeDist = distances[c.clydeLoc.x / 8, c.clydeLoc.y / 8];   //GhostController.Dist(pacLoc.x / 8, pacLoc.y / 8, c.clydeLoc.x / 8, c.clydeLoc.y / 8);
        inkDist   = distances[c.inkyLoc.x / 8, c.inkyLoc.y / 8];     //GhostController.Dist(pacLoc.x / 8, pacLoc.y / 8, c.inkyLoc.x / 8, c.inkyLoc.y / 8);
        blinkDist = distances[c.blinkyLoc.x / 8, c.blinkyLoc.y / 8]; //GhostController.Dist(pacLoc.x / 8, pacLoc.y / 8, c.blinkyLoc.x / 8, c.blinkyLoc.y / 8);

        if (pinkDist < minDist)
        {
            minDist   = pinkDist;
            returnLoc = c.pinkyLoc;
        }
        if (clydeDist < minDist)
        {
            minDist   = clydeDist;
            returnLoc = c.clydeLoc;
        }
        if (inkDist < minDist)
        {
            minDist   = inkDist;
            returnLoc = c.inkyLoc;
        }
        if (blinkDist < minDist)
        {
            minDist   = blinkDist;
            returnLoc = c.blinkyLoc;
        }
        distance = minDist;
        return(new xyLoc(returnLoc.x / 8, returnLoc.y / 8));
    }
Beispiel #9
0
    void DoGamePlayLogic()
    {
        if (pacmanElapsed > frameRate)
        {
            pacmanLoc     = HandleAction(pacmanLoc, pacman.GetComponent <ControlledObject> (), true);
            pacmanElapsed = 0f;            //-= 1.0f / 30.0f;
        }
        if (blinkyElapsed > frameRate)
        {
            blinkyLoc     = HandleAction(blinkyLoc, blinky.GetComponent <ControlledObject> (), false);
            blinkyElapsed = 0f;             //-= 1.0f / 30.0f;
        }
        if (pinkyElapsed > frameRate)
        {
            pinkyLoc     = HandleAction(pinkyLoc, pinky.GetComponent <ControlledObject> (), false);
            pinkyElapsed = 0f;             //-= 1.0f / 30.0f;
        }
        if (inkyElapsed > frameRate)
        {
            inkyLoc     = HandleAction(inkyLoc, inky.GetComponent <ControlledObject> (), false);
            inkyElapsed = 0f;             //-= 1.0f / 30.0f;
        }
        if (clydeElapsed > frameRate)
        {
            clydeLoc     = HandleAction(clydeLoc, clyde.GetComponent <ControlledObject> (), false);
            clydeElapsed = 0f;             //-= 1.0f / 30.0f;
        }

        CheckPacmanCollision(blinkyLoc, blinky.GetComponent <ControlledObject> ());
        CheckPacmanCollision(pinkyLoc, pinky.GetComponent <ControlledObject> ());
        CheckPacmanCollision(inkyLoc, inky.GetComponent <ControlledObject> ());
        CheckPacmanCollision(clydeLoc, clyde.GetComponent <ControlledObject> ());
    }
Beispiel #10
0
    // Continue the previous search. (Assumes Init is called first.)
    // Returns true when search is complete
    public bool Step(xyLoc start, xyLoc goal, Map m)
    {
        xyLoc nodeToExplore = GetNextToExpand();

        if (nodeToExplore.x != -1 && nodeToExplore != g)
        {
            Expand(m, nodeToExplore);
            AddToClosed(nodeToExplore);
        }
        else if (nodeToExplore.x == -1)
        {
            success = false;
            return(true);
        }
        else if (nodeToExplore == g)
        {
            success = true;
            return(true);
        }

        //Get best from open
        // Expand best
        //Put best on closed
        // Write code here.

        return(false);
    }
Beispiel #11
0
 public occupancy GetCellType(xyLoc loc)
 {
     if (loc.x < 0 || loc.x >= boardWidth || loc.y < 0 || loc.y >= boardHeight)
     {
         return(occupancy.kOutOfBounds);
     }
     loc.y = boardHeight - loc.y - 1;
     return(board[loc.y, loc.x]);
 }
Beispiel #12
0
    // Initialize any variables specific for this search
    public void Init(xyLoc start, xyLoc goal, Map m, Heuristic heur)
    {
        h = heur;
        g = goal;
        round++;
        success = false;

        AddToOpen(start);
    }
Beispiel #13
0
 public GameController.direction GetAction(GameMaze m, GameController c, xyLoc yourLoc)
 {
     if (c.CanMove(yourLoc, currentDirection))
     {
         lastDirection = currentDirection;
         return(currentDirection);
     }
     return(lastDirection);
 }
Beispiel #14
0
 float GetChasePowerPelletValue(GameController c, xyLoc closestPowerPellet)
 {
     if (powerUp)
     {
         return(0);
     }
     //return 1 - GetQuadraticCurveValue(GhostController.Dist(c.pacmanLoc, GetClosestGhostLoc(c)), .01f, 4);
     return(1 - GetLinearCurveValue(GhostController.Dist(new xyLoc(c.pacmanLoc.x / 8, c.pacmanLoc.y / 8), closestPowerPellet) * 4, .01f));
 }
Beispiel #15
0
 // Initialize any variables specific for this search
 public void Init(xyLoc start, xyLoc goal, Map m, Heuristic heur)
 {
     // Write code here.
     round++;
     g       = goal;
     h       = heur;
     success = false;
     AddToOpen(start);
 }
Beispiel #16
0
    void ResetCharacterLocations()
    {
        pacmanLoc = new xyLoc(13 * 8 + 4, 9 * 8);
        blinkyLoc = new xyLoc(13 * 8 + 4, 21 * 8);
        pinkyLoc  = new xyLoc(13 * 8 + 4, 18 * 8);
        inkyLoc   = new xyLoc(12 * 8, 18 * 8);
        clydeLoc  = new xyLoc(15 * 8, 18 * 8);

        blinky.GetComponent <ControlledObject> ().Reset();
        inky.GetComponent <ControlledObject> ().Reset();
        pinky.GetComponent <ControlledObject> ().Reset();
        clyde.GetComponent <ControlledObject> ().Reset();
    }
Beispiel #17
0
    // Find complete path from start to goal using incremental search
    // functions defined above
    public List <xyLoc> GetPath(xyLoc start, xyLoc goal, Map m, Heuristic heur)
    {
        if (start == goal)
        {
            return(new List <xyLoc>());
        }
        Init(start, goal, m, heur);

        while (Step(start, goal, m) == false)
        {
        }

        return(ExtractPath());
    }
Beispiel #18
0
    // Assume we are in quadrant 0
    bool LineOfSight(xyLoc p1, xyLoc p2)
    {
        Vector2 slope       = new Vector2((p2.x - p1.x), (p2.y - p1.y));
        Vector2 currentSpot = new Vector2(p1.x, p1.y);

        for (int i = p1.x; i < p2.x; i++)
        {
            currentSpot += slope / Mathf.Abs(p1.x - p2.x);
            if (map.IsOccupied((int)currentSpot.x, (int)currentSpot.y) ||
                map.IsOccupied((int)currentSpot.x, (int)currentSpot.y + 1) ||
                map.IsOccupied((int)currentSpot.x, (int)currentSpot.y - 1))
            {
                return(false);
            }
        }
        return(true);
    }
Beispiel #19
0
    // Extract the path from the given state to the goal.
    // (Only runs if search successfully found the goal.)
    public List <xyLoc> ExtractPath()
    {
        List <xyLoc> result = new List <xyLoc> ();

        if (!success)
        {
            return(result);
        }
        xyLoc s = g;

        while (openClosed [s.x, s.y].parent != s)
        {
            result.Add(s);
            s = openClosed [s.x, s.y].parent;
        }
        return(result);
    }
Beispiel #20
0
    GameController.direction MoveToTarget(int targetx, int targety, xyLoc myLoc,
                                          GameController.direction forbiddenDirection,
                                          GameController c)
    {
        GameController.direction best = GameController.direction.kUp;
        float distance = 1000f;

        if (c.CanMove(myLoc, GameController.direction.kUp) && forbiddenDirection != GameController.direction.kUp)
        {
            float thisDist = Dist(targetx, targety, myLoc.x / 8, myLoc.y / 8 + 1);
            if (thisDist < distance)
            {
                best     = GameController.direction.kUp;
                distance = thisDist;
            }
        }
        if (c.CanMove(myLoc, GameController.direction.kLeft) && forbiddenDirection != GameController.direction.kLeft)
        {
            float thisDist = Dist(targetx, targety, myLoc.x / 8 - 1, myLoc.y / 8);
            if (thisDist < distance)
            {
                best     = GameController.direction.kLeft;
                distance = thisDist;
            }
        }
        if (c.CanMove(myLoc, GameController.direction.kDown) && forbiddenDirection != GameController.direction.kDown)
        {
            float thisDist = Dist(targetx, targety, myLoc.x / 8, myLoc.y / 8 - 1);
            if (thisDist < distance)
            {
                best     = GameController.direction.kDown;
                distance = thisDist;
            }
        }
        if (c.CanMove(myLoc, GameController.direction.kRight) && forbiddenDirection != GameController.direction.kRight)
        {
            float thisDist = Dist(targetx, targety, myLoc.x / 8 + 1, myLoc.y / 8);
            if (thisDist < distance)
            {
                best     = GameController.direction.kRight;
                distance = thisDist;
            }
        }
        return(best);
    }
Beispiel #21
0
 void GetAgentLocation()
 {
     currentLoc = new xyLoc(-1, -1);
     for (int x = 0; x < 100; x++)
     {
         if (map.IsOccupied(currentLoc.x, currentLoc.y))
         {
             currentLoc.x = Random.Range(0, Map.width);
             currentLoc.y = Random.Range(0, Map.height);
         }
         else
         {
             transform.position = GetLocation(currentLoc);
             return;
         }
     }
     Debug.Log("Failure placing agent");
 }
Beispiel #22
0
    // Find the next best state to expand
    xyLoc GetNextToExpand()
    {
        xyLoc best  = new xyLoc(-1, -1);
        float fCost = Mathf.Infinity;

        // Write code here.
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                if (openClosed[x, y].round == round && openClosed[x, y].open && openClosed[x, y].fCost < fCost)
                {
                    fCost  = openClosed[x, y].fCost;
                    best.x = x;
                    best.y = y;
                }
            }
        }

        return(best);
    }
Beispiel #23
0
    void GetDistances(GameController c, GameMaze m, int x, int y)
    {
        dotx    = doty = 1000;
        pelletx = pellety = 1000;

        for (int xLoc = 0; xLoc < GameMaze.boardWidth; xLoc++)
        {
            for (int yLoc = 0; yLoc < GameMaze.boardHeight; yLoc++)
            {
                distances[xLoc, yLoc] = 1000;
            }
        }

        distances [x, y] = 0;
        // Here we are using xyLoc to store grid cells, not pixel cells

        Queue <xyLoc> q = new Queue <xyLoc> ();

        AddNeighbors(q, m, x, y);
        while (q.Count > 0)
        {
            xyLoc l = q.Dequeue();
            if (distances[l.x, l.y] == 1000)
            {
                if (dotx == 1000 && (m.GetCellType(l.x, l.y) == GameMaze.occupancy.kDot))
                {
                    dotx = l.x;
                    doty = l.y;
                }
                if (pelletx == 1000 && m.GetCellType(l.x, l.y) == GameMaze.occupancy.kPowerUp)
                {
                    pelletx = l.x;
                    pellety = l.y;
                }

                distances [l.x, l.y] = GetBestNeighborDist(l.x, l.y) + 1;
                AddNeighbors(q, m, l.x, l.y);
            }
        }
    }
Beispiel #24
0
    GameController.direction MoveTowards(xyLoc loc)
    {
        if (distances[loc.x, loc.y] == 0)
        {
            return(lastDirection);
        }
        if (distances[loc.x, loc.y] == 1)
        {
            // Move is to get to our loc; need to reverse it
            switch (GetBestNeighborMove(loc.x, loc.y))
            {
            case GameController.direction.kLeft:
                return(GameController.direction.kRight);

            case GameController.direction.kRight:
                return(GameController.direction.kLeft);

            case GameController.direction.kUp:
                return(GameController.direction.kDown);

            case GameController.direction.kDown:
                return(GameController.direction.kUp);
            }
        }
        switch (GetBestNeighborMove(loc.x, loc.y))
        {
        case GameController.direction.kLeft:
            return(MoveTowards(loc.x - 1, loc.y));

        case GameController.direction.kRight:
            return(MoveTowards(loc.x + 1, loc.y));

        case GameController.direction.kUp:
            return(MoveTowards(loc.x, loc.y + 1));

        case GameController.direction.kDown:
            return(MoveTowards(loc.x, loc.y - 1));
        }
        return(GameController.direction.kNone);
    }
Beispiel #25
0
    public GameController.direction GetAction(GameMaze m, GameController c, xyLoc yourLoc)
    {
        if ((yourLoc.x / 8 != lastx || yourLoc.y / 8 != lasty) &&
            (yourLoc.x % 8 == 0 && yourLoc.y % 8 == 0))
        {
            lastx = yourLoc.x / 8;
            lasty = yourLoc.y / 8;
            GetDistances(c, m, lastx, lasty);

            float lUtil, rUtil, dUtil, uUtil;

            lUtil = GetDirectionUtility(c, m, GameController.direction.kLeft);
            rUtil = GetDirectionUtility(c, m, GameController.direction.kRight);
            dUtil = GetDirectionUtility(c, m, GameController.direction.kDown);
            uUtil = GetDirectionUtility(c, m, GameController.direction.kUp);
            float max = Mathf.NegativeInfinity;
            if (lUtil > max)
            {
                lastDirection = GameController.direction.kLeft;
                max           = lUtil;
            }
            if (rUtil > max)
            {
                lastDirection = GameController.direction.kRight;
                max           = rUtil;
            }
            if (dUtil > max)
            {
                lastDirection = GameController.direction.kDown;
                max           = dUtil;
            }
            if (uUtil > max)
            {
                lastDirection = GameController.direction.kUp;
                max           = uUtil;
            }
        }

        return(lastDirection);
    }
Beispiel #26
0
 void CheckPacmanCollision(xyLoc ghost, ControlledObject obj)
 {
     if (!obj.IsAlive())
     {
         return;
     }
     if ((pacmanLoc.x + 4) / 8 == (ghost.x + 4) / 8 && (pacmanLoc.y + 4) / 8 == (ghost.y + 4) / 8)
     {
         if (currentGameMode == gameMode.kPowerUpGameMode)
         {
             obj.Kill();
             GetSound(gameSound.kEatGhost).Play();
         }
         else
         {
             currentGameMode = gameMode.kLifeOver;
             elapsedTime     = 0;
             GetSound(gameSound.kBackgroundSound).Stop();
             GetSound(gameSound.kDieSound).Play();
         }
     }
 }
Beispiel #27
0
    // Extract the path from the given state to the goal.
    // (Only runs if search successfully found the goal.)
    public List <xyLoc> ExtractPath()
    {
        List <xyLoc> result = new List <xyLoc>();

        if (!success)
        {
            return(result);
        }
        // Write code here.
        xyLoc item = new xyLoc(g.x, g.y);

        result.Add(item);
        xyLoc parentNode;

        do
        {
            parentNode = openClosed[item.x, item.y].parent;
            result.Add(parentNode);
            item.x = parentNode.x;
            item.y = parentNode.y;
        } while (item != openClosed[item.x, item.y].parent);
        return(result);
    }
Beispiel #28
0
    // Continue the previous search. (Assumes Init is called first.)
    public bool Step(xyLoc start, xyLoc goal, Map m)
    {
        xyLoc next = GetNextToExpand();

        // Found optimal path
        if (next == goal)
        {
            success = true;
            return(true);
        }

        // Exhausted open list
        if (next.x == -1)
        {
            return(true);
        }

        // Continue search
        Expand(m, next);
        AddToClosed(next);

        return(false);
    }
Beispiel #29
0
    GameController.direction MakeRandomAction(xyLoc myLoc, GameController.direction forbidden, GameController c)
    {
        while (true)
        {
            switch (Random.Range(0, 4))
            {
            case 0:
                if (c.CanMove(myLoc, GameController.direction.kUp) && forbidden != GameController.direction.kUp)
                {
                    return(GameController.direction.kUp);
                }
                break;

            case 1:
                if (c.CanMove(myLoc, GameController.direction.kLeft) && forbidden != GameController.direction.kLeft)
                {
                    return(GameController.direction.kLeft);
                }
                break;

            case 2:
                if (c.CanMove(myLoc, GameController.direction.kDown) && forbidden != GameController.direction.kDown)
                {
                    return(GameController.direction.kDown);
                }
                break;

            case 3:
                if (c.CanMove(myLoc, GameController.direction.kRight) && forbidden != GameController.direction.kRight)
                {
                    return(GameController.direction.kRight);
                }
                break;
            }
        }
    }
Beispiel #30
0
    public void GetTarget(out int x, out int y, GhostController.ghostMode currentMode, GameController c)
    {
        // default code that needs to be written
        x = y = 0;
        switch (currentMode)
        {
        case GhostController.ghostMode.kChase:
            // Where do you go in chase mode?
            //Vector2 offset = new Vector2 (c.inkyLoc.x, c.inkyLoc.y) - new Vector2 (c.pacmanLoc.x, c.pacmanLoc.y);
            xyLoc offset = new xyLoc(c.blinkyLoc.x - c.pacmanLoc.x, c.blinkyLoc.y - c.pacmanLoc.y);
            int   xOff   = 0;
            int   yOff   = 0;
            switch (c.pacmanLastMove)
            {
            case GameController.direction.kLeft:
                xOff = c.pacmanLoc.x - 2;
                yOff = c.pacmanLoc.y;
                x    = (xOff + offset.x) / 8;
                y    = (yOff + offset.y) / 8;
                break;

            case GameController.direction.kRight:
                xOff = c.pacmanLoc.x + 2;
                yOff = c.pacmanLoc.y;
                x    = (xOff + offset.x) / 8;
                y    = (yOff + offset.y) / 8;
                break;

            case GameController.direction.kUp:
                xOff = c.pacmanLoc.x;
                yOff = c.pacmanLoc.y + 2;
                x    = (xOff + offset.x) / 8;
                y    = (yOff + offset.y) / 8;
                break;

            case GameController.direction.kDown:
                xOff = c.pacmanLoc.x;
                yOff = c.pacmanLoc.y - 2;
                x    = (xOff + offset.x) / 8;
                y    = (yOff + offset.y) / 8;
                break;

            default:
                break;
            }
            break;

        case GhostController.ghostMode.kScatter:
            // Where do you go in scatter mode?
            y = 0;
            x = 244 / 8;
            break;

        case GhostController.ghostMode.kDead:         // back in ghost box
            // Moves to top of ghost box before regenerating
            x = 13;
            y = 21;
            break;

        case GhostController.ghostMode.kLeavingHouse:         // back in ghost box
            // Moves to top of ghost box before starting regular behavior
            x = 13;
            y = 21;
            break;

        default:         // no target
            x = y = 0;
            break;
        }
    }