c# 實(shí)現(xiàn)康威生命游戲(細(xì)胞自動(dòng)機(jī))的示例
規(guī)則(來自百度百科,康威生命游戲詞條)
游戲開始時(shí),每個(gè)細(xì)胞隨機(jī)地設(shè)定為“生”或“死”之一的某個(gè)狀態(tài)。然后,根據(jù)某種規(guī)則,計(jì)算出下一代每個(gè)細(xì)胞的狀態(tài),畫出下一代細(xì)胞的生死分布圖。
應(yīng)該規(guī)定什么樣的迭代規(guī)則呢?需要一個(gè)簡單的,但又反映生命之間既協(xié)同又競爭的生存定律。為簡單起見,最基本的考慮是假設(shè)每一個(gè)細(xì)胞都遵循完全一樣的生存定律;再進(jìn)一步,把細(xì)胞之間的相互影響只限制在最靠近該細(xì)胞的8個(gè)鄰居中。
也就是說,每個(gè)細(xì)胞迭代后的狀態(tài)由該細(xì)胞及周圍8個(gè)細(xì)胞狀態(tài)所決定。作了這些限制后,仍然還有很多方法來規(guī)定“生存定律”的具體細(xì)節(jié)。例如,在康威的生命游戲中,規(guī)定了如下生存定律。
(1)當(dāng)前細(xì)胞為死亡狀態(tài)時(shí),當(dāng)周圍有3個(gè)存活細(xì)胞時(shí),則迭代后該細(xì)胞變成存活狀態(tài)(模擬繁殖);若原先為生,則保持不變。
(2)當(dāng)前細(xì)胞為存活狀態(tài)時(shí),當(dāng)周圍的鄰居細(xì)胞低于兩個(gè)(不包含兩個(gè))存活時(shí),該細(xì)胞變成死亡狀態(tài)(模擬生命數(shù)量稀少)。
(3)當(dāng)前細(xì)胞為存活狀態(tài)時(shí),當(dāng)周圍有兩個(gè)或3個(gè)存活細(xì)胞時(shí),該細(xì)胞保持原樣。
(4)當(dāng)前細(xì)胞為存活狀態(tài)時(shí),當(dāng)周圍有3個(gè)以上的存活細(xì)胞時(shí),該細(xì)胞變成死亡狀態(tài)(模擬生命數(shù)量過多)。
控制臺(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; } 黑色用來表示生存的細(xì)胞,白色用來表示死亡的細(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ú)寫成類而不是一個(gè)bool值是為了后續(xù)可能的擴(kuò)展。
grid變量是一個(gè)二維數(shù)組,代表格子,大小可以通過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)康威生命游戲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#中用foreach語句遍歷數(shù)組及將數(shù)組作為參數(shù)的用法
這篇文章主要介紹了C#中用foreach語句遍歷數(shù)組及將數(shù)組作為參數(shù)的用法,C#的數(shù)組可作為實(shí)參傳遞給方法形參,需要的朋友可以參考下2016-01-01
C#百萬數(shù)據(jù)查詢出現(xiàn)超時(shí)問題的解決方法
這篇文章主要介紹了C#百萬數(shù)據(jù)查詢出現(xiàn)超時(shí)問題的解決方法,是非常實(shí)用的技巧,需要的朋友可以參考下2014-09-09
C#常見應(yīng)用函數(shù)實(shí)例小結(jié)
這篇文章主要介紹了C#常見應(yīng)用函數(shù),結(jié)合實(shí)例形式總結(jié)分析了C#常用的時(shí)間、URL、HTML、反射、小數(shù)運(yùn)算等相關(guān)函數(shù),需要的朋友可以參考下2017-01-01
解析c#顯示友好時(shí)間的實(shí)現(xiàn)代碼
本篇文章是對c#中顯示友好時(shí)間的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友參考下2013-05-05
C#程序(含多個(gè)Dll)合并成一個(gè)Exe的簡單方法
這篇文章主要為大家詳細(xì)介紹了C#程序(含多個(gè)Dll)合并成一個(gè)Exe的簡單方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
C#隨機(jī)設(shè)置900-1100毫秒延遲的方法
這篇文章主要介紹了C#隨機(jī)設(shè)置900-1100毫秒延遲的方法,涉及C#中Thread.Sleep方法的使用技巧,需要的朋友可以參考下2015-04-04

