<commit_before>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#include <cstdio>
#include <nix.hpp>
#include <nix/NDArray.hpp>
#include <queue>
#include <random>
#include <type_traits>
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <stdexcept>

/* ************************************ */

class Stopwatch {

public:
    typedef std::chrono::high_resolution_clock::time_point time_point_t;
    typedef std::chrono::high_resolution_clock clock_t;

    Stopwatch() : t_start(clock_t::now()) { };

    ssize_t ms() {
        time_point_t t_end = clock_t::now();
        ssize_t count = std::chrono::duration_cast<std::chrono::milliseconds>(t_end - t_start).count();
        return count;
    }

private:
    time_point_t t_start;
};

/* ************************************ */

class RndGenBase {
public:
    RndGenBase() : rd(), rd_gen(rd()) { };

protected:
    std::random_device rd;
    std::mt19937 rd_gen;
};

template<typename T, typename Enable = void>
class RndGen { };

template<typename T>
class RndGen<T, typename std::enable_if<std::is_floating_point<T>::value >::type> : RndGenBase {
public:
    RndGen() : dis(-1024.0, +1024.0) { };

    T operator()(void) {
        return dis(rd_gen);
    };

private:
    std::uniform_real_distribution<T> dis;
};

template<typename T>
class RndGen<T, typename std::enable_if<std::is_integral<T>::value >::type> : RndGenBase {
public:
    RndGen() : dis(-1024, +1024) { };

    T operator()(void) {
        return dis(rd_gen);
    };

private:
    std::uniform_real_distribution<T> dis;
};

/* ************************************ */

template<typename T>
class BlockGenerator {
public:

    BlockGenerator(size_t blocksize, size_t bufsize) : blocksize(blocksize), bufsize(bufsize) { };

    std::vector<T> make_block() {
        std::vector<T> block(blocksize);
        std::generate(block.begin(), block.end(), std::ref(rnd_gen));
        return block;
    }

    std::vector<T> next_block() {
        std::unique_lock<std::mutex> lock(mtx);

        if (queue.empty()) {
            cnd.wait(lock, [this]{ return !queue.empty(); });
        }

        std::vector<T> x(std::move(queue.front()));
        queue.pop();
        cnd.notify_all();
        return x;
    }

    void worker_thread() {
        while (do_run) {
            std::unique_lock<std::mutex> lock(mtx);
            std::vector<T> block = make_block();

            if (queue.size() > bufsize) {
                //wait until there is room
                cnd.wait(lock, [this]{ return !do_run || queue.size() < bufsize;});
                if (!do_run) {
                    return;
                }
            }

            queue.push(std::move(block));
            cnd.notify_all();
        }
    }

    void start_worker() {
        workers.emplace_back(&BlockGenerator::worker_thread, this);
    }

    ~BlockGenerator() {
        do_run = false;
        cnd.notify_all();
        for (auto &w : workers) {
            w.join();
        }
    }

    double speed_test() {

        Stopwatch sw;

        size_t N = 100;
        size_t iterations = 0;

        do {
            Stopwatch inner;

            for (size_t i = 0; i < N; i++) {
                std::vector<double> block = next_block();
                iterations++;
            }

            if (inner.ms() < 100) {
                N *= 2;
            }

        } while (sw.ms() < 1000);

        ssize_t count = sw.ms();
        return iterations * blocksize * sizeof(T) * (1000.0/count) / (1024.0*1024.0);
    }

private:
    bool do_run = true;
    size_t blocksize;
    size_t bufsize;
    RndGen<T> rnd_gen;
    std::mutex mtx;
    std::condition_variable cnd;
    std::queue<std::vector<T>> queue;
    std::vector<std::thread> workers;
};

class Config {

public:
    Config(nix::DataType data_type, const nix::NDSize &blocksize)
            : data_type(data_type), block_size(blocksize) {

        sdim = find_single_dim();
        shape = blocksize;
        shape[sdim] = 0;

        make_name();
    };

    size_t find_single_dim() {
        size_t sdim;
        bool have_rdim = false;
        for (size_t i = 0; i < block_size.size(); i ++) {
            if (block_size[i] == 1) {
                sdim = i;
                have_rdim = true;
            }
        }

        if (!have_rdim) {
            throw std::runtime_error("Could not find singelton dimension");
        }
        return sdim;
    }

    nix::DataType dtype() const { return data_type; }
    const nix::NDSize& size() const { return block_size; }
    const nix::NDSize& extend() const { return shape; }
    size_t singleton_dimension() const { return sdim; }
    const std::string & name() const { return my_name; };

private:
    void make_name() {
        std::stringstream s;

        s << data_type << "@{ ";
        for (auto x : block_size) {
            s << x << " ";
        }
        s << "}";

        my_name = s.str();
    }

private:
    const nix::DataType data_type;
    const nix::NDSize block_size;

    size_t        sdim;
    nix::NDSize   shape;

    std::string   my_name;
};

class Benchmark {

public:
    Benchmark(const Config &cfg)
            : config(cfg) {
    };

    void test_write_io(nix::Block block) {
        block_id = block.id();

        nix::DataArray da = block.createDataArray(config.name(), "nix.test.da", config.dtype(), config.extend());
        dset_id = da.id();

        switch (config.dtype()) {

            case nix::DataType::Double:
                do_write_test<double>(da);
                break;

            default:
                throw std::runtime_error("Unsupported DataType!");
        }
    }

    void test_read_io(nix::File fd) {
        nix::Block block = fd.getBlock(block_id);
        nix::DataArray da = block.getDataArray(dset_id);

        speed_read = test_read_io(da);
    }

    double test_read_io(nix::DataArray da) {

        nix::NDArray array(config.dtype(), config.size());
        nix::NDSize extend = da.dataExtent();
        size_t N = extend[config.singleton_dimension()];

        nix::NDSize pos = {0, 0};

        ssize_t ms = time_it([this, &da, &N, &pos, &array] {
            for(size_t i = 0; i < N; i++) {
                da.getData(config.dtype(), array.data(), config.size(), pos);
                pos[config.singleton_dimension()] += 1;
            }
        });

        return calc_speed_mbs(ms, N);
    }

    void test_read_io_polynom(nix::File fd) {
        nix::Block block = fd.getBlock(block_id);
        nix::DataArray da = block.getDataArray(dset_id);

        da.polynomCoefficients({3, 4, 5, 6});

        speed_read_poly = test_read_io(da);
    }

    void report() {
        std::cout << config.name() << ": "
                << "G: " << speed_generator << " MB/s, "
                << "W: " << speed_write << " MB/s, "
                << "R: " << speed_read << " MB/s, "
                << "P: " << speed_read_poly << " MB/s" << std::endl;
    }

    template<typename F>
    ssize_t time_it(F func) {
        Stopwatch watch;
        func();
        return watch.ms();
    }

private:
    template<typename T>
    void do_write_test(nix::DataArray da) {
        size_t nelms = config.size().nelms();
        BlockGenerator<T> generator(nelms, 10);
        generator.start_worker();
        speed_generator = generator.speed_test();

        size_t N = 100;
        size_t iterations = 0;

        nix::NDSize pos = {0, 0};
        Stopwatch sw;
        ssize_t ms = 0;
        do {
            Stopwatch inner;

            for (size_t i = 0; i < N; i++) {
                std::vector<T> block = generator.next_block();
                da.dataExtent(config.size() + pos);
                da.setData(config.dtype(), block.data(), config.size(), pos);
                pos[config.singleton_dimension()] += 1;
                iterations++;
            }

            if (inner.ms() < 100) {
                N *= 2;
            }

        } while ((ms = sw.ms()) < 3*1000);
        speed_write = calc_speed_mbs(ms, iterations);
    }

    double calc_speed_mbs(ssize_t ms, size_t iterations) {
        return iterations * config.size().nelms() * nix::data_type_to_size(config.dtype()) * (1000.0/ms) /
                (1024.0*1024.0);
    }

private:

    const Config config;

    std::string   dset_id;
    std::string   block_id;

    double        speed_write;
    double        speed_read;
    double        speed_generator;
    double        speed_read_poly;
};

/* ************************************ */

static std::vector<Benchmark> make_benchmarks() {
    std::vector<Benchmark> marks;

    //TODO: auto-generate
    marks.emplace_back(Config(nix::DataType::Double, nix::NDSize{2048, 1}));
    marks.emplace_back(Config(nix::DataType::Double, nix::NDSize{1, 2048}));

    return marks;
}

int main(int argc, char **argv)
{
    nix::File fd = nix::File::open("iospeed.h5", nix::FileMode::Overwrite);
    nix::Block block = fd.createBlock("speed", "nix.test");

    std::vector<Benchmark> marks = make_benchmarks();

    std::cout << "Performing write tests..." << std::endl;
    for (Benchmark &mark : marks) {
        mark.test_write_io(block);
    }

    std::cout << "Performing read tests..." << std::endl;
    for (Benchmark &mark : marks) {
        mark.test_read_io(fd);
    }

    std::cout << "Performing read (poly) tests..." << std::endl;
    for (Benchmark &mark : marks) {
        mark.test_read_io_polynom(fd);
    }

    std::cout << " === Reports ===" << std::endl;
    for (Benchmark &mark : marks) {
        mark.report();
    }

    return 0;
}
<commit_msg>[test] Benchmark: extract Benchmark base class<commit_after>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#include <cstdio>
#include <nix.hpp>
#include <nix/NDArray.hpp>
#include <queue>
#include <random>
#include <type_traits>
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <stdexcept>

/* ************************************ */

class Stopwatch {

public:
    typedef std::chrono::high_resolution_clock::time_point time_point_t;
    typedef std::chrono::high_resolution_clock clock_t;

    Stopwatch() : t_start(clock_t::now()) { };

    ssize_t ms() {
        time_point_t t_end = clock_t::now();
        ssize_t count = std::chrono::duration_cast<std::chrono::milliseconds>(t_end - t_start).count();
        return count;
    }

private:
    time_point_t t_start;
};

/* ************************************ */

class RndGenBase {
public:
    RndGenBase() : rd(), rd_gen(rd()) { };

protected:
    std::random_device rd;
    std::mt19937 rd_gen;
};

template<typename T, typename Enable = void>
class RndGen { };

template<typename T>
class RndGen<T, typename std::enable_if<std::is_floating_point<T>::value >::type> : RndGenBase {
public:
    RndGen() : dis(-1024.0, +1024.0) { };

    T operator()(void) {
        return dis(rd_gen);
    };

private:
    std::uniform_real_distribution<T> dis;
};

template<typename T>
class RndGen<T, typename std::enable_if<std::is_integral<T>::value >::type> : RndGenBase {
public:
    RndGen() : dis(-1024, +1024) { };

    T operator()(void) {
        return dis(rd_gen);
    };

private:
    std::uniform_real_distribution<T> dis;
};

/* ************************************ */

template<typename T>
class BlockGenerator {
public:

    BlockGenerator(size_t blocksize, size_t bufsize) : blocksize(blocksize), bufsize(bufsize) { };

    std::vector<T> make_block() {
        std::vector<T> block(blocksize);
        std::generate(block.begin(), block.end(), std::ref(rnd_gen));
        return block;
    }

    std::vector<T> next_block() {
        std::unique_lock<std::mutex> lock(mtx);

        if (queue.empty()) {
            cnd.wait(lock, [this]{ return !queue.empty(); });
        }

        std::vector<T> x(std::move(queue.front()));
        queue.pop();
        cnd.notify_all();
        return x;
    }

    void worker_thread() {
        while (do_run) {
            std::unique_lock<std::mutex> lock(mtx);
            std::vector<T> block = make_block();

            if (queue.size() > bufsize) {
                //wait until there is room
                cnd.wait(lock, [this]{ return !do_run || queue.size() < bufsize;});
                if (!do_run) {
                    return;
                }
            }

            queue.push(std::move(block));
            cnd.notify_all();
        }
    }

