Example #1
0
 public override void onMovementStart()
 {
     if (moving && board.getBlock(x, y).name == "Lever")
     {
         LeverBlock lever = (LeverBlock)board.getBlock(x, y);
         lever.toggle();
         toggleCount++;
     }
     lastMovement = Time.time;
 }
Example #2
0
    public List <IntPoint> solveLevel()
    {
        enemyList = new List <ToyEnemy>();
        Dictionary <DistanceDictKey, int>[,] distanceGrid = new Dictionary <DistanceDictKey, int> [width, height];
        foreach (Enemy e in board.getEnemyList())
        {
            IntPoint pos = e.getPos();
            IntPoint dir = e.getDirection();
            enemyList.Add(new ToyEnemy(pos.x, pos.y, dir.x, dir.y));
        }
        bool foundPath = false;
        int  targetX   = exit.x;
        int  targetY   = exit.y;

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                for (int c = 0; c < CustomColors.colors.Length; c++)
                {
                    distanceGrid[x, y] = new Dictionary <DistanceDictKey, int>();
                }
            }
        }
        List <QueueEntry> queue     = new List <QueueEntry>();
        IntPoint          playerPos = player.getPos();
//		GameManager.print("Player is at (" + playerPos.x + ", " + playerPos.y + ")");
        int bgColor = CustomColors.indexOf(board.getNextBGColor());

