Task: Conway's Game of Life


C++: #include <algorithm>
#include <vector>
#include <iostream>
#include <string>

typedef unsigned char byte; 

class world {
public:
    world( int x, int y ) : _wid( x ), _hei( y ) {
        int s = _wid * _hei * sizeof( byte );
        _cells = new byte[s];
        memset( _cells, 0, s );
    }
    ~world() {
        delete [] _cells;
    }
    int wid() const {
        return _wid;
    }
    int hei() const {
        return _hei;
    }
    byte at( int x, int y ) const {
        return _cells[x + y * _wid];
    }
    void set( int x, int y, byte c ) {
        _cells[x + y * _wid] = c;
    }
    void swap( world* w ) {
        memcpy( _cells, w->_cells, _wid * _hei * sizeof( byte ) );
    }
private:
    int _wid, _hei;
    byte* _cells;
};
class rule {
public:
    rule( world* w ) : wrd( w ) {
        wid = wrd->wid();
        hei = wrd->hei();
        wrdT = new world( wid, hei );
    }
    ~rule() {
        if( wrdT ) delete wrdT;
    }
    bool hasLivingCells() {
        for( int y = 0; y < hei; y++ )
            for( int x = 0; x < wid; x++ )
                if( wrd->at( x, y ) ) return true;
        std::cout << "*** All cells are dead!!! ***\n\n";
        return false;
    }
    void swapWrds() {
        wrd->swap( wrdT );
    }
    void setRuleB( std::vector<int>& birth ) {
        _birth = birth;
    }
    void setRuleS( std::vector<int>& stay ) {
        _stay = stay;
    }
    void applyRules() {
        int n;
        for( int y = 0; y < hei; y++ ) {
            for( int x = 0; x < wid; x++ ) {
                n = neighbours( x, y );
                if( wrd->at( x, y ) ) {
                    wrdT->set( x, y, inStay( n ) ? 1 : 0 );
                } else {
                    wrdT->set( x, y, inBirth( n ) ? 1 : 0 );
                }
            }
        }
    }
private:
    int neighbours( int xx, int yy ) {
        int n = 0, nx, ny;
        for( int y = -1; y < 2; y++ ) {
            for( int x = -1; x < 2; x++ ) {
                if( !x && !y ) continue;
                nx = ( wid + xx + x ) % wid;
                ny = ( hei + yy + y ) % hei;
                n += wrd->at( nx, ny ) > 0 ? 1 : 0;
            }
        }
        return n;
    }
    bool inStay( int n ) {
        return( _stay.end() != find( _stay.begin(), _stay.end(), n ) );
    }
    bool inBirth( int n ) {
        return( _birth.end() != find( _birth.begin(), _birth.end(), n ) );
    }
    int wid, hei;
    world *wrd, *wrdT;
    std::vector<int> _stay, _birth;
};
class cellular {
public:
    cellular( int w, int h ) : rl( 0 ) {
        wrd = new world( w, h );
    }
    ~cellular() {
        if( rl ) delete rl;
        delete wrd;
    }
    void start( int r ) {
        rl = new rule( wrd );
        gen = 1;
        std::vector<int> t;
        switch( r ) {
            case 1: 
                t.push_back( 2 ); t.push_back( 3 ); rl->setRuleS( t );
                t.clear(); t.push_back( 3 ); rl->setRuleB( t );
                break;
            case 2: 
                t.push_back( 1 ); t.push_back( 3 ); t.push_back( 5 ); t.push_back( 8 ); rl->setRuleS( t );
                t.clear(); t.push_back( 3 ); t.push_back( 5 ); t.push_back( 7 ); rl->setRuleB( t );
                break;
            case 3: 
                t.push_back( 3 ); t.push_back( 4 ); rl->setRuleS( t );
                rl->setRuleB( t );
                break;
            case 4: 
                t.push_back( 1 ); t.push_back( 2 ); t.push_back( 3 ); t.push_back( 4 ); t.push_back( 5 ); rl->setRuleS( t );
                t.clear(); t.push_back( 3 ); rl->setRuleB( t );
                break;
        }

        
        
        wrd->set( 6, 1, 1 ); wrd->set( 7, 2, 1 );
        wrd->set( 5, 3, 1 ); wrd->set( 6, 3, 1 );
        wrd->set( 7, 3, 1 );
        
        wrd->set( 1, 3, 1 ); wrd->set( 2, 3, 1 );
        wrd->set( 3, 3, 1 );
        
        generation();
    }
private:
    void display() {
        system( "cls" );
        int wid = wrd->wid(),
            hei = wrd->hei();
        std::cout << "+" << std::string( wid, '-' ) << "+\n";
        for( int y = 0; y < hei; y++ ) {
            std::cout << "|";
            for( int x = 0; x < wid; x++ ) {
                if( wrd->at( x, y ) ) std::cout << "#";
                else std::cout << ".";
            }
            std::cout << "|\n";
        }
        std::cout << "+" << std::string( wid, '-' ) << "+\n";
        std::cout << "Generation: " << gen << "\n\nPress [RETURN] for the next generation...";
        std::cin.get();
    }
    void generation() {
        do {
            display();
            rl->applyRules();
            rl->swapWrds();
            gen++;
        }
        while ( rl->hasLivingCells() );
    }
    rule* rl;
    world* wrd;
    int gen; 
};

