效果

規則(來自百度百科,康威生命游戲詞條)
游戲開始時,每個細胞隨機地設定為“生”或“死”之一的某個狀態,然后,根據某種規則,計算出下一代每個細胞的狀態,畫出下一代細胞的生死分布圖, 應該規定什么樣的迭代規則呢?需要一個簡單的,但又反映生命之間既協同又競爭的生存定律,為簡單起見,最基本的考慮是假設每一個細胞都遵循完全一樣的生存定律;再進一步,把細胞之間的相互影響只限制在最靠近該細胞的8個鄰居中, 也就是說,每個細胞迭代后的狀態由該細胞及周圍8個細胞狀態所決定,作了這些限制后,仍然還有很多方法來規定“生存定律”的具體細節,例如,在康威的生命游戲中,規定了如下生存定律, (1)當前細胞為死亡狀態時,當周圍有3個存活細胞時,則迭代后該細胞變成存活狀態(模擬繁殖);若原先為生,則保持不變, (2)當前細胞為存活狀態時,當周圍的鄰居細胞低于兩個(不包含兩個)存活時,該細胞變成死亡狀態(模擬生命數量稀少), (3)當前細胞為存活狀態時,當周圍有兩個或3個存活細胞時,該細胞保持原樣, (4)當前細胞為存活狀態時,當周圍有3個以上的存活細胞時,該細胞變成死亡狀態(模擬生命數量過多),控制臺實作的關鍵介面
設定控制臺游標的函式:public static void SetCursorPosition (int left, int top); 其中left引數是列,top引數是行,
設定控制臺背景色的屬性:public static ConsoleColor BackgroundColor { get; set; } 黑色用來表示生存的細胞,白色用來表示死亡的細胞,
代碼實作
using System; using System.Threading; namespace CellularAutomata { class Program { private static int gridRowCol = 32; private static Cell[,] grid = new Cell[gridRowCol, gridRowCol]; private static int sleepMs = 33; private static int initAlivePossibility = 4; // 4 means 1/4 static void Main(string[] args) { try { Init(); // Main loop while (true) { Update(); Thread.Sleep(sleepMs); } } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(); } } private static void Init() { // Set Console Size Console.BufferHeight = 256; Console.BufferWidth = 256; Console.WindowWidth = 256; Console.WindowHeight = 80; Random random = new Random(); for (int i = 0; i < grid.GetLength(0); i++) { for (int j = 0; j < grid.GetLength(1); j++) { grid[i, j] = new Cell(); int value = https://www.cnblogs.com/jingjiangtao/archive/2021/02/24/random.Next(0, initAlivePossibility); if (value =https://www.cnblogs.com/jingjiangtao/archive/2021/02/24/= 0) { grid[i, j].Value = true; } else { grid[i, j].Value = false; } } } } private static void Update() { for (int i = 0; i < grid.GetLength(0); i++) { for (int j = 0; j < grid.GetLength(1); j++) { int aliveCount = NeighborAliveCount(i, j); if (grid[i, j].Value) // Alive { if (aliveCount < 2 || aliveCount > 3) { grid[i, j].Value = false; } } else // Death { if (aliveCount == 3) { grid[i, j].Value = true; } } if (grid[i, j].Value) { SetAlive(i, j); } else { SetDeath(i, j); } } } } private static int NeighborAliveCount(int i, int j) { int count = 0; for (int m = i - 1; m <= i + 1; m++) { for (int n = j - 1; n <= j + 1; n++) { if (m == i && n == j) continue; if (m < 0 || m >= grid.GetLength(0)) continue; if (n < 0 || n >= grid.GetLength(1)) continue; if (grid[m, n].Value) count++; } } return count; } private static void SetAlive(int i, int j) { string aliveStr = " "; Console.SetCursorPosition(j * aliveStr.Length, i); Console.BackgroundColor = ConsoleColor.Black; Console.Write(aliveStr); } private static void SetDeath(int i, int j) { string deathStr = " "; Console.SetCursorPosition(j * deathStr.Length, i); Console.BackgroundColor = ConsoleColor.White; Console.Write(deathStr); } } public class Cell { public bool Value { get; set; } } }
完整代碼:https://github.com/jingjiangtao/CellularAutomata
Cell類是細胞類,其中有一個bool屬性Value,true表示存活,false表示死亡,將細胞單獨寫成類而不是一個bool值是為了后續可能的擴展,
grid變數是一個二維陣列,代表格子,大小可以通過gridRowCol設定,默認32,不宜太大,
sleepMs變數是回圈之間的間隔時間,單位是毫秒,默認33ms.
initAlivePossibility變數決定格子中的細胞初始化時存活的概率,計算方式為 1/initAlivePossibility,如initAlivePossibility=4,表示初始化時每個細胞的存活概率是1/4.
Main()函式中先初始化了格子中的細胞和控制臺大小,設定控制臺大小這一步可能會拋出越界例外,如果出現的話需要修改這個值, 接著是主回圈,每次回圈的間隔是sleepMs,
Update()就是實作規則的函式,
NeighborAliveCount()函式獲取指定細胞的相鄰細胞存活數,
SetAlive()函式和SetDeath()函式設定控制臺上的顯示,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/263164.html
標籤:.NET技术
