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(); }
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); }