int main( int argc, char* argv[] ) {
    cellular c( 20, 12 );
    std::cout << "\n\t*** CELLULAR AUTOMATA ***" << "\n\n Which one you want to run?\n\n\n";
    std::cout << " [1]\tConway's Life\n [2]\tAmoeba\n [3]\tLife 34\n [4]\tMaze\n\n > ";
    int o; 
    do {
        std::cin >> o;
    } 
    while( o < 1 || o > 4 );
    std::cin.ignore();
    c.start( o );
    return system( "pause" );
}


C#: using System;
using System.Text;
using System.Threading;
 
namespace ConwaysGameOfLife
{
    
    class Program
    {
        
        private const int DELAY = 50;
 
        
        private const ConsoleColor DEAD_COLOR = ConsoleColor.White;
        private const ConsoleColor LIVE_COLOR = ConsoleColor.Black;
 
        
        private const ConsoleColor EXTRA_COLOR = ConsoleColor.Gray;
 
        private const char EMPTY_BLOCK_CHAR = ' ';
        private const char FULL_BLOCK_CHAR = '\u2588';
 
        
        private static bool[,] board;
 
        
        private static int width = 32;
        private static int height = 32;
 
        
        private static bool loopEdges = true;
 
 
        static void Main(string[] args)
        {
            
            initializeDemoBoard();
 
            initializeConsole();
 
            
            while (!Console.KeyAvailable || Console.ReadKey(true).Key != ConsoleKey.Escape) {
                Program.drawBoard();
                Program.updateBoard();
 
                
                Thread.Sleep(DELAY);
            }
        }
 
        
        private static void initializeConsole()
        {
            Console.BackgroundColor = EXTRA_COLOR;
            Console.Clear();
 
            Console.CursorVisible = false;
 
            
            
            int width = Math.Max(Program.width, 8) * 2 + 1;
            int height = Math.Max(Program.height, 8) + 1;
            Console.SetWindowSize(width, height);
            Console.SetBufferSize(width, height);
 
            Console.BackgroundColor = DEAD_COLOR;
            Console.ForegroundColor = LIVE_COLOR;
        }
 
        
        private static void initializeRandomBoard()
        {
            var random = new Random();
 
            Program.board = new bool[Program.width, Program.height];
            for (var y = 0; y < Program.height; y++) {
                for (var x = 0; x < Program.width; x++) {
                    
                    Program.board[x, y] = random.Next(2) == 0;
                }
            }
        }
 
        
        private static void initializeDemoBoard()
        {
            Program.width = 3;
            Program.height = 3;
 
            Program.loopEdges = false;
 
            Program.board = new bool[3, 3];
            Program.board[1, 0] = true;
            Program.board[1, 1] = true;
            Program.board[1, 2] = true;
        }
 
        
        private static void drawBoard()
        {
            
            var builder = new StringBuilder();
 
            for (var y = 0; y < Program.height; y++) {
                for (var x = 0; x < Program.width; x++) {
                    char c = Program.board[x, y] ? FULL_BLOCK_CHAR : EMPTY_BLOCK_CHAR;
 
                    
                    builder.Append(c);
                    builder.Append(c);
                }
                builder.Append('\n');
            }
 
            
            Console.SetCursorPosition(0, 0);
            Console.Write (builder.ToString());
        }
 
        
        private static void updateBoard()
        {
            
            bool[,] newBoard = new bool[Program.width, Program.height];
 
            for (var y = 0; y < Program.height; y++) {
                for (var x = 0; x < Program.width; x++) {
                    var n = countLiveNeighbors(x, y);
                    var c = Program.board[x, y];
 
                    
                    
                    newBoard[x, y] = c && (n == 2 || n == 3) || !c && n == 3;
                }
            }
 
            
            Program.board = newBoard;
        }
 
        
        private static int countLiveNeighbors(int x, int y)
        {
            
            int value = 0;
 
            
            for (var j = -1; j <= 1; j++) {
                
                if (!Program.loopEdges && y + j < 0 || y + j >= Program.height) {
                    continue;
                }
 
                
                int k = (y + j + Program.height) % Program.height;
 
                for (var i = -1; i <= 1; i++) {
                    
                    if (!Program.loopEdges && x + i < 0 || x + i >= Program.width) {
                        continue;
                    }
 
                    
                    int h = (x + i + Program.width) % Program.width;
 
                    
                    value += Program.board[h, k] ? 1 : 0;
                }
            }
 
            
            return value - (Program.board[x, y] ? 1 : 0);
        }
    }
}