Is it okay to use a non standard library?
This is my first challenge so I don't know the rules.
Language is C++ and SFML for the graphics.
PHP Code:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <SFML/Graphics.hpp>
typedef std::vector< std::vector<char> > matrix_type;
struct Point
{
Point(int x = 0, int y = 0)
: x(x),y(y){}
int x;
int y;
};
int ToInt(const std::string& str)
{
std::istringstream is(str);
int x = 0;
is >> x;
return x;
}
void PrintMatrix(const matrix_type& matrix)
{
for(int i = 0; i < matrix.size(); ++i)
{
for(int j = 0; j < matrix[i].size(); ++j)
std::cout << matrix[i][j];
std::cout << "\n";
}
std::cout << "\n";
}
void LoadMatrix(matrix_type& matrix, std::ifstream& isfile)
{
for(int i = 0; i < matrix.size(); ++i)
for(int j = 0; j < matrix.size(); ++j)
isfile >> matrix[i][j];
}
const int PossibleMovements = 8;
const Point Movements[PossibleMovements] =
{
Point(1, 0), Point(-1, 0),
Point(0, 1), Point(0, -1),
Point(1, 1), Point(1, -1),
Point(-1, 1), Point(-1, -1)
};
enum State{Dead = '0', Alive = '1'};
void ChangeState(matrix_type& matrix, int row, int col, std::vector<Point>& changes)
{
int count = 0;
for(int i = 0; i < PossibleMovements; ++i)
{
int x = Movements[i].x + col;
int y = Movements[i].y + row;
if(x < 0 || y < 0 || x >= matrix.size() || y >= matrix.size() )
continue;
if(matrix[y][x] == Alive) ++count;
}
if(matrix[row][col] == Alive )
{
if(count < 2 || count > 3)
changes.push_back(Point(col, row) );
}
else if(count == 3)
changes.push_back( Point(col, row) );
}
void Pulse(matrix_type& matrix)
{
std::vector<Point> changes;
for(int i = 0; i < matrix.size(); ++i)
for(int j = 0; j < matrix.size(); ++j)
ChangeState(matrix, i, j, changes);
for(int i = 0; i < changes.size(); ++i)
{
char& c = (matrix[changes[i].y][changes[i].x]);
c = (c == '0') ? ('1') : ('0');
}
}
void CommandLine(matrix_type& matrix)
{
PrintMatrix(matrix);
while(std::cin.get())
{
Pulse(matrix);
PrintMatrix(matrix);
std::cout << "Enter - Next pulse\n";
}
}
void Graphics(matrix_type& matrix)
{
sf::RenderWindow app(sf::VideoMode(800, 600), "Life");
const int TileSize = 10;
sf::Clock timer;
while(app.IsOpened())
{
sf::Event event;
while(app.GetEvent(event))
if(event.Type == sf::Event::Closed)
app.Close();
app.Clear();
if(timer.GetElapsedTime() > 0.5f)
{
Pulse(matrix);
timer.Reset();
}
for(int i = 0; i < matrix.size(); ++i)
{
for(int j = 0; j < matrix.size(); ++j)
if(matrix[i][j] == Alive)
app.Draw(sf::Shape::Rectangle(TileSize * j, TileSize * i, TileSize, TileSize, sf::Color::Red));
}
app.Display();
}
}
void Run(matrix_type& matrix)
{
std::cout << "Graphics? [Y/N]: ";
char answer;
std::cin >> answer;
if(std::tolower(answer) == 'y')
Graphics(matrix);
else
CommandLine(matrix);
}
int main(int argc, char** argv)
{
if(argc < 3)
{
std::cout << "Usage: " << argv[0] << " <filename> <size>\n";
return 1;
}
std::ifstream isfile(argv[1]);
if(!isfile)
{
std::cout << "Error: bad filename\n";
return 1;
}
const int Size = ToInt(argv[2]);
matrix_type matrix(Size, std::vector<char>(Size));
LoadMatrix(matrix, isfile);
Run(matrix);
}
/*
CPP=g++
FLAGS=-Wall -Wextra -pedantic -ansi
LIBS=-lsfml2-graphics -lsfml2-window -lsfml2-system
Main: main.o
$(CPP) $(FLAGS) -o Main main.o $(LIBS)
Main.o: main.cpp
$(CPP) -c main.cpp
*/
Bookmarks