2009-12-29
Once again, Conway's Game of Life. This time written in Vala using SDL for the graphics.

In comparison to my previous Game of Life implementation, this version starts faster; much much faster. In the time it takes the Python/Clutter version to make 100 cells, the Vala/SDL version creates 100000 cells. I attribute the speed increase on the following factors:
  • Vala code is compiled to machine code, while Python code needs to be executed by the Python runtime.
  • SDL is a much lower level library than Clutter.
  • Since Clutter utilizes OpenGL for graphics, my graphics card, which is rather old, my not be the best OpenGL renderer

To test the code, save the following as game_of_life.vala
/*compile with valac --pkg sdl game_of_life.vala -o game_of_life */ using SDL; public class Cell {     public Rect on_screen_rect;     public Rect self_rect;     public Surface surface;     public weak Screen screen;     public bool alive {get;set;}     public bool updated;     public int16 size;     private uint32 life_color;     private uint32 dead_color;     public Cell(Screen suint32 flags,int16 xint16 yint16 size,uint32 lcolor,uint32 bg_color )              life_color lcolor;         dead_color bg_color;         updated=false;         screen s;         on_screen_rect.size;         on_screen_rect.size;         on_screen_rect.x;         on_screen_rect.y;         self_rect.size;         self_rect.size;         self_rect.x=0;         self_rect.y=0;         this.size = (int16)size;         alive=false;         //create the surface          surface new Surface.RGB(flagssizesize320,0,0255);        }     public void set_life(bool life)     {         alive=life;         if (alive)         {             surface.fill(null,life_color);         }else{             surface.fill(null,dead_color);         }     }     public void draw()     {         surface.blit(self_rect,screen,on_screen_rect);     } } public class Game {     private const int SCREEN_WIDTH 800;     private const int SCREEN_HEIGHT 600;     private const int SCREEN_BPP 32;     private const int DELAY 100;     private weak SDL.Screen screen;     private bool do_loop;     private Cell[,] cells;     private int16 num_cols;     private int16 num_rows;     private uint32 bg_color;     private int random_max;          public Game(int16 cell_sizeint random_max)     {         this.random_max random_max;         //initialize the video         uint32 surface_flags SurfaceFlag.DOUBLEBUF |                             SurfaceFlag.HWACCEL                            SurfaceFlag.HWSURFACE;         screen Screen.set_video_mode (SCREEN_WIDTHSCREEN_HEIGHT,                                         SCREEN_BPPsurface_flags);         if (screen == null) {             GLib.error ("Could not set video mode.");         }         //we have a screen, define some colors         bg_color=screen.format.map_rgb(0,0,0);         uint32 life_color=screen.format.map_rgb(0,255,0);         SDL.WindowManager.set_caption ("Game of Life: Vala, SDL""");         //make all of the cells         //'''fill the screen with rectangles'''         num_cols = (int16)SCREEN_WIDTH/cell_size;         num_rows = (int16)SCREEN_HEIGHT/cell_size;         uint32 cells_to_create num_cols*num_rows;         int16 y;         int16 x;         cells new Cell[num_rows,num_cols];         stdout.printf"%0.f cells to create\n",cells_to_create);         for int16 row=0row<num_rowsrow++)         {             row*cell_size;             for int16 column=0column<num_colscolumn++)             {                 x=column*cell_size;                 //set the column index to a rect that is cell_size by cell_size                 cells[row,column] = new Cell(screen,surface_flags,x,y,cell_size,life_color,bg_color);             }             cells_to_create-=num_cols;         }         stdout.printf"cells created\n" );         do_loop true;     }          private void seed_life(bool reseed=false)     {         Rand rand new Rand();         stdout.printf"adding random life\n" );         //loop through the rows         for(int r=0r<num_rows;r++)         {             //loop through the columns             for(int c=0c<num_cols c++)             {                 //generate a number                 int rand.int_range(0,random_max);                 if (i==0)                 {                     //r,c is alive                     cells[r,c].set_life(true);                 }else if (reseed)                 {                     cells[r,c].set_life(false);                 }             }         }     }          public void run()     {         //seed life into the cells         seed_life();         //do stuff         while (do_loop) {             this.draw ();             this.process_events ();             detect_life();             SDL.Timer.delay (DELAY);         }     }     private void quit()     {         do_loop false;     }     private void process_events()     {         Event event Event ();         while (Event.poll (event) == 1) {             switch (event.type) {             case EventType.QUIT:                 quit();                 break;             case EventType.KEYDOWN:                 this.on_keyboard_event (event.key);                 break;             }         }     }           private void on_keyboard_event (KeyboardEvent event)      {         if(event.keysym.sym==KeySymbol.q)         {             quit();         }         if(event.keysym.sym==KeySymbol.r)         {             seed_life(true);         }     }          private void draw()     {         screen.fill (nullbg_color);         foreachCell in cells )         {             c.draw();         }         screen.update_rect(0,0,screen.w,screen.h);     }          private int living_neighbors(int rint c)     {         int alive 0;         int r_min r-1;         int r_max r+1;         int c_min c-1;         int c_max c+1;         if(r==0)         {             r_min=r;         }         else if (== num_rows-1)         {             r_max=r;         }         if c==)         {             c_min=c;         }         else if (== num_cols-1)         {             c_max=c;          }            int tr r_min;         int tc c_min;         while(tr <= r_max)         {             tc c_min;             while(tc <= c_max)             {                 if tr!=|| tc!=)                 {                     if cells[tr,tc].alive)                     {                         alive+=1;                     }                 }                 tc+=1;             }             tr+=1;         }         return alive;     }          public void detect_life()     {         int r;         int c;         int index;         Array<int>? dead_array new Array<int>(false,false,(uint)sizeof(int));         Array<int>? alive_array new Array<int>(false,false,(uint)sizeof(int));         bool alive;         int ln;         for(r=0r<num_rowsr++)         {             for(c=0c<num_colsc++)             {                 alive cells[r,c].alive;                 ln living_neighbors(r,c);                 ifalive && ( ln<|| ln>))                 {                     //this cell will die; boohoo                     dead_array.append_val(r);                     dead_array.append_val(c);                 }                 else if(!alive && ln==3)                 {                     //this cell is now alive; damn zombies                     alive_array.append_val(r);                     alive_array.append_val(c);                 }             }         }         //kill what needs killing          uint final_index dead_array.length-1;         for(index=index<final_index index+=2)         {             dead_array.index(index);             cdead_array.index(index+1);             cells[r,c].set_life(false);         }         //frankenstein what needs life         final_index alive_array.length-1;         for(index=index<final_index index+=2)         {             alive_array.index(index);             calive_array.index(index+1);             cells[r,c].set_life(true);         }     }    } public static void main(string[] args) {     int16 cell_size 2;     int random_max 15;     SDL.init (InitFlag.VIDEO);     Game game new Game(cell_size,random_max);     game.run();     SDL.quit(); }
or you can just download game_of_life.vala
The code is compiled with
valac --pkg sdl game_of_life.vala -o game_of_life

As in the Python/Clutter example, pressing "q" will quit the game, and pressing "r" will reset the game.

Now stop reading, and get mesmerized by little green blocks.
Comments
2010-04-17 Yuvi:
Copy pasting the code messes up the formatting big time :(

I'd mucho appreciate it if you put it up in a way where we can get a raw version out easily.

:)
2010-04-17 jezra:
What text editor are you pasting the code into?
2010-04-20 (((1/f))):
Hi, I have the same problem as Yuvi. I have two editors on Puppy Linux 431 namely Geany and NicoEdit and they won't accept the copypasta.
2010-04-21 jezra:
I have added a link, after the code, to a source file containing the code.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
1 minus 0
Answer:
required
subscribe
 
2019
2016
2015
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008