subscribe
Tags:
 
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
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:
4 minus 4
Answer:
required