private void OnSubmitButtonPressed()
    {
        if (solved || !activated)
        {
            return;
        }
        Unselect();
        Debug.LogFormat("[Starmap Reconstruction #{0}] Submit pressed", moduleId);
        Starmap map = new Starmap(stars.Length);

        foreach (StarComponent star in stars)
        {
            int expectedAdjacentsCount = StarmapReconstructionData.GetAdjacentStarsCount(star.Race, star.Regime, BombInfo);
            int actualAdjacentsCount   = star.connectedStars.Count;
            if (expectedAdjacentsCount != actualAdjacentsCount)
            {
                Debug.LogFormat("[Starmap Reconstruction #{0}] STRIKE: Star {1} has {2} connected stars. Expected: {3}", moduleId, star.Name, actualAdjacentsCount,
                                expectedAdjacentsCount);
                Module.HandleStrike();
                return;
            }
            foreach (StarComponent other in star.connectedStars)
            {
                map.Add(star.Id, other.Id);
            }
        }
        Debug.LogFormat("[Starmap Reconstruction #{0}] Submitted map: {1}", moduleId, map.ToShortString());
        foreach (StarComponent star in stars)
        {
            KeyValuePair <string, int>?requiredDistance = StarmapReconstructionData.GetRequiredDistanceFrom(star.Name);
            if (requiredDistance == null)
            {
                continue;
            }
            string to = requiredDistance.Value.Key;
            int    expectedDistance = requiredDistance.Value.Value;
            int    otherIndex       = stars.IndexOf(s => s.Name == to);
            if (otherIndex < 0)
            {
                continue;
            }
            StarComponent other          = stars[otherIndex];
            int           actualDistance = map.GetDistance(star.Id, other.Id);
            if (expectedDistance != actualDistance)
            {
                Debug.LogFormat("[Starmap Reconstruction #{0}] STRIKE: Distance from {1} to {2} is {3}. Expected: {4}", moduleId, star.Name, other.Name, actualDistance,
                                expectedDistance);
                Module.HandleStrike();
                return;
            }
        }
        Debug.LogFormat("[Starmap Reconstruction #{0}] Module solved", moduleId);
        solved = true;
        Audio.PlayGameSoundAtTransform(KMSoundOverride.SoundEffect.CorrectChime, transform);
        Module.HandlePass();
    }
