⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 life.c

📁 Conway s Game of life 算法程序
💻 C
字号:
#define CURSES 0

#include <stdio.h>
#include <stdlib.h>
#if CURSES
#include <curses.h>
#endif
#include "simple.h"


#define LIFE_GRID 20		// Defines the width x height of the arrays used.
//#define N 5		// Defines the number of generations the program should simulate.
int N;
typedef int byte;
#define TRUE  1
#define FALSE 0

#define LASTROW (my_rank == (LIFE_GRID-1))
#define FIRSTROW (my_rank == 0)

void load_init (unsigned int, byte[LIFE_GRID][LIFE_GRID]);
// Function to setup initial generation. 
void step_generation (byte [], int);
// Function to move forward one generation. 
void print_grid (byte [LIFE_GRID][LIFE_GRID]);
// Function to print the array. 
int neighbors ();
// Function to figure the number of neighbors for a given cell. 
void copy_array ();
// Function to copy the contents of one array to another. 
  byte grid[LIFE_GRID][LIFE_GRID];
int main (int argc, char *argv[])
{
  byte *myrow;
//  byte grid[LIFE_GRID][LIFE_GRID];
  int i;
  unsigned int seed;		// Holds the user entered seed for the random number generator. 

  int my_rank, p;

  Init (&argc, &argv);
  my_rank = GetRank ();
  myrow = &grid[my_rank][0];
  p = GetSize ();
  if (p != LIFE_GRID )
  {
    if (my_rank == 0)
    {
      fprintf (stderr, "Wrong number of processes.\nUse -np %d\n", LIFE_GRID );
    }
    Finalize ();
    exit (1);
  }
  if (argc != 3)
  {
    if (my_rank == 0)
    {
      fprintf (stderr,
	"Input number of generations and seed\nUse %s <no.gen.> <seed>\n",
	argv[0]);
    }
    Finalize ();
    exit (2);
  }
  // Get a unsigned int from the user and use it to seed the random number generator. 
  if (0 == my_rank)
  {
    sscanf (argv[1],"%u", &N);
    sscanf (argv[2],"%u", &seed);
    // Print a message to the screen and run load_init to setup the initial generation. 
    printf ("\nGenerating initial grid...\n");
    load_init (seed, grid);
  }
  else
  {
    Recv (INT, myrow, LIFE_GRID, 0);
  }
  Bcast(INT,&N,1,0);
  // Loop to cycle through the different generations. 
  for (i = 1; i <= N; i++)
  {    
    step_generation (myrow, my_rank);	// Call step_generation to generate the next generation. 
    if(my_rank != 0) Send (INT, myrow, LIFE_GRID, 0);
    Barrier();
    if (0==my_rank)
    {
#if CURSES
      sleep(1); 
      move (0, 0);
      printw ("\nGeneration: %i\n\n", i);	// Print the generation number on the screen. 
#else
      printf ("\nGeneration: %i\n\n", i);	// Print the generation number on the screen. 
#endif
      print_grid (grid);		// Call print_grid to display the contents of the array. 
    }
    Barrier();
  }
#if CURSES
  if (0 == my_rank)
  {
    sleep(3);
    endwin();
    printf("\nDone.\n");
  }
#endif
  Finalize ();
  return 0;
}

/*
 *  load_init() is passed the address of an array of characters.  It moves through
 *  each cell in the array, based on a random number provided by the rand() function
 *  it places a * or a space in the given cell of the array.
 */

void load_init (unsigned int seed, byte grid[LIFE_GRID][LIFE_GRID])
{
  int y, x, z;
  byte cell;

  
  srand (seed);
#if CURSES
  initscr();
  printw ("\nGeneration: %i\n\n", 0);	// Print the generation number on the screen. 
#else
  printf ("\nGeneration: %i\n\n", 0);	// Print the generation number on the screen. 
#endif
#if CURSES
  // Print column numbers left to right. 
  printw ("  ");
  for (x = 0; x < LIFE_GRID; x++)
    printw ("%i ", x);
  printw ("\n");
#endif
  for (y = 0; y < LIFE_GRID; y++)
  { 
#if CURSES
    printw ("%i ", y);
#endif
    for (x = 0; x < LIFE_GRID; x++)
    {
      z = (int) (10.0 * rand () / RAND_MAX + 1.0);	// Generates a random number between 0 and 10. 
      if (z < 5)
	grid[y][x] = FALSE;
      else
	grid[y][x] = TRUE;
#if CURSES
      printw("%d ",grid[y][x]); 
#else
      printf("%d ",grid[y][x]);
#endif
    }
    if (y>0) 
    { 
        Send (INT, &grid[y][0], LIFE_GRID, y );
    }
#if CURSES
    printw("\n");
#else
    printf("\n");
#endif
  }
#if CURSES
  refresh();
  sleep(1);
#endif
}

/*
 *  step_generation() is passed the address of an array of characters.  It also sets
 *  up an array of the exact same size as the one whose address was passed.  The
 *  function moves through each cell in the array, calling neighbors() to get
 *  the number of neighbors the current cell has.  Based on the data from neighbors()
 *  and the rules of Life, it either places a * or space in the corresponding cell
 *  of the second array.  Once the function has finished, it calls copy_array() to
 *  copy the contents of the second array into the first array.
 */

void step_generation (byte *myrow, int my_rank)
{
  int x, i;
  byte *prevrow, *nextrow, newrow[LIFE_GRID];
  prevrow = myrow - LIFE_GRID;
  nextrow = myrow + LIFE_GRID;
  if (!FIRSTROW)
  {
//        printf("Process %d sending info to process %d\n",my_rank,my_rank-1);
	Send (INT, myrow, LIFE_GRID, my_rank - 1);
//        printf("Process %d sent info to process %d\n",my_rank,my_rank-1);
	Recv (INT, prevrow, LIFE_GRID, my_rank - 1);
//        printf("Process %d received info from process %d\n",my_rank,my_rank-1);
  }
  if (!LASTROW)
  {
//        printf("Process %d sending info to process %d\n",my_rank,my_rank+1);
	Send (INT, myrow, LIFE_GRID, my_rank + 1);
//        printf("Process %d sent info to process %d\n",my_rank,my_rank+1);        
	Recv (INT, nextrow, LIFE_GRID, my_rank + 1);
//        printf("Process %d received info from process %d\n",my_rank,my_rank+1);
  }
  // now, count the neighbors
  for(i=0; i < LIFE_GRID; i++)
  {
      x = 0;
      if (!FIRSTROW) 
      {
        if(i!=0) x+=prevrow[i-1];
        x+=prevrow[i];
        if(i!=LIFE_GRID-1) x+=prevrow[i+1]; 
      }
      if (!LASTROW) 
      {
        if(i!=0) x+=nextrow[i-1];
        x+=nextrow[i];
        if(i!=LIFE_GRID-1) x+=nextrow[i+1]; 
      }
      if(i!=0) x+=myrow[i-1];
      if(i!=LIFE_GRID-1) x+=myrow[i+1]; 
      if (myrow[i] == TRUE)	// If the cell has an organism in it now. 
      {
	if ((x == 2) || (x == 3))
	  newrow[i] = TRUE;
	else
	  newrow[i] = FALSE;
      }
      else			// If the cell is empty. 
      {
	if (x == 3)
	  newrow[i] = TRUE;
	else
	  newrow[i] = FALSE;
      }
//      printf("%d, %d, %d, %d\n", my_rank, i, x, newrow[i]);
  }
  for(i=0; i < LIFE_GRID; i++) myrow[i] = newrow[i];
}

/*
 *	print_grid() is passed the address of an array of characters.  It moves through this
 *	array printing each character to the display.  It also prints cell numbers across the
 *	top, and along the left side of the output.
 */

void print_grid (byte grid[LIFE_GRID][LIFE_GRID])
{
  int y, x;
  byte cell;
#if CURSES
#define PRINT printw
#else
#define PRINT printf
#endif
  // Print column numbers left to right. 
  PRINT ("  ");
  for (x = 0; x < LIFE_GRID; x++)
    PRINT ("%i ", x);
  PRINT ("\n");

  // Print a row number and the contens of that row. 
  for (y = 0; y < LIFE_GRID; y++)
  {
    PRINT ("%i ", y);
    if (y > 0) Recv (INT, &grid[y][0],LIFE_GRID, y);
    for (x = 0; x < LIFE_GRID; x++)
    {
      if (grid[y][x] == TRUE)
	PRINT ("* ");
      else
	PRINT ("  ");
    }
    PRINT ("\n");
  }
#if CURSES
  refresh();
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -