Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*compile with
- valac --pkg sdl game_of_life.vala -o game_of_life
- */
- using SDL;
- bool mouse_is_down = false;
- 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 s, uint32 flags,int16 x, int16 y, int16 size,uint32 lcolor,uint32 bg_color )
- {
- life_color = lcolor;
- dead_color = bg_color;
- updated=false;
- screen = s;
- on_screen_rect.w = size;
- on_screen_rect.h = size;
- on_screen_rect.x = x;
- on_screen_rect.y = y;
- self_rect.w = size;
- self_rect.h = size;
- self_rect.x=0;
- self_rect.y=0;
- this.size = (int16)size;
- alive=false;
- //create the surface
- surface = new Surface.RGB(flags, size, size, 32, 0,0,0, 255);
- }
- 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;
- private uint16 cell_size;
- public Game(int16 cell_size, int random_max)
- {
- this.cell_size = cell_size; //game object needs to know this to update on position
- this.random_max = random_max;
- //initialize the video
- uint32 surface_flags = SurfaceFlag.DOUBLEBUF |
- SurfaceFlag.HWACCEL
- | SurfaceFlag.HWSURFACE;
- screen = Screen.set_video_mode (SCREEN_WIDTH, SCREEN_HEIGHT,
- SCREEN_BPP, surface_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=0; row<num_rows; row++)
- {
- y = row*cell_size;
- for ( int16 column=0; column<num_cols; column++)
- {
- 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 set_cell_alive(uint16 x, uint16 y)
- {
- cells[(int16)(y / cell_size), (int16)(x / cell_size)].set_life(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=0; r<num_rows;r++)
- {
- //loop through the columns
- for(int c=0; c<num_cols ; c++)
- {
- //generate a number
- int i = 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;
- case EventType.MOUSEMOTION:
- if (mouse_is_down) {
- set_cell_alive(event.motion.x, event.motion.y);
- }
- break;
- case EventType.MOUSEBUTTONDOWN:
- if (event.button.button == 1) { //left click
- mouse_is_down = true;
- }
- break;
- case EventType.MOUSEBUTTONUP:
- if (event.button.button == 1) {
- mouse_is_down = false;
- }
- break;
- }
- }
- }
- private void on_keyboard_event (KeyboardEvent event)
- {
- if(event.keysym.sym==KeySymbol.q)
- {
- quit();
- }
- if(event.keysym.sym==KeySymbol.ESCAPE)
- {
- quit();
- }
- if(event.keysym.sym==KeySymbol.r)
- {
- seed_life(true);
- }
- }
- private void draw()
- {
- screen.fill (null, bg_color);
- foreach( Cell c in cells )
- {
- c.draw();
- }
- screen.update_rect(0,0,screen.w,screen.h);
- }
- private int living_neighbors(int r, int 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 (r == num_rows-1)
- {
- r_max=r;
- }
- if ( c==0 )
- {
- c_min=c;
- }
- else if (c == 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!=r || tc!=c )
- {
- 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=0; r<num_rows; r++)
- {
- for(c=0; c<num_cols; c++)
- {
- alive = cells[r,c].alive;
- ln = living_neighbors(r,c);
- if( alive && ( ln<2 || ln>3 ))
- {
- //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=0 ; index<final_index ; index+=2)
- {
- r = dead_array.index(index);
- c= dead_array.index(index+1);
- cells[r,c].set_life(false);
- }
- //frankenstein what needs life
- final_index = alive_array.length-1;
- for(index=0 ; index<final_index ; index+=2)
- {
- r = alive_array.index(index);
- c= alive_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();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement