internal void UpdateTilesIGonextTo(List <SmartTile> smartTiles) { foreach (int friendID in Friends) { SmartTile smartTile = smartTiles[friendID]; TilesIGoNextTo.UnionWith(smartTile.TilesICanPlace); TilesIGoNextTo.UnionWith(smartTile.Extras); } }
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); }
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; } }