Esempio n. 2
0
    public static void GenerateStarmap(KMBombInfo bomb, out StarInfo[] stars, out Starmap answerExample)
    {
        KeyValuePair <int, int>[] corridorsCount = CorridorsCountVariants.PickRandom().Select((a, i) => new KeyValuePair <int, int>(a, i)).ToArray();
        Debug.LogFormat("<Starmap Reconstruction> Generator: corridors counts: {0}", corridorsCount.Select(kv => kv.Key).Join(""));
        Starmap           map = new Starmap(corridorsCount.Length);
        int               n   = corridorsCount.Length - 1;
        Action <int, int> add = (int i, int j) => {
            map.Add(corridorsCount[i].Value, corridorsCount[j].Value);
            corridorsCount[i] = new KeyValuePair <int, int>(corridorsCount[i].Key - 1, corridorsCount[i].Value);
            corridorsCount[j] = new KeyValuePair <int, int>(corridorsCount[j].Key - 1, corridorsCount[j].Value);
        };

        while (true)
        {
            Array.Sort(corridorsCount, (a, b) => b.Key - a.Key);
            for (int i = 0; i < corridorsCount.Length; i++)
            {
                for (int j = i + 1; j < corridorsCount.Length; j++)
                {
                    if (corridorsCount[i].Key != corridorsCount[j].Key)
                    {
                        continue;
                    }
                    if (Random.Range(0, 2) == 0)
                    {
                        continue;
                    }
                    KeyValuePair <int, int> temp = corridorsCount[i];
                    corridorsCount[i] = corridorsCount[j];
                    corridorsCount[j] = temp;
                }
            }
            // Debug.LogFormat("<Starmap Reconstruction> Generator: corridors counts: {0}", corridorsCount.Select(kv => kv.Key).Join(""));
            while (n > 0 && corridorsCount[n].Key == 0)
            {
                n--;
            }
            if (n == 0)
            {
                break;
            }
            if (corridorsCount[n].Key == 1)
            {
                int pos = 0;
                for (int i = 0; i < n; i++)
                {
                    if ((corridorsCount[i].Key % 2 == 1) && (corridorsCount[i].Key > 1))
                    {
                        pos = i;
                        break;
                    }
                }
                if (corridorsCount[pos].Key == 1 && n > 1)
                {
                    throw new Exception("Unable to create starmap: left corridors eq 1");
                }
                add(pos, n);
                continue;
            }
            if (corridorsCount[n].Key != 2)
            {
                throw new Exception("Unable to create starmap: corridors counts gt 2");
            }
            if (n < 2)
            {
                throw new Exception("Unable to create starmap: lt 2 corridors left");
            }
            if (corridorsCount[0].Key == 2)
            {
                for (int i = 0; i < n - 1; i++)
                {
                    add(i, i + 1);
                }
                add(0, n);
                continue;
            }
            if (corridorsCount[n - 1].Key != 2)
            {
                throw new Exception("Unable to create starmap: only one corridor eq 2");
            }
            add(n - 1, n);
            add(n, 0);
            add(0, n - 1);
        }
        Dictionary <int, HashSet <KeyValuePair <string, string> > > infos = new Dictionary <int, HashSet <KeyValuePair <string, string> > >();

        foreach (string race in Races)
        {
            foreach (string regime in Regimes)
            {
                int adj = GetAdjacentStarsCount(race, regime, bomb);
                if (!infos.ContainsKey(adj))
                {
                    infos[adj] = new HashSet <KeyValuePair <string, string> >();
                }
                infos[adj].Add(new KeyValuePair <string, string>(race, regime));
            }
        }
        HashSet <int>    unnamedStars = new HashSet <int>(Enumerable.Range(0, 8));
        HashSet <string> usedNames    = new HashSet <string>();

        string[] starNames = Enumerable.Range(0, 8).Select(_ => "").ToArray();
        while (unnamedStars.Count > 0)
        {
            int starId = unnamedStars.PickRandom();
            unnamedStars.Remove(starId);
            HashSet <int> otherStars = new HashSet <int>(unnamedStars);
            while (otherStars.Count > 0)
            {
                int otherStarId = otherStars.PickRandom();
                otherStars.Remove(otherStarId);
                int dist = map.GetDistance(starId, otherStarId);
                IEnumerable <Distance> pairs = Distances.Where(d => d.distance == dist && !usedNames.Contains(d.from) && !usedNames.Contains(d.to));
                if (pairs.Count() == 0)
                {
                    continue;
                }
                Distance pair = pairs.PickRandom();
                starNames[starId]      = pair.from;
                starNames[otherStarId] = pair.to;
                usedNames.Add(pair.from);
                usedNames.Add(pair.to);
                unnamedStars.Remove(otherStarId);
                break;
            }
        }
        for (int i = 0; i < 8; i++)
        {
            if (starNames[i] != "")
            {
                continue;
            }
            starNames[i] = _randomStarNames.Where(s => !usedNames.Contains(s)).PickRandom();
            usedNames.Add(starNames[i]);
        }
        int[] idTransform = Enumerable.Range(0, 8).ToArray().Shuffle();
        Debug.LogFormat("<Starmap Reconstruction> Generator: ID transform: {0}", idTransform.Join(""));
        stars = Enumerable.Range(0, 8).Select(id => {
            int adj = map.GetAdjacentNodesCount(id);
            KeyValuePair <string, string> info = infos[adj].PickRandom();;
            return(new StarInfo(idTransform[id], starNames[id], info.Key, info.Value));
        }).ToArray();
        Array.Sort(stars, (a, b) => a.id - b.id);
        answerExample = map.TransformIds(idTransform);
    }