    void start_worker() {
        workers.emplace_back(&BlockGenerator::worker_thread, this);
    }

    ~BlockGenerator() {
        do_run = false;
        cnd.notify_all();
        for (auto &w : workers) {
            w.join();
        }
    }

    double speed_test() {

        Stopwatch sw;

        size_t N = 100;
        size_t iterations = 0;

        do {
            Stopwatch inner;

            for (size_t i = 0; i < N; i++) {
                std::vector<double> block = next_block();
                iterations++;
            }

            if (inner.ms() < 100) {
                N *= 2;
            }

        } while (sw.ms() < 1000);

        ssize_t count = sw.ms();
        return iterations * blocksize * sizeof(T) * (1000.0/count) / (1024.0*1024.0);
    }

private:
    bool do_run = true;
    size_t blocksize;
    size_t bufsize;
    RndGen<T> rnd_gen;
    std::mutex mtx;
    std::condition_variable cnd;
    std::queue<std::vector<T>> queue;
    std::vector<std::thread> workers;
};

class Config {

public:
    Config(nix::DataType data_type, const nix::NDSize &blocksize)
            : data_type(data_type), block_size(blocksize) {

        sdim = find_single_dim();
        shape = blocksize;
        shape[sdim] = 0;

        make_name();
    };

    size_t find_single_dim() {
        size_t sdim;
        bool have_rdim = false;
        for (size_t i = 0; i < block_size.size(); i ++) {
            if (block_size[i] == 1) {
                sdim = i;
                have_rdim = true;
            }
        }

        if (!have_rdim) {
            throw std::runtime_error("Could not find singelton dimension");
        }
        return sdim;
    }

    nix::DataType dtype() const { return data_type; }
    const nix::NDSize& size() const { return block_size; }
    const nix::NDSize& extend() const { return shape; }
    size_t singleton_dimension() const { return sdim; }
    const std::string & name() const { return my_name; };

private:
    void make_name() {
        std::stringstream s;

        s << data_type << "@{ ";
        for (auto x : block_size) {
            s << x << " ";
        }
        s << "}";

        my_name = s.str();
    }

private:
    const nix::DataType data_type;
    const nix::NDSize block_size;

    size_t        sdim;
    nix::NDSize   shape;

    std::string   my_name;
};

class Benchmark {
public:
    Benchmark(const Config &cfg) : config(cfg) { }
    const Config & cfg() const { return config; }

    virtual ~Benchmark() { }

    double speed_in_mbs() {
        return count * config.size().nelms() * nix::data_type_to_size(config.dtype()) *
                (1000.0/millis) / (1024 * 1024);
    }

    template<typename F>
    ssize_t time_it(F func) {
        Stopwatch watch;
        func();
        return watch.ms();
    }

protected:
    const Config config;
    size_t       count;
    double       millis;
};

class IOBenchmark : Benchmark {

public:
    IOBenchmark(const Config &cfg)
            : Benchmark(cfg) {
    };

    void test_write_io(nix::Block block) {
        block_id = block.id();

        nix::DataArray da = block.createDataArray(config.name(), "nix.test.da", config.dtype(), config.extend());
        dset_id = da.id();

        switch (config.dtype()) {

            case nix::DataType::Double:
                do_write_test<double>(da);
                break;

            default:
                throw std::runtime_error("Unsupported DataType!");
        }
    }

    void test_read_io(nix::File fd) {
        nix::Block block = fd.getBlock(block_id);
        nix::DataArray da = block.getDataArray(dset_id);

        speed_read = test_read_io(da);
    }

    double test_read_io(nix::DataArray da) {

        nix::NDArray array(config.dtype(), config.size());
        nix::NDSize extend = da.dataExtent();
        size_t N = extend[config.singleton_dimension()];

        nix::NDSize pos = {0, 0};

        ssize_t ms = time_it([this, &da, &N, &pos, &array] {
            for(size_t i = 0; i < N; i++) {
                da.getData(config.dtype(), array.data(), config.size(), pos);
                pos[config.singleton_dimension()] += 1;
            }
        });

        return calc_speed_mbs(ms, N);
    }

    void test_read_io_polynom(nix::File fd) {
        nix::Block block = fd.getBlock(block_id);
        nix::DataArray da = block.getDataArray(dset_id);

        da.polynomCoefficients({3, 4, 5, 6});

        speed_read_poly = test_read_io(da);
    }

    void report() {
        std::cout << config.name() << ": "
                << "G: " << speed_generator << " MB/s, "
                << "W: " << speed_write << " MB/s, "
                << "R: " << speed_read << " MB/s, "
                << "P: " << speed_read_poly << " MB/s" << std::endl;
    }

private:
    template<typename T>
    void do_write_test(nix::DataArray da) {
        size_t nelms = config.size().nelms();
        BlockGenerator<T> generator(nelms, 10);
        generator.start_worker();
        speed_generator = generator.speed_test();

        size_t N = 100;
        size_t iterations = 0;

        nix::NDSize pos = {0, 0};
        Stopwatch sw;
        ssize_t ms = 0;
        do {
            Stopwatch inner;

            for (size_t i = 0; i < N; i++) {
                std::vector<T> block = generator.next_block();
                da.dataExtent(config.size() + pos);
                da.setData(config.dtype(), block.data(), config.size(), pos);
                pos[config.singleton_dimension()] += 1;
                iterations++;
            }

            if (inner.ms() < 100) {
                N *= 2;
            }

        } while ((ms = sw.ms()) < 3*1000);
        speed_write = calc_speed_mbs(ms, iterations);
    }

    double calc_speed_mbs(ssize_t ms, size_t iterations) {
        return iterations * config.size().nelms() * nix::data_type_to_size(config.dtype()) * (1000.0/ms) /
                (1024.0*1024.0);
    }

private:
    std::string   dset_id;
    std::string   block_id;

    double        speed_write;
    double        speed_read;
    double        speed_generator;
    double        speed_read_poly;
};

/* ************************************ */

static std::vector<IOBenchmark> make_benchmarks() {
    std::vector<IOBenchmark> marks;

    //TODO: auto-generate
    marks.emplace_back(Config(nix::DataType::Double, nix::NDSize{2048, 1}));
    marks.emplace_back(Config(nix::DataType::Double, nix::NDSize{1, 2048}));

    return marks;
}

