Grid and file reading
This commit is contained in:
		
							
								
								
									
										105
									
								
								src/life.cpp
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								src/life.cpp
									
									
									
									
									
								
							@@ -4,10 +4,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "grid.h"
 | 
					#include "grid.h"
 | 
				
			||||||
#include "lifeutil.h"
 | 
					#include "lifeutil.h"
 | 
				
			||||||
 | 
					#include "unistd.h"
 | 
				
			||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *const FORMAT_UNDERSCORE = "\033[4m";
 | 
				
			||||||
 | 
					const char *const END_FORMATTING = "\033[0m";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void printWelcome() {
 | 
					void printWelcome() {
 | 
				
			||||||
    std::cout << "Welcome to the TDDD86 Game of Life,\n"
 | 
					    std::cout << "Welcome to the TDDD86 Game of Life,\n"
 | 
				
			||||||
              << "a simulation of the lifecycle of a bacteria colony.\n"
 | 
					              << "a simulation of the lifecycle of a bacteria colony.\n"
 | 
				
			||||||
@@ -20,16 +24,19 @@ void printWelcome() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
std::string input(const char *message) {
 | 
					std::string input(const char *message) {
 | 
				
			||||||
    if (message != nullptr) {
 | 
					    if (message != nullptr) {
 | 
				
			||||||
        std::cout << message;
 | 
					        std::cout << message << FORMAT_UNDERSCORE;
 | 
				
			||||||
        std::flush(std::cout);
 | 
					        std::flush(std::cout);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    std::string ret;
 | 
					    std::string ret;
 | 
				
			||||||
    std::getline(std::cin, ret);
 | 
					    std::getline(std::cin, ret);
 | 
				
			||||||
 | 
					    if (message != nullptr)
 | 
				
			||||||
 | 
					        std::cout << END_FORMATTING;
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string readFile(const char *filePath) {
 | 
					bool fileExists(const char *fileName) { return access(fileName, 0) == 0; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string fileRead(const char *filePath) {
 | 
				
			||||||
    std::ifstream file(filePath, std::ios::binary);
 | 
					    std::ifstream file(filePath, std::ios::binary);
 | 
				
			||||||
    if (!file.is_open())
 | 
					    if (!file.is_open())
 | 
				
			||||||
        throw std::runtime_error("File couldn't be found");
 | 
					        throw std::runtime_error("File couldn't be found");
 | 
				
			||||||
@@ -45,8 +52,100 @@ std::string readFile(const char *filePath) {
 | 
				
			|||||||
    return content;
 | 
					    return content;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum UserAction { NO_ACTION, ACTION, TICK, QUIT };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UserAction askUserForAction() {
 | 
				
			||||||
 | 
					    std::string userInput = input("a)nimate, t)ick, q)uit? ");
 | 
				
			||||||
 | 
					    if (userInput == "a")
 | 
				
			||||||
 | 
					        return UserAction::ACTION;
 | 
				
			||||||
 | 
					    else if (userInput == "t")
 | 
				
			||||||
 | 
					        return UserAction::TICK;
 | 
				
			||||||
 | 
					    else if (userInput == "q")
 | 
				
			||||||
 | 
					        return UserAction::QUIT;
 | 
				
			||||||
 | 
					    return UserAction::NO_ACTION;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<std::string> split(const std::string &s, const char at) {
 | 
				
			||||||
 | 
					    std::vector<std::string> ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t last = 0, idx;
 | 
				
			||||||
 | 
					    while ((idx = s.find(at, last)) != std::string::npos) {
 | 
				
			||||||
 | 
					        std::string sub = s.substr(last, idx - last);
 | 
				
			||||||
 | 
					        ret.push_back(sub);
 | 
				
			||||||
 | 
					        last = idx + 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret.push_back(s.substr(last));
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Cell { ALIVE, DEAD };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
    printWelcome();
 | 
					    printWelcome();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string inputFile;
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
 | 
					        inputFile = input("Grid input file name? ");
 | 
				
			||||||
 | 
					        if (fileExists(inputFile.c_str()))
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        std::cout << "File '" << inputFile << "' doesn't exist!" << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::string fileContents;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        fileContents = fileRead(inputFile.c_str());
 | 
				
			||||||
 | 
					    } catch (std::exception &e) {
 | 
				
			||||||
 | 
					        std::cerr << "Failed to read file: " << e.what() << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::vector<std::string> lines = split(fileContents, '\n');
 | 
				
			||||||
 | 
					    if (lines.size() <= 2) {
 | 
				
			||||||
 | 
					        std::cerr << "No column, row header, in the file!" << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int columns, rows;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					        columns = std::stoi(lines[0]);
 | 
				
			||||||
 | 
					        rows = std::stoi(lines[1]);
 | 
				
			||||||
 | 
					    } catch (const std::invalid_argument &e) {
 | 
				
			||||||
 | 
					        std::cerr << "Column or row wasn't a number" << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    } catch (const std::out_of_range &e) {
 | 
				
			||||||
 | 
					        std::cerr << "Column or row was too large" << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (lines.size() - 2 < rows) {
 | 
				
			||||||
 | 
					        std::cerr << "There's less rows than described in the header!" << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid<Cell> grid(columns, rows);
 | 
				
			||||||
 | 
					    for (int x = 0; x < rows; x++) {
 | 
				
			||||||
 | 
					        std::string &row = lines[x];
 | 
				
			||||||
 | 
					        if (columns < row.size()) {
 | 
				
			||||||
 | 
					            std::cerr << "There's less columns, than described in the header!"
 | 
				
			||||||
 | 
					                      << std::endl;
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int y = 0; y < columns; y++) {
 | 
				
			||||||
 | 
					            char sign = row[y];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (sign) {
 | 
				
			||||||
 | 
					            case '-':
 | 
				
			||||||
 | 
					                grid.set(x, y, Cell::DEAD);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'X':
 | 
				
			||||||
 | 
					                grid.set(x, y, Cell::ALIVE);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                std::cerr << "Invalid option '" << sign << "' in grid description!"
 | 
				
			||||||
 | 
					                          << std::endl;
 | 
				
			||||||
 | 
					                return 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user