SHARE
TWEET

Untitled

a guest Sep 17th, 2019 113 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Linq;
  5.  
  6. struct Point
  7. {
  8.     public int x;
  9.     public int y;
  10.  
  11.     public Point(int xp, int yp)
  12.     {
  13.         x = xp;
  14.         y = yp;
  15.     }
  16. }
  17.  
  18. public class MyEqualityComparer : IEqualityComparer<int[,]>
  19. {
  20.     public bool Equals(int[,] x, int[,] y)
  21.     {
  22.         if (x.Length != y.Length || x.GetLength(0) != y.GetLength(0) || x.GetLength(1) != y.GetLength(1))
  23.         {
  24.             return false;
  25.         }
  26.         for (int i = 0; i < x.GetLength(0); i++)
  27.         {
  28.             for (int j = 0; j < x.GetLength(1); j++)
  29.             {
  30.                 if (x[i, j] != y[i, j])
  31.                 {
  32.                     return false;
  33.                 }
  34.             }
  35.         }
  36.         return true;
  37.     }
  38.  
  39.     public int GetHashCode(int[,] obj)
  40.     {
  41.         int result = 17;
  42.         for (int i = 0; i < obj.GetLength(0); i++)
  43.         {
  44.             for (int j = 0; i < obj.GetLength(1); i++)
  45.             {
  46.                 unchecked
  47.                 {
  48.                     result = result * 23 + obj[i, j];
  49.                 }
  50.             }
  51.         }
  52.         return result;
  53.     }
  54. }
  55.  
  56. public class WaveformcCollapse : MonoBehaviour
  57. {
  58.     public int n = 2;
  59.     public int maxVal = 1;
  60.     public int outputSizeX = 20;
  61.     public int outputSizeY = 20;
  62.  
  63.     public List<Color> colors = new List<Color> {
  64.         Color.black,
  65.         Color.white
  66.     };
  67.  
  68.     public List<List<int>> input = new List<List<int>>  {
  69.         new List<int> { 0, 0, 0, 0, 0, },
  70.         new List<int> { 0, 0, 0, 0, 0, },
  71.         new List<int> { 0, 0, 1, 0, 1, },
  72.         new List<int> { 0, 0, 0, 0, 0, },
  73.         new List<int> { 0, 0, 0, 0, 0, },
  74.     };
  75.  
  76.     private Dictionary<int[,], int> patterns;
  77.     private Dictionary<int[,], bool>[,] wave;
  78.     private Dictionary<Point, GameObject> squaresDrawn;
  79.  
  80.     public GameObject blackSquare;
  81.     public GameObject whiteSquare;
  82.     public bool autorun = false;
  83.     int offsetx = 0;
  84.     int offsety = 0;
  85.     int steps = 0;
  86.     bool contradictive = false;
  87.  
  88.     HashSet<Point> interestingPoints;
  89.  
  90.     // Start is called before the first frame update
  91.     void Start()
  92.     {
  93.         squaresDrawn = new Dictionary<Point, GameObject>();
  94.         transpose(input);
  95.         Random.InitState(41);
  96.         patterns = new Dictionary<int[,], int>(new Dictionary<int[,], int>(), new MyEqualityComparer());
  97.  
  98.         wave = new Dictionary<int[,], bool>[outputSizeX, outputSizeY];
  99.         foreach (var permutationp in new List<List<List<int>>> { input, rotate90(input), rotate180(input), rotate270(input), flip(input), flip(rotate90(input)) })
  100.         {
  101.             var permutation = Make2DArray(permutationp);
  102.  
  103.             foreach (int x in Enumerable.Range(0, permutation.GetLength(0) - n + 1))
  104.             {
  105.                 foreach (int y in Enumerable.Range(0, permutation.GetLength(1) - n + 1))
  106.                 {
  107.                     var l = new int[n, n];
  108.                     foreach (int xi in Enumerable.Range(0, n))
  109.                     {
  110.                         foreach (int yi in Enumerable.Range(0, n))
  111.                         {
  112.                             l[xi, yi] = permutation[x + xi, y + yi];
  113.                         }
  114.                     }
  115.                     if (patterns.ContainsKey(l))
  116.                     {
  117.                         patterns[l] += 1;
  118.                     }
  119.                     else
  120.                     {
  121.                         patterns[l] = 1;
  122.                     }
  123.                 }
  124.             }
  125.         }
  126.  
  127.         foreach (int x in Enumerable.Range(0, outputSizeX))
  128.         {
  129.             wave.Add(new List<Dictionary<List<List<int>>, bool>> { });
  130.             foreach (int y in Enumerable.Range(0, outputSizeY))
  131.             {
  132.                 wave[x].Add(new Dictionary<List<List<int>>, bool> { });
  133.                 foreach (var pattern in patterns)
  134.                 {
  135.                     wave[x][y][pattern.Key] = true;
  136.                 }
  137.             }
  138.         }
  139.  
  140.         foreach (int rendery in Enumerable.Range(0, input.Count))
  141.         {
  142.             foreach (int renderx in Enumerable.Range(0, input[0].Count))
  143.             {
  144.  
  145.                 GameObject sq = Instantiate(whiteSquare);
  146.                 sq.GetComponent<SpriteRenderer>().color = colors[input[rendery][renderx]];
  147.                 sq.transform.position = new Vector3(renderx - outputSizeX / 2 - input.Count - 1, -rendery + outputSizeX / 2 + input[0].Count, 0);
  148.             }
  149.         }
  150.  
  151.  
  152.  
  153.         foreach (var square in squaresDrawn.Values)
  154.         {
  155.             Destroy(square);
  156.         }
  157.         foreach (var x in Enumerable.Range(0, outputSizeX))
  158.         {
  159.  
  160.             foreach (var y in Enumerable.Range(0, outputSizeX))
  161.             {
  162.                 squaresDrawn[new Point(x, y)] = Instantiate(whiteSquare);
  163.                 squaresDrawn[new Point(x, y)].transform.position = new Vector3(x, y);
  164.             }
  165.         }
  166.  
  167.         return;
  168.     }
  169.  
  170.     // Update is called once per frame
  171.     void Update()
  172.     {
  173.         if (autorun)
  174.         {
  175.             step();
  176.         }
  177.     }
  178.  
  179.     public void step()
  180.     {
  181.         if (contradictive) return;
  182.         steps++;
  183.  
  184.         interestingPoints = new HashSet<Point>();
  185.  
  186.         void detectContradictions(List<List<Dictionary<List<List<int>>, bool>>> wave, out bool d, out Point maxNeg)
  187.         {
  188.             // Find the position with the most negentropy
  189.             d = true;
  190.             var ps = new List<Point>();
  191.             var maxscore = 0;
  192.             var choiceIsValid = false;
  193.             foreach (int y in Enumerable.Range(0, wave.Count))
  194.             {
  195.                 foreach (int x in Enumerable.Range(0, wave[0].Count))
  196.                 {
  197.                     var numberOfFalses = 0;
  198.                     var numberOfTrues = 0;
  199.                     foreach (var possibility in wave[y][x])
  200.                     {
  201.                         if (possibility.Value == false)
  202.                         {
  203.                             numberOfFalses += 1;
  204.                         }
  205.                         else
  206.                         {
  207.                             numberOfTrues += 1;
  208.                         }
  209.                     }
  210.                     if (numberOfTrues == 0)
  211.                     {
  212.                         contradictive = true;
  213.                         Debug.Log("We have encountered a contradiction at " + x.ToString() + ", " + y.ToString() + "!");
  214.                     }
  215.                     if (numberOfTrues > 1)
  216.                     {
  217.                         if (!choiceIsValid || numberOfFalses > maxscore)
  218.                         {
  219.                             d = false;
  220.                             ps = new List<Point>();
  221.                             ps.Add(new Point(x, y));
  222.                             maxscore = numberOfFalses;
  223.                             choiceIsValid = true;
  224.                         }
  225.                         else if (numberOfFalses == maxscore)
  226.                         {
  227.                             ps.Add(new Point(x, y));
  228.                         }
  229.                     }
  230.                 }
  231.             }
  232.             maxNeg = new Point(0, 0);
  233.             if (choiceIsValid)
  234.             {
  235.                 maxNeg = ps[Random.Range(0, ps.Count)];
  236.             }
  237.  
  238.         }
  239.         Point toCollapse;
  240.         bool done;
  241.         detectContradictions(wave, out done, out toCollapse);
  242.         offsetx = offsety = (int)Mathf.Floor(n / 2);
  243.  
  244.         if (!done)
  245.         {
  246.             // collapse the superposition
  247.             Debug.Log("collapsing wavefunction at " + toCollapse.x.ToString() + ", " + toCollapse.y.ToString());
  248.             var onesToMaybeKeep = (from entry in wave[toCollapse.y][toCollapse.x]
  249.                                   where entry.Value
  250.                                   select entry.Key).ToList();
  251.             var total = (from key in onesToMaybeKeep
  252.                         select patterns[key]).Sum();
  253.  
  254.             var oneToKeep = Random.Range(0, total-1);
  255.             int i = 0;
  256.             var patternToKeep = onesToMaybeKeep.ToList()[0];
  257.             foreach (var maybe in onesToMaybeKeep)
  258.             {
  259.                 i += patterns[maybe];
  260.                 if (i >= oneToKeep)
  261.                 {
  262.                     patternToKeep = maybe;
  263.                 }
  264.             }
  265.  
  266.  
  267.             foreach (var possibility in wave[toCollapse.y][toCollapse.x].Keys.ToArray())
  268.             {
  269.                 wave[toCollapse.y][toCollapse.x][possibility] = possibility == patternToKeep;
  270.                 detectContradictions(wave, out _, out _);
  271.             }
  272.             interestingPoints.UnionWith(generatePointsInSquare(toCollapse));
  273.  
  274.  
  275.             // propagate updates
  276.             while (interestingPoints.Count() != 0)
  277.             {
  278.                 detectContradictions(wave, out _, out _);
  279.                 foreach (Point p in interestingPoints.ToList())
  280.                 {
  281.                     interestingPoints.Remove(p);
  282.                     if (p.x < 0 || p.y < 0 || p.y >= wave.Count() || p.x >= wave[0].Count())
  283.                     {
  284.                         continue;
  285.                     }
  286.                    
  287.  
  288.                     var truePossibilities = from entry in wave[p.y][p.x]
  289.                                             where entry.Value
  290.                                             select entry.Key;
  291.                     int c = truePossibilities.Count();
  292.                     if (c < 2)
  293.                     {
  294.                         continue;
  295.                     }
  296.                     foreach (var possibility in truePossibilities.ToArray())
  297.                     {
  298.                         bool possibilityValid = true;
  299.                         foreach (int yr in Enumerable.Range(0, n))
  300.                         {
  301.                             foreach (int xr in Enumerable.Range(0, n))
  302.                             {
  303.                                 var posx = p.x + xr;
  304.                                 var posy = p.y + yr;
  305.                                 var color = possibility[yr][xr];
  306.                                 foreach (int xi in Enumerable.Range(0, n))
  307.                                 {
  308.                                     foreach (int yi in Enumerable.Range(0, n))
  309.                                     {
  310.                                         if ((posx - xi) >= 0 && (posy - yi) >= 0 && (posx - xi) < wave[0].Count && (posy - yi) < wave.Count)
  311.                                         {
  312.                                             bool foundOne = false;
  313.                                             foreach (var possibility2 in wave[posy - yi][posx - xi])
  314.                                             {
  315.                                                 if (possibility2.Value && possibility2.Key[yi][xi] == color)
  316.                                                 {
  317.                                                     foundOne = true;
  318.                                                     break;
  319.                                                 }
  320.                                             }
  321.                                             if (!foundOne)
  322.                                             {
  323.                                                 possibilityValid = false;
  324.                                             }
  325.                                         }
  326.                                     }
  327.                                 }
  328.                             }
  329.                         }
  330.                         if (!possibilityValid)
  331.                         {
  332.                             wave[p.y][p.x][possibility] = false;
  333.                             interestingPoints.UnionWith(generatePointsInSquare(p));
  334.  
  335.                             if ((from w in wave[p.y][p.x]
  336.                                  where w.Value
  337.                                  select w.Value).Count() == 0)
  338.                             {
  339.                                 Debug.Log("Found a contradiction at " + p.x.ToString() + ", " + p.y.ToString() + ".");
  340.                                 contradictive = true;
  341.                                 squaresDrawn[p].GetComponent<SpriteRenderer>().color = Color.red;
  342.                                 return;
  343.                             }
  344.                         }
  345.                     }
  346.                 }
  347.             }
  348.  
  349.             var pointsToDraw = new HashSet<Point>(from x in Enumerable.Range(0, wave[0].Count())
  350.                                                   from y in Enumerable.Range(0, wave.Count())
  351.                                                   select new Point(x, y));
  352.             /*foreach (var p in pointsToDraw)
  353.             {
  354.                 if (squaresDrawn.ContainsKey(p))
  355.                 {
  356.                     if ((from w in wave[p.y][p.x]
  357.                          where w.Value
  358.                          select w.Value).Count() <= 1)
  359.                     {
  360.                         pointsToDraw.Remove(p);
  361.                     }
  362.                 }
  363.             }*/
  364.  
  365.             foreach (var p in pointsToDraw)
  366.             {
  367.                 var possibilities = (from entry in wave[p.y][p.x]
  368.                                      where entry.Value
  369.                                      select new LABColor(colors[entry.Key[offsety][offsetx]])).ToList();
  370.                 if (possibilities.Count() > 0)
  371.                 {
  372.                     var l = (from c in possibilities
  373.                               select c.l).Sum() / possibilities.Count();
  374.                     var a = (from c in possibilities
  375.                               select c.a).Sum() / possibilities.Count();
  376.                     var b = (from c in possibilities
  377.                               select c.b).Sum() / possibilities.Count();
  378.                     var color = (new LABColor(l, a, b)).ToColor();
  379.                     if (possibilities.Count() > 1)
  380.                     {
  381.                         color.a = Mathf.Lerp(.7f, .1f, possibilities.Count() / 5);
  382.                     }
  383.                     else
  384.                     {
  385.                         color.a = 1f;
  386.                     }
  387.                    
  388.                     squaresDrawn[p].GetComponent<SpriteRenderer>().color = color;
  389.                     squaresDrawn[p].transform.position = new Vector3(p.x + transform.position.x, -p.y + transform.position.y, 0);
  390.                 }
  391.             }
  392.         }
  393.     }
  394.  
  395.     List<List<int>> transpose(List<List<int>> input)
  396.     {
  397.         var output = new List<List<int>>();
  398.  
  399.         foreach (var value in input[0])
  400.         {
  401.             output.Add(new List<int>());
  402.         }
  403.  
  404.         foreach (int y in Enumerable.Range(0, input.Count))
  405.         {
  406.             foreach (int x in Enumerable.Range(0, input[0].Count))
  407.             {
  408.                 output[x].Add(input[y][x]);
  409.             }
  410.         }
  411.         return output;
  412.     }
  413.  
  414.     List<List<int>> flip(List<List<int>> input)
  415.     {
  416.         var output = new List<List<int>>();
  417.         foreach (int y in Enumerable.Range(0, input.Count))
  418.         {
  419.             output.Add(input[y].AsEnumerable().Reverse().ToList());
  420.         }
  421.         return output;
  422.     }
  423.  
  424.     List<List<int>> rotate90(List<List<int>> input)
  425.     {
  426.         return flip(transpose(input));
  427.     }
  428.     List<List<int>> rotate180(List<List<int>> input)
  429.     {
  430.         return rotate90(rotate90(input));
  431.     }
  432.     List<List<int>> rotate270(List<List<int>> input)
  433.     {
  434.         return rotate90(rotate90(rotate90(input)));
  435.     }
  436.  
  437.     IEnumerable<Point> generatePointsInSquare(Point p)
  438.     {
  439.         var a = from x in Enumerable.Range(-n+1, n*2)
  440.                from y in Enumerable.Range(-n+1, n*2)
  441.                select new Point(x + p.x, y + p.y);
  442.         var b = a.ToList();
  443.         return a;
  444.     }
  445.  
  446. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top