예제 #1
0
 internal void UpdateTilesIGonextTo(List <SmartTile> smartTiles)
 {
     foreach (int friendID in Friends)
     {
         SmartTile smartTile = smartTiles[friendID];
         TilesIGoNextTo.UnionWith(smartTile.TilesICanPlace);
         TilesIGoNextTo.UnionWith(smartTile.Extras);
     }
 }
예제 #2
0
        public bool Apply(ArrayMap <ushort> localTiles, ref ushort tileID)
        {
            ArrayMap <bool?>      LocalTilesAreRelated = new ArrayMap <bool?>(5, 6);
            Func <int, int, bool> getRelatedness       = (x, y) =>
            {
                x += 2;
                y += 3;
                return(LocalTilesAreRelated[x, y] ?? (LocalTilesAreRelated[x, y] = TilesIGoNextTo.Contains(localTiles[x, y], TilesIGoNextTo.Comparer)).Value);
            };

            int assignmentID = 47;

            switch (
                (getRelatedness(0, -1) ? 1 : 0) |
                (getRelatedness(0, 1) ? 2 : 0) |
                (getRelatedness(-1, 0) ? 4 : 0) |
                (getRelatedness(1, 0) ? 8 : 0)
                )
            {
            case 0:     //no neighbors at all
                assignmentID = 47;
                break;

            case 1:     //U
                assignmentID = 77;
                break;

            case 2:     //D
                if (getRelatedness(0, 2))
                {
                    if (getRelatedness(-1, 1) && !getRelatedness(1, 1) && getRelatedness(-1, 2))
                    {
                        assignmentID = 80; break;
                    }
                    else if (getRelatedness(1, 1) && !getRelatedness(-1, 1) && getRelatedness(1, 2))
                    {
                        assignmentID = 81; break;
                    }
                }
                assignmentID = 57;
                break;

            case 3:     //UD
                assignmentID = 67;
                break;

            case 4:     //L
                assignmentID = 32;
                break;

            case 5:                                                                                          //LU
                if (!getRelatedness(-1, -1))                                                                 //thin
                {
                    if (getRelatedness(1, -1) && !getRelatedness(0, -2) && Assignments[94].Tiles.Count != 0) //horizontal tube slope
                    {
                        assignmentID = 94;
                    }
                    else if (getRelatedness(-1, 1) && !getRelatedness(-2, 0))     //vertical tube slope
                    {
                        assignmentID = 87;
                    }
                    else
                    {
                        assignmentID = 25;
                    }
                }
                else     //thick
                {
                    if (!getRelatedness(1, -1) && !getRelatedness(0, -2) && getRelatedness(-1, -2) && !getRelatedness(-1, -3))
                    {
                        assignmentID = 93;
                        break;
                    }
                    if (Assignments[53].Tiles.Count != 0 && getRelatedness(1, -1))     //ceiling slope
                    {
                        if (getRelatedness(0, -2))
                        {
                            if (getRelatedness(-1, -2) && getRelatedness(1, -2) && Assignments[43].Tiles.Count != 0)
                            {
                                assignmentID = 53;
                                break;
                            }
                        }
                        else
                        {
                            if (Assignments[63].Tiles.Count != 0)
                            {
                                assignmentID = 53;
                                break;
                            }
                        }
                    }
                    if (Assignments[75].Tiles.Count != 0 && getRelatedness(-1, 1))     //wall slope
                    {
                        if (getRelatedness(-2, 0))
                        {
                            if (getRelatedness(-2, -1) && Assignments[74].Tiles.Count != 0)
                            {
                                assignmentID = 75;
                                break;
                            }
                        }
                        else
                        {
                            if (Assignments[76].Tiles.Count != 0)
                            {
                                assignmentID = 75;
                                break;
                            }
                        }
                    }
                    assignmentID = 22;
                }
                break;

            case 6:                                                                                        //LD
                if (!getRelatedness(-1, 1))                                                                //thin
                {
                    if (getRelatedness(1, 1) && !getRelatedness(0, 2) && Assignments[85].Tiles.Count != 0) //horizontal tube slope
                    {
                        assignmentID = 85;
                    }
                    else if (getRelatedness(-1, -1) && !getRelatedness(-2, 0))     //vertical tube slope
                    {
                        assignmentID = 97;
                    }
                    else
                    {
                        assignmentID = 5;
                    }
                }
                else                                                                                                                                       //thick
                {
                    if (Assignments[41].Tiles.Count != 0)                                                                                                  //floor slope
                    {
                        if (getRelatedness(1, 1))                                                                                                          //normal slope
                        {
                            if (Assignments[getRelatedness(0, 2) ? (getRelatedness(1, 2) ? (getRelatedness(-1, 2) ? 51 : 79) : 99) : 61].Tiles.Count != 0) //99 is a cheat, it will be false, there's no such tile
                            {
                                assignmentID = 41;
                                break;
                            }
                        }
                        else                                                       //downward slope at the end of the platform
                        {
                            if (getRelatedness(-1, -1) && !getRelatedness(-1, -2)) //slope continues above but is not outright wall
                            {
                                if (!getRelatedness(0, 2))
                                {
                                    if (Assignments[93].Tiles.Count != 0)
                                    {
                                        assignmentID = 41;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (getRelatedness(-1, 2) && Assignments[83].Tiles.Count != 0)
                                    {
                                        assignmentID = 41;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (Assignments[65].Tiles.Count != 0 && getRelatedness(-1, -1))     //wall slope
                    {
                        if (getRelatedness(-2, 0))
                        {
                            if (getRelatedness(-2, 1) && Assignments[64].Tiles.Count != 0)
                            {
                                assignmentID = 65;
                                break;
                            }
                        }
                        else
                        {
                            if (Assignments[66].Tiles.Count != 0)
                            {
                                assignmentID = 65;
                                break;
                            }
                        }
                    }
                    assignmentID = 2;
                }
                break;

            case 7:     //LUD
                if (getRelatedness(-1, -1))
                {
                    assignmentID = getRelatedness(-1, 1) ? (!getRelatedness(1, -1) && !getRelatedness(0, -2) && getRelatedness(-1, -2) && !getRelatedness(-1, -3) ? 83 : 12) : (getRelatedness(-2, 0) ? 27 : 56);
                }
                else
                {
                    assignmentID = getRelatedness(-1, 1) ? (getRelatedness(1, -1) || getRelatedness(0, -2) ? (getRelatedness(-2, 0) ? 37 : 46) : 90) : 15;
                }
                break;

            case 8:     //R
                assignmentID = 30;
                break;

            case 9:                                                                                           //RU
                if (!getRelatedness(1, -1))                                                                   //thin
                {
                    if (getRelatedness(-1, -1) && !getRelatedness(0, -2) && Assignments[95].Tiles.Count != 0) //horizontal tube slope
                    {
                        assignmentID = 95;
                    }
                    else if (getRelatedness(1, 1) && !getRelatedness(2, 0))     //vertical tube slope
                    {
                        assignmentID = 96;
                    }
                    else
                    {
                        assignmentID = 23;
                    }
                }
                else     //thick
                {
                    if (!getRelatedness(-1, -1) && !getRelatedness(0, -2) && getRelatedness(1, -2) && !getRelatedness(1, -3))
                    {
                        assignmentID = 92;
                        break;
                    }
                    if (Assignments[52].Tiles.Count != 0 && getRelatedness(-1, -1))     //ceiling slope
                    {
                        if (getRelatedness(0, -2))
                        {
                            if (getRelatedness(1, -2) && getRelatedness(-1, -2) && Assignments[42].Tiles.Count != 0)
                            {
                                assignmentID = 52;
                                break;
                            }
                        }
                        else
                        {
                            if (Assignments[62].Tiles.Count != 0)
                            {
                                assignmentID = 52;
                                break;
                            }
                        }
                    }
                    if (Assignments[54].Tiles.Count != 0 && getRelatedness(1, 1))     //wall slope
                    {
                        if (getRelatedness(2, 0))
                        {
                            if (getRelatedness(2, -1) && Assignments[55].Tiles.Count != 0)
                            {
                                assignmentID = 54;
                                break;
                            }
                        }
                        else
                        {
                            if (Assignments[56].Tiles.Count != 0)
                            {
                                assignmentID = 54;
                                break;
                            }
                        }
                    }
                    assignmentID = 20;
                }
                break;

            case 10:                                                                                        //RD
                if (!getRelatedness(1, 1))                                                                  //thin
                {
                    if (getRelatedness(-1, 1) && !getRelatedness(0, 2) && Assignments[84].Tiles.Count != 0) //horizontal tube slope
                    {
                        assignmentID = 84;
                    }
                    else if (getRelatedness(1, -1) && !getRelatedness(2, 0))     //vertical tube slope
                    {
                        assignmentID = 86;
                    }
                    else
                    {
                        assignmentID = 3;
                    }
                }
                else                                      //thick
                {
                    if (Assignments[40].Tiles.Count != 0) //floor slope
                    {
                        if (getRelatedness(-1, 1))        //normal slope
                        {
                            if (Assignments[getRelatedness(0, 2) ? (getRelatedness(-1, 2) ? (getRelatedness(1, 2) ? 50 : 78) : 99) : 60].Tiles.Count != 0)
                            {
                                assignmentID = 40;
                                break;
                            }
                        }
                        else                                                     //downward slope at the end of the platform
                        {
                            if (getRelatedness(1, -1) && !getRelatedness(1, -2)) //slope continues above but is not outright wall
                            {
                                if (!getRelatedness(0, 2))
                                {
                                    if (Assignments[92].Tiles.Count != 0)
                                    {
                                        assignmentID = 40;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (getRelatedness(1, 2) && Assignments[82].Tiles.Count != 0)
                                    {
                                        assignmentID = 40;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (Assignments[44].Tiles.Count != 0 && getRelatedness(1, -1))     //wall slope
                    {
                        if (getRelatedness(2, 0))
                        {
                            if (getRelatedness(2, 1) && Assignments[45].Tiles.Count != 0)
                            {
                                assignmentID = 44;
                                break;
                            }
                        }
                        else
                        {
                            if (Assignments[46].Tiles.Count != 0)
                            {
                                assignmentID = 44;
                                break;
                            }
                        }
                    }
                    assignmentID = 0;
                }
                break;

            case 11:     //RUD
                if (getRelatedness(1, -1))
                {
                    assignmentID = getRelatedness(1, 1) ? (!getRelatedness(-1, -1) && !getRelatedness(0, -2) && getRelatedness(1, -2) && !getRelatedness(1, -3) ? 82 : 10) : (getRelatedness(2, 0) ? 26 : 76);
                }
                else
                {
                    assignmentID = getRelatedness(1, 1) ? (getRelatedness(-1, -1) || getRelatedness(0, -2) ? (getRelatedness(2, 0) ? 36 : 66) : 91) : 13;
                }
                break;

            case 12:     //LR
                assignmentID = 31;
                break;

            case 13:     //LRU
                if (getRelatedness(-1, -1))
                {
                    assignmentID = getRelatedness(1, -1) ? 21 : (getRelatedness(0, -2) ? 18 : 61);
                }
                else
                {
                    assignmentID = getRelatedness(1, -1) ? (getRelatedness(0, -2) ? 19 : 60) : 24;
                }
                break;

            case 14:     //LRD
                if (getRelatedness(-1, 1))
                {
                    assignmentID = getRelatedness(1, 1) ? 1 : (getRelatedness(0, 2) ? 8 : 63);
                }
                else
                {
                    assignmentID = getRelatedness(1, 1) ? (getRelatedness(0, 2) ? 9 : 62) : 4;
                }
                break;

            case 15:     //LRUD
                switch (
                    (getRelatedness(-1, -1) ? 1 : 0) |
                    (getRelatedness(1, -1) ? 2 : 0) |
                    (getRelatedness(1, 1) ? 4 : 0) |
                    (getRelatedness(-1, 1) ? 8 : 0)
                    )
                {
                case 0:         //no corners at all, full pipe plus
                    assignmentID = 14;
                    break;

                case 1:
                    assignmentID = 39;
                    break;

                case 2:
                    assignmentID = 38;
                    break;

                case 3:
                    assignmentID = 58;
                    break;

                case 4:
                    assignmentID = 28;
                    break;

                case 5:
                    assignmentID = (getRelatedness(-1, -1) && !getRelatedness(0, -2)) ? 79 : 69;
                    break;

                case 6:
                    assignmentID = 48;
                    break;

                case 7:
                    if (!getRelatedness(0, 2))
                    {
                        assignmentID = 42;
                    }
                    else if (!getRelatedness(-2, 0))
                    {
                        assignmentID = 55;
                    }
                    else
                    {
                        assignmentID = 7;
                    }
                    break;

                case 8:
                    assignmentID = 29;
                    break;

                case 9:
                    assignmentID = 49;
                    break;

                case 10:
                    assignmentID = (getRelatedness(1, -1) && !getRelatedness(0, -2)) ? 78 : 68;
                    break;

                case 11:
                    if (!getRelatedness(0, 2))
                    {
                        assignmentID = 43;
                    }
                    else if (!getRelatedness(2, 0))
                    {
                        assignmentID = 74;
                    }
                    else
                    {
                        assignmentID = 6;
                    }
                    break;

                case 12:
                    assignmentID = 59;
                    break;

                case 13:
                    if (!getRelatedness(0, -2))
                    {
                        assignmentID = 51;
                    }
                    else if (!getRelatedness(2, 0))
                    {
                        assignmentID = 64;
                    }
                    else
                    {
                        assignmentID = 16;
                    }
                    break;

                case 14:
                    if (!getRelatedness(0, -2))
                    {
                        assignmentID = 50;
                    }
                    else if (!getRelatedness(-2, 0))
                    {
                        assignmentID = 45;
                    }
                    else
                    {
                        assignmentID = 17;
                    }
                    break;

                case 15:         //totally surrounded, normal wall tile
                    assignmentID = 11;
                    break;
                }
                break;
            }

            ResolveAssignmentIDToSomethingWithTilesInIt(ref assignmentID);

            bool lastRuleApplied = true;

            foreach (Rule rule in Assignments[assignmentID].Rules)
            {
                List <ushort> frames  = rule.Result;
                bool          applies = lastRuleApplied && rule.Applies(localTiles, Tileset.SmartTiles, TilesICanPlace.Comparer);
                if (frames.Count == 0) //and
                {
                    lastRuleApplied = applies;
                }
                else //then
                {
                    if (applies)
                    {
                        tileID = frames[frames.Count == 1 ? 0 : Rand.Next(frames.Count)];
                        return(true);
                    }
                    lastRuleApplied = true;
                }
            }

            var tiles = Assignments[assignmentID].Tiles;

            if (tiles.Count >= 1)
            {
                tileID = tiles[tiles.Count == 1 ? 0 : Rand.Next(tiles.Count)];
            }
            else
            {
                return(false);
            }
            return(true);
        }
예제 #3
0
        internal void UpdateAllPossibleTiles(List <SmartTile> smartTiles, bool updateFriends = true)
        {
            TilesICanPlace.Clear();
            foreach (var assignment in Assignments)
            {
                if (assignment.Tiles != Extras)
                {
                    assignment.UnionWith(TilesICanPlace);
                }
            }

            TilesIGoNextTo.Clear();
            TilesIGoNextTo.UnionWith(TilesICanPlace);
            TilesIGoNextTo.UnionWith(Extras);

            if (updateFriends)
            {
                UpdateTilesIGonextTo(smartTiles);
            }

            try
            {
                var               qualifyingAssignment = Assignments[MandatoryAssignmentIDs.First(i => !Assignments[i].Empty)];
                ushort            qualifyingTileID     = qualifyingAssignment.Tiles[0];
                ArrayMap <ushort> surroundingTiles     = new ArrayMap <ushort>(3 + 2 * 2, 3 + 3 + 2);
                for (int x = 2; x < 5; ++x)
                {
                    for (int y = 3; y < 6; ++y)
                    {
                        surroundingTiles[x, y] = qualifyingTileID;
                    }
                }
                for (int pass = 0; pass < 2; ++pass) //why not
                {
                    for (int x = 2; x < 5; ++x)
                    {
                        for (int y = 3; y < 6; ++y)
                        {
                            ArrayMap <ushort> localTiles = new ArrayMap <ushort>(5, 6);
                            for (int xx = 0; xx < 5; ++xx)
                            {
                                for (int yy = 0; yy < 6; ++yy)
                                {
                                    localTiles[xx, yy] = surroundingTiles[x + xx - 2, y + yy - 3];
                                }
                            }
                            ushort tileID = surroundingTiles[x, y];
                            if (Apply(localTiles, ref tileID)) //not sure why this would return false, but...
                            {
                                surroundingTiles[x, y] = tileID;
                            }
                        }
                    }
                }
                PreviewTileIDs = Enumerable.Range(0, 9).Select(i => surroundingTiles[(i % 3) + 2, (i / 3) + 3]).ToArray();
                Available      = true;
            }
            catch //in First
            {
                PreviewTileIDs = new ushort[9];
                Available      = false;
            }
        }