int main(int argc, char **argv)
{
    nix::File fd = nix::File::open("iospeed.h5", nix::FileMode::Overwrite);
    nix::Block block = fd.createBlock("speed", "nix.test");

    std::vector<IOBenchmark> marks = make_benchmarks();

    std::cout << "Performing write tests..." << std::endl;
    for (IOBenchmark &mark : marks) {
        mark.test_write_io(block);
    }

    std::cout << "Performing read tests..." << std::endl;
    for (IOBenchmark &mark : marks) {
        mark.test_read_io(fd);
    }

    std::cout << "Performing read (poly) tests..." << std::endl;
    for (IOBenchmark &mark : marks) {
        mark.test_read_io_polynom(fd);
    }

    std::cout << " === Reports ===" << std::endl;
    for (IOBenchmark &mark : marks) {
        mark.report();
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <catch.hpp>
#include "../ris_lib/ris_late.h"

#include <unordered_map>
#include <sstream>

typedef std::unordered_map<std::string, std::string> default_context_t;

TEST_CASE("splitting along simple mustache tags and skipping others") {
    const char* temp = R"(Hello {{name}}
You have just won {{value }} dollars!
{{#in_ca}}
    Well, {{ taxed_value }} dollars, after taxes.
{{/in_ca}}
)";

    const char* expected = R"(Hello John
You have just won 33 dollars!

    Well, 42 dollars, after taxes.

)";

    default_context_t context {
        { "name", "John" },
        { "taxed_value", "42" },
        { "value", "33" }
    };

    std::stringstream output;
    ris::render(temp, context, output);

    std::string output_str(output.str());
    CHECK(output_str == expected);
}

TEST_CASE("newlines are preserved and non-variables are ignored") {
    std::stringstream output;
    default_context_t context;
    ris::render("\n{{#a}}\n", context, output);

    CHECK(output.str() == "\n\n");
}

TEST_CASE("spaces in tags are allowed") {
    std::stringstream output;
    default_context_t context{
        { "a", "42" }
    };
    ris::render("{{a}}{{  a   }}", context, output);

    CHECK(output.str() == "4242");
}

TEST_CASE("empty templates are ok") {
    std::stringstream output;
    default_context_t context;
    REQUIRE_NOTHROW(ris::render("", context, output));

    CHECK(output.str() == "");
}
<commit_msg>confusion avoidance tests<commit_after>#include <catch.hpp>
#include "../ris_lib/ris_late.h"

#include <unordered_map>
#include <sstream>

typedef std::unordered_map<std::string, std::string> default_context_t;

TEST_CASE("splitting along simple mustache tags and skipping others") {
    const char* temp = R"(Hello {{name}}
You have just won {{value }} dollars!
{{#in_ca}}
    Well, {{ taxed_value }} dollars, after taxes.
{{/in_ca}}
)";

    const char* expected = R"(Hello John
You have just won 33 dollars!

    Well, 42 dollars, after taxes.

)";

    default_context_t context {
        { "name", "John" },
        { "taxed_value", "42" },
        { "value", "33" }
    };

    std::stringstream output;
    ris::render(temp, context, output);

    std::string output_str(output.str());
    CHECK(output_str == expected);
}

TEST_CASE("newlines are preserved and non-variables are ignored") {
    std::stringstream output;
    default_context_t context;
    ris::render("\n{{#a}}\n", context, output);

    CHECK(output.str() == "\n\n");
}

TEST_CASE("spaces in tags are allowed") {
    std::stringstream output;
    default_context_t context{
        { "a", "42" }
    };
    ris::render("{{a}}{{  a   }}", context, output);

    CHECK(output.str() == "4242");
}

TEST_CASE("empty templates are ok") {
    std::stringstream output;
    default_context_t context;
    REQUIRE_NOTHROW(ris::render("", context, output));

    CHECK(output.str() == "");
}

TEST_CASE("confusion avoidance") {
    std::stringstream output;
    default_context_t context;
    ris::render("{{{a}}", context, output);

    CHECK(output.str() == "{");

    output.str("");
    ris::render("{{{a }}}", context, output);
    CHECK(output.str() == "{}");
}
<|endoftext|>


<commit_before>//#include "closedlist.hpp"
#include "plat2d.hpp"
#include "../search/main.hpp"
#include "../utils/utils.hpp"
#include <cstdio>
#include <cerrno>

const char *lvl = NULL;

static void parseargs(int, const char*[]);

int main(int argc, const char *argv[]) {
	parseargs(argc, argv);

	FILE *infile = stdin;
	if (lvl) {
		infile = fopen(lvl, "r");
		if (!infile)
			fatalx(errno, "Failed to open %s for reading", lvl);
		dfpair(stdout, "level", "%s", lvl);
	}

	Plat2d d(infile);
	if (infile != stdin)
		fclose(infile);

	Result<Plat2d> res = search<Plat2d>(d, argc, argv);

	std::vector<unsigned int> controls;
	Player p(2 * Tile::Width + Player::Offx, 2 * Tile::Height + Player::Offy,
		0, Player::Width, Player::Height);
	for (int i = res.ops.size() - 1; i >= 0; i--) {
		controls.push_back(res.ops[i]);
		p.act(d.level(), res.ops[i]);
		assert(p == res.path[i].player);
	}
	const Player &final = res.path[0].player;
	assert(d.level().majorblk(final.body.z, final.body.bbox).tile.flags &
			Tile::Down);

	dfpair(stdout, "final x loc", "%g", final.body.bbox.min.x);
	dfpair(stdout, "final y loc", "%g", final.body.bbox.min.y);
	dfpair(stdout, "controls", "%s", controlstr(controls).c_str());

	return 0;
}

static void parseargs(int argc, const char *argv[]) {
	for (int i = 1; i < argc; i++) {
		if (i < argc - 1 && strcmp(argv[i], "-lvl") == 0)
			lvl = argv[++i];
	}
}
<commit_msg>plat2d: don't use the closed list for now. This needs some more thought to make sure that hashing is fast and such.<commit_after>#include "closedlist.hpp"
#include "../search/main.hpp"
#include "../utils/utils.hpp"
#include <cstdio>
#include <cerrno>

const char *lvl = NULL;

static void parseargs(int, const char*[]);

int main(int argc, const char *argv[]) {
	parseargs(argc, argv);

	FILE *infile = stdin;
	if (lvl) {
		infile = fopen(lvl, "r");
		if (!infile)
			fatalx(errno, "Failed to open %s for reading", lvl);
		dfpair(stdout, "level", "%s", lvl);
	}

	Plat2d d(infile);
	if (infile != stdin)
		fclose(infile);

	Result<Plat2d> res = search<Plat2d>(d, argc, argv);

	std::vector<unsigned int> controls;
	Player p(2 * Tile::Width + Player::Offx, 2 * Tile::Height + Player::Offy,
		0, Player::Width, Player::Height);
	for (int i = res.ops.size() - 1; i >= 0; i--) {
		controls.push_back(res.ops[i]);
		p.act(d.level(), res.ops[i]);
		assert(p == res.path[i].player);
	}
	const Player &final = res.path[0].player;
	assert(d.level().majorblk(final.body.z, final.body.bbox).tile.flags &
			Tile::Down);

	dfpair(stdout, "final x loc", "%g", final.body.bbox.min.x);
	dfpair(stdout, "final y loc", "%g", final.body.bbox.min.y);
	dfpair(stdout, "controls", "%s", controlstr(controls).c_str());

	return 0;
}

static void parseargs(int argc, const char *argv[]) {
	for (int i = 1; i < argc; i++) {
		if (i < argc - 1 && strcmp(argv[i], "-lvl") == 0)
			lvl = argv[++i];
	}
}
<|endoftext|>


<commit_before>#define cimg_display 0
#include <stdlib.h>
#include <pthread.h>
#include "CImg.h"
using namespace cimg_library;

#include <list>
#include <string>
#include <algorithm>
using namespace std;

#if !cimg_display
#include <mug.h>
#endif

#define ROUND_NUM   10
#define SCR_WIDTH   16
#define SCR_HEIGHT  12

#define MOLE_COL    4
#define MOLE_ROW    3

#define MOLE_MAX    (MOLE_COL * MOLE_ROW)

#define MOLE_WIDTH  (SCR_WIDTH  / MOLE_COL)
#define MOLE_HEIGHT (SCR_HEIGHT / MOLE_ROW)

#define MOLE_PIC      "mole.bmp"
#define MOLE_HIT_PIC  "mole_hit.bmp"

typedef unsigned char * color_t;

CImg<unsigned char> canvas(SCR_WIDTH, SCR_HEIGHT, 1, 3, 0);
CImg<unsigned char> mole_pic;
CImg<unsigned char> mole_hit_pic;

class mole_t
{
  public:
    int idx;
    int col, row;
    int width, height;
    bool touched;

    mole_t(int i);
    mole_t(int c, int w);
};

typedef list<mole_t> mole_list_t;

mole_t::mole_t(int i)
{
  idx = i;
  width = MOLE_WIDTH;
  height = MOLE_HEIGHT;
  col = idx % MOLE_COL * MOLE_WIDTH;
  row = idx / MOLE_COL * MOLE_HEIGHT;
  touched = false;
}

mole_t::mole_t(int c, int w)
{
  idx = -1;
  width = mole_pic.width();
  height = mole_pic.height();

  col = c;
  row = w;
}

class score_t
{
  public:
    int touched;
    int all;
    void reset();
};

void score_t::reset()
{
  touched = 0;
  all = 0;
}

pthread_mutex_t mutex;

void my_lock()
{
  static int i = 0;
  pthread_mutex_lock(&mutex);
  printf("locked %d\n", i++);
}

void my_unlock()
{
  static int i = 0;
  pthread_mutex_unlock(&mutex);
  printf("unlocked %d\n", i++);
}

#define LOCK_  pthread_mutex_lock(&mutex)
#define UNLOCK_  pthread_mutex_unlock(&mutex)
//#define LOCK_ my_lock()
//#define UNLOCK_ my_unlock()
mole_list_t mole_list;
score_t     score;
int         round_num = ROUND_NUM;
#if !cimg_display
handle_t    disp_handle;
#endif
handle_t    touch_handle;

void draw_mole(mole_t *mole, CImg<unsigned char> *pic)
{
  canvas.draw_image(mole->col, mole->row, 0, 0,
                    *pic);
}

void draw_all(CImg<unsigned char> *pic)
{
  for(mole_list_t::iterator itr = mole_list.begin();
      itr != mole_list.end();
      itr++) {
    draw_mole(&(*itr), pic);
  }
}

void save_canvas(int i)
{
  char fname[256];

  sprintf(fname, "save_%d.bmp", i);

  canvas.save(fname);
}

#if cimg_display
void disp_canvas()
{
  CImgDisplay draw_disp(canvas, "mole");

  while(!draw_disp.is_closed()) {
    draw_disp.wait();
  }
}
#else
void disp_canvas()
{
  mug_disp_cimg(disp_handle, &canvas);
}
#endif

void clear_canvas()
{
  canvas.draw_rectangle(0, 0, 0,
                        SCR_WIDTH, SCR_HEIGHT, 0,
                        black);

}

mole_t* is_in(int c, int r)
{
  for(mole_list_t::iterator itr = mole_list.begin();
      itr != mole_list.end();
      itr++) {
    if(   (*itr).col <= c && c < (*itr).col + (*itr).width
       && (*itr).row <= r && r < (*itr).row + (*itr).height) {
      return &(*itr);
    }
  }

  return NULL;
}

void gen_round_mole(int *x, int *y)
{
}

void next_round(int num)
{
  LOCK_;

  printf("-------\n");
  clear_canvas();
  mole_list.clear();
  score.all += num;

  int col = rand() % (SCR_WIDTH  - mole_pic.width());
  int row = rand() % (SCR_HEIGHT - mole_pic.height());

  for(int i = 0; i < num; i++) {
    while(is_in(col, row)) {
      col = rand() % (SCR_WIDTH  - mole_pic.width());
      row = rand() % (SCR_HEIGHT - mole_pic.height());
    }
    printf("(%d, %d)\n", col, row);
    mole_t mole(col, row);
    mole_list.push_back(mole);
  }

  draw_all(&mole_pic);

  disp_canvas();

  UNLOCK_;
}

void show_result()
{
  printf("%d / %d\n", score.touched, score.all);

  clear_canvas();

  int width, height;
  mug_number_text_shape(&width, &height);

  char temp[4];
  sprintf(temp, "%02d", score.touched);
  mug_draw_number_cimg(&canvas, 0, 0, temp, red);

  sprintf(temp, "%02d", score.all);
  mug_draw_number_cimg(&canvas, width * 2 , 0, temp, green);

  disp_canvas();
}

void touch_on(int x, int y, int id)
{
  if(id != 0) return;
  LOCK_;

  mole_t *mole;
  bool changed = false;

  mole = is_in(x, y);

  if(mole && !mole->touched) {
    changed = true;
    mole->touched = true;
    score.touched++;
    printf("(%d, %d) -> (%d, %d)\n", x, y, mole->col, mole->row);
    draw_mole(mole, &mole_hit_pic);
  }

  if(changed)
    disp_canvas();

  UNLOCK_;
}

void *touch_thread(void *arg)
{
  mug_run_touch_thread(touch_handle);
}

void init()
{

  string proc_dir(get_proc_dir());

  mole_pic.load((proc_dir + "/" +  MOLE_PIC).c_str());
  mole_hit_pic.load((proc_dir + "/" +  MOLE_HIT_PIC).c_str());
  pthread_mutex_init(&mutex, NULL);

#if !cimg_display
  disp_handle = mug_disp_init();
  touch_handle = mug_touch_init();
  mug_touch_on(touch_handle, touch_on);

#ifdef USE_LIBUV
  pthread_t hdl;
  pthread_create(&hdl, NULL, touch_thread, NULL);
#else
  mug_run_touch_thread();
#endif

#endif

}

void finish()
{
  mug_stop_touch_thread(touch_handle);
  pthread_mutex_destroy(&mutex);
}

int main(int argc, char **argv)
{
  if(argc == 2) {
    round_num = atoi(argv[1]);
  }

  init();

  for(int i = 0; i < round_num; i++) {
    next_round(2);
    usleep(1000*1000);
  }

  show_result();

  finish();
}
<commit_msg>- added welcome display to mole<commit_after>#define cimg_display 0
#include <stdlib.h>
#include <pthread.h>
#include "CImg.h"
using namespace cimg_library;

#include <list>
#include <string>
#include <algorithm>
using namespace std;

#if !cimg_display
#include <mug.h>
#endif

#define ROUND_NUM   10
#define SCR_WIDTH   16
#define SCR_HEIGHT  12

#define MOLE_COL    4
#define MOLE_ROW    3

#define MOLE_MAX    (MOLE_COL * MOLE_ROW)

#define MOLE_WIDTH  (SCR_WIDTH  / MOLE_COL)
#define MOLE_HEIGHT (SCR_HEIGHT / MOLE_ROW)

#define MOLE_PIC      "mole.bmp"
#define MOLE_HIT_PIC  "mole_hit.bmp"

typedef unsigned char * color_t;

CImg<unsigned char> canvas(SCR_WIDTH, SCR_HEIGHT, 1, 3, 0);
CImg<unsigned char> mole_pic;
CImg<unsigned char> mole_hit_pic;

class mole_t
{
  public:
    int idx;
    int col, row;
    int width, height;
    bool touched;

    mole_t(int i);
    mole_t(int c, int w);
};

typedef list<mole_t> mole_list_t;

mole_t::mole_t(int i)
{
  idx = i;
  width = MOLE_WIDTH;
  height = MOLE_HEIGHT;
  col = idx % MOLE_COL * MOLE_WIDTH;
  row = idx / MOLE_COL * MOLE_HEIGHT;
  touched = false;
}

mole_t::mole_t(int c, int w)
{
  idx = -1;
  width = mole_pic.width();
  height = mole_pic.height();

  col = c;
  row = w;
}

class score_t
{
  public:
    int touched;
    int all;
    void reset();
};

void score_t::reset()
{
  touched = 0;
  all = 0;
}

pthread_mutex_t mutex;

void my_lock()
{
  static int i = 0;
  pthread_mutex_lock(&mutex);
  printf("locked %d\n", i++);
}

void my_unlock()
{
  static int i = 0;
  pthread_mutex_unlock(&mutex);
  printf("unlocked %d\n", i++);
}

#define LOCK_  pthread_mutex_lock(&mutex)
#define UNLOCK_  pthread_mutex_unlock(&mutex)
//#define LOCK_ my_lock()
//#define UNLOCK_ my_unlock()
mole_list_t mole_list;
score_t     score;
int         round_num = ROUND_NUM;
#if !cimg_display
handle_t    disp_handle;
#endif
handle_t    touch_handle;

void draw_mole(mole_t *mole, CImg<unsigned char> *pic)
{
  canvas.draw_image(mole->col, mole->row, 0, 0,
                    *pic);
}

void draw_all(CImg<unsigned char> *pic)
{
  for(mole_list_t::iterator itr = mole_list.begin();
      itr != mole_list.end();
      itr++) {
    draw_mole(&(*itr), pic);
  }
}

void save_canvas(int i)
{
  char fname[256];

  sprintf(fname, "save_%d.bmp", i);

  canvas.save(fname);
}

#if cimg_display
void disp_canvas()
{
  CImgDisplay draw_disp(canvas, "mole");

  while(!draw_disp.is_closed()) {
    draw_disp.wait();
  }
}
#else
void disp_canvas()
{
  mug_disp_cimg(disp_handle, &canvas);
}
#endif

void clear_canvas()
{
  canvas.draw_rectangle(0, 0, 0,
                        SCR_WIDTH, SCR_HEIGHT, 0,
                        black);

}

mole_t* is_in(int c, int r)
{
  for(mole_list_t::iterator itr = mole_list.begin();
      itr != mole_list.end();
      itr++) {
    if(   (*itr).col <= c && c < (*itr).col + (*itr).width
       && (*itr).row <= r && r < (*itr).row + (*itr).height) {
      return &(*itr);
    }
  }

  return NULL;
}

void gen_round_mole(int *x, int *y)
{
}

void next_round(int num)
{
  LOCK_;

  printf("-------\n");
  clear_canvas();
  mole_list.clear();
  score.all += num;

  int col = rand() % (SCR_WIDTH  - mole_pic.width());
  int row = rand() % (SCR_HEIGHT - mole_pic.height());

  for(int i = 0; i < num; i++) {
    while(is_in(col, row)) {
      col = rand() % (SCR_WIDTH  - mole_pic.width());
      row = rand() % (SCR_HEIGHT - mole_pic.height());
    }
    printf("(%d, %d)\n", col, row);
    mole_t mole(col, row);
    mole_list.push_back(mole);
  }

  draw_all(&mole_pic);

  disp_canvas();

  UNLOCK_;
}

void show_result()
{
  printf("%d / %d\n", score.touched, score.all);

  clear_canvas();

  int width, height;
  mug_number_text_shape(&width, &height);

  char temp[4];
  sprintf(temp, "%02d", score.touched);
  mug_draw_number_cimg(&canvas, 0, 0, temp, red);

  sprintf(temp, "%02d", score.all);
  mug_draw_number_cimg(&canvas, width * 2 , 0, temp, green);

  disp_canvas();
}

void touch_on(int x, int y, int id)
{
  if(id != 0) return;
  LOCK_;

  mole_t *mole;
  bool changed = false;

  mole = is_in(x, y);

  if(mole && !mole->touched) {
    changed = true;
    mole->touched = true;
    score.touched++;
    printf("(%d, %d) -> (%d, %d)\n", x, y, mole->col, mole->row);
    draw_mole(mole, &mole_hit_pic);
  }

  if(changed)
    disp_canvas();

  UNLOCK_;
}

void *touch_thread(void *arg)
{
  mug_run_touch_thread(touch_handle);
}

void init()
{

  string proc_dir(get_proc_dir());

  mole_pic.load((proc_dir + "/" +  MOLE_PIC).c_str());
  mole_hit_pic.load((proc_dir + "/" +  MOLE_HIT_PIC).c_str());
  pthread_mutex_init(&mutex, NULL);

#if !cimg_display
  disp_handle = mug_disp_init();
  touch_handle = mug_touch_init();
  mug_touch_on(touch_handle, touch_on);

#ifdef USE_LIBUV
  pthread_t hdl;
  pthread_create(&hdl, NULL, touch_thread, NULL);
#else
  mug_run_touch_thread();
#endif

#endif

}

void finish()
{
  mug_stop_touch_thread(touch_handle);
  pthread_mutex_destroy(&mutex);
}

int main(int argc, char **argv)
{
  if(argc == 2) {
    round_num = atoi(argv[1]);
  }

  init();

  clear_canvas();
  canvas.draw_text(0, 0, "ok?", yellow, 1.0, 6);
  disp_canvas();
  usleep(1000 * 1000);

  clear_canvas();
  canvas.draw_text(0, 0, "GO!", magenta, 1.0, 6);
  disp_canvas();
  usleep(1000 * 1000);

  for(int i = 0; i < round_num; i++) {
    next_round(2);
    usleep(1000*1000);
  }

  show_result();

  finish();
}
<|endoftext|>


<commit_before>#include <iostream>
#include "AADate.h"
#include "sexagesimal.h"
#include "AACoordinateTransformation.h"
#include "AA3DCoordinate.h"
#include "solar_system.h"
#include "AAParallax.h"
#include "AAGlobe.h"
#include "AASidereal.h"
#include <cmath>
#include "binary_tidbits.h"
#include "horizontal_parallax.h"

using std::cout;
using std::endl;

/*
   Write up the caculationa again, this time returning the Coordinates, not the Delta Coordinates.
 */
CAA2DCoordinate Equatorial2TopocentricRigorousVerbose(double Alpha, double Delta, double Distance, double Longitude, double Latitude, double Height, double JD){
  // g_AAParallax_C1 is a constant and probably shouldn't be repetitively defined.
  double g_AAParallax_C1 = sin(CAACoordinateTransformation::DegreesToRadians(CAACoordinateTransformation::DMSToDegrees(0, 0, 8.794)));

  double RhoSinThetaPrime = CAAGlobe::RhoSinThetaPrime(Latitude, Height);
  double RhoCosThetaPrime = CAAGlobe::RhoCosThetaPrime(Latitude, Height);

  const double declination_degrees_geocentric = Delta;
  printf( "\nApril 4, 2015 New Code:\n");
  printf( "declination_degrees_geocentric = %18.9lf\n", declination_degrees_geocentric);
  printf( "              RhoSinThetaPrime = %18.9lf\n", RhoSinThetaPrime);
  printf( "              RhoCosThetaPrime = %18.9lf\n", RhoCosThetaPrime);

  //Calculate the Sidereal time
  double theta = CAASidereal::ApparentGreenwichSiderealTime(JD);
  printf( "           theta = %18.9lf\n", theta);
  cout << "Apparent Greenwich Sidereal Time " << sexagesimal::Sexagesimal(theta).to_string() << endl;
  //Convert to radians
  printf( "           Delta = %18.9lf Degrees\n", Delta);
  Delta = CAACoordinateTransformation::DegreesToRadians(Delta);
  printf( "           Delta = %18.9lf Radians\n", Delta);
  double cosDelta = cos(Delta);
  double sinDelta = sin(Delta);
  printf( "        sinDelta = %18.9lf\n", sinDelta);
  printf( "        cosDelta = %18.9lf\n", cosDelta);
  //Calculate the Parallax

  double pi = asin(g_AAParallax_C1 / Distance);

  printf( "              pi = %18.9lf\n", pi);

  //Calculate the hour angle
  double H;
  if( binary_tidbits::west_longitude_is_positive() ){
    H = CAACoordinateTransformation::HoursToRadians(theta - Longitude/15 - Alpha);
  }else{
    H = CAACoordinateTransformation::HoursToRadians(theta + Longitude/15 - Alpha);
  }
  double cosH = cos(H);
  double sinH = sin(H);

  double sin_pi = sin( pi );
  printf( "               H = %18.9lf\n", H);
  printf( "            cosH = %18.9lf\n", cosH);
  printf( "            sinH = %18.9lf\n", sinH);
  /*
     denominator is that of equations 40.2 and 40.3.
     Jean Meeus, Astronomical Algorithms 2nd ed. pp.279
  */
  double denominator = cosDelta - RhoCosThetaPrime *sin_pi*cosH;
  double arg = ( -RhoCosThetaPrime * sin_pi * sinH )/denominator;  // RHS of eq. 40.2.
  /*
    In variable name delta_alpha, delta indciates it is a change in the
    Value of alpha, the Right Ascension. (celestial longitude expressed as hours.)
  */
  double delta_alpha = atan( arg );
  double cos_delta_alpha = cos( delta_alpha );
  delta_alpha = CAACoordinateTransformation::RadiansToHours( delta_alpha );
  printf( "     delta_alpha = %18.9lf Hours Right Ascension\n", delta_alpha);

  arg = ((sinDelta - RhoSinThetaPrime * sin_pi )*cos_delta_alpha)/denominator;  // RHS of eq. 40.3
  /*
    In variable name delta_prime, delta indicates it is a declination, not a difference.
  */
  double delta_prime = atan(arg);
  delta_prime = CAACoordinateTransformation::RadiansToDegrees( delta_prime );
  printf( "     delta_prime = %18.9lf\n", delta_prime);

  CAA2DCoordinate Topocentric_RA_Dec;
  // pack the return value.
  Topocentric_RA_Dec.X = Alpha + delta_alpha;
  Topocentric_RA_Dec.Y = delta_prime;
  return Topocentric_RA_Dec;
}

CAA2DCoordinate Equatorial2TopocentricDeltaRigorous(double Alpha, double Delta, double Distance, double Longitude, double Latitude, double Height, double JD)
{
  double g_AAParallax_C1 = sin(CAACoordinateTransformation::DegreesToRadians(CAACoordinateTransformation::DMSToDegrees(0, 0, 8.794)));
  double RhoSinThetaPrime = CAAGlobe::RhoSinThetaPrime(Latitude, Height);
  double RhoCosThetaPrime = CAAGlobe::RhoCosThetaPrime(Latitude, Height);

  double declination_degrees_geocentric = Delta;

  printf( "RhoSinThetaPrime = %18.9lf\n", RhoSinThetaPrime);
  printf( "RhoCosThetaPrime = %18.9lf\n", RhoCosThetaPrime);

  //Calculate the Sidereal time
  double theta = CAASidereal::ApparentGreenwichSiderealTime(JD);
  printf( "           theta = %18.9lf\n", theta);
  cout << "Apparent Greenwich Sidereal Time " << sexagesimal::Sexagesimal(theta).to_string() << endl;
  //Convert to radians
  printf( "           Delta = %18.9lf Degrees\n", Delta);
  Delta = CAACoordinateTransformation::DegreesToRadians(Delta);
  printf( "           Delta = %18.9lf Radians\n", Delta);
  double cosDelta = cos(Delta);
  double sinDelta = sin(Delta);
  printf( "        cosDelta = %18.9lf\n", cosDelta);
  //Calculate the Parallax
  double pi = asin(g_AAParallax_C1 / Distance);

  printf( "              pi = %18.9lf\n", pi);

  //Calculate the hour angle
  double H;
  if( binary_tidbits::west_longitude_is_positive() ){
    H = CAACoordinateTransformation::HoursToRadians(theta - Longitude/15 - Alpha);
  }else{
    H = CAACoordinateTransformation::HoursToRadians(theta + Longitude/15 - Alpha);
  }
  double cosH = cos(H);
  double sinH = sin(H);

  double sin_pi = sin( pi );
  printf( "               H = %18.9lf\n", H);
  printf( "            cosH = %18.9lf\n", cosH);
  printf( "            sinH = %18.9lf\n", sinH);
  double denominator = cosDelta - RhoCosThetaPrime *sin_pi*cosH;
  double arg = ( -RhoCosThetaPrime * sin_pi * sinH )/denominator;
  double delta_alpha = atan( arg );
  double cos_delta_alpha = cos( delta_alpha );
  delta_alpha = CAACoordinateTransformation::RadiansToHours( delta_alpha );
  printf( "     delta_alpha = %18.9lf\n", delta_alpha);

  arg = ((sinDelta - RhoSinThetaPrime * sin_pi )*cos_delta_alpha)/denominator;
  double delta_prime = atan(arg);
  delta_prime = CAACoordinateTransformation::RadiansToDegrees( delta_prime );
  printf( "     delta_prime = %18.9lf\n", delta_prime);

  CAA2DCoordinate DeltaTopocentric;
  DeltaTopocentric.X = delta_alpha;
  DeltaTopocentric.Y = delta_prime - declination_degrees_geocentric;
  return DeltaTopocentric;
}

/*
 *
 */
int main( int argc, char **argv){
  long check;
  long unix_time = time( &check );
  CAADate unix_epoch {1970,1,1, true};

  CAADate timestamp;

  if( 1 ){
    timestamp = CAADate( unix_epoch.Julian() + static_cast<double>(unix_time)/86400.0, true );
  }else{
    //    timestamp = CAADate( 2015,3,31,15,55,0.0, true );
    timestamp = CAADate( 1992,4,12,0,0,0.0, true );
  }
  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  double hour = timestamp.Hour();
  hour += static_cast<double>(timestamp.Minute())/60.0;
  hour += static_cast<double>(timestamp.Second())/3600.0;
  sexagesimal::Sexagesimal time{hour};

  cout << timestamp.Year() << "  ";
  cout << timestamp.Month() << "  ";
  cout << timestamp.Day() << "  ";
  cout << time.to_string() << endl;
  cout << endl;

  CAA3DCoordinate RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());

  //  cout << "Lunar Distance = " << RA_Dec_Dist.Z << endl;
  printf( "Lunar Distance = %12.6lf km\n", RA_Dec_Dist.Z );
  cout << "         Geocentric RA " << sexagesimal::Sexagesimal(RA_Dec_Dist.X).to_string() << endl;
  printf( "%12.6f km\n", RA_Dec_Dist.X );
  cout << "Geocentric Declination " << sexagesimal::Sexagesimal(RA_Dec_Dist.Y).to_string() << endl;
  printf( "%12.6f km\n", RA_Dec_Dist.Y );
  double distance_AU = RA_Dec_Dist.Z/solar_system::AU_kilometers;
  printf( "Lunar Distance = %12.6lf Astronomical Units\n", distance_AU );
  double altitude = 0.0;

  //    Sexagesimal( int32_t hhh, uint8_t mm, uint8_t ss, uint16_t xxx);
  sexagesimal::Sexagesimal longitude{ 93, 6, 6, 0};  /* Saint Paul, Minnesota  West Longitude is negative per Meeus */
  sexagesimal::Sexagesimal latitude{ 44, 57, 19, 0};
  if( 0 ){
    longitude = sexagesimal::Sexagesimal{ 0, 0, 0, 0};  /* Greenwich */
    latitude = sexagesimal::Sexagesimal{ 51, 28, 6, 0};
  }
  cout << altitude << endl;

  cout << "Longitude: " << longitude.to_string() << endl;
  printf( "%f\n", longitude.to_double() );
  cout << " Latitude: " << latitude.to_string() << endl;
  printf( "%f\n", latitude.to_double() );
  double lat = CAACoordinateTransformation::DegreesToRadians(latitude.to_double());
  double rho = 0.9983271 + .0016764*cos(2.0*lat) -.0000035*cos(4*lat);
  cout << rho << endl;

  CAA2DCoordinate correction = CAAParallax::Equatorial2TopocentricDelta( RA_Dec_Dist.X,
									 RA_Dec_Dist.Y,
									 distance_AU,
									 longitude.to_double(),
									 latitude.to_double(),
									 0.0,
									 timestamp.Julian());
  cout << "Corrections for parallax" << endl;

  printf( "            X = %18.9f\n", correction.X);
  printf( "            Y = %18.9f\n", correction.Y);

  RA_Dec_Dist.X += correction.X;
  RA_Dec_Dist.Y += correction.Y;

  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(RA_Dec_Dist.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(RA_Dec_Dist.Y).to_string() << endl;

  cout << "Do Over!" << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  CAA2DCoordinate correction_rigorous = Equatorial2TopocentricDeltaRigorous( RA_Dec_Dist.X,
									     RA_Dec_Dist.Y,
									     RA_Dec_Dist.Z/solar_system::AU_kilometers,
									     longitude.to_double(),
									     latitude.to_double(),
									     0.0,
									     timestamp.Julian());
  cout << "Local Corrections for parallax" << endl;

  printf( "            X = %18.9f\n", correction_rigorous.X);
  printf( "            Y = %18.9f\n", correction_rigorous.Y);

  RA_Dec_Dist.X += correction_rigorous.X;
  RA_Dec_Dist.Y += correction_rigorous.Y;

  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(RA_Dec_Dist.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(RA_Dec_Dist.Y).to_string() << endl;

  cout << "\nDo Over!  Again!" << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  CAA2DCoordinate Topocentric_RA_Dec = Equatorial2TopocentricRigorousVerbose( RA_Dec_Dist.X,
									     RA_Dec_Dist.Y,
									     RA_Dec_Dist.Z/solar_system::AU_kilometers,
									     longitude.to_double(),
									     latitude.to_double(),
									     0.0,
									     timestamp.Julian());

  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.Y).to_string() << endl;

  cout << "\nDo Over!  Non Rigorous Method " << endl;
  cout << "This time with the actual uC code." << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  Topocentric_RA_Dec = Equatorial2TopocentricNonRigorous( RA_Dec_Dist.X,
							      RA_Dec_Dist.Y,
							      RA_Dec_Dist.Z/solar_system::AU_kilometers,
							      longitude.to_double(),
							      latitude.to_double(),
							      0.0,
							      timestamp.Julian());

  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.Y).to_string() << endl;

  cout << "\nDo Over!  Yet Again!!" << endl;
  cout << "This time with the actual uC code." << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  Topocentric_RA_Dec = Equatorial2TopocentricRigorous( RA_Dec_Dist.X,
							      RA_Dec_Dist.Y,
							      RA_Dec_Dist.Z/solar_system::AU_kilometers,
							      longitude.to_double(),
							      latitude.to_double(),
							      0.0,
							      timestamp.Julian());

  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.Y).to_string() << endl;

  cout << "\nDo Over!  Yet Again!!! Alternative " << endl;
  cout << "This time with the actual uC code." << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  Topocentric_RA_Dec = Equatorial2TopocentricRigorousAlternative( RA_Dec_Dist.X,
							      RA_Dec_Dist.Y,
							      RA_Dec_Dist.Z/solar_system::AU_kilometers,
							      longitude.to_double(),
							      latitude.to_double(),
							      0.0,
							      timestamp.Julian());

  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.Y).to_string() << endl;

  cout << "\nDo Over!  Yet Again!!! PJ Naughter method " << endl;
  cout << "This time with the actual uC code." << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  Topocentric_RA_Dec = Equatorial2TopocentricRigorous_PJ( RA_Dec_Dist.X,
							      RA_Dec_Dist.Y,
							      RA_Dec_Dist.Z/solar_system::AU_kilometers,
							      longitude.to_double(),
							      latitude.to_double(),
							      0.0,
							      timestamp.Julian());

  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.Y).to_string() << endl;

  return 0;
}
<commit_msg>Removed crust from moon_test.cpp<commit_after>#include <iostream>
#include "AADate.h"
#include "sexagesimal.h"
#include "AACoordinateTransformation.h"
#include "AA3DCoordinate.h"
#include "solar_system.h"
#include "AAParallax.h"
#include "AAGlobe.h"
#include "AASidereal.h"
#include <cmath>
#include "binary_tidbits.h"
#include "horizontal_parallax.h"

using std::cout;
using std::endl;

int main( int argc, char **argv){
  long check;
  long unix_time = time( &check );
  CAADate unix_epoch {1970,1,1, true};

  CAADate timestamp;

  if( 1 ){
    timestamp = CAADate( unix_epoch.Julian() + static_cast<double>(unix_time)/86400.0, true );
  }else{
    //    timestamp = CAADate( 2015,3,31,15,55,0.0, true );
    timestamp = CAADate( 1992,4,12,0,0,0.0, true );
  }
  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  double hour = timestamp.Hour();
  hour += static_cast<double>(timestamp.Minute())/60.0;
  hour += static_cast<double>(timestamp.Second())/3600.0;
  sexagesimal::Sexagesimal time{hour};

  cout << timestamp.Year() << "  ";
  cout << timestamp.Month() << "  ";
  cout << timestamp.Day() << "  ";
  cout << time.to_string() << endl;
  cout << endl;

  CAA3DCoordinate RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());

  //  cout << "Lunar Distance = " << RA_Dec_Dist.Z << endl;
  printf( "Lunar Distance = %12.6lf km\n", RA_Dec_Dist.Z );
  cout << "         Geocentric RA " << sexagesimal::Sexagesimal(RA_Dec_Dist.X).to_string() << endl;
  printf( "%12.6f \n", RA_Dec_Dist.X );
  cout << "Geocentric Declination " << sexagesimal::Sexagesimal(RA_Dec_Dist.Y).to_string() << endl;
  printf( "%12.6f \n", RA_Dec_Dist.Y );
  double distance_AU = RA_Dec_Dist.Z/solar_system::AU_kilometers;
  printf( "Lunar Distance = %12.6lf Astronomical Units\n", distance_AU );
  double altitude_asl = 0.0; /* Above Sea Level */

  //    Sexagesimal( int32_t hhh, uint8_t mm, uint8_t ss, uint16_t xxx);
  sexagesimal::Sexagesimal longitude{ 93, 6, 6, 0};  /* Saint Paul, Minnesota  West Longitude is negative per Meeus */
  sexagesimal::Sexagesimal latitude{ 44, 57, 19, 0};
  if( 0 ){
    longitude = sexagesimal::Sexagesimal{ 0, 0, 0, 0};  /* Greenwich */
    latitude = sexagesimal::Sexagesimal{ 51, 28, 6, 0};
  }
  cout << "altitude = " << altitude_asl << " meters above sea level. " << endl;

  cout << "Longitude: " << longitude.to_string() << endl;
  printf( "%f\n", longitude.to_double() );
  cout << " Latitude: " << latitude.to_string() << endl;
  printf( "%f\n", latitude.to_double() );

  CAA2DCoordinate correction = CAAParallax::Equatorial2TopocentricDelta( RA_Dec_Dist.X,
									 RA_Dec_Dist.Y,
									 distance_AU,
									 longitude.to_double(),
									 latitude.to_double(),
									 0.0,
									 timestamp.Julian());
  cout << "Corrections for parallax" << endl;

  printf( "            X = %18.9f\n", correction.X);
  printf( "            Y = %18.9f\n", correction.Y);

  RA_Dec_Dist.X += correction.X;
  RA_Dec_Dist.Y += correction.Y;

  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(RA_Dec_Dist.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(RA_Dec_Dist.Y).to_string() << endl;

  cout << "\nDo Over, RigorousAlternative ... " << endl;
  cout << "using actual uC code." << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  CAA2DCoordinate Topocentric_RA_Dec;
  Topocentric_RA_Dec = Equatorial2TopocentricRigorousAlternative( RA_Dec_Dist.X,
							      RA_Dec_Dist.Y,
							      RA_Dec_Dist.Z/solar_system::AU_kilometers,
							      longitude.to_double(),
							      latitude.to_double(),
							      0.0,
							      timestamp.Julian());

  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.Y).to_string() << endl;

  cout << "\nDo Over!  Yet Again!!! PJ Naughter method " << endl;
  cout << "This time with the actual uC code." << endl;
  RA_Dec_Dist = solar_system::calculate_moon_RA_Dec_Dist(timestamp.Julian());
  Topocentric_RA_Dec = Equatorial2TopocentricRigorous_PJ( RA_Dec_Dist.X,
							      RA_Dec_Dist.Y,
							      RA_Dec_Dist.Z/solar_system::AU_kilometers,
							      longitude.to_double(),
							      latitude.to_double(),
							      0.0,
							      timestamp.Julian());

  printf( "Julian Date = %18.9lf\n", timestamp.Julian() );
  cout << "       Topocentric RA " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.X).to_string() << endl;
  cout << "Topocentric Declination " << sexagesimal::Sexagesimal(Topocentric_RA_Dec.Y).to_string() << endl;

  return 0;
}
<|endoftext|>


