数模论坛

 找回密码
 注-册-帐-号
搜索
热搜: 活动 交友 discuz
查看: 3852|回复: 2

[强烈推荐]生命游戏

[复制链接]
发表于 2004-3-15 04:19:32 | 显示全部楼层 |阅读模式
http://www.shumo.org/bbs/dispbbs.asp?boardid=108&id=4025&star=1#4025
发表于 2004-3-15 04:44:59 | 显示全部楼层
用c语言演绎“生命游戏”



    豆豆技术网制作 legume 制作 修改于:2003-4-24 投稿信箱:web@ddvip.net

    本世纪70年代,人们曾疯魔一种被称作“生命游戏”的小游戏,这种游戏相当简单。假设有一个像棋盘一样的方格网,每个方格中放置一个生命细胞,生命细胞只有两种状态:“生”或“死”。游戏规则如下:
  1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生,即该细胞若原先为死,则转为生,若原先为生,则保持不变;
  2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
  3. 在其它情况下,该细胞为死,即该细胞若原先为生,则转为死,若原先为死,则保持不变。
  依此规则进行迭代变化,使细胞生生死死,会得到一些有趣的结果。该游戏之所以被称为“生命游戏”,是因为其简单的游戏规则,反映了自然界中的生存规律:如果一个生命,其周围的同类生命太少的话,会因为得不到帮助而死亡;如果太多,则会因为得不到足够的资源而死亡。
  用计算机模拟这个“生命游戏”也相当简单,可以用一个M×N像素的图像来代表M×N个细胞,其中每一个像素,代表一个细胞,像素为黑色表示细胞为生,像素为白色代表细胞为死。
  设定图像中每个像素的初始状态后依据上述的游戏规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案。
  下面给出的小程序是用TC2.0编写。演示100×100个生命细胞初始状态全为生时的变代情况,变化时边缘细胞不参与变化。随着迭代次数的不同,在屏幕显示的图案精彩纷呈,像万花筒般引人入胜。
  #include <graphics.h>
  main(){
  int orgData[100][100],resData[100][100];/*分别记录每次迭代的初始和结果状态*/
  int nCount,nRows,nCols,i,j,times; /*times记录迭代次数*/
  int GraphDriver=DETECT,GraphMode;
  for (i=0;i<100;i++) /*初始化数据,令每一个细胞为生*/
  for (j=0;j<100;j++) orgData[j]=1;
  initgraph(&GraphDriver,&GraphMode,′′′′); /*初始化屏幕显示*/
  setcolor(WHITE);
  rectangle(270,190,370,290); /*作显示边框*/
  for (times=1;times<200;times++){
  for (nRows=1;nRows<99;nRows++) {
  for (nCols=1;nCols<99;nCols++){
  /*计算每一个细胞周围的活的细胞数*/
  nCount=orgData[nRows-1][nCols-1]+orgData[nRows-1][nCols]
  +orgData[nRows-1][nCols+1]+orgData[nRows][nCols-1]
  +orgData[nRows][nCols+1]+orgData[nRows+1][nCols-1]
  +orgData[nRows+1][nCols]+orgData[nRows+1][nCols+1];
  switch(nCount){
  /*周围有3个活细胞,该细胞为生,在屏幕上用黑色像素表示*
  case 3: putpixel(nCols+210,120+nRows,BLACK);
  resData[nRows][nCols]=1;break;
  /*周围有2个活细胞,该细胞不变,在屏幕显示也不变*/
  case 2: resData[nRows][nCols]=orgData[nRows][nCols];
  break;
  /*其它情况下,细胞为死,在屏幕上用白色像素表示*/
  default:resData[nRows][nCols]=0;
  putpixel(nCols+210,120+nRows,WHITE);
  }
  }
  }
  for (i=1;i<99;i++)
  for (j=1;j<99;j++) orgData[j]=resData[j];
  getch();
  }
  }
  在计算机上运行上述程序,得到迭代次数为45、69、74、78、97、116、119和156时的图像分别如上图所示。
  在实际模拟时,可以取更多的生命细胞,也可以考虑生命细胞的初始状态是依一定概率设定的随机状态,变化时也可以让边缘细胞参与变化。只要对上述程序略作更改,就会得到另外一系列美妙绝伦的图案。

请记住我们的口号是:让计算机真正大众化,让更多的人了解计算机,使用计算机!!

发表于 2004-3-15 05:16:16 | 显示全部楼层
MATLAB也可以做这东西
MATLAB的例子中有
代码:

function life(action)
%LIFE   MATLAB's version of Conway's Game of Life.
%   "Life" is a cellular automaton invented by John
%   Conway that involves live and dead cells in a  
%   rectangular, two-dimensional universe. In      
%   MATLAB, the universe is a sparse matrix that   
%   is initially all zero.                        
%                                                  
%   Whether cells stay alive, die, or generate new
%   cells depends upon how many of their eight     
%   possible neighbors are alive. By using sparse  
%   matrices, the calculations required become     
%   astonishingly simple. We use periodic (torus)  
%   boundary conditions at the edges of the        
%   universe. Pressing the "Start" button         
%   automatically seeds this universe with several
%   small random communities. Some will succeed   
%   and some will fail.     

%   C. Moler, 7-11-92, 8-7-92.
%   Adapted by Ned Gulley, 6-21-93
%   Copyright 1984-2002 The MathWorks, Inc.
%   $Revision: 5.10 $  $Date: 2002/04/08 20:04:46 $

% Possible actions:
% initialize
% start

% Information regarding the play status will be held in
% the axis user data according to the following table:
play= 1;
stop=-1;

if nargin<1,
   action='initialize';
end;

