blob: 5657a05bf6c5405fe9f9b52e7ef2105cadd9587a [file] [log] [blame]
/*
Copyright 2005-2010 Intel Corporation. All Rights Reserved.
This file is part of Threading Building Blocks.
Threading Building Blocks is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
Threading Building Blocks is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Threading Building Blocks; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software
library without restriction. Specifically, if other files instantiate
templates or use macros or inline functions from this file, or you compile
this file and link it with other files to produce an executable, this
file does not by itself cause the resulting executable to be covered by
the GNU General Public License. This exception does not however
invalidate any other reasons why the executable file might be covered by
the GNU General Public License.
*/
/*
Game_of_life.cpp :
main project file.
*/
#include "Board.h"
#include "Form1.h"
#define WIN32_LEAN_AND_MEAN
#ifndef _CONSOLE
#include <windows.h>
#else
#include <iostream>
#include <sstream>
#include <time.h>
#include "Evolution.h"
#define BOARD_SQUARE_SIZE 2
int low; //! lower range limit of threads
int high; //! high range limit of threads
double execution_time; //! time for game of life iterations
#endif
Board::Board(int width, int height, int squareSize, LabelPtr counter)
: m_width(width), m_height(height), m_squareSize(squareSize), m_counter(counter)
{
#ifndef _CONSOLE
InitializeComponent();
DoubleBuffered = true;
this->Width = m_squareSize*width;
this->Height = m_squareSize*height;
#endif
m_matrix = new Matrix();
m_matrix->width = width;
m_matrix->height = height;
m_matrix->data = new char[width*height];
memset(m_matrix->data, 0, width*height);
#ifndef _CONSOLE
m_occupiedBrush = gcnew SolidBrush(Color::Black);
m_freeBrush = gcnew SolidBrush(Color::LightGray);
m_graphics = CreateGraphics();
m_bmp = gcnew Bitmap(Width, Height);
m_mem_dc = Graphics::FromImage(m_bmp);
#endif
}
Board::~Board()
{
#ifndef _CONSOLE
if (components)
{
delete components;
}
#endif
delete[] m_matrix->data;
delete m_matrix;
}
void Board::seed(int s)
{
srand(s);
for (int j=0; j<m_height; j++)
{
for (int i=0; i<m_width; i++)
{
int x = rand()/(int)(((unsigned)RAND_MAX + 1) / 100);
m_matrix->data[i+j*m_width] = x>75? 1: 0; // 25% occupied
}
}
#ifndef _CONSOLE
Invalidate();
#endif
}
void Board::seed( const BoardPtr src )
{
memcpy(m_matrix->data, src->m_matrix->data, m_height*m_width);
#ifndef _CONSOLE
Invalidate();
#endif
}
#ifndef _CONSOLE
void Board::draw(Graphics^ g)
{
m_mem_dc->FillRectangle(m_freeBrush, Drawing::Rectangle(0, 0, m_width*m_squareSize, m_height*m_squareSize));
for (int j=0; j<m_height; j++)
{
for (int i=0; i<m_width; i++)
{
if ( m_matrix->data[i+j*m_width] )
{
m_mem_dc->FillRectangle(m_occupiedBrush, Drawing::Rectangle(i*m_squareSize, j*m_squareSize, m_squareSize, m_squareSize));
}
}
}
g->DrawImage(m_bmp, 0, 0);
}
void Board::OnPaint(PaintEventArgs^ e)
{
draw(e->Graphics);
}
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}
#else
//! Print usage of this program
void PrintUsage()
{
printf("Usage: gol [M[:N] -t execution_time]\nM and N are a range of numbers of threads to be used.\nexecution_time is a time (in sec) for execution game_of_life iterations\n");
printf("Default values:\nM:\t\tautomatic\nN:\t\tM\nexecution_time:\t10\n");
}
//! Parse command line
bool ParseCommandLine(int argc, char * argv [])
{
char* s = argv[1];
char* end;
//! command line without parameters
if(argc == 1)
{
low = tbb::task_scheduler_init::automatic;
high = low;
execution_time = 5;
return true;
}
//! command line with parameters
if(argc != 4)
{
PrintUsage();
return false;
}
if(std::string("-t") != argv[argc-2])
//! process M[:N] parameter
high = strtol(s,&end,0);
low = strtol(s,&end,0);
switch( *end )
{
case ':':
high = strtol(end+1,0,0);
break;
case '\0':
break;
default:
PrintUsage();
return false;
}
if (high < low)
{
std::cout << "Set correct range. Current range: " << low << ":" << high << std::endl;
PrintUsage();
return false;
}
//! process execution_time parameter
execution_time = strtol(argv[argc-1],&end,0);
return true;
}
int main( int argc, char* argv[] )
{
if(!ParseCommandLine( argc, argv ))
return 1;
SequentialEvolution* m_seq;
ParallelEvolution* m_par;
Board* m_board1;
Board* m_board2;
int* count = NULL;
int boardWidth = 300;
int boardHeight = 300;
m_board1 = new Board(boardWidth, boardHeight, BOARD_SQUARE_SIZE, count);
m_board2 = new Board(boardWidth, boardHeight, BOARD_SQUARE_SIZE, count);
time_t now = time(NULL);
printf("Generate Game of life board\n");
m_board1->seed((int)now);
m_board2->seed(m_board1);
m_seq = new SequentialEvolution(m_board1->m_matrix, m_board1);
m_seq->Run(execution_time, 1);
delete m_seq;
m_par = new ParallelEvolution(m_board2->m_matrix, m_board2);
for( int p = low; p <= high; ++p )
{
m_par->Run(execution_time, p);
}
delete m_par;
delete m_board1;
delete m_board2;
return 0;
}
#endif