<commit_before>#include "board.h"
#include "movegen.h"
#include "catch.hpp"

int perft(int depth, Board board) {
  if (depth == 0) {
    return 1;
  }

  MoveGen movegen(board);

  int nodes = 0;
  for (auto move : movegen.getMoves()) {
    Board tempBoard = board;
    tempBoard.doMove(move);

    if (!tempBoard.WHITE_TO_MOVE && tempBoard.whiteIsInCheck()) {
      continue;
    } else if (tempBoard.WHITE_TO_MOVE && tempBoard.blackIsInCheck()) {
      continue;
    }

    nodes += perft(depth - 1, tempBoard);
  }

  return nodes;
}

TEST_CASE("Perft is correct") {
  Board board;

  SECTION("Perft is correct from the starting position") {
    board.setToStartPos();
    REQUIRE(perft(1, board) == 20);
    REQUIRE(perft(2, board) == 400);
    REQUIRE(perft(3, board) == 8902);
    REQUIRE(perft(4, board) == 197281);
  }

  SECTION("Perft is correct from r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -") {
    board.setToFen("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -");

    REQUIRE(perft(1, board) == 48);
    REQUIRE(perft(2, board) == 2039);
    REQUIRE(perft(3, board) == 97862);
    REQUIRE(perft(4, board) == 4085603);
  //  REQUIRE(perft(5, board) == 193690690); // SLOW
  }

  SECTION("Perft is correct from 8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -") {
    board.setToFen("8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -");

    REQUIRE(perft(1, board) == 14);
    REQUIRE(perft(2, board) == 191);
    REQUIRE(perft(3, board) == 2812);
    REQUIRE(perft(4, board) == 43238);
    REQUIRE(perft(5, board) == 674624);
  //  REQUIRE(perft(6, board) == 11030083); // SLOW
  }

  SECTION("Perft is correct from r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1") {
    board.setToFen("r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1");

    REQUIRE(perft(1, board) == 6);
    REQUIRE(perft(2, board) == 264);
    REQUIRE(perft(3, board) == 9467);
    REQUIRE(perft(4, board) == 422333);
    // REQUIRE(perft(5, board) == 15833292); // SLOW
  }

  SECTION("Perft is correct from rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8 ") {
    board.setToFen("rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8 ");

    REQUIRE(perft(1, board) == 44);
    REQUIRE(perft(2, board) == 1486);
    REQUIRE(perft(3, board) == 62379);
    REQUIRE(perft(4, board) == 2103487);
    // REQUIRE(perft(5, board) == 89941194); // SLOW
  }

  SECTION("Perft is correct from r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10") {
    board.setToFen("r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10");

    REQUIRE(perft(1, board) == 46);
    REQUIRE(perft(2, board) == 2079);
    REQUIRE(perft(3, board) == 89890);
    REQUIRE(perft(4, board) == 3894594);
  }
}
<commit_msg>Add more perft tests<commit_after>#include "board.h"
#include "movegen.h"
#include "catch.hpp"