if strcmp(action,'initialize'),
   figNumber=figure( ...
      'Name','Life: Conway''s Game of Life', ...
      'NumberTitle','off', ...
      'DoubleBuffer','on', ...
      'Visible','off', ...
      'Color','white', ...
      'BackingStore','off');
   axes( ...
      'Units','normalized', ...
      'Position',[0.05 0.05 0.75 0.90], ...
      'Visible','off', ...
      'DrawMode','fast', ...
      'NextPlot','add');
   
   text(0,0,'Press the "Start" button to see the Game of Life demo', ...
      'HorizontalAlignment','center');
   axis([-1 1 -1 1]);
   
   %===================================
   % Information for all buttons
   labelColor=[0.8 0.8 0.8];
   yInitPos=0.90;
   xPos=0.85;
   btnLen=0.10;
   btnWid=0.10;
   % Spacing between the button and the next command's label
   spacing=0.05;
   
   %====================================
   % The CONSOLE frame
   frmBorder=0.02;
   yPos=0.05-frmBorder;
   frmPos=[xPos-frmBorder yPos btnLen+2*frmBorder 0.9+2*frmBorder];
   h=uicontrol( ...
      'Style','frame', ...
      'Units','normalized', ...
      'Position',frmPos, ...
      'BackgroundColor',[0.50 0.50 0.50]);
   
   %====================================
   % The START button
   btnNumber=1;
   yPos=0.90-(btnNumber-1)*(btnWid+spacing);
   labelStr='Start';
   cmdStr='start';
   callbackStr='life(''start'');';
   
   % Generic button information
   btnPos=[xPos yPos-spacing btnLen btnWid];
   startHndl=uicontrol( ...
      'Style','pushbutton', ...
      'Units','normalized', ...
      'Position',btnPos, ...
      'String',labelStr, ...
      'Interruptible','on', ...
      'Callback',callbackStr);
   
   %====================================
   % The STOP button
   btnNumber=2;
   yPos=0.90-(btnNumber-1)*(btnWid+spacing);
   labelStr='Stop';
   % Setting userdata to -1 (=stop) will stop the demo.
   callbackStr='set(gca,''Userdata'',-1)';
   
   % Generic button information
   btnPos=[xPos yPos-spacing btnLen btnWid];
   stopHndl=uicontrol( ...
      'Style','pushbutton', ...
      'Units','normalized', ...
      'Position',btnPos, ...
      'Enable','off', ...
      'String',labelStr, ...
      'Callback',callbackStr);
   
   %====================================
   % The INFO button
   labelStr='Info';
   callbackStr='life(''info'')';
   infoHndl=uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[xPos 0.20 btnLen 0.10], ...
      'String',labelStr, ...
      'Callback',callbackStr);
   
   %====================================
   % The CLOSE button
   labelStr='Close';
   callbackStr='close(gcf)';
   closeHndl=uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[xPos 0.05 btnLen 0.10], ...
      'String',labelStr, ...
      'Callback',callbackStr);
   
   % Uncover the figure
   hndlList=[startHndl stopHndl infoHndl closeHndl];
   set(figNumber,'Visible','on', ...
      'UserData',hndlList);
   
elseif strcmp(action,'start'),
   cla;
   axHndl=gca;
   figNumber=gcf;
   hndlList=get(figNumber,'Userdata');
   startHndl=hndlList(1);
   stopHndl=hndlList(2);
   infoHndl=hndlList(3);
   closeHndl=hndlList(4);
   set([startHndl closeHndl infoHndl],'Enable','off');
   set(stopHndl,'Enable','on');
   
   % ====== Start of Demo
   set(axHndl, ...
      'UserData',play, ...
      'DrawMode','fast', ...
      'Visible','off');
   m = 101;
   X = sparse(m,m);
   
   p = -1:1;
   for count=1:15,
      kx=floor(rand*(m-4))+2; ky=floor(rand*(m-4))+2;
      X(kx+p,ky+p)=(rand(3)>0.5);
   end;
   
   % The following statements plot the initial configuration.
   % The "find" function returns the indices of the nonzero elements.
   [i,j] = find(X);
   figure(gcf);
   plothandle = plot(i,j,'.', ...
      'Color','blue', ...
      'MarkerSize',12);
   axis([0 m+1 0 m+1]);
   
   % Whether cells stay alive, die, or generate new cells depends
   % upon how many of their eight possible neighbors are alive.
   % Here we generate index vectors for four of the eight neighbors.
   % We use periodic (torus) boundary conditions at the edges of the universe.
   
   n = [m 1:m-1];
   e = [2:m 1];
   s = [2:m 1];
   w = [m 1:m-1];
   
   while get(axHndl,'UserData')==play,
      % How many of eight neighbors are alive.
      N = X(n, + X(s, + X(:,e) + X(:,w) + ...
         X(n,e) + X(n,w) + X(s,e) + X(s,w);
      
      % A live cell with two live neighbors, or any cell with three
      % neigbhors, is alive at the next time step.
      X = (X & (N == 2)) | (N == 3);
      
      % Update plot.
      [i,j] = find(X);
      set(plothandle,'xdata',i,'ydata',j)
      drawnow
   end
   
   % ====== End of Demo
   set([startHndl closeHndl infoHndl],'Enable','on');
   set(stopHndl,'Enable','off');
   
elseif strcmp(action,'info');
   helpwin(mfilename);
   
end;    % if strcmp(action, ...
您需要登录后才可以回帖 登录 | 注-册-帐-号

本版积分规则

小黑屋|手机版|Archiver|数学建模网 ( 湘ICP备11011602号 )

GMT+8, 2024-5-20 22:53 , Processed in 0.049556 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表