Home   Cover Cover Cover Cover
 

Gleichnamige Typen aus verschiedenen Namensräumen

GameOfLife.cs
/* Spiel des Lebens (Game of Life)
   ----------------
   Dies ist das bekannte Beispiel eines zellulaeren Automaten, der aus
   eine N*N-Matrix von Zellen besteht, die lebend oder tot sein koennen.
   Die naechste Generation der Matrix berechnet sich wie folgt:
   - Hat eine lebende Zelle weniger als 2 oder mehr als 3 lebende Nachbarn, 
     stirbt sie, ansonsten bleibt sie am Leben.
   - Hat eine tote Zelle genau 3 lebende Nachbarn, wird sie zum Leben erweckt.
   Die Raender der Matrix werden so betrachtet wie wenn sie mit dem 
   gegenueberliegenden Rand verbunden waeren.
   
   Die einzelnen Zellen der naechsten Generation werden parallel
   berechnet, wofuer 2 geschachtelte Aufrufe der Methode
   Parallel.For() verwendet werden.
   
   Aufruf: GameOfLife boardSize generations
------------------------------------------------------------*/
using System;
using System.Threading.Tasks;


public class GameOfLife {
  
  static int N;  // board dimension
  
  // Creates an N*N board and initializes it with 1 (life) and 0 (dead)
  static int[,] NewBoard() {
    int[,] board = new int[N, N];
    Random rand = new Random();
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        board[i, j] = rand.NextDouble() > 0.5 ? 1 : 0;
      }
    }
    return board;
  }
  
  // Prints the board to the console
  static void print(int[,] board) {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        if (board[i, j] == 1) Console.Write("*"); else Console.Write(".");
      }
      Console.WriteLine();
    }
    Console.WriteLine();
  }
  
  // Computes how many of the 8 neighbors of board[i, j] are alive.
  // At the borders the board "wraps around".
  static int Neighbors(int[,] board, int i, int j) {
    int top   = i == 0     ? N - 1 : i - 1;
    int bot   = i == N - 1 ?     0 : i + 1;
    int left  = j == 0     ? N - 1 : j - 1;
    int right = j == N - 1 ?     0 : j + 1;
    return board[top, left] + board[top, j] + board[top, right]
         + board[i, left]                   + board[i, right]
         + board[bot, left] + board[bot, j] + board[bot, right];
  }
  
  // Computes the next generation of the board.
  // All the cells are computed in parallel.
  static int[,] NextGeneration(int[,] board) {
    int[,] newBoard = new int[N, N];
    Parallel.For(0, N, i => {
      Parallel.For(0, N, j => {
        int neighbors = Neighbors(board, i, j);
        if (board[i, j] == 1) { // life
          newBoard[i, j] = (neighbors < 2 || neighbors > 3) ? 0 : 1;
        } else { // dead
          newBoard[i, j] = neighbors == 3 ? 1 : 0;
        }
      });
    });
    return newBoard;
  }
  
  public static void Main(string[] arg) {
    if (arg.Length == 2) {
      try {
        N = Convert.ToInt32(arg[0]);
        int generations = Convert.ToInt32(arg[1]);
        int[,] board = NewBoard();
        print(board);
        for (int i = 0; i < generations; i++) {
          board = NextGeneration(board);
          print(board);
        }
      } catch (FormatException) {
        Console.WriteLine("-- Arguments must be integers");
      }
    } else {
      Console.WriteLine("-- Synopsis: GameOfLife boardSize generations");
    }
  }
}