int perft(int depth, Board board) {
  if (depth == 0) {
    return 1;
  }

  MoveGen movegen(board);

  int nodes = 0;
  for (auto move : movegen.getMoves()) {
    Board tempBoard = board;
    tempBoard.doMove(move);

    if (!tempBoard.WHITE_TO_MOVE && tempBoard.whiteIsInCheck()) {
      continue;
    } else if (tempBoard.WHITE_TO_MOVE && tempBoard.blackIsInCheck()) {
      continue;
    }

    nodes += perft(depth - 1, tempBoard);
  }

  return nodes;
}

TEST_CASE("Perft is correct") {
  Board board;

  SECTION("Perft is correct from the starting position") {
    board.setToStartPos();

    REQUIRE(perft(1, board) == 20);
    REQUIRE(perft(2, board) == 400);
    REQUIRE(perft(3, board) == 8902);
    REQUIRE(perft(4, board) == 197281);

    // SLOW
    // REQUIRE(perft(5, board) == 4865609);
    // REQUIRE(perft(6, board) == 119060324);
    // REQUIRE(perft(7, board) == 3195901860);
    // REQUIRE(perft(8, board) == 84998978956);
  }

  SECTION("Perft is correct from r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -") {
    board.setToFen("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -");

    REQUIRE(perft(1, board) == 48);
    REQUIRE(perft(2, board) == 2039);
    REQUIRE(perft(3, board) == 97862);
    REQUIRE(perft(4, board) == 4085603);

    // SLOW
    // REQUIRE(perft(5, board) == 193690690);
  }

  SECTION("Perft is correct from 8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -") {
    board.setToFen("8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -");

    REQUIRE(perft(1, board) == 14);
    REQUIRE(perft(2, board) == 191);
    REQUIRE(perft(3, board) == 2812);
    REQUIRE(perft(4, board) == 43238);
    REQUIRE(perft(5, board) == 674624);

    // SLOW
    // REQUIRE(perft(7, board) == 178633661);
    // REQUIRE(perft(6, board) == 11030083); // SLOW
  }

  SECTION("Perft is correct from r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1") {
    board.setToFen("r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1");

    REQUIRE(perft(1, board) == 6);
    REQUIRE(perft(2, board) == 264);
    REQUIRE(perft(3, board) == 9467);
    REQUIRE(perft(4, board) == 422333);

    // SLOW
    // REQUIRE(perft(5, board) == 15833292);
    // REQUIRE(perft(6, board) == 706045033);
  }

  SECTION("Perft is correct from rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8 ") {
    board.setToFen("rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8 ");

    REQUIRE(perft(1, board) == 44);
    REQUIRE(perft(2, board) == 1486);
    REQUIRE(perft(3, board) == 62379);
    REQUIRE(perft(4, board) == 2103487);

    // SLOW
    // REQUIRE(perft(5, board) == 89941194);
  }

  SECTION("Perft is correct from r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10") {
    board.setToFen("r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10");

    REQUIRE(perft(1, board) == 46);
    REQUIRE(perft(2, board) == 2079);
    REQUIRE(perft(3, board) == 89890);
    REQUIRE(perft(4, board) == 3894594);

    // SLOW
    // REQUIRE(perft(5, board) == 164075551);
    // REQUIRE(perft(6, board) == 6923051137);
    // REQUIRE(perft(7, board) == 287188994746);
    // REQUIRE(perft(8, board) == 11923589843526);
    // REQUIRE(perft(9, board) == 490154852788714);
  }

  SECTION("Perft is correct from n1n5/PPPk4/8/8/8/8/4Kppp/5N1N b - - 0 1") {
    board.setToFen("n1n5/PPPk4/8/8/8/8/4Kppp/5N1N b - - 0 1");

    REQUIRE(perft(1, board) == 24);
    REQUIRE(perft(2, board) == 496);
    REQUIRE(perft(3, board) == 9483);
    REQUIRE(perft(4, board) == 182838);

    // SLOW
    // REQUIRE(perft(5, board) == 3605103);
    // REQUIRE(perft(6, board) == 71179139);
  }

  SECTION("Perft is correct from k1q4b/1qq3bR/qq3b1R/r2Rr2R/r2rR2R/r1B3QQ/rB3QQ1/B4Q1K w - -") {
    board.setToFen("k1q4b/1qQ3bR/qQ3b1R/r2RR2R/r2rr2R/r1B3qQ/rB3qQ1/B4Q1K w - -");

    REQUIRE(perft(1, board) == 78);
    REQUIRE(perft(2, board) == 5451);
    REQUIRE(perft(3, board) == 388081);

    // SLOW
    // REQUIRE(perft(4, board) == 26438936);
  }

}
<|endoftext|>


<commit_before>// pc.cpp: show standard posit components: show the sign/scale/regime/exponent/fraction components of a posit
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include "stdafx.h"

#include <posit>

using namespace std;
using namespace sw::unum;

typedef std::numeric_limits< double > dbl;

// receive a float and print its components
int main(int argc, char** argv)
try {
	if (argc != 2) {
		cerr << "Show the sign/scale/regime/exponent/fraction components of a posit." << endl;
	    cerr << "Usage: pc float_value" << endl;
		cerr << "Example: pc -1.123456789e17" << endl;
		cerr << "posit< 8,0>: " << endl;
		cerr << "posit<16,1>: " << endl;
		cerr << "posit<32,2>: " << endl;
		cerr << "posit<64,3>: " << endl;
		return EXIT_SUCCESS;  // signal successful completion for ctest
	}
	double d = atof(argv[1]);
	posit<8, 0>  p8(d);
	posit<16, 1> p16(d);
	posit<32, 2> p32(d);
	posit<48, 2> p48(d);
	//posit<64, 3> p64(d);

	int precision = dbl::max_digits10;
	cout << "posit< 8,0> = " << pretty_print(p8, precision) << endl;
	cout << "posit<16,1> = " << pretty_print(p16, precision) << endl;
	cout << "posit<32,2> = " << pretty_print(p32, precision) << endl;
	cout << "posit<48,2> = " << pretty_print(p48, precision) << endl;
	//cout << "posit<64,3> = " << pretty_print(p64, precision) << endl;

	return EXIT_SUCCESS;
}
catch (char* msg) {
	cerr << msg << endl;
	return EXIT_FAILURE;
}
<commit_msg>Adding a collection of standard posit configs to compare<commit_after>// pc.cpp: show standard posit components: show the sign/scale/regime/exponent/fraction components of a posit
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

#include "stdafx.h"

#include <posit>

using namespace std;
using namespace sw::unum;

typedef std::numeric_limits< double > dbl;

// receive a float and print its components
int main(int argc, char** argv)
try {
	if (argc != 2) {
		cerr << "Show the sign/scale/regime/exponent/fraction components of a posit." << endl;
	    cerr << "Usage: pc float_value" << endl;
		cerr << "Example: pc -1.123456789e17" << endl;
		cerr << "posit< 8,0>: " << endl;
		cerr << "posit<16,1>: " << endl;
		cerr << "posit<32,2>: " << endl;
		cerr << "posit<64,3>: " << endl;
		return EXIT_SUCCESS;  // signal successful completion for ctest
	}
	double d = atof(argv[1]);
	posit<8, 0>  p8_0(d);
	posit<8, 1>  p8_1(d);
	posit<8, 2>  p8_2(d);
	posit<8, 3>  p8_3(d);
	posit<16, 1> p16_1(d);
	posit<16, 2> p16_2(d);
	posit<16, 3> p16_3(d);
	posit<32, 1> p32_1(d);
	posit<32, 2> p32_2(d);
	posit<32, 3> p32_3(d);
	posit<48, 1> p48_1(d);
	posit<48, 2> p48_2(d);
	posit<48, 3> p48_3(d);
	posit<64, 1> p64_1(d);
	posit<64, 2> p64_2(d);
	posit<64, 3> p64_3(d);

	int precision = dbl::max_digits10;
	cout << "posit< 8,0> = " << pretty_print(p8_0, precision) << endl;
	cout << "posit< 8,1> = " << pretty_print(p8_1, precision) << endl;
	cout << "posit< 8,2> = " << pretty_print(p8_2, precision) << endl;
	cout << "posit< 8,3> = " << pretty_print(p8_3, precision) << endl;
	cout << "posit<16,1> = " << pretty_print(p16_1, precision) << endl;
	cout << "posit<16,2> = " << pretty_print(p16_2, precision) << endl;
	cout << "posit<16,3> = " << pretty_print(p16_3, precision) << endl;
	cout << "posit<32,1> = " << pretty_print(p32_1, precision) << endl;
	cout << "posit<32,2> = " << pretty_print(p32_2, precision) << endl;
	cout << "posit<32,3> = " << pretty_print(p32_3, precision) << endl;
	cout << "posit<48,1> = " << pretty_print(p48_1, precision) << endl;
	cout << "posit<48,2> = " << pretty_print(p48_2, precision) << endl;
	cout << "posit<48,3> = " << pretty_print(p48_3, precision) << endl;
	cout << "posit<64,1> = " << pretty_print(p64_1, precision) << endl;
	cout << "posit<64,2> = " << pretty_print(p64_2, precision) << endl;
	cout << "posit<64,3> = " << pretty_print(p64_3, precision) << endl;

	return EXIT_SUCCESS;
}
catch (char* msg) {
	cerr << msg << endl;
	return EXIT_FAILURE;
}
<|endoftext|>


