c# 實(shí)現(xiàn)康威生命游戲(細(xì)胞自動(dòng)機(jī))的示例
規(guī)則(來(lái)自百度百科,康威生命游戲詞條)
游戲開(kāi)始時(shí),每個(gè)細(xì)胞隨機(jī)地設(shè)定為“生”或“死”之一的某個(gè)狀態(tài)。然后,根據(jù)某種規(guī)則,計(jì)算出下一代每個(gè)細(xì)胞的狀態(tài),畫(huà)出下一代細(xì)胞的生死分布圖。
應(yīng)該規(guī)定什么樣的迭代規(guī)則呢?需要一個(gè)簡(jiǎn)單的,但又反映生命之間既協(xié)同又競(jìng)爭(zhēng)的生存定律。為簡(jiǎn)單起見(jiàn),最基本的考慮是假設(shè)每一個(gè)細(xì)胞都遵循完全一樣的生存定律;再進(jìn)一步,把細(xì)胞之間的相互影響只限制在最靠近該細(xì)胞的8個(gè)鄰居中。
也就是說(shuō),每個(gè)細(xì)胞迭代后的狀態(tài)由該細(xì)胞及周?chē)?個(gè)細(xì)胞狀態(tài)所決定。作了這些限制后,仍然還有很多方法來(lái)規(guī)定“生存定律”的具體細(xì)節(jié)。例如,在康威的生命游戲中,規(guī)定了如下生存定律。
(1)當(dāng)前細(xì)胞為死亡狀態(tài)時(shí),當(dāng)周?chē)?個(gè)存活細(xì)胞時(shí),則迭代后該細(xì)胞變成存活狀態(tài)(模擬繁殖);若原先為生,則保持不變。
(2)當(dāng)前細(xì)胞為存活狀態(tài)時(shí),當(dāng)周?chē)泥従蛹?xì)胞低于兩個(gè)(不包含兩個(gè))存活時(shí),該細(xì)胞變成死亡狀態(tài)(模擬生命數(shù)量稀少)。
(3)當(dāng)前細(xì)胞為存活狀態(tài)時(shí),當(dāng)周?chē)袃蓚€(gè)或3個(gè)存活細(xì)胞時(shí),該細(xì)胞保持原樣。
(4)當(dāng)前細(xì)胞為存活狀態(tài)時(shí),當(dāng)周?chē)?個(gè)以上的存活細(xì)胞時(shí),該細(xì)胞變成死亡狀態(tài)(模擬生命數(shù)量過(guò)多)。
控制臺(tái)實(shí)現(xiàn)的關(guān)鍵接口
設(shè)置控制臺(tái)游標(biāo)的函數(shù):public static void SetCursorPosition (int left, int top); 其中l(wèi)eft參數(shù)是列,top參數(shù)是行。
設(shè)置控制臺(tái)背景色的屬性:public static ConsoleColor BackgroundColor { get; set; } 黑色用來(lái)表示生存的細(xì)胞,白色用來(lái)表示死亡的細(xì)胞。
代碼實(shí)現(xiàn)
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 = random.Next(0, initAlivePossibility); if (value == 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類是細(xì)胞類,其中有一個(gè)bool屬性Value,true表示存活,false表示死亡。將細(xì)胞單獨(dú)寫(xiě)成類而不是一個(gè)bool值是為了后續(xù)可能的擴(kuò)展。
grid變量是一個(gè)二維數(shù)組,代表格子,大小可以通過(guò)gridRowCol設(shè)置,默認(rèn)32,不宜太大。
sleepMs變量是循環(huán)之間的間隔時(shí)間,單位是毫秒,默認(rèn)33ms.
initAlivePossibility變量決定格子中的細(xì)胞初始化時(shí)存活的概率,計(jì)算方式為 1/initAlivePossibility,如initAlivePossibility=4,表示初始化時(shí)每個(gè)細(xì)胞的存活概率是1/4.
Main()函數(shù)中先初始化了格子中的細(xì)胞和控制臺(tái)大小。設(shè)置控制臺(tái)大小這一步可能會(huì)拋出越界異常,如果出現(xiàn)的話需要修改這個(gè)值。 接著是主循環(huán),每次循環(huán)的間隔是sleepMs。
Update()就是實(shí)現(xiàn)規(guī)則的函數(shù)。
NeighborAliveCount()函數(shù)獲取指定細(xì)胞的相鄰細(xì)胞存活數(shù)。
SetAlive()函數(shù)和SetDeath()函數(shù)設(shè)置控制臺(tái)上的顯示。
如有錯(cuò)誤,歡迎指正,謝謝!
以上就是c# 實(shí)現(xiàn)康威生命游戲(細(xì)胞自動(dòng)機(jī))的示例的詳細(xì)內(nèi)容,更多關(guān)于c# 實(shí)現(xiàn)康威生命游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C# 通過(guò) inline-asm 解決嵌入x86匯編
此篇文章通過(guò)C#語(yǔ)言解決嵌入x86匯編,主要通過(guò)INline-asm方法來(lái)實(shí)現(xiàn),下面我通過(guò)圖片和代碼的形式給大家分享下,需要的朋友可以參考下2015-07-07C#微信開(kāi)發(fā)之微信公眾號(hào)標(biāo)簽管理功能
這篇文章主要介紹了C#微信開(kāi)發(fā)之微信公眾號(hào)標(biāo)簽管理功能 的相關(guān)資料,需要的朋友可以參考下2016-05-05C#判斷一個(gè)類是否實(shí)現(xiàn)了某個(gè)接口3種實(shí)現(xiàn)方法
這篇文章主要介紹了C#判斷一個(gè)類是否實(shí)現(xiàn)了某個(gè)接口3種實(shí)現(xiàn)方法,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06Unity的Console的控制類LogEntries深入解析與實(shí)用案例
這篇文章主要為大家介紹了Unity的Console的控制類LogEntries深入解析與實(shí)用案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07C# NetRemoting實(shí)現(xiàn)雙向通信
本篇文章主要介紹了C# NetRemoting實(shí)現(xiàn)雙向通信,.Net Remoting 是由客戶端通過(guò)Remoting,訪問(wèn)通道以獲得服務(wù)端對(duì)象,再通過(guò)代理解析為客戶端對(duì)象來(lái)實(shí)現(xiàn)通信的2017-03-03C#/VB.NET 給Excel添加、刪除數(shù)字簽名的方法
這篇文章主要介紹了C#/VB.NET 給Excel添加、刪除數(shù)字簽名的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11C# winform點(diǎn)擊生成二維碼實(shí)例代碼
這篇文章主要介紹了 C# winform點(diǎn)擊生成二維碼實(shí)例代碼,需要的朋友可以參考下2017-04-04C#實(shí)現(xiàn)滑動(dòng)開(kāi)關(guān)效果
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)滑動(dòng)開(kāi)關(guān)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07