Hi,
ich wollte mich mal an Conway's Game of Life setzen. Finde die Simulation sehr interessant.
Nun bin ich soweit, dass es eigentlich fertig ist, aber noch Probleme auftauchen könnten. Ich habe die Zellen, bestimme, ob sie leben oder tot sind und kann neue durch Klicken zum Leben erwecken. Wenn der Zyklus aber normal abläuft, könnte es ja passieren, dass die Zellen sich gegenseitig prüfen und es zu Unstimmigkeiten kommt, wenn eine Zelle stirbt und die vorherig prüfende davon natürlich noch nichts weiß.
Im Netz stand etwas davon, ein zweites Grid anzulegen, wo man dann sämtliche Züge der Zellen ablegt und hinterher gezielt wieder auf das erste Grid überträgt. Wie macht man dann sowas?
Meine Gridverwaltung ist recht überschaubar (ist dann eigentlich auch das komplette Programm, außer der Klasse für die Zelle mit ein paar Eigenschaften drin),
|
C#-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
[SerializeField]
GameObject cellObject;
private Vector2 mapSize;
private List<GameObject> cells = new List<GameObject>();
public float countTime { get; set; }
public float cycleInterval { get { return 2; } }
private void Start()
{
mapSize = new Vector2(10, 10); // 100 Zellen zum Testen
for (int x = 0; x < mapSize.x; x++)
{
for (int y = 0; y < mapSize.y; y++)
{
GameObject cell = Instantiate(cellObject, new Vector2(x, y), Quaternion.identity); // Map erzeugen und alle Zellen in die Liste packen
cells.Add(cell);
}
}
}
private void Update()
{
countTime += Time.deltaTime;
if (countTime >= cycleInterval)
{
NextCycle();
countTime = 0;
}
}
private void NextCycle() // neue Folgegeneration starten
{
foreach (GameObject cell in cells) // Für alle Zellen durchführen
{
CellController c = cell.GetComponent<CellController>();
bool isAlive = c.GetState(); // Lebt die Zelle?
Vector2 cellPositon = c.GetCellPosition();
int x = (int)cellPositon.x;
int y = (int)cellPositon.y;
int neighbourCount = GetNeighbourCount(x, y); // Anzahl aller lebendigen Nachbarszellen
bool result = false;
if (isAlive && neighbourCount < 2)
result = false;
if (isAlive && (neighbourCount == 2 || neighbourCount == 3))
result = true;
if (isAlive && neighbourCount > 3)
result = false;
if (!isAlive && neighbourCount == 3)
result = true;
c.SetState(result); // Zelle lebendig setzen oder sterben lassen
}
}
private int GetNeighbourCount(int x, int y) // Alle Nachbarn der Zelle prüfen
{
int count = 0;
if (x != mapSize.x - 1)
if (GetNeighbourCell(x + 1, y).GetComponent<CellController>().GetState())
count++;
if (x != mapSize.x - 1 && y != mapSize.y - 1)
if (GetNeighbourCell(x + 1, y + 1).GetComponent<CellController>().GetState())
count++;
if (y != mapSize.y - 1)
if (GetNeighbourCell(x, y + 1).GetComponent<CellController>().GetState())
count++;
if (x != 0 && y != mapSize.y - 1)
if (GetNeighbourCell(x - 1, y + 1).GetComponent<CellController>().GetState())
count++;
if (x != 0)
if (GetNeighbourCell(x - 1, y).GetComponent<CellController>().GetState())
count++;
if (x != 0 && y != 0)
if (GetNeighbourCell(x - 1, y - 1).GetComponent<CellController>().GetState())
count++;
if (y != 0)
if (GetNeighbourCell(x, y - 1).GetComponent<CellController>().GetState())
count++;
if (x != mapSize.x - 1 && y != 0)
if (GetNeighbourCell(x + 1, y - 1).GetComponent<CellController>().GetState())
count++;
return count;
}
private GameObject GetNeighbourCell(int x, int y) // Zelle anhand der Koordinaten suchen
{
GameObject cell = null;
foreach (GameObject c in cells)
{
if (c.GetComponent<CellController>().GetCellPosition() == new Vector2(x, y))
{
cell = c;
break;
}
}
return cell;
}
|
Ich bin mir auch ziemlich sicher, dass da noch was für die Performance getan werden kann. So viele "GetComponents" lassen mich dann doch schonmal nachdenklich werden. Aber erstmal wollte ich die möglicherweise auftretenden Fehler beseitigen.
Wäre cool, wenn mir jemand den Trick mit dem 2. Grid verraten kann