<commit_before>// Brock Ferrell
// CS2401
// November 23, 2015
// Project7

#include "game.h"
#include "othello.h"
using namespace main_savitch_14;

int main()
{
	Othello theGame;
	theGame.restart();
	theGame.play();
}
<commit_msg>Updated main.cc<commit_after>// Brock Ferrell
// CS2401
// November 23, 2015
// Project7

/*!
	@file main.cc
	@brief Main function to run othello
	@author
*/

#include "game.h"
#include "othello.h"
using namespace main_savitch_14;

/*!
	@brief
*/
int main()
{
	Othello theGame;
	theGame.restart();
	theGame.play();
}
<|endoftext|>


<commit_before>/****************************************************************************
** irexec.c ****************************************************************
****************************************************************************
*
* irexec  - execute programs according to the pressed remote control buttons
*
* Copyright (C) 1998 Trent Piepho <xyzzy@u.washington.edu>
* Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
*
*/

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "lirc_client.h"
#include "lirc_log.h"

static const logchannel_t logchannel = LOG_APP;

static const char* const USAGE =
	"Usage: irexec [options] [lircrc config_file]\n"
	"\t-d --daemon\t\tRun in background\n"
	"\t-D --loglevel=level\t'error', 'info', 'notice',... or 0..10\n"
	"\t-n --name=progname\tUse this program name for lircrc matching\n"
	"\t-h --help\t\tDisplay usage summary\n"
	"\t-v --version\t\tDisplay version\n";

static const struct option options[] = {
	{ "help",     no_argument,	 NULL, 'h' },
	{ "version",  no_argument,	 NULL, 'v' },
	{ "daemon",   no_argument,	 NULL, 'd' },
	{ "name",     required_argument, NULL, 'n' },
	{ "loglevel", required_argument, NULL, 'D' },
	{ 0,          0,		 0,    0   }
};

static int opt_daemonize	= 0;
static loglevel_t opt_loglevel	= LIRC_NOLOG;
static const char* opt_progname	= "irexec";

static char path[256] = {0};

/** Run shell command line in isolated process using double fork(). */
static void run_command(const char* cmd)
{
	pid_t pid1;
	pid_t pid2;

	pid1 = fork();
	if (pid1 < 0) {
		log_perror_err("Cannot fork");
		perror("Cannot fork()");
		exit(EXIT_FAILURE);
	}
	if (pid1 == 0) {
		pid2 = fork();
		if (pid2 < 0) {
			log_perror_err("Cannot do secondary fork()");
			exit(EXIT_FAILURE);
		}
		if (pid2 == 0) {
			log_debug("Execing command \"%s\"", cmd);
			char* const vp[] = {strdup(SH_PATH),
			      strdup("-c"),
			      strdup(cmd),
			      NULL
			};
			execvp(SH_PATH, vp);
			/* not reached */
			log_perror_err("execvp failed");
			fputs("execvp failed\n", stderr);
		} else {
			waitpid(pid2, NULL, WNOHANG);
			exit(0);
		}
	} else {
		waitpid(pid1, NULL, 0);
	}
}

/** Get buttonclick messages from lircd socket and process them. */
static void process_input(struct lirc_config* config)
{
	char* code;
	char* c;
	int r;

	while (lirc_nextcode(&code) == 0) {
		if (code == NULL)
			continue;
		r = lirc_code2char(config, code, &c);
		while (r == 0 && c != NULL) {
			run_command(c);
			r = lirc_code2char(config, code, &c);
		}
		free(code);
		if (r == -1)
			break;
	}
}

int irexec(const char* configfile)
{
	struct lirc_config* config;

	if (opt_daemonize) {
		if (daemon(0, 0) == -1) {
			perror("Can't daemonize");
			return EXIT_FAILURE;
		}
	}
	if (lirc_init(opt_progname, opt_daemonize ? 0 : 1) == -1)
		return EXIT_FAILURE;

	if (lirc_readconfig(configfile, &config, NULL) != 0) {
		fputs("Cannot parse config file\n", stderr);
		return EXIT_FAILURE;
	}
	lirc_log_get_clientlog("irexec", path, sizeof(path));
	unlink(path);
	lirc_log_set_file(path);
	lirc_log_open("irexec", 1, opt_loglevel);

	process_input(config);
	lirc_deinit();

	lirc_freeconfig(config);
	return EXIT_SUCCESS;
}

int main(int argc, char* argv[])
{
	int c;

	while ((c = getopt_long(argc, argv, "D:hvdn:", options, NULL)) != -1) {
		switch (c) {
		case 'h':
			puts(USAGE);
			return EXIT_SUCCESS;
		case 'v':
			puts("irexec " VERSION);
			return EXIT_SUCCESS;
		case 'd':
			opt_daemonize = 1;
			break;
		case 'n':
			opt_progname = optarg;
			break;
		case 'D':
			opt_loglevel = string2loglevel(optarg);
			break;
		default:
			fputs(USAGE, stderr);
			return EXIT_FAILURE;
		}
	}
	if (optind < argc - 1) {
		fputs("Too many arguments\n", stderr);
		return EXIT_FAILURE;
	}
	if (opt_loglevel == LIRC_BADLEVEL) {
		fprintf(stderr, "Bad debug level: %s\n", optarg);
		return EXIT_FAILURE;
	}
	return irexec(optind != argc ? argv[optind] : NULL);
}
<commit_msg>irexec: Handle non-working shells gracefully (#314).<commit_after>/****************************************************************************
** irexec.c ****************************************************************
****************************************************************************
*
* irexec  - execute programs according to the pressed remote control buttons
*
* Copyright (C) 1998 Trent Piepho <xyzzy@u.washington.edu>
* Copyright (C) 1998 Christoph Bartelmus <lirc@bartelmus.de>
*
*/

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "lirc_client.h"
#include "lirc_log.h"

static const logchannel_t logchannel = LOG_APP;

static const char* const USAGE =
	"Usage: irexec [options] [lircrc config_file]\n"
	"\t-d --daemon\t\tRun in background\n"
	"\t-D --loglevel=level\t'error', 'info', 'notice',... or 0..10\n"
	"\t-n --name=progname\tUse this program name for lircrc matching\n"
	"\t-h --help\t\tDisplay usage summary\n"
	"\t-v --version\t\tDisplay version\n";

static const struct option options[] = {
	{ "help",     no_argument,	 NULL, 'h' },
	{ "version",  no_argument,	 NULL, 'v' },
	{ "daemon",   no_argument,	 NULL, 'd' },
	{ "name",     required_argument, NULL, 'n' },
	{ "loglevel", required_argument, NULL, 'D' },
	{ 0,          0,		 0,    0   }
};

static int opt_daemonize	= 0;
static loglevel_t opt_loglevel	= LIRC_NOLOG;
static const char* opt_progname	= "irexec";

static char path[256] = {0};

/** Run shell command line in isolated process using double fork(). */
static void run_command(const char* cmd)
{
	pid_t pid1;
	pid_t pid2;

	pid1 = fork();
	if (pid1 < 0) {
		log_perror_err("Cannot fork");
		perror("Cannot fork()");
		exit(EXIT_FAILURE);
	}
	if (pid1 == 0) {
		pid2 = fork();
		if (pid2 < 0) {
			log_perror_err("Cannot do secondary fork()");
			exit(EXIT_FAILURE);
		}
		if (pid2 == 0) {
			log_debug("Execing command \"%s\"", cmd);
			char* const vp[] = {strdup(SH_PATH),
			      strdup("-c"),
			      strdup(cmd),
			      NULL
			};
			execvp(SH_PATH, vp);
			/* not reached, unless there was an error */
			log_perror_err("execvp failed");
			fputs("execvp failed\n", stderr);
			exit(EXIT_FAILURE);
		} else {
			waitpid(pid2, NULL, WNOHANG);
			exit(0);
		}
	} else {
		waitpid(pid1, NULL, 0);
	}
}

/** Get buttonclick messages from lircd socket and process them. */
static void process_input(struct lirc_config* config)
{
	char* code;
	char* c;
	int r;

	while (lirc_nextcode(&code) == 0) {
		if (code == NULL)
			continue;
		r = lirc_code2char(config, code, &c);
		while (r == 0 && c != NULL) {
			run_command(c);
			r = lirc_code2char(config, code, &c);
		}
		free(code);
		if (r == -1)
			break;
	}
}

int irexec(const char* configfile)
{
	struct lirc_config* config;

	if (opt_daemonize) {
		if (daemon(0, 0) == -1) {
			perror("Can't daemonize");
			return EXIT_FAILURE;
		}
	}
	if (lirc_init(opt_progname, opt_daemonize ? 0 : 1) == -1)
		return EXIT_FAILURE;

	if (lirc_readconfig(configfile, &config, NULL) != 0) {
		fputs("Cannot parse config file\n", stderr);
		return EXIT_FAILURE;
	}
	lirc_log_get_clientlog("irexec", path, sizeof(path));
	unlink(path);
	lirc_log_set_file(path);
	lirc_log_open("irexec", 1, opt_loglevel);

	process_input(config);
	lirc_deinit();

	lirc_freeconfig(config);
	return EXIT_SUCCESS;
}

int main(int argc, char* argv[])
{
	int c;

	while ((c = getopt_long(argc, argv, "D:hvdn:", options, NULL)) != -1) {
		switch (c) {
		case 'h':
			puts(USAGE);
			return EXIT_SUCCESS;
		case 'v':
			puts("irexec " VERSION);
			return EXIT_SUCCESS;
		case 'd':
			opt_daemonize = 1;
			break;
		case 'n':
			opt_progname = optarg;
			break;
		case 'D':
			opt_loglevel = string2loglevel(optarg);
			break;
		default:
			fputs(USAGE, stderr);
			return EXIT_FAILURE;
		}
	}
	if (optind < argc - 1) {
		fputs("Too many arguments\n", stderr);
		return EXIT_FAILURE;
	}
	if (opt_loglevel == LIRC_BADLEVEL) {
		fprintf(stderr, "Bad debug level: %s\n", optarg);
		return EXIT_FAILURE;
	}
	return irexec(optind != argc ? argv[optind] : NULL);
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2013 Christoph Malek
// See LICENSE for more information.
//

#include <mlk/time/time.h>

#include <iostream>

int main()
{
    auto time_now(mlk::tm::time_stmp()); // get current time as long long; f.e.: 1385206783049705

    auto start(mlk::tm::time_pnt());

    std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // do work

    auto end(mlk::tm::time_pnt());

    std::cout << mlk::tm::duration(start, end) << std::endl; // prints 5000
    // use mlk::tm::duration<std::chrono::microseconds>(start, end) to get microseconds etc..
    std::cout << mlk::tm::timed_out(start, 1000) << std::endl; // prints 1 because the duration of start and now is higher than 1000

    std::cout << mlk::tm::time_str() << std::endl; // prints the current time as string; f.e.: Sat Nov 32 12:13:44 2013
}<commit_msg>adapted test_time.cpp<commit_after>//
// Copyright (c) 2013 Christoph Malek
// See LICENSE for more information.
//

#include <mlk/time/time.h>

#include <iostream>

int main()
{
    auto time_now(mlk::tm::time_stmp()); // get current time as long long; f.e.: 1385206783049705

    auto start(mlk::tm::time_pnt());

    mlk::tm::sleep(5000); // do work

    auto end(mlk::tm::time_pnt());

    std::cout << mlk::tm::duration(start, end) << std::endl; // prints 5000
    // use mlk::tm::duration<std::chrono::microseconds>(start, end) to get microseconds etc..
    std::cout << mlk::tm::timed_out(start, 1000) << std::endl; // prints 1 because the duration of start and now is higher than 1000

    std::cout << mlk::tm::time_str() << std::endl; // prints the current time as string; f.e.: Sat Nov 32 12:13:44 2013
}<|endoftext|>


<commit_before>#ifndef UTILS_HPP
#define UTILS_HPP

#include <cppformat/format.h>

#include <glm/glm.hpp>

#include <SDL.h>
#include <SDL_ttf.h>

#ifdef OPENCL
#include <boost/compute/core.hpp>
#endif

#include <chrono>
#include <cmath>
#include <string>
#include <thread>

namespace trac0r {

inline void print_sysinfo() {
    fmt::print("Rendering on\n");
#ifdef OPENCL
    auto device = boost::compute::system::default_device();
    const auto &devices = boost::compute::system::devices();
    for (size_t i = 0; i < devices.size(); i++) {
        fmt::print("    GPU (Device {}: {}, OpenCL version: {}, driver version: {})\n", i + 1,
                   devices[i].name(), devices[i].version(), devices[i].driver_version());
    }
#else
    auto threads = std::thread::hardware_concurrency();
    fmt::print("    CPU ({} threads)\n", threads);
#endif
}

inline SDL_Texture *make_text(SDL_Renderer *renderer, TTF_Font *font, std::string text,
                              const SDL_Color &color) {
    auto text_surface = TTF_RenderText_Blended(font, text.c_str(), color);
    auto text_tex = SDL_CreateTextureFromSurface(renderer, text_surface);
    SDL_FreeSurface(text_surface);

    return text_tex;
}

inline void render_text(SDL_Renderer *renderer, SDL_Texture *texture, int pos_x, int pos_y) {
    int tex_width;
    int tex_height;

    SDL_QueryTexture(texture, 0, 0, &tex_width, &tex_height);
    SDL_Rect rect{pos_x, pos_y, tex_width, tex_height};
    SDL_RenderCopy(renderer, texture, 0, &rect);
}

inline uint32_t pack_color_argb(uint8_t a, uint8_t r, uint8_t g, uint8_t b) {
    uint32_t new_color = a << 24 | r << 16 | g << 8 | b;
    return new_color;
}

inline uint32_t pack_color_argb(glm::i8vec4 color) {
    uint32_t new_color = color.a << 24 | color.r << 16 | color.g << 8 | color.b;
    return new_color;
}

inline uint32_t pack_color_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
    uint32_t packed_color = r << 24 | g << 16 | b << 8 | a;
    return packed_color;
}

inline uint32_t pack_color_rgba(glm::i8vec4 color) {
    uint32_t packed_color = color.r << 24 | color.g << 16 | color.b << 8 | color.a;
    return packed_color;
}

inline uint32_t pack_color_rgba(glm::vec4 color) {
    uint32_t packed_color =
        static_cast<int>(glm::round(glm::clamp(color.r, 0.f, 1.f) * 255)) << 24 |
        static_cast<int>(glm::round(glm::clamp(color.g, 0.f, 1.f) * 255)) << 16 |
        static_cast<int>(glm::round(glm::clamp(color.b, 0.f, 1.f) * 255)) << 8 |
        static_cast<int>(glm::round(glm::clamp(color.a, 0.f, 1.f) * 255));
    return packed_color;
}

inline uint32_t pack_color_argb(glm::vec4 color) {
    uint32_t packed_color =
        static_cast<int>(glm::round(glm::clamp(color.a, 0.f, 1.f) * 255)) << 24 |
        static_cast<int>(glm::round(glm::clamp(color.r, 0.f, 1.f) * 255)) << 16 |
        static_cast<int>(glm::round(glm::clamp(color.g, 0.f, 1.f) * 255)) << 8 |
        static_cast<int>(glm::round(glm::clamp(color.b, 0.f, 1.f) * 255));
    return packed_color;
}

inline glm::i8vec4 unpack_color_rgba_to_i8vec4(uint32_t packed_color_rgba) {
    glm::i8vec4 unpacked_color;
    unpacked_color.r = packed_color_rgba >> 24 & 0xFF;
    unpacked_color.g = packed_color_rgba >> 16 & 0xFF;
    unpacked_color.b = packed_color_rgba >> 8 & 0xFF;
    unpacked_color.a = packed_color_rgba & 0xFF;
    return unpacked_color;
}

inline glm::i8vec4 unpack_color_argb_to_i8vec4(uint32_t packed_color_argb) {
    glm::i8vec4 unpacked_color;
    unpacked_color.a = packed_color_argb >> 24 & 0xFF;
    unpacked_color.r = packed_color_argb >> 16 & 0xFF;
    unpacked_color.g = packed_color_argb >> 8 & 0xFF;
    unpacked_color.b = packed_color_argb & 0xFF;
    return unpacked_color;
}

inline glm::vec4 unpack_color_rgbb_to_vec4(uint32_t packed_color_rgba) {
    glm::i8vec4 unpacked_color;
    unpacked_color.r = (packed_color_rgba >> 24 & 0xFF) / 255.f;
    unpacked_color.g = (packed_color_rgba >> 16 & 0xFF) / 255.f;
    unpacked_color.b = (packed_color_rgba >> 8 & 0xFF) / 255.f;
    unpacked_color.a = (packed_color_rgba & 0xFF) / 255.f;
    return unpacked_color;
}

inline glm::vec4 unpack_color_argb_to_vec4(uint32_t packed_color_argb) {
    glm::vec4 unpacked_color;
    unpacked_color.a = (packed_color_argb >> 24 & 0xFF) / 255.f;
    unpacked_color.r = (packed_color_argb >> 16 & 0xFF) / 255.f;
    unpacked_color.g = (packed_color_argb >> 8 & 0xFF) / 255.f;
    unpacked_color.b = (packed_color_argb & 0xFF) / 255.f;
    return unpacked_color;
}
}

#endif /* end of include guard: UTILS_HPP */
<commit_msg>Better names for accelerators<commit_after>#ifndef UTILS_HPP
#define UTILS_HPP

#include <cppformat/format.h>

#include <glm/glm.hpp>

#include <SDL.h>
#include <SDL_ttf.h>

#ifdef OPENCL
#include <boost/compute/core.hpp>
#endif

#include <chrono>
#include <cmath>
#include <string>
#include <thread>

namespace trac0r {

inline void print_sysinfo() {
    fmt::print("Rendering on\n");
#ifdef OPENCL
    auto device = boost::compute::system::default_device();
    const auto &devices = boost::compute::system::devices();
    for (size_t i = 0; i < devices.size(); i++) {
        fmt::print("    OpenCL (Device {}: {}, OpenCL version: {}, driver version: {})\n", i + 1,
                   devices[i].name(), devices[i].version(), devices[i].driver_version());
    }
#else
    auto threads = std::thread::hardware_concurrency();
    fmt::print("    OpenMP ({} threads)\n", threads);
#endif
}

inline SDL_Texture *make_text(SDL_Renderer *renderer, TTF_Font *font, std::string text,
                              const SDL_Color &color) {
    auto text_surface = TTF_RenderText_Blended(font, text.c_str(), color);
    auto text_tex = SDL_CreateTextureFromSurface(renderer, text_surface);
    SDL_FreeSurface(text_surface);

    return text_tex;
}

inline void render_text(SDL_Renderer *renderer, SDL_Texture *texture, int pos_x, int pos_y) {
    int tex_width;
    int tex_height;

    SDL_QueryTexture(texture, 0, 0, &tex_width, &tex_height);
    SDL_Rect rect{pos_x, pos_y, tex_width, tex_height};
    SDL_RenderCopy(renderer, texture, 0, &rect);
}

inline uint32_t pack_color_argb(uint8_t a, uint8_t r, uint8_t g, uint8_t b) {
    uint32_t new_color = a << 24 | r << 16 | g << 8 | b;
    return new_color;
}

inline uint32_t pack_color_argb(glm::i8vec4 color) {
    uint32_t new_color = color.a << 24 | color.r << 16 | color.g << 8 | color.b;
    return new_color;
}

inline uint32_t pack_color_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
    uint32_t packed_color = r << 24 | g << 16 | b << 8 | a;
    return packed_color;
}

inline uint32_t pack_color_rgba(glm::i8vec4 color) {
    uint32_t packed_color = color.r << 24 | color.g << 16 | color.b << 8 | color.a;
    return packed_color;
}

inline uint32_t pack_color_rgba(glm::vec4 color) {
    uint32_t packed_color =
        static_cast<int>(glm::round(glm::clamp(color.r, 0.f, 1.f) * 255)) << 24 |
        static_cast<int>(glm::round(glm::clamp(color.g, 0.f, 1.f) * 255)) << 16 |
        static_cast<int>(glm::round(glm::clamp(color.b, 0.f, 1.f) * 255)) << 8 |
        static_cast<int>(glm::round(glm::clamp(color.a, 0.f, 1.f) * 255));
    return packed_color;
}

inline uint32_t pack_color_argb(glm::vec4 color) {
    uint32_t packed_color =
        static_cast<int>(glm::round(glm::clamp(color.a, 0.f, 1.f) * 255)) << 24 |
        static_cast<int>(glm::round(glm::clamp(color.r, 0.f, 1.f) * 255)) << 16 |
        static_cast<int>(glm::round(glm::clamp(color.g, 0.f, 1.f) * 255)) << 8 |
        static_cast<int>(glm::round(glm::clamp(color.b, 0.f, 1.f) * 255));
    return packed_color;
}

inline glm::i8vec4 unpack_color_rgba_to_i8vec4(uint32_t packed_color_rgba) {
    glm::i8vec4 unpacked_color;
    unpacked_color.r = packed_color_rgba >> 24 & 0xFF;
    unpacked_color.g = packed_color_rgba >> 16 & 0xFF;
    unpacked_color.b = packed_color_rgba >> 8 & 0xFF;
    unpacked_color.a = packed_color_rgba & 0xFF;
    return unpacked_color;
}

inline glm::i8vec4 unpack_color_argb_to_i8vec4(uint32_t packed_color_argb) {
    glm::i8vec4 unpacked_color;
    unpacked_color.a = packed_color_argb >> 24 & 0xFF;
    unpacked_color.r = packed_color_argb >> 16 & 0xFF;
    unpacked_color.g = packed_color_argb >> 8 & 0xFF;
    unpacked_color.b = packed_color_argb & 0xFF;
    return unpacked_color;
}

inline glm::vec4 unpack_color_rgbb_to_vec4(uint32_t packed_color_rgba) {
    glm::i8vec4 unpacked_color;
    unpacked_color.r = (packed_color_rgba >> 24 & 0xFF) / 255.f;
    unpacked_color.g = (packed_color_rgba >> 16 & 0xFF) / 255.f;
    unpacked_color.b = (packed_color_rgba >> 8 & 0xFF) / 255.f;
    unpacked_color.a = (packed_color_rgba & 0xFF) / 255.f;
    return unpacked_color;
}

inline glm::vec4 unpack_color_argb_to_vec4(uint32_t packed_color_argb) {
    glm::vec4 unpacked_color;
    unpacked_color.a = (packed_color_argb >> 24 & 0xFF) / 255.f;
    unpacked_color.r = (packed_color_argb >> 16 & 0xFF) / 255.f;
    unpacked_color.g = (packed_color_argb >> 8 & 0xFF) / 255.f;
    unpacked_color.b = (packed_color_argb & 0xFF) / 255.f;
    return unpacked_color;
}
}

#endif /* end of include guard: UTILS_HPP */
<|endoftext|>