//		GameManager.print("Current background color is: " + bgColor);
//		foreach (ToyEnemy e in enemyList) {
//			GameManager.print("Enemy at (" + e.x + ", " + e.y + ") facing (" + e.dx + ", " + e.dy + ")");
//		}
        queue.Add(new QueueEntry(0, playerPos.x, playerPos.y, bgColor, copyEnemyList(enemyList)));
        if (!board.getBlock(playerPos.x, playerPos.y).name.Equals("Lever"))
        {
            distanceGrid[playerPos.x, playerPos.y].Add(new DistanceDictKey(bgColor, copyEnemyList(enemyList)), 0);
        }
        while (queue.Count > 0)
        {
            QueueEntry firstEntry = queue[0];
            queue.RemoveAt(0);
            int             x          = firstEntry.x;
            int             y          = firstEntry.y;
            bool            playerDead = false;
            List <ToyEnemy> enemies    = firstEntry.enemies;
            if (!board.onBoard(x, y))
            {
                continue;
            }
            if (x == targetX && y == targetY)
            {
                foundPath = true;
                break;
            }

            DistanceDictKey key = new DistanceDictKey(firstEntry.color, copyEnemyList(firstEntry.enemies));

            Block currBlock = board.getBlock(x, y);
            if (firstEntry.distance > 0)
            {
                if (board.getBlock(x, y).name == "Lever")
                {
                    LeverBlock lever      = (LeverBlock)currBlock;
                    int        leverColor = CustomColors.indexOf(lever.leverColor);
                    if ((firstEntry.color & leverColor) == leverColor)
                    {
                        firstEntry.color = firstEntry.color & ~leverColor;
                    }
                    else
                    {
                        firstEntry.color = firstEntry.color | leverColor;
                    }
                }
                for (int i = enemies.Count - 1; i >= 0; i--)
                {
                    ToyEnemy e = enemies[i];
                    if (!e.canPassThrough(board, e.x, e.y, firstEntry.color))
                    {
                        enemies.RemoveAt(i);
                    }
                    else
                    {
                        e.move(board, firstEntry.color);
                        if (e.x == firstEntry.x && e.y == firstEntry.y)
                        {
                            playerDead = true;
                            distanceGrid[firstEntry.x, firstEntry.y].Remove(key);
                            break;
                        }
                    }
                }
                if (playerDead)
                {
                    continue;
                }
            }
            int             newBGColor = firstEntry.color;
            DistanceDictKey newKey     = new DistanceDictKey(newBGColor, copyEnemyList(firstEntry.enemies));
            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    if ((i == 0 || j == 0) && !(i == 0 && j == 0) && board.onBoard(x + i, y + j))
                    {
                        if (distanceGrid[x + i, y + j].ContainsKey(newKey))
                        {
                            continue;
                        }
                        else
                        {
                            playerDead = false;
                            foreach (ToyEnemy e in firstEntry.enemies)
                            {
                                if (e.x == firstEntry.x && e.y == firstEntry.y)
                                {
                                    playerDead = true;
                                    break;
                                }
                            }
                            if (playerDead)
                            {
                                continue;
                            }
                            Block neighbor = board.getBlock(x + i, y + j);
                            switch (neighbor.name)
                            {
                            case "Block":
                                if (newBGColor == CustomColors.indexOf(neighbor.getBaseColor()))
                                {
                                    queue.Add(new QueueEntry(firstEntry.distance + 1,
                                                             x + i, y + j, newBGColor, copyEnemyList(firstEntry.enemies)));
                                    distanceGrid[x + i, y + j].Add(newKey, firstEntry.distance + 1);
                                }
                                break;

                            case "Lever":
                                queue.Add(new QueueEntry(firstEntry.distance + 1,
                                                         x + i, y + j, newBGColor, copyEnemyList(firstEntry.enemies)));
                                distanceGrid[x + i, y + j].Add(newKey, firstEntry.distance + 1);
                                break;

                            case "Empty Block":
                                queue.Add(new QueueEntry(firstEntry.distance + 1,
                                                         x + i, y + j, newBGColor, copyEnemyList(firstEntry.enemies)));
                                distanceGrid[x + i, y + j].Add(newKey, firstEntry.distance + 1);
                                if (x + i == targetX && y + j == targetY)
                                {
                                    foundPath = true;
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
        if (foundPath)
        {
            return(reconstructPath(distanceGrid));
        }
        else
        {
            return(new List <IntPoint>());
        }
    }
Example #3
0
    List <IntPoint> reconstructPath(Dictionary <DistanceDictKey, int>[,] distanceGrid)
    {
        List <IntPoint> path = new List <IntPoint>();
        int             minRemainingDistance = 100000;
        int             x = exit.x;
        int             y = exit.y;
//		int numColors = distanceGrid.GetLength(2);
        DistanceDictKey currKey = null;

        path.Add(new IntPoint(x, y));
        foreach (DistanceDictKey key in distanceGrid[x, y].Keys)
        {
            int value = distanceGrid[x, y][key];
            if (value < minRemainingDistance)
            {
                minRemainingDistance = value;
                currKey = key;
            }
        }
//		for (int color = 0; color < numColors; color++) {
//			if (distanceGrid[x, y, color] < minRemainingDistance && distanceGrid[x, y, color] > -1) {
//				bgColor = color;
//				minRemainingDistance = distanceGrid[x, y].;
//			}
//		}
        while (minRemainingDistance > 0)
        {
            bool foundNextStep = false;
            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    if ((i == 0 || j == 0) && !(i == 0 && j == 0) && board.onBoard(x + i, y + j))
                    {
                        Dictionary <DistanceDictKey, List <DistanceDictKey> > translateDict = new Dictionary <DistanceDictKey, List <DistanceDictKey> >();
                        foreach (DistanceDictKey key in distanceGrid[x + i, y + j].Keys)
                        {
                            List <ToyEnemy> enemies = copyEnemyList(key.enemies);
                            if (minRemainingDistance > 1)
                            {
                                for (int k = enemies.Count - 1; k >= 0; k--)
                                {
                                    ToyEnemy e = enemies[k];
                                    if (!e.canPassThrough(board, e.x, e.y, key.color))
                                    {
                                        enemies.RemoveAt(k);
                                    }
                                    else
                                    {
                                        e.move(board, key.color);
                                    }
                                }
                            }
                            DistanceDictKey newKey = new DistanceDictKey(key.color, enemies);
                            if (!translateDict.ContainsKey(newKey))
                            {
                                translateDict.Add(newKey, new List <DistanceDictKey>());
                            }
                            translateDict[newKey].Add(key);
                        }
                        int newBGColor = currKey.color;
                        if (minRemainingDistance > 1)
                        {
                            if (board.getBlock(x + i, y + j).name == "Lever")
                            {
                                LeverBlock lever      = (LeverBlock)board.getBlock(x + i, y + j);
                                int        leverColor = CustomColors.indexOf(lever.leverColor);
                                if ((currKey.color & leverColor) == leverColor)
                                {
                                    newBGColor = currKey.color & ~leverColor;
                                }
                                else
                                {
                                    newBGColor = currKey.color | leverColor;
                                }
                            }
                        }
                        DistanceDictKey trialKey = new DistanceDictKey(newBGColor, currKey.enemies);
                        if (translateDict.ContainsKey(trialKey))
                        {
                            foreach (DistanceDictKey translation in translateDict[trialKey])
                            {
                                if (distanceGrid[x + i, y + j][translation] == minRemainingDistance - 1)
                                {
                                    currKey = translation;
                                    x       = x + i;
                                    y       = y + j;
                                    minRemainingDistance--;
                                    path.Add(new IntPoint(x, y));
                                    foundNextStep = true;
                                    break;
                                }
                            }
                            if (foundNextStep)
                            {
                                break;
                            }
                        }
                    }
                }
                if (foundNextStep)
                {
                    break;
                }
            }
            if (!foundNextStep)
            {
                break;
            }
        }
        path.Reverse();
//		print("Before");
//		printList<IntPoint>(path);
        if (path[0] != board.getPlayer().getPos())
        {
            path.Insert(0, board.getPlayer().getPos());
        }
//		print("After");
//		printList<IntPoint>(path);
        return(path);
    }