《Data structures and program design in c》
从书中整理出来的代码。
事实上,life游戏只是一个模拟游戏,在life 游戏中没有真正的玩家.life游戏在一个没有边界的矩形网格中展开,其中的各个元胞都可以被一个有机体占用或者处于空闲状态.被占用的元胞处于alive状态,未被占用的元胞处于dead状态,元胞状态从一代向另一代转换,是否为alive状态主要取决于与其相邻的元胞alive状态的数量,其规则如下:
1.与给定的元胞相邻的元胞是指与改元胞垂直相连、或者是通过对角线相连的元胞。
2.如果某元胞状态为alive,并且与其相邻的元胞没有一个处于alive状态,或者坏死与其相邻的元胞仅有一个处于alive,那么在下一代中该元胞就因鼓励而转变为dead状态。
3.如果某元胞状态为alive,并且与其相邻的状态为alive的元胞的数量为4个或者更多,那么在下一代中该元胞由于过分拥塞而转变为dead状态。
4. 如果某个状态为alive的元胞有2个或者3个相邻的状态为alive的元胞,那么在下一代中该元胞状态仍然为alive。
5.如果某元胞状态为dead,并且与其相邻的钻柜台色ialive 的元胞数量恰好为3个,那么在下一代中该元胞将转变为alive。其他所有状态为dead的元胞状态保持不变。
6.所有的alive和的dead发生在相同的时间。这样一个正在转变为dead状态的元胞将有助于另外一个元胞转变为alive状态,但是通过降低拥塞并不能阻止其他元胞转变为dead。同时,正在转变为alive的元胞不会保持或取消上一代中状态为alive的元胞
2
3 #include " common.h " /* Common include files and definitions */
4 #include " life.h " /* Life's define, typedefs, and prototypes */
5
6
7 /* simulation of Conway's of life on a bounded grid
8 **Pre: The user must supply an initial configuration of living cells
9 **Post: The program prints a sequence of maps showing the changes in
10 the configuration of living cells according to the rule of life
11 games.
12 **Uses: Function Initialize, WriteMap, NeighborCount, and UserSyasYes.
13 */
14 int main( void )
15 {
16 int row, col;
17 Grid map;
18 Grid newmap;
19 Initialize(map);
20 WriteMap(map);
21 printf( " This is the initial configuration you have chosen.\n "
22 " Press
23 while (getchar() != ' \n ' );
24 do {
25 for (row = 1 ; row <= MAXROW; row ++ )
26 {
27 for (col = 1 ; col <= MAXCOL; col ++ )
28 {
29 switch (NeighborCount(map, row, col))
30 {
31 case 0 :
32 case 1 :
33 newmap[row][col] = DEAD;
34 break ;
35 case 2 :
36 newmap[row][col] = map[row][col];
37 break ;
38 case 3 :
39 newmap[row][col] = ALIVE;
40 break ;
41 case 4 :
42 case 5 :
43 case 6 :
44 case 7 :
45 case 8 :
46 newmap[row][col] = DEAD;
47 break ;
48 default :
49 break ;
50 }
51 } /* for */
52 } /* for */
53 CopyMap(map, newmap);
54 WriteMap(map);
55 printf( " Do you wish to continue viewing the new generations " );
56 } while (UserSaysYes());
57
58 return 0 ;
59 }
2
3
4 #ifndef _COMMON_H_
5 #define _COMMON_H_
6
7 #include < stdio.h >
8 #include < stdlib.h >
9 /*
10 #define TURE 1
11 #define FALSE 0
12 */
13 typedef enum Boolean{TURE, FLASE}Boolean;
14
15 void Error( char * );
16 // void Warning(char *);
17
18 #endif
2
3 #include " common.h "
4
5 /* Error: report program error.
6 **Pre: s points to he message to be printed.
7 **Post: The function will prints the message and terminates the Program.
8 */
9 void Error( char * s)
10 {
11 fprintf(stderr, " %s\n " , s);
12 exit( 1 );
13 }
14
15 /*
16
17 */
2 file: file.h
3 */
4 #ifndef _LIFE_H_
5 #define _LIFE_H_
6
7 #include " common.h "
8
9 typedef enum state{DEAD, ALIVE}State;
10
11 #define MAXROW 20 /* maximum row range */
12 #define MAXCOL 60 /* maximum column range */
13
14 typedef State Grid[MAXROW + 2 ][MAXCOL + 2 ];
15
16 void CopyMap(Grid map, Grid newmap);
17 Boolean UserSaysYes();
18 void Initialize(Grid map);
19 int NeighborCount(Grid map, int row, int col);
20 void WriteMap(Grid map);
21
22
23 #endif
#include " life.h "
#include < stdio.h >
/* Initialize: initialize grid map
**Pre : None
**Post: All the cells in the grid map have been set to initial configuration of living cells
*/
void Initialize(Grid map)
{
int row, col; /* coordinates of a cell */
printf( " The program is a simulation of the game of a Life.\n "
" The gird has a size of %d rows and "
" %d columns " , MAXROW, MAXCOL);
for (row = 0 ; row < MAXROW; row ++ )
for ( col = 0 ; col < MAXCOL; col ++ )
map[row][col] = DEAD; /* Set all cells empty, including the hedage. */
printf( " On each line give a pair of coordinates for living cell.\n "
" Terminate the list with the special pair 0 0.\n " );
scanf( " %d %d " , & row, & col);
while (row != 0 && col != 0 )
{ /* Check termination condition */
if (row >= 1 && row <= MAXROW + 1 && col >= 1 && col <= MAXCOL)
{
map[row][col] = ALIVE;
}
else
{
printf( " Values are not within range.\n " );
}
scanf( " %d %d " , & row, & col);
}
while (getchar() != ' \n ' )
;
}
/* WriteMap: display grid map.
**Pre: The rectangular array map contains the current Life configuration.
**Post: The current Life configuration wirtes to user.
*/
void WriteMap(Grid map)
{
int row, col;
putchar( ' \n ' );
putchar( ' \n ' );
for (row = 1 ; row <= MAXROW; row ++ )
{
for (col = 1 ; col <= MAXCOL; col ++ )
{
if (map[row][col] == ALIVE)
putchar( ' * ' );
else
putchar( ' - ' );
}
putchar( ' \n ' );
}
}
/* CopyMap: copy newmap into map.
**Pre: The grid newmap has the current Life configuration.
**Post: The grid map has a copy of newmap.
*/
void CopyMap(Grid map, Grid newmap)
{
int row, col;
for (row = 1 ; row <= MAXROW; row ++ )
for (col = 1 ; col <= MAXCOL; col ++ )
map[row][col] = newmap[row][col];
}
/* UserSyasYes: TRUE if the User wants to continue execution.
**Pre: None.
**Post: Returns TRUE if the users answer begins with either Y or y. FALSE if the user
reponds with any response beginning with either n or N.
*/
Boolean UserSaysYes( void )
{
int c;
printf( " (y,n)? " );
do {
while ((c = getchar()) == ' \n ' )
; /* Ignore new line character */
if (c == ' Y ' || c == ' y ' || c == ' N ' || c == ' n ' )
return (c == ' y ' || c == ' Y ' );
} while ( 1 );
}
/* NeghborCount: count neighbors of row,col
**Pre: The pair row,col is a valid cell in a Life configuration.
**Post: The function returns the number of living neighbors of the living cell.
*/
int NeighborCount(Grid map, int row, int col)
{
int i; /* row of a neighbor of the cell(row, col) */
int j; /* column of a neighbor of the cell(row, col) */
int count = 0 ;
for (i = row - 1 ; i <= row + 1 ; i ++ )
for (j = col - 1 ; j <= col + 1 ; j ++ )
if (map[i][j] == ALIVE)
{
count ++ ;
}
if (map[row][col] == ALIVE)
count -- ;
return count;
}
个人