Chinaunix首页 | 论坛 | 博客
  • 博客访问: 832584
  • 博文数量: 330
  • 博客积分: 9641
  • 博客等级: 中将
  • 技术积分: 3181
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
文章分类

全部博文(330)

文章存档

2012年(17)

2011年(135)

2010年(85)

2009年(57)

2008年(36)

我的朋友

分类: Delphi

2011-02-03 20:59:30

  迷上了这种根据简单规则不断演化的东西,自己实现了下。
  算法:
    用两个二维数组,一个用来存储每个格子的状态,另一个用来记录临时状态,计算后写入第一个数组。边界以外的全部认为是死亡的格子。规则是普通的B3/S23。加入了信号量处理,可以方便被"kill -USR1 pid"却正常结束。没有图形界面全是打印,形状大小可根据命令行参数调节。
  C实现(代码颜色为autumn):
001 #include
002 #include
003 #include
004 #include
005 #include
006 #include
007 
008 #define LINE 30
009 
010 char *g_version = "0.1";
011 int g_length = 0;
012 char g_symbol = '*';
013 useconds_t g_interval = 100000;
014 
015 
016 void usage()
017 {
018     printf("\nUsage:\t./game_of_life [-V] [-h] ...\n");
019     printf("\t-l, --length\t\tspecify the side length\n");
020     printf("\t-s, --symbol\t\tspecify the print symbol\n");
021     printf("\t-i, --interval\t\tspecify the evolution interval(microsecond)\n");
022     printf("\t-V, --version\t\tPrint the software version\n");
023     printf("\t-h, --help\t\tPrint the usage\n");
024     printf("\n\nExample: ./game_of_life -l 50 -s '#'\n\n");
025 
026     return;
027 }
028 
029 void parseArg(int argc, char **argv)
030 {
031     int opt;
032     opterr = 0;
033 
034     struct option long_opts[] = {
035         {"length", 1, NULL, 'l'},
036         {"symbol", 1, NULL, 's'},
037         {"interval", 1, NULL, 'i'},
038         {"version", 0, NULL, 'V'},
039         {"help", 0, NULL, 'h'},
040         {NULL, 0, NULL, 0}
041     };
042 
043     while ( (opt = getopt_long(argc, argv, "l:s:i:Vh", long_opts, NULL)) != -1 )
044     {
045         switch(opt)
046         {
047             case 'l':
048                 g_length = atoi(optarg);
049                 break;
050             case 's':
051                 g_symbol = *optarg;
052                 break;
053             case 'i':
054                 g_interval = atoi(optarg);
055                 break;
056             case 'V':
057                 printf("game_of_life version: %s\n", g_version);
058                 exit(0);
059             case '?':
060                 printf("Unknown parameter!\n\n");
061             case 'h':
062                 usage();
063                 exit(0);
064         }
065     }
066 
067     return;
068 }
069 
070 char randNum()
071 {
072     /* generate a number in (0,2) */
073     int random = (int)(2.0 * ( rand() / (RAND_MAX + 1.0) ));
074     if (random == 1)
075         return g_symbol;
076     else
077         return '\0';
078 }
079 
080 int init(char ***ppp_area)
081 {
082     int i, j;
083 
084     /* set the pseudo-random seed */
085     struct timeval tseed;
086     if (gettimeofday(&tseed, NULL== -1)
087         return -1;
088     srand(tseed.tv_sec ^ tseed.tv_usec);
089 
090     /* set the windows area */
091     if (g_length == 0)
092         g_length = 100;
093     else if (g_length > 200)
094         g_length = 130;
095         else if (g_length < 10)
096             g_length = 10;
097 
098     *ppp_area = (char **)malloc(sizeof(char ** LINE);
099     if (*ppp_area == NULL)
100         return -1;
101 
102     for (i = 0i < LINE++i)
103     {
104         (*ppp_area)[i] = (char *)malloc(sizeof(char* g_length);
105         for (j = 0j < g_length++j)
106             (*ppp_area)[i][j] = randNum();
107     }
108 
109     return 0;
110 }
111 
112 void showStat(char **pp_area)
113 {
114     int i, j;
115 
116     for (i = 0i < LINE++i)
117     {
118         for (j = 0j < g_length++j)
119         {
120             if (pp_area[i][j] == '\0')
121                 putchar(' ');
122             else
123                 putchar(pp_area[i][j]);
124         }
125         putchar('\n');
126     }
127     putchar('\n');
128 
129     usleep(g_interval);
130 
131     return;
132 }
133 
134 void evolvement(char ***ppp_area)
135 {
136     int i, j;
137     char tmp_area[LINE][g_length];
138     char **pp_area = *ppp_area;
139 
140     for (i = 0i < LINE++i)
141         for (j = 0j < g_length++j)
142             tmp_area[i][j] = pp_area[i][j];
143 
144     /* i = 0 */
145     i = 0;
146     for (j = 0j < g_length++j)
147     {
148         int lives = 0;
149 
150         if (j == 0)
151         {
152             if (tmp_area[i][j+1] != '\0'++lives;
153             if (tmp_area[i+1][j] != '\0'++lives;
154             if (tmp_area[i+1][j+1] != '\0'++lives;
155         }
156         else if (j + 1 == g_length)
157         {
158             if (tmp_area[i][j-1] != '\0'++lives;
159             if (tmp_area[i+1][j-1] != '\0'++lives;
160             if (tmp_area[i+1][j] != '\0'++lives;
161         }
162         else
163         {
164             if (tmp_area[i][j-1] != '\0'++lives;
165             if (tmp_area[i][j+1] != '\0'++lives;
166             if (tmp_area[i+1][j-1] != '\0'++lives;
167             if (tmp_area[i+1][j] != '\0'++lives;
168             if (tmp_area[i+1][j+1] != '\0'++lives;
169         }
170 
171         /* 3 reproduce, 2 no change */
172         if (lives == 3)
173             pp_area[i][j] = g_symbol;
174         else if (lives == 2)
175             ;
176         else
177             pp_area[i][j] = '\0';
178     }
179 
180     /* 0 < i < LINE - 1 */
181     for (i = 1i < LINE - 1++i)
182     {
183         for (j = 0j < g_length++j)
184         {
185             int lives = 0;
186 
187             if (j == 0)
188             {
189                 if (tmp_area[i-1][j] != '\0'++lives;
190                 if (tmp_area[i-1][j+1] != '\0'++lives;
191                 if (tmp_area[i][j+1] != '\0'++lives;
192                 if (tmp_area[i+1][j] != '\0'++lives;
193                 if (tmp_area[i+1][j+1] != '\0'++lives;
194             }
195             else if (j + 1 == LINE)
196             {
197                 if (tmp_area[i-1][j-1] != '\0'++lives;
198                 if (tmp_area[i-1][j] != '\0'++lives;
199                 if (tmp_area[i][j-1] != '\0'++lives;
200                 if (tmp_area[i+1][j-1] != '\0'++lives;
201                 if (tmp_area[i+1][j] != '\0'++lives;
202             }
203             else
204             {
205                 if (tmp_area[i-1][j-1] != '\0'++lives;
206                 if (tmp_area[i-1][j] != '\0'++lives;
207                 if (tmp_area[i-1][j+1] != '\0'++lives;
208                 if (tmp_area[i][j-1] != '\0'++lives;
209                 if (tmp_area[i][j+1] != '\0'++lives;
210                 if (tmp_area[i+1][j-1] != '\0'++lives;
211                 if (tmp_area[i+1][j] != '\0'++lives;
212                 if (tmp_area[i+1][j+1] != '\0'++lives;
213             }
214 
215             if (lives == 3)
216                 pp_area[i][j] = g_symbol;
217             else if (lives == 2)
218                 ;
219             else
220                 pp_area[i][j] = '\0';
221         }
222     }
223 
224     /* i = LINE - 1 */
225     i = LINE - 1;
226     for (j = 0j < g_length++j)
227     {
228         int lives = 0;
229 
230         if (j == 0)
231         {
232             if (tmp_area[i-1][j] != '\0'++lives;
233             if (tmp_area[i-1][j+1] != '\0'++lives;
234             if (tmp_area[i][j+1] != '\0'++lives;
235         }
236         else if (j + 1 == g_length)
237         {
238             if (tmp_area[i-1][j-1] != '\0'++lives;
239             if (tmp_area[i-1][j] != '\0'++lives;
240             if (tmp_area[i][j-1] != '\0'++lives;
241         }
242         else
243         {
244             if (tmp_area[i-1][j-1] != '\0'++lives;
245             if (tmp_area[i-1][j] != '\0'++lives;
246             if (tmp_area[i-1][j+1] != '\0'++lives;
247             if (tmp_area[i][j-1] != '\0'++lives;
248             if (tmp_area[i][j+1] != '\0'++lives;
249         }
250 
251         if (lives == 3)
252             pp_area[i][j] = g_symbol;
253         else if (lives == 2)
254             ;
255         else
256             pp_area[i][j] = '\0';
257     }
258 
259     return;
260 }
261 
262 void fn(int sig)
263 {
264     exit(1);
265 }
266 int main(int argc, char **argv)
267 {
268     char **area;
269 
270     parseArg(argc, argv);
271 
272     signal(SIGUSR1, fn);
273 
274     /* malloc area, don't forget to free! */
275     if (init(&area== -1)
276     {
277         printf("Initialization failed!\n");
278         return 1;
279     }
280 
281     for (;;)
282     {
283         showStat(area);
284         evolvement(&area);puts("\033[2J");
285     }
286 
287     int n;
288     for (n = 0; n < LINE++n)
289         free(area[n]);
290     free(area);
291 
292     return 0;
293 }
阅读(1152) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~