![]() |
#2
风吹过b2016-02-15 15:20
我写的代码:
窗体上要放一个定时器控件。 ![]() Option Explicit Private Const 横 = 78 '横竖格子数 Private Const 竖 = 45 Private Const 灰 = 8421504 '线框颜色 Private Const 死 = 16777215 '死颜色 Private Const 生 = 65280 '生颜色 Dim z(横 + 1, 竖 + 1) As Byte '目标数组 Dim l(横 + 1, 竖 + 1) As Byte '中间数组 Dim hd As Long '格子大小,横竖 Dim ld As Long Dim js As Long '演变回合 Private Sub Form_Click() Timer1.Enabled = Not Timer1.Enabled '单击开始或暂停演变 End Sub Private Sub Form_Load() Randomize '初始化随机数 Dim i As Long, j As Long For i = 1 To 横 For j = 1 To 竖 If Rnd() > 0.5 Then '随机情况 z(i, j) = 1 Else z(i, j) = 0 End If Next j Next i Me.WindowState = 2 '最大化窗口 DoEvents End Sub Public Sub view() '显示每个格子 If hd < Screen.TwipsPerPixelX * 3 Or ld < Screen.TwipsPerPixelY * 3 Then Exit Sub '如果不够绘图,则直接退出 Dim i As Long, j As Long For i = 0 To 横 - 1 For j = 0 To 竖 - 1 If z(i + 1, j + 1) = 1 Then '生,就用生画格 Me.Line (i * hd + Screen.TwipsPerPixelX, j * ld + Screen.TwipsPerPixelY)-(i * hd + hd - Screen.TwipsPerPixelX, j * ld + ld - Screen.TwipsPerPixelY), 生, BF Else '死,就用死画格 Me.Line (i * hd + Screen.TwipsPerPixelX, j * ld + Screen.TwipsPerPixelY)-(i * hd + hd - Screen.TwipsPerPixelX, j * ld + ld - Screen.TwipsPerPixelY), 死, BF End If Next j Next i End Sub Private Sub Form_Paint() '当窗口需要重绘时,绘制网络 Dim i As Long, j As Long Me.Cls '清屏 For i = 0 To 横 - 1 For j = 0 To 竖 - 1 Me.Line (i * hd, j * ld)-(i * hd + hd, j * ld + ld), 灰, B '副格子线,按每个格子均画线,也可以按横和竖分别画线 Next j Next i Call view '重绘格子 End Sub Private Sub Form_Resize() '窗体大小改变时,计算格子大小 Dim i As Long i = Me.ScaleWidth hd = i \ 横 i = Me.ScaleHeight ld = i \ 竖 Call Form_Paint '缩小时,不会产生重绘事件,需要手动调用 End Sub Public Sub r() '运算函数 Dim i As Long, j As Long Dim o As Long For i = 1 To 横 For j = 1 To 竖 o = 0 '统计8个格子,这里分了8行写,也可以使用一个二次循环来写,循环需要6行代码 o = o + z(i - 1, j - 1) o = o + z(i, j - 1) o = o + z(i + 1, j - 1) o = o + z(i - 1, j) o = o + z(i + 1, j) o = o + z(i - 1, j + 1) o = o + z(i, j + 1) o = o + z(i + 1, j + 1) Select Case o Case 3 '规则1:如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞), '则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。 l(i, j) = 1 Case 2 '规则2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变; l(i, j) = z(i, j) Case Else '规则3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变) l(i, j) = 0 End Select Next j Next i '把中间结果写入目标 For i = 1 To 横 For j = 1 To 竖 z(i, j) = l(i, j) Next j Next i Call view End Sub Private Sub Timer1_Timer() '定时器调用演变 js = js + 1 Call r Me.Caption = "生命游戏(Game of Life) -- " & js End Sub |
想起以前看到这个生命游戏,这个题目本身是要求用C来的,现在考虑用VB写一下。我试了一下,认为这个题目适合新手,可以锻炼以下几个方面的内容:
1、数组,特别是二维数组
2、绘图
---------------------
题目的要求如下:
1.题目描述
生命游戏(GameofLife)是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。在一个二维矩形世界中,每个方格居住着一个活着的或死了的细胞。一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量。
规则1.如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变)。
规则2.如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
规则3.在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)
最早研究细胞自动机的科学家是冯·诺伊曼。后来人工生命之父克里斯·朗顿进一步发展了元胞自动机理论,由此认为生命诞生于“混沌的边缘”,从此开辟了“人工生命”这一新兴的交叉学科。
本题目要求你设计一个生命游戏,开始时设置好生命的初始状态(也可以随机设置),模拟其中生命随时间的变化过程。
2.设计提示
1)细胞的世界可以用二维数组表示,每个生命的状态只有两种,即生或死;
2)为便于在屏幕上打印,世界的大小不宜过大,可以取20行70列;
3)程序开始时,设置生命的初始状态,即哪些地方有活着的生命。然后根据上述规则计算出下一个时刻生命的状态,并打印出来;
-------------------
注1:这个题目实在是太古老了,所以最后的要求是打印,其实应该是显示
注2:规则已被精练化,很适合写代码。未精练的版本如下:
1.一個活的格子若只有一個或沒有鄰居,在下一秒將因寂寞而亡.
2.一個活的格子若有四個或四個以上的鄰居,在下一秒將因拥擠而亡.
3.一個活的格子若有二個或三個鄰居,在下一秒將継續活著.
4.一個死的格子若有三個鄰居,在下一秒將活過來.