<commit_before>/*
 * Copyright (c) 2014-2015 Kartik Kumar (me@kartikkumar.com)
 * Distributed under the MIT License.
 * See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
 */

#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <string>

#include <boost/array.hpp>

#include <catch.hpp>

#include <libsgp4/Eci.h>

#include <rapidjson/document.h>

#include <Astro/astro.hpp>

namespace d2d
{

//! 3-Vector.
typedef boost::array< double, 3 > Vector3;

//! 6-Vector.
typedef boost::array< double, 6 > Vector6;

//! State history.
typedef std::map< double, Vector6 > StateHistory;

//! JSON config iterator.
typedef rapidjson::Value::ConstMemberIterator ConfigIterator;

//! Create custom CATCH Approx object with tolerance for comparing doubles.
/*!
 * Creates a custom CATCH Approx object that can be used for comparing doubles in unit tests. The
 * tolerance is set based on machine precision (epsilon) for doubles.
 *
 * Using this comparison object ensures that large numbers are compared in a relative sense and
 * small numbers in an absolute sense.
 *
 * @see CATCH
 * @see
 *      Harris, R. (2013)
 */
static Approx approx
  = Approx::custom( ).epsilon( std::numeric_limits< double >::epsilon( ) * 100.0 );

//! Get root-path for D2D.
/*!
 * Returns path to root-directory of the D2D application (trailing slash included).
 *
 * @todo    Find a way to test the root-path function.
 *
 * @return  D2D root-path.
 */
static inline std::string getRootPath( )
{
    std::string filePath( __FILE__ );
    return filePath.substr(
      0, filePath.length( ) - std::string( "include/D2D/tools.hpp" ).length( ) );
}

//! Sample Kepler orbit.
/*!
 * Samples a Kepler orbit and generates a state-history stored in a STL map (key=epoch). The
 * Kepler orbit is sampled by using propagate_lagrangian() provided with PyKep (Izzo, 2012).
 *
 * @param[in]  initialState           Initial Cartesian state [km; km/s]
 * @param[in]  propagationTime        Total propagation time [s]
 * @param[in]  numberOfSamples        Number of samples, distributed evenly over propagation time
 * @param[in]  gravitationalParameter Gravitational parameter of central body [km^3 s^-2]
 * @param[in]  initialEpoch           Epoch corresponding to initial Cartesian state
 *                                    (default = 0.0) [Julian date]
 * @return                            State-history of sampled Kepler orbit
 */
StateHistory sampleKeplerOrbit( const Vector6& initialState,
                                const double propagationTime,
                                const int numberOfSamples,
                                const double gravitationalParameter,
                                const double initialEpoch = 0.0 );

//! Convert SGP4 ECI object to state vector.
/*!
 * Converts a Cartesian state stored in an object of the Eci class in the SGP4 library () into a
 * boost::array of 6 elements.
 *
 * @sa Eci, boost::array
 * @param  state State stored in Eci object
 * @return       State stored in boost::array
 */
Vector6 getStateVector( const Eci state );

//! Print value to stream.
/*!
 * Prints a specified value to stream provided, given a specified width and a filler character.
 *
 * @tparam     DataType  Type for specified value
 * @param[out] stream    Output stream
 * @param[in]  value     Specified value to print
 * @param[in]  width     Width of value printed to stream, in terms of number of characters
 *                       (default = 25)
 * @param[in]  filler    Character used to fill fixed-width (default = ' ')
 */
template< typename DataType >
inline void print( std::ostream& stream,
                   const DataType value,
                   const int width = 25,
                   const char filler = ' ' )
{
    stream << std::left << std::setw( width ) << std::setfill( filler ) << value;
}

//! Print metadata parameter to stream.
/*!
 * Prints metadata parameter to stream provided, given a specified name, value, units, and
 * delimiter.
 *
 * @tparam     DataType      Type for specified value
 * @param[out] stream        Output stream
 * @param[in]  parameterName Name for metadata parameter
 * @param[in]  value         Specified value to print
 * @param[in]  units         Units for value
 * @param[in]  delimiter     Character used to delimiter entries in stream (default = ' ')
 * @param[in]  width         Width of value printed to stream, in terms of number of characters
 *                           (default = 25)
 * @param[in]  filler        Character used to fill fixed-width (default = ' ')
 */
template< typename DataType >
inline void print( std::ostream& stream,
                   const std::string& parameterName,
                   const DataType value,
                   const std::string& units,
                   const char delimiter = ',',
                   const int width = 25,
                   const char filler = ' ' )
{
    print( stream, parameterName, width, filler );
    stream << delimiter;
    print( stream, value, width, filler );
    stream << delimiter;
    print( stream, units, width, filler );
}

//! Print state history to stream.
/*!
 * Prints state history to stream provided, given a specified tate history object, a stream header,
 * and a number of digits of precision.
 *
 * @param[out] stream        Output stream
 * @param[in]  stateHistory  State history containing epochs and associated state vectors
 * @param[in]  streamHeader  A header for the output stream (file header if a file stream is
 *                           provided) (default = "")
 * @param[in]  precision     Digits of precision for state history entries printed to stream
 *                           (default = number of digits of precision for a double)
 */
void print( std::ostream& stream,
            const StateHistory stateHistory,
            const std::string& streamHeader = "",
            const int precision = std::numeric_limits< double >::digits10 );

//! Find parameter.
/*!
 * Finds parameter in config stored in JSON document. An error is thrown if the parameter cannot
 * be found. If the parameter is found, an iterator to the member in the JSON document is returned.
 *
 * @param[in] config        JSON document containing config parameters
 * @param[in] parameterName Name of parameter to find
 * @return                  Iterator to parameter retreived from JSON document
 */
ConfigIterator find( const rapidjson::Document& config, const std::string& parameterName );

//! Remove newline characters from string.
/*!
 * Removes newline characters from a string by making use of the STL erase() and remove()
 * functions. Removes '\\n' and '\\r' characters.
 *
 * @param[in,out] string String from which newline characters should be removed
 */
void removeNewline( std::string& string );

//! Get TLE catalog type.
/*!
 * Determines the TLE catalog type (2-line or 3-line) based on the TLE format.
 *
 * @param[in] catalogFirstLine First line in TLE catalog
 * @return                     Number of lines per TLE in catalog
 */
int getTleCatalogType( const std::string& catalogFirstLine );

} // namespace d2d
<commit_msg>Increase tolerance of Approx object for floating-point comparison using CATCH (solves test failure on Ubuntu in lambert_scanner unit test).<commit_after>/*
 * Copyright (c) 2014-2015 Kartik Kumar (me@kartikkumar.com)
 * Distributed under the MIT License.
 * See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
 */

#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <string>

#include <boost/array.hpp>

#include <catch.hpp>

#include <libsgp4/Eci.h>

#include <rapidjson/document.h>

#include <Astro/astro.hpp>

namespace d2d
{

//! 3-Vector.
typedef boost::array< double, 3 > Vector3;

//! 6-Vector.
typedef boost::array< double, 6 > Vector6;

//! State history.
typedef std::map< double, Vector6 > StateHistory;

//! JSON config iterator.
typedef rapidjson::Value::ConstMemberIterator ConfigIterator;

//! Create custom CATCH Approx object with tolerance for comparing doubles.
/*!
 * Creates a custom CATCH Approx object that can be used for comparing doubles in unit tests. The
 * tolerance is set based on machine precision (epsilon) for doubles.
 *
 * Using this comparison object ensures that large numbers are compared in a relative sense and
 * small numbers in an absolute sense.
 *
 * @see CATCH
 * @see
 *      Harris, R. (2013)
 */
static Approx approx
  = Approx::custom( ).epsilon( std::numeric_limits< double >::epsilon( ) * 1000.0 );

//! Get root-path for D2D.
/*!
 * Returns path to root-directory of the D2D application (trailing slash included).
 *
 * @todo    Find a way to test the root-path function.
 *
 * @return  D2D root-path.
 */
static inline std::string getRootPath( )
{
    std::string filePath( __FILE__ );
    return filePath.substr(
      0, filePath.length( ) - std::string( "include/D2D/tools.hpp" ).length( ) );
}

//! Sample Kepler orbit.
/*!
 * Samples a Kepler orbit and generates a state-history stored in a STL map (key=epoch). The
 * Kepler orbit is sampled by using propagate_lagrangian() provided with PyKep (Izzo, 2012).
 *
 * @param[in]  initialState           Initial Cartesian state [km; km/s]
 * @param[in]  propagationTime        Total propagation time [s]
 * @param[in]  numberOfSamples        Number of samples, distributed evenly over propagation time
 * @param[in]  gravitationalParameter Gravitational parameter of central body [km^3 s^-2]
 * @param[in]  initialEpoch           Epoch corresponding to initial Cartesian state
 *                                    (default = 0.0) [Julian date]
 * @return                            State-history of sampled Kepler orbit
 */
StateHistory sampleKeplerOrbit( const Vector6& initialState,
                                const double propagationTime,
                                const int numberOfSamples,
                                const double gravitationalParameter,
                                const double initialEpoch = 0.0 );

//! Convert SGP4 ECI object to state vector.
/*!
 * Converts a Cartesian state stored in an object of the Eci class in the SGP4 library () into a
 * boost::array of 6 elements.
 *
 * @sa Eci, boost::array
 * @param  state State stored in Eci object
 * @return       State stored in boost::array
 */
Vector6 getStateVector( const Eci state );

//! Print value to stream.
/*!
 * Prints a specified value to stream provided, given a specified width and a filler character.
 *
 * @tparam     DataType  Type for specified value
 * @param[out] stream    Output stream
 * @param[in]  value     Specified value to print
 * @param[in]  width     Width of value printed to stream, in terms of number of characters
 *                       (default = 25)
 * @param[in]  filler    Character used to fill fixed-width (default = ' ')
 */
template< typename DataType >
inline void print( std::ostream& stream,
                   const DataType value,
                   const int width = 25,
                   const char filler = ' ' )
{
    stream << std::left << std::setw( width ) << std::setfill( filler ) << value;
}

//! Print metadata parameter to stream.
/*!
 * Prints metadata parameter to stream provided, given a specified name, value, units, and
 * delimiter.
 *
 * @tparam     DataType      Type for specified value
 * @param[out] stream        Output stream
 * @param[in]  parameterName Name for metadata parameter
 * @param[in]  value         Specified value to print
 * @param[in]  units         Units for value
 * @param[in]  delimiter     Character used to delimiter entries in stream (default = ' ')
 * @param[in]  width         Width of value printed to stream, in terms of number of characters
 *                           (default = 25)
 * @param[in]  filler        Character used to fill fixed-width (default = ' ')
 */
template< typename DataType >
inline void print( std::ostream& stream,
                   const std::string& parameterName,
                   const DataType value,
                   const std::string& units,
                   const char delimiter = ',',
                   const int width = 25,
                   const char filler = ' ' )
{
    print( stream, parameterName, width, filler );
    stream << delimiter;
    print( stream, value, width, filler );
    stream << delimiter;
    print( stream, units, width, filler );
}

//! Print state history to stream.
/*!
 * Prints state history to stream provided, given a specified tate history object, a stream header,
 * and a number of digits of precision.
 *
 * @param[out] stream        Output stream
 * @param[in]  stateHistory  State history containing epochs and associated state vectors
 * @param[in]  streamHeader  A header for the output stream (file header if a file stream is
 *                           provided) (default = "")
 * @param[in]  precision     Digits of precision for state history entries printed to stream
 *                           (default = number of digits of precision for a double)
 */
void print( std::ostream& stream,
            const StateHistory stateHistory,
            const std::string& streamHeader = "",
            const int precision = std::numeric_limits< double >::digits10 );

//! Find parameter.
/*!
 * Finds parameter in config stored in JSON document. An error is thrown if the parameter cannot
 * be found. If the parameter is found, an iterator to the member in the JSON document is returned.
 *
 * @param[in] config        JSON document containing config parameters
 * @param[in] parameterName Name of parameter to find
 * @return                  Iterator to parameter retreived from JSON document
 */
ConfigIterator find( const rapidjson::Document& config, const std::string& parameterName );

//! Remove newline characters from string.
/*!
 * Removes newline characters from a string by making use of the STL erase() and remove()
 * functions. Removes '\\n' and '\\r' characters.
 *
 * @param[in,out] string String from which newline characters should be removed
 */
void removeNewline( std::string& string );

//! Get TLE catalog type.
/*!
 * Determines the TLE catalog type (2-line or 3-line) based on the TLE format.
 *
 * @param[in] catalogFirstLine First line in TLE catalog
 * @return                     Number of lines per TLE in catalog
 */
int getTleCatalogType( const std::string& catalogFirstLine );

} // namespace d2d
<|endoftext|>


<commit_before><commit_msg>Fix comparison in window_sizer_linux. There can be multiple desktops so data_len can be greater.<commit_after><|endoftext|>


<commit_before>/*
 *  CWrap - A library to use C-code in C++.
 *  Copyright (C) 2016  Marcus Gelderie
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 */

#pragma once

#include <cerrno>
#include <cstring>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <type_traits>
#include <utility>

namespace cwrap {

namespace error {

struct ReportReturnValueErrorPolicy {
    template <class Rv>
    static inline void handleError(const Rv& rv) {
        std::ostringstream stream{"Return value indicated error. Got: "};
        stream << rv;
        throw std::runtime_error(stream.str());
    }
};

struct ErrnoErrorPolicy {
    template <class Rv>
    static inline void handleError(const Rv&) {
        throw std::runtime_error(std::strerror(errno));
    }
};

struct ErrorCodeErrorPolicy {
    static inline void handleError(int rv) { throw std::runtime_error(std::strerror(-rv)); }
};

using DefaultErrorPolicy = ReportReturnValueErrorPolicy;

struct IsZeroReturnCheckPolicy {
    template <class Rv>
    static inline bool returnValueIsOk(const Rv& rv) {
        static_assert(std::is_integral<std::remove_reference_t<Rv>>::value,
                      "Must be an integral value");

        return rv == 0;
    }
};

struct IsNotNegativeReturnCheckPolicy {
    template <class Rv>
    static inline bool returnValueIsOk(const Rv& rv) {
        static_assert(std::is_integral<std::remove_reference_t<Rv>>::value,
                      "Must be an integral value");
        static_assert(std::is_signed<std::remove_reference_t<Rv>>::value, "Must be a signed type");

        return rv >= 0;
    }
};

struct IsNotZeroReturnCheckPolicy {
    template <class Rv>
    static inline bool returnValueIsOk(const Rv& rv) {
        static_assert(std::is_integral<std::remove_reference_t<Rv>>::value,
                      "Must be an integral value");
        static_assert(std::is_signed<std::remove_reference_t<Rv>>::value, "Must be a signed type");

        return rv != 0;
    }
};

using DefaultReturnCheckPolicy = IsZeroReturnCheckPolicy;

template <class Functor>
using FunctorOrFuncRefType = std::conditional_t<std::is_function<Functor>::value,
                                                std::add_lvalue_reference_t<Functor>,
                                                Functor>;

template <class Functor,
          class ReturnCheckPolicy = DefaultReturnCheckPolicy,
          class ErrorPolicy = DefaultErrorPolicy>
class CallGuard {
public:
    template <class T>
    CallGuard(T&& t) : _functor{std::forward<T>(t)} {}

    template <class T = Functor,
              typename = std::enable_if_t<std::is_default_constructible<T>::value>>
    CallGuard() : _functor{} {}

    // TODO: make this more sane by allowing only "correct" invocations
    template <class... Args>
    auto operator()(Args&&... args) {
        auto retVal = _functor(std::forward<Args>(args)...);
        if (!ReturnCheckPolicy::returnValueIsOk(retVal)) {
            ErrorPolicy::handleError(retVal);
        }
        return retVal;
    }

private:
    FunctorOrFuncRefType<Functor> _functor;
};

template <class R = DefaultReturnCheckPolicy,
          class E = DefaultErrorPolicy,
          class Rv = void,
          class... Args>
auto CALL_CHECKED(Rv (*func)(Args...), Args&&... args) {
    CallGuard<decltype(func), R, E> guard(func);
    return guard(std::forward<Args>(args)...);
}

template <class R = DefaultReturnCheckPolicy,
          class E = DefaultErrorPolicy,
          class Rv = void,
          class... Args>
auto CALL_CHECKED(std::function<Rv(Args...)> func, Args&&... args) {
    CallGuard<decltype(func), R, E> guard(func);
    return guard(std::forward<Args>(args)...);
}

}  // namepsace error

}  // namespace cwrap
<commit_msg>checkcall: Simplify implementation<commit_after>/*
 *  CWrap - A library to use C-code in C++.
 *  Copyright (C) 2016  Marcus Gelderie
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 */

#pragma once

#include <cerrno>
#include <cstring>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <type_traits>
#include <utility>

namespace cwrap {

namespace error {

struct ReportReturnValueErrorPolicy {
    template <class Rv>
    static inline void handleError(const Rv& rv) {
        std::ostringstream stream{"Return value indicated error. Got: "};
        stream << rv;
        throw std::runtime_error(stream.str());
    }
};

struct ErrnoErrorPolicy {
    template <class Rv>
    static inline void handleError(const Rv&) {
        throw std::runtime_error(std::strerror(errno));
    }
};

struct ErrorCodeErrorPolicy {
    static inline void handleError(int rv) { throw std::runtime_error(std::strerror(-rv)); }
};

using DefaultErrorPolicy = ReportReturnValueErrorPolicy;

struct IsZeroReturnCheckPolicy {
    template <class Rv>
    static inline bool returnValueIsOk(const Rv& rv) {
        static_assert(std::is_integral<std::remove_reference_t<Rv>>::value,
                      "Must be an integral value");

        return rv == 0;
    }
};

struct IsNotNegativeReturnCheckPolicy {
    template <class Rv>
    static inline bool returnValueIsOk(const Rv& rv) {
        static_assert(std::is_integral<std::remove_reference_t<Rv>>::value,
                      "Must be an integral value");
        static_assert(std::is_signed<std::remove_reference_t<Rv>>::value, "Must be a signed type");

        return rv >= 0;
    }
};

struct IsNotZeroReturnCheckPolicy {
    template <class Rv>
    static inline bool returnValueIsOk(const Rv& rv) {
        static_assert(std::is_integral<std::remove_reference_t<Rv>>::value,
                      "Must be an integral value");
        static_assert(std::is_signed<std::remove_reference_t<Rv>>::value, "Must be a signed type");

        return rv != 0;
    }
};

using DefaultReturnCheckPolicy = IsZeroReturnCheckPolicy;

template <class R = DefaultReturnCheckPolicy,
          class E = DefaultErrorPolicy,
          class Callable=std::function<void(void)>,
          class... Args>
inline auto CALL_CHECKED(Callable&& callable, Args&&... args) {
    const auto& retVal = callable(std::forward<Args>(args)...);
    if (!R::returnValueIsOk(retVal)) {
        E::handleError(retVal);
    }
    return retVal;
}

template <class Functor,
          class ReturnCheckPolicy = DefaultReturnCheckPolicy,
          class ErrorPolicy = DefaultErrorPolicy>
class CallGuard {
private:
    using FunctorOrFuncRefType = std::conditional_t<std::is_function<Functor>::value,
                                                    std::add_lvalue_reference_t<Functor>,
                                                    Functor>;
public:
    template <class T>
    CallGuard(T&& t) : _functor{std::forward<T>(t)} {}

    template <class T = Functor,
              typename = std::enable_if_t<std::is_default_constructible<T>::value>>
    CallGuard() : _functor{} {}

    template <class... Args>
    auto operator()(Args&&... args) {
        return CALL_CHECKED<ReturnCheckPolicy, ErrorPolicy>(_functor, std::forward<Args>(args)...);
    }

private:
    FunctorOrFuncRefType _functor;
};

}  // namepsace error

}  // namespace cwrap
<|endoftext|>


<commit_before>// Used for testing, do not use it as an example
#include <iostream>

#include "qpp.h"
#include "experimental/experimental.h"

using namespace qpp;

template <class T>
class QCirc {
    idx d_;                      // dimension, qubit circuit (d = 2) by default
    idx nq_, nc_;                // quantum bits, classical bits/dits
    ket psi_;                    // current state of the circuit
    std::vector<bool> measured_; // set elements to one if the corresponding
    // qubit had been measured
    std::vector<idx> results_; // get_results of the measurements
    std::vector<idx> bits_;    // store the values of the classical bits/dits

  protected:
    std::vector<idx> update_subsys_(const std::vector<idx>& subsys) {
        std::vector<idx> result = subsys;
        idx subsys_size = subsys.size();
        for (idx i = 0; i < subsys_size; ++i) {
            for (idx m = 0; m < subsys[i]; ++m) {
                if (measured_[m]) { // if the qubit m was measured
                    --result[i];
                }
            }
        }
        std::sort(std::begin(result), std::end(result), std::less<idx>{});
        return result;
    }

  public:
    QCirc(idx nq, idx nc, idx d = 2)
        : d_{d}, nq_{nq}, nc_{nc}, psi_{st.zero(nq_, d_)},
          measured_(nq_, false), results_(nq_, -1), bits_(nc_, 0) {}

    // destructive measurement
    void measure(std::vector<idx> subsys) {
        // sort subsys in decreasing order
        idx subsys_size = subsys.size();
        for (idx i = 0; i < subsys_size; ++i) {
            if (measured_[subsys[i]])
                throw exception::CustomException(
                    "qpp::QCirc::measure()", "Subsystem was measured before");
        }
        // update subsystem labels
        std::vector<idx> subsys_updated = update_subsys_(subsys);
        for (idx i = 0; i < subsys_size; ++i) {
            measured_[subsys[i]] = true;
        }
        auto m = measure_seq(psi_, subsys_updated, d_);
        auto result = std::get<0>(m); // measurement result
        for (idx i = 0; i < subsys_size; ++i)
            results_[subsys[i]] = result[i];
        // update psi_
        psi_ = std::get<2>(m);
        // std::cout << disp(psi_) << '\n';
    }

    // destructive measurement of all remaining qubits
    void measure_all() {
        std::vector<idx> subsys;
        for (idx i = 0; i < nq_; ++i) {
            if (!measured_[i])
                subsys.push_back(i);
        }
        // update subsystem labels
        std::vector<idx> subsys_updated = update_subsys_(subsys);
        if (subsys.size() != 0)
            this->measure(subsys);
        else
            throw exception::CustomException("qpp::QCirc::measure_all()",
                                             "All qubits were measured before");
    }

    void apply(const cmat& gate, const std::vector<idx>& subsys) {
        psi_ = qpp::apply(psi_, gate, update_subsys_(subsys), d_);
    }

    void applyCTRL(const cmat& gate, const std::vector<idx>& ctrl,
                   const std::vector<idx>& target) {
        psi_ = qpp::applyCTRL(psi_, gate, ctrl, target, d_);
    }

    void apply_all(const cmat& gate) {
        for (idx i = 0; i < nq_; ++i)
            if (!measured_[i]) {
                psi_ = qpp::apply(psi_, gate, update_subsys_({i}), d_);
            }
    }

    // resets the circuit
    void reset() {
        psi_ = st.zero(nq_);
        measured_ = std::vector<bool>(nq_, false);
        results_ = std::vector<idx>(nq_, -1);
        bits_ = std::vector<idx>(nc_, 0);
    }

    /* getters */
    // local dimension
    idx d() const noexcept { return d_; }

    // total number of qubits, regardless of being measured or not
    idx get_nq() const noexcept { return nq_; }

    // total number of classical bits/dits
    idx get_nc() const noexcept { return nc_; }

    // total number of qubits AND classical bits/dits
    idx get_size() const noexcept { return nq_ + nc_; }

    // total number of measured qubits
    idx get_num_measured_qubits() const noexcept {
        return std::count(std::begin(measured_), std::end(measured_), true);
    }

    // total number of non-measured qubits
    idx get_num_active_qubits() const noexcept {
        return this->get_nq() - this->get_num_measured_qubits();
    }

    // returns the up-to-date quantum state
    ket get_psi() const { return psi_; }

    // returns the results of the measurements
    std::vector<idx> get_results() const { return results_; }

    // returns the current result of the measurement as an integer,
    // ignores non-measured qubits
    idx get_results_as_N() const {
        std::vector<idx> tmp;
        for (idx i = 0; i < nq_; ++i) {
            if (measured_[i])
                tmp.push_back(results_[i]);
        }

        return multiidx2n(tmp, std::vector<idx>(tmp.size(), d_));
    }

    // returns the classical bits/dits array
    std::vector<idx>& bits() noexcept { return bits_; }
    /* end getters */
};

int main() {
    QCirc<int> qc(10, 10);
    qc.apply_all(gt.H);
    qc.measure({3, 1, 7});
    std::cout << qc.get_num_measured_qubits() << '\n';
    std::cout << qc.get_num_active_qubits() << '\n';
    qc.measure({2, 4, 5, 6, 0});
    std::cout << disp(qc.get_results(), " ") << '\n';
    qc.apply_all(gt.H);
    qc.apply_all(gt.X);
    qc.measure_all();
    // qc.measure_all();
    std::cout << disp(qc.get_results(), "") << '\n';
    std::cout << qc.get_results_as_N() << '\n';
    std::cout << qc.get_nq() << '\n';
    std::cout << qc.get_num_measured_qubits() << '\n';
    std::cout << qc.get_num_active_qubits() << "\n\n";
    std::cout << "\n\n";

    QCirc<int> qc1(2, 0);
    qc1.apply(gt.H, {0});
    qc1.applyCTRL(gt.X, {0}, {1});
    qc1.apply(gt.CNOT, {0, 1});
    qc1.measure({0});

    std::cout << qc1.get_num_measured_qubits() << '\n';
    std::cout << qc1.get_num_active_qubits() << '\n';
    std::cout << disp(qc1.get_results(), " ") << '\n';
    std::cout << disp(qc1.get_psi()) << "\n\n";

    qc1.reset();
    std::cout << qc1.get_num_measured_qubits() << '\n';
    std::cout << qc1.get_num_active_qubits() << '\n';
    std::cout << disp(qc1.get_results(), " ") << '\n';
    std::cout << disp(qc1.get_psi()) << "\n\n";

    QCirc<int> qc2(2, 10, 3);
    qc2.apply(gt.Xd(3), {0});
    qc2.measure({1});
    std::cout << disp(qc2.get_psi()) << "\n\n";
    std::cout << qc2.get_size() << " " << qc2.d() << "\n\n";
}
<commit_msg>commit<commit_after>// Used for testing, do not use it as an example
#include <iostream>

#include "qpp.h"
#include "experimental/experimental.h"

using namespace qpp;

template <class T>
class QCirc {
    idx d_;                      // dimension, qubit circuit (d = 2) by default
    idx nq_, nc_;                // quantum bits, classical bits/dits
    ket psi_;                    // current state of the circuit
    std::vector<bool> measured_; // set elements to one if the corresponding
                                 // qubit had been measured
    std::vector<idx> results_;   // get_results of the measurements
    std::vector<idx> bits_;      // store the values of the classical bits/dits

  protected:
    std::vector<idx> update_subsys_(const std::vector<idx>& subsys) {
        std::vector<idx> result = subsys;
        idx subsys_size = subsys.size();
        for (idx i = 0; i < subsys_size; ++i) {
            for (idx m = 0; m < subsys[i]; ++m) {
                if (measured_[m]) { // if the qubit m was measured
                    --result[i];
                }
            }
        }
        std::sort(std::begin(result), std::end(result), std::less<idx>{});
        return result;
    }

  public:
    QCirc(idx nq, idx nc, idx d = 2)
        : d_{d}, nq_{nq}, nc_{nc}, psi_{st.zero(nq_, d_)},
          measured_(nq_, false), results_(nq_, -1), bits_(nc_, 0) {}

    // destructive measurement
    void measure(std::vector<idx> subsys) {
        // sort subsys in decreasing order
        idx subsys_size = subsys.size();
        for (idx i = 0; i < subsys_size; ++i) {
            if (measured_[subsys[i]])
                throw exception::CustomException(
                    "qpp::QCirc::measure()", "Subsystem was measured before");
        }
        // update subsystem labels
        std::vector<idx> subsys_updated = update_subsys_(subsys);
        for (idx i = 0; i < subsys_size; ++i) {
            measured_[subsys[i]] = true;
        }
        auto m = measure_seq(psi_, subsys_updated, d_);
        auto result = std::get<0>(m); // measurement result
        for (idx i = 0; i < subsys_size; ++i)
            results_[subsys[i]] = result[i];
        // update psi_
        psi_ = std::get<2>(m);
        // std::cout << disp(psi_) << '\n';
    }

    // destructive measurement of all remaining qubits
    void measure_all() {
        std::vector<idx> subsys;
        for (idx i = 0; i < nq_; ++i) {
            if (!measured_[i])
                subsys.push_back(i);
        }
        // update subsystem labels
        std::vector<idx> subsys_updated = update_subsys_(subsys);
        if (subsys.size() != 0)
            this->measure(subsys);
        else
            throw exception::CustomException("qpp::QCirc::measure_all()",
                                             "All qubits were measured before");
    }

    void apply(const cmat& gate, const std::vector<idx>& subsys) {
        psi_ = qpp::apply(psi_, gate, update_subsys_(subsys), d_);
    }

    void applyCTRL(const cmat& gate, const std::vector<idx>& ctrl,
                   const std::vector<idx>& target) {
        psi_ = qpp::applyCTRL(psi_, gate, ctrl, target, d_);
    }

    void apply_all(const cmat& gate) {
        for (idx i = 0; i < nq_; ++i)
            if (!measured_[i]) {
                psi_ = qpp::apply(psi_, gate, update_subsys_({i}), d_);
            }
    }

    // resets the circuit
    void reset() {
        psi_ = st.zero(nq_);
        measured_ = std::vector<bool>(nq_, false);
        results_ = std::vector<idx>(nq_, -1);
        bits_ = std::vector<idx>(nc_, 0);
    }

    /* getters */
    // local dimension
    idx d() const noexcept { return d_; }

    // total number of qubits, regardless of being measured or not
    idx get_nq() const noexcept { return nq_; }

    // total number of classical bits/dits
    idx get_nc() const noexcept { return nc_; }

    // total number of qubits AND classical bits/dits
    idx get_size() const noexcept { return nq_ + nc_; }

    // total number of measured qubits
    idx get_num_measured_qubits() const noexcept {
        return std::count(std::begin(measured_), std::end(measured_), true);
    }

    // total number of non-measured qubits
    idx get_num_active_qubits() const noexcept {
        return this->get_nq() - this->get_num_measured_qubits();
    }

    // returns the up-to-date quantum state
    ket get_psi() const { return psi_; }

    // returns the results of the measurements
    std::vector<idx> get_results() const { return results_; }

    // returns the current result of the measurement as an integer,
    // ignores non-measured qubits
    idx get_results_as_N() const {
        std::vector<idx> tmp;
        for (idx i = 0; i < nq_; ++i) {
            if (measured_[i])
                tmp.push_back(results_[i]);
        }

        return multiidx2n(tmp, std::vector<idx>(tmp.size(), d_));
    }

    // returns the classical bits/dits array
    std::vector<idx>& bits() noexcept { return bits_; }
    /* end getters */
};

int main() {
    QCirc<int> qc(10, 10);
    qc.apply_all(gt.H);
    qc.measure({3, 1, 7});
    std::cout << qc.get_num_measured_qubits() << '\n';
    std::cout << qc.get_num_active_qubits() << '\n';
    qc.measure({2, 4, 5, 6, 0});
    std::cout << disp(qc.get_results(), " ") << '\n';
    qc.apply_all(gt.H);
    qc.apply_all(gt.X);
    qc.measure_all();
    // qc.measure_all();
    std::cout << disp(qc.get_results(), "") << '\n';
    std::cout << qc.get_results_as_N() << '\n';
    std::cout << qc.get_nq() << '\n';
    std::cout << qc.get_num_measured_qubits() << '\n';
    std::cout << qc.get_num_active_qubits() << "\n\n";
    std::cout << "\n\n";

    QCirc<int> qc1(2, 0);
    qc1.apply(gt.H, {0});
    qc1.applyCTRL(gt.X, {0}, {1});
    qc1.apply(gt.CNOT, {0, 1});
    qc1.measure({0});

    std::cout << qc1.get_num_measured_qubits() << '\n';
    std::cout << qc1.get_num_active_qubits() << '\n';
    std::cout << disp(qc1.get_results(), " ") << '\n';
    std::cout << disp(qc1.get_psi()) << "\n\n";

    qc1.reset();
    std::cout << qc1.get_num_measured_qubits() << '\n';
    std::cout << qc1.get_num_active_qubits() << '\n';
    std::cout << disp(qc1.get_results(), " ") << '\n';
    std::cout << disp(qc1.get_psi()) << "\n\n";

    QCirc<int> qc2(2, 10, 3);
    qc2.apply(gt.Xd(3), {0});
    qc2.measure({1});
    std::cout << disp(qc2.get_psi()) << "\n\n";
    std::cout << qc2.get_size() << " " << qc2.d() << "\n\n";
}
<|endoftext|>


<commit_before>#include "Genes/Piece_Strength_Gene.h"

#include <string>
#include <array>
#include <map>

#include "Genes/Gene.h"
#include "Game/Piece.h"
#include "Game/Color.h"

#include "Utility/Random.h"

class Board;

Piece_Strength_Gene::Piece_Strength_Gene() noexcept
{
    piece_strength.fill(100.0);
    renormalize_values();
    zero_out_priority();
}

void Piece_Strength_Gene::adjust_properties(std::map<std::string, double>& properties) const noexcept
{
    properties.erase("Priority");
    for(auto piece_type : {Piece_Type::PAWN, Piece_Type::ROOK, Piece_Type::KNIGHT, Piece_Type::BISHOP, Piece_Type::QUEEN, Piece_Type::KING})
    {
        auto piece = Piece{Piece_Color::WHITE, piece_type};
        properties[std::string(1, piece.fen_symbol())] = piece_value(piece_type);
    }
}

void Piece_Strength_Gene::load_gene_properties(const std::map<std::string, double>& properties)
{
    for(auto piece_type : {Piece_Type::PAWN, Piece_Type::ROOK, Piece_Type::KNIGHT, Piece_Type::BISHOP, Piece_Type::QUEEN, Piece_Type::KING})
    {
        auto piece = Piece{Piece_Color::WHITE, piece_type};
        piece_value(piece_type) = properties.at(std::string(1, piece.fen_symbol()));
    }

    renormalize_values();
}

void Piece_Strength_Gene::gene_specific_mutation() noexcept
{
    auto& value = Random::random_element(piece_strength);
    value += Random::random_laplace(0.005);
    renormalize_values();
}

void Piece_Strength_Gene::renormalize_values() noexcept
{
    auto normalizing_value = 8*std::abs(piece_value(Piece_Type::PAWN)) +
                             2*std::abs(piece_value(Piece_Type::ROOK)) +
                             2*std::abs(piece_value(Piece_Type::KNIGHT)) +
                             2*std::abs(piece_value(Piece_Type::BISHOP)) +
                             1*std::abs(piece_value(Piece_Type::QUEEN)) +
                             1*std::abs(piece_value(Piece_Type::KING));

    if(normalizing_value > 0.0)
    {
        for(auto& v : piece_strength)
        {
            v /= normalizing_value;
        }
    }
}

double Piece_Strength_Gene::piece_value(Piece_Type type) const noexcept
{
    return piece_strength[static_cast<int>(type)];
}

double& Piece_Strength_Gene::piece_value(Piece_Type type) noexcept
{
    return piece_strength[static_cast<int>(type)];
}

double Piece_Strength_Gene::piece_value(Piece piece) const noexcept
{
    if( ! piece || ! is_active())
    {
        return 0.0;
    }
    else
    {
        return piece_value(piece.type());
    }
}

const std::array<double, 6>& Piece_Strength_Gene::piece_values() const noexcept
{
    if(is_active())
    {
        return piece_strength;
    }
    else
    {
        static const auto inactive_piece_values = std::array<double, 6>{};
        return inactive_piece_values;
    }
}

std::string Piece_Strength_Gene::name() const noexcept
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, Piece_Color, size_t) const noexcept
{
    return 0.0;
}
<commit_msg>Reduce need to explicitly list all piece types<commit_after>#include "Genes/Piece_Strength_Gene.h"

#include <string>
#include <array>
#include <map>

#include "Genes/Gene.h"
#include "Game/Piece.h"
#include "Game/Color.h"

#include "Utility/Random.h"

class Board;

Piece_Strength_Gene::Piece_Strength_Gene() noexcept
{
    piece_strength.fill(100.0);
    renormalize_values();
    zero_out_priority();
}

void Piece_Strength_Gene::adjust_properties(std::map<std::string, double>& properties) const noexcept
{
    properties.erase("Priority");
    for(size_t piece_index = 0; piece_index < piece_strength.size(); ++piece_index)
    {
        auto piece = Piece{Piece_Color::WHITE, static_cast<Piece_Type>(piece_index)};
        properties[std::string(1, piece.fen_symbol())] = piece_value(piece);
    }
}

void Piece_Strength_Gene::load_gene_properties(const std::map<std::string, double>& properties)
{
    for(size_t piece_index = 0; piece_index < piece_strength.size(); ++piece_index)
    {
        auto piece = Piece{Piece_Color::WHITE, static_cast<Piece_Type>(piece_index)};
        piece_value(piece.type()) = properties.at(std::string(1, piece.fen_symbol()));
    }

    renormalize_values();
}

void Piece_Strength_Gene::gene_specific_mutation() noexcept
{
    auto& value = Random::random_element(piece_strength);
    value += Random::random_laplace(0.005);
    renormalize_values();
}

void Piece_Strength_Gene::renormalize_values() noexcept
{
    auto normalizing_value = 8*std::abs(piece_value(Piece_Type::PAWN)) +
                             2*std::abs(piece_value(Piece_Type::ROOK)) +
                             2*std::abs(piece_value(Piece_Type::KNIGHT)) +
                             2*std::abs(piece_value(Piece_Type::BISHOP)) +
                             1*std::abs(piece_value(Piece_Type::QUEEN)) +
                             1*std::abs(piece_value(Piece_Type::KING));

    if(normalizing_value > 0.0)
    {
        for(auto& v : piece_strength)
        {
            v /= normalizing_value;
        }
    }
}

double Piece_Strength_Gene::piece_value(Piece_Type type) const noexcept
{
    return piece_strength[static_cast<int>(type)];
}

double& Piece_Strength_Gene::piece_value(Piece_Type type) noexcept
{
    return piece_strength[static_cast<int>(type)];
}

double Piece_Strength_Gene::piece_value(Piece piece) const noexcept
{
    if( ! piece || ! is_active())
    {
        return 0.0;
    }
    else
    {
        return piece_value(piece.type());
    }
}

const std::array<double, 6>& Piece_Strength_Gene::piece_values() const noexcept
{
    if(is_active())
    {
        return piece_strength;
    }
    else
    {
        static const auto inactive_piece_values = std::array<double, 6>{};
        return inactive_piece_values;
    }
}

std::string Piece_Strength_Gene::name() const noexcept
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, Piece_Color, size_t) const noexcept
{
    return 0.0;
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "tilemap.h"

/*
TODO:

- Make the drawing calls here avoid using a buffer, consider drawing to the screen directly.
*/

void* al_img_loader2(const char* path)
{
    ALLEGRO_BITMAP *res = NULL;
    ALLEGRO_PATH   *alpath = NULL;

    if (!(alpath = al_create_path(path))) return NULL;

    al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA);
    res = al_load_bitmap(al_path_cstr(alpath, ALLEGRO_NATIVE_PATH_SEP));

    al_destroy_path(alpath);

    return (void*) res;
}

TileMap::TileMap(std::string path)
{
    tmx_img_load_func = al_img_loader2;
    tmx_img_free_func = (void(*)(void*))al_destroy_bitmap;

    map = tmx_load(path.c_str());
    if (map == nullptr)
    {
        std::cerr << tmx_strerr() << std::endl;
        return;
    }

    int bmpWidth = map->tile_width * map->width;
    int bmpHeight = map->tile_height * map->height;
    fullMap = al_create_bitmap(bmpWidth, bmpHeight);
    if (fullMap == nullptr)
    {
        std::cerr << "Could not create a new bitmap resource! " << this << std::endl;
        tmx_map_free(map);
        return;
    }

    renderFullMap();

    int arrLength = map->height * map->width;
    walkTable = new int[arrLength];
    for (int i = 0; i < arrLength; i++)
    {
        walkTable[i] = 1; // Default to all spaces walkable in the tilemap
    }
    readWalkProperty(arrLength);
}

TileMap::~TileMap()
{
    tmx_map_free(map);
    al_destroy_bitmap(fullMap);
    delete [] walkTable;
}

ALLEGRO_BITMAP* TileMap::GetFullMap()
{
    return fullMap;
}

void TileMap::DrawLayerMap(std::string LayerName)
{
    tmx_layer *layer = getLayerByName(LayerName);

    if (layer == nullptr)
    {
        return; // Error message is printed by getLayerByName, so not needed here.
    }

    if (layer->visible)
    {
        identLayer(layer);
    }
}

bool TileMap::CanWalktoTileAt(Vec2D pixCoord, Vec2D pixSize, Vec2D offset)
{
	float tileW = map->tile_width;
	float tileH = map->tile_height;
	float x = (pixCoord.x + offset.x) / tileW;
	float y = (pixCoord.y + offset.y) / tileH;

    unsigned int range = (int)x * (int)y;
    if (range > ((map->height * map->width) - 1))
    {
        std::cerr << "Warning: Tile outside range: (" << (int)x << "," << (int)y << ")" <<std::endl;
        return false;
    }

    // arrayPosition = (y * numberOfColumns) + x
    int value = walkTable[((int)y * map->width) + (int)x];
	if (value > 0) // If its 0 or less (unlikely) you cannot walk, anything else is ok
	{
		return true; // can walk
	}
	else
	{

		/*public bool intersects(aabb other)
		{
			if (this.max.x < other.min.x ||
				this.max.y < other.min.y ||
				this.min.x > other.max.x ||
				this.min.y > other.max.y)
			{
				return false;
			}
			return true;
		}*/

		Vec2D tilePos = { x * tileW, y * tileH };
		Vec2D tileSize = { (x * tileW) + tileW, (y * tileH) + tileH };
		if (tileSize.x < pixCoord.x ||
			tileSize.y < pixCoord.y ||
			tilePos.x > pixSize.x ||
			tilePos.y > pixSize.y)
		{
			return false;
		}
		return true;
	}
}

ALLEGRO_COLOR TileMap::int_to_al_color(int color)
{
    unsigned char r, g, b;

    r = (color >> 16) & 0xFF;
    g = (color >> 8) & 0xFF;
    b = (color) & 0xFF;

    return al_map_rgb(r, g, b);
}

void TileMap::draw_polyline(double **points, double x, double y, int pointsC, ALLEGRO_COLOR color)
{
    int i;
    for (i = 1; i<pointsC; i++)
    {
        al_draw_line(x + points[i - 1][0], y + points[i - 1][1], x + points[i][0], y + points[i][1], color, LINE_THICKNESS);
    }
}

void TileMap::draw_polygone(double **points, double x, double y, int pointsC, ALLEGRO_COLOR color)
{
    draw_polyline(points, x, y, pointsC, color);
    if (pointsC > 2)
    {
        al_draw_line(x + points[0][0], y + points[0][1], x + points[pointsC - 1][0], y + points[pointsC - 1][1], color, LINE_THICKNESS);
    }
}

void TileMap::draw_objects(tmx_object *head, ALLEGRO_COLOR color)
{
    while (head)
    {
        if (head->visible)
        {
            switch (head->shape)
            {
                case S_SQUARE:
                    al_draw_rectangle(head->x, head->y, head->x + head->width, head->y + head->height, color, LINE_THICKNESS);
                    break;
                case S_POLYGON:
                    draw_polygone(head->points, head->x, head->y, head->points_len, color);
                    break;
                case S_POLYLINE:
                    draw_polyline(head->points, head->x, head->y, head->points_len, color);
                    break;
                case S_ELLIPSE:
                    al_draw_ellipse(head->x + head->width / 2.0, head->y + head->height / 2.0, head->width / 2.0, head->height / 2.0, color, LINE_THICKNESS);
                    break;
                default:
                    std::cerr << "Warning: An unknown object type was found: " << head->shape << std::endl;
                    break;
            }
        }

        head = head->next;
    }
}

int TileMap::gid_extract_flags(unsigned int gid)
{
    int res = 0;

    if (gid & TMX_FLIPPED_HORIZONTALLY) res |= ALLEGRO_FLIP_HORIZONTAL;
    if (gid & TMX_FLIPPED_VERTICALLY)   res |= ALLEGRO_FLIP_VERTICAL;
    /* FIXME allegro has no diagonal flip */
    return res;
}

int TileMap::gid_clear_flags(unsigned int gid)
{
    return gid & TMX_FLIP_BITS_REMOVAL;
}

void TileMap::draw_layer(tmx_map *map, tmx_layer *layer)
{
    unsigned long x, y; // The map coordinates
    unsigned int sx, sy, sw, sh, flags; // Individual tile coordinates
    float op; // Tile opacity value

    tmx_tileset *ts;
    ALLEGRO_BITMAP *tileset; /* Owned by the tmx library */

    op = layer->opacity;

    al_hold_bitmap_drawing(true);
    for (y = 0; y < map->height; y++)
    {
        for (x = 0; x < map->width; x++)
        {
            ts = tmx_get_tileset(map, layer->content.gids[(y*map->width) + x], &sx, &sy);
            if (ts)
            {
                sw = ts->tile_width;
                sh = ts->tile_height;

                tileset = (ALLEGRO_BITMAP*) ts->image->resource_image;
                flags = gid_extract_flags(layer->content.gids[(y*map->width) + x]);

                al_draw_tinted_bitmap_region(tileset, al_map_rgba_f(op, op, op, op),
                    sx, sy, sw, sh, x*ts->tile_width, y*ts->tile_height, flags);
            }
        }
    }
    al_hold_bitmap_drawing(false);
}

void TileMap::renderFullMap()
{
    tmx_layer *layers = map->ly_head;

    if (map->orient != O_ORT)
    {
        std::cerr << "Error: I only render Ortogonal maps!" << std::endl;
        return;
    }

    al_set_target_bitmap(fullMap);
    al_clear_to_color(int_to_al_color(map->backgroundcolor));

    while (layers)
    {
        identLayer(layers);
        layers = layers->next;
    }

    al_set_target_backbuffer(al_get_current_display());
}

tmx_layer *TileMap::getLayerByName(std::string name)
{
    tmx_layer *currLayer = map->ly_head;
    std::string layerName = currLayer->name;

    while (currLayer)
    {
        if (layerName == name)
        {
            return currLayer;
        } else
        {
            currLayer = currLayer->next;
            layerName = currLayer->name;
        }
    }

    std::cerr << "Error: Layer " << name << " not found." << std::endl;
    return nullptr;
}

void TileMap::readWalkProperty(int arrLength)
{
    tmx_layer *layer = map->ly_head;

    while (layer)
    {
        if (layer->type == L_LAYER)
        {
            for (int i = 0; i < arrLength; i++)
            {
                tmx_tile *tile = tmx_get_tile(map, layer->content.gids[i]);

                if (tile != nullptr)
                {
                    tmx_property *props = tile->properties;
                    while (props)
                    {
                        std::string name = props->name;
                        if (name == "canWalk")
                        {
                            walkTable[i] = atoi(props->value);
                        }
                        props = props->next;
                    }
                }
            }
        }

        layer = layer->next;
    }
}

// Decides how to render a layer. then renders it.
void TileMap::identLayer(tmx_layer *layer)
{
    switch (layer->type)
    {
        case L_OBJGR:
            draw_objects(layer->content.head, int_to_al_color(layer->color));
            break;
        case L_IMAGE:
            if (layer->opacity < 1.)
            {
                float op = layer->opacity;
                al_draw_tinted_bitmap((ALLEGRO_BITMAP*) layer->content.image->resource_image, al_map_rgba_f(op, op, op, op), 0, 0, 0); /* TODO: does not render at correct position */
            } else
            {
                al_draw_bitmap((ALLEGRO_BITMAP*) layer->content.image->resource_image, 0, 0, 0);
            }
            break;
        case L_LAYER:
            draw_layer(map, layer);
            break;
        default:
            std::cerr << "Warning: I just dropped an unknown layer: " << layer->name << std::endl;
            break;
    }
}
<commit_msg>Apply formatting<commit_after>#include "stdafx.h"
#include "tilemap.h"

/*
TODO:

- Make the drawing calls here avoid using a buffer, consider drawing to the screen directly.
*/

void* al_img_loader2(const char* path)
{
    ALLEGRO_BITMAP *res = NULL;
    ALLEGRO_PATH   *alpath = NULL;

    if (!(alpath = al_create_path(path))) return NULL;

    al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA);
    res = al_load_bitmap(al_path_cstr(alpath, ALLEGRO_NATIVE_PATH_SEP));

    al_destroy_path(alpath);

    return (void*)res;
}

TileMap::TileMap(std::string path)
{
    tmx_img_load_func = al_img_loader2;
    tmx_img_free_func = (void(*)(void*))al_destroy_bitmap;

    map = tmx_load(path.c_str());
    if (map == nullptr)
    {
        std::cerr << tmx_strerr() << std::endl;
        return;
    }

    int bmpWidth = map->tile_width * map->width;
    int bmpHeight = map->tile_height * map->height;
    fullMap = al_create_bitmap(bmpWidth, bmpHeight);
    if (fullMap == nullptr)
    {
        std::cerr << "Could not create a new bitmap resource! " << this << std::endl;
        tmx_map_free(map);
        return;
    }

    renderFullMap();

    int arrLength = map->height * map->width;
    walkTable = new int[arrLength];
    for (int i = 0; i < arrLength; i++)
    {
        walkTable[i] = 1; // Default to all spaces walkable in the tilemap
    }
    readWalkProperty(arrLength);
}

TileMap::~TileMap()
{
    tmx_map_free(map);
    al_destroy_bitmap(fullMap);
    delete[] walkTable;
}

ALLEGRO_BITMAP* TileMap::GetFullMap()
{
    return fullMap;
}

void TileMap::DrawLayerMap(std::string LayerName)
{
    tmx_layer *layer = getLayerByName(LayerName);

    if (layer == nullptr)
    {
        return; // Error message is printed by getLayerByName, so not needed here.
    }

    if (layer->visible)
    {
        identLayer(layer);
    }
}

bool TileMap::CanWalktoTileAt(Vec2D pixCoord, Vec2D pixSize, Vec2D offset)
{
	float tileW = map->tile_width;
	float tileH = map->tile_height;
	float x = (pixCoord.x + offset.x) / tileW;
	float y = (pixCoord.y + offset.y) / tileH;

    unsigned int range = (int)x * (int)y;
    if (range > ((map->height * map->width) - 1))
    {
        std::cerr << "Warning: Tile outside range: (" << (int)x << "," << (int)y << ")" <<std::endl;
        return false;
    }

    // arrayPosition = (y * numberOfColumns) + x
    int value = walkTable[((int)y * map->width) + (int)x];
	if (value > 0) // If its 0 or less (unlikely) you cannot walk, anything else is ok
	{
		return true; // can walk
	}
	else
	{

		/*public bool intersects(aabb other)
		{
			if (this.max.x < other.min.x ||
				this.max.y < other.min.y ||
				this.min.x > other.max.x ||
				this.min.y > other.max.y)
			{
				return false;
			}
			return true;
		}*/

		Vec2D tilePos = { x * tileW, y * tileH };
		Vec2D tileSize = { (x * tileW) + tileW, (y * tileH) + tileH };
		if (tileSize.x < pixCoord.x ||
			tileSize.y < pixCoord.y ||
			tilePos.x > pixSize.x ||
			tilePos.y > pixSize.y)
		{
			return false;
		}
		return true;
	}
}

ALLEGRO_COLOR TileMap::int_to_al_color(int color)
{
    unsigned char r, g, b;

    r = (color >> 16) & 0xFF;
    g = (color >> 8) & 0xFF;
    b = (color)& 0xFF;

    return al_map_rgb(r, g, b);
}

void TileMap::draw_polyline(double **points, double x, double y, int pointsC, ALLEGRO_COLOR color)
{
    int i;
    for (i = 1; i < pointsC; i++)
    {
        al_draw_line(x + points[i - 1][0], y + points[i - 1][1], x + points[i][0], y + points[i][1], color, LINE_THICKNESS);
    }
}

void TileMap::draw_polygone(double **points, double x, double y, int pointsC, ALLEGRO_COLOR color)
{
    draw_polyline(points, x, y, pointsC, color);
    if (pointsC > 2)
    {
        al_draw_line(x + points[0][0], y + points[0][1], x + points[pointsC - 1][0], y + points[pointsC - 1][1], color, LINE_THICKNESS);
    }
}

void TileMap::draw_objects(tmx_object *head, ALLEGRO_COLOR color)
{
    while (head)
    {
        if (head->visible)
        {
            switch (head->shape)
            {
                case S_SQUARE:
                    al_draw_rectangle(head->x, head->y, head->x + head->width, head->y + head->height, color, LINE_THICKNESS);
                    break;
                case S_POLYGON:
                    draw_polygone(head->points, head->x, head->y, head->points_len, color);
                    break;
                case S_POLYLINE:
                    draw_polyline(head->points, head->x, head->y, head->points_len, color);
                    break;
                case S_ELLIPSE:
                    al_draw_ellipse(head->x + head->width / 2.0, head->y + head->height / 2.0, head->width / 2.0, head->height / 2.0, color, LINE_THICKNESS);
                    break;
                default:
                    std::cerr << "Warning: An unknown object type was found: " << head->shape << std::endl;
                    break;
            }
        }

        head = head->next;
    }
}

int TileMap::gid_extract_flags(unsigned int gid)
{
    int res = 0;

    if (gid & TMX_FLIPPED_HORIZONTALLY) res |= ALLEGRO_FLIP_HORIZONTAL;
    if (gid & TMX_FLIPPED_VERTICALLY)   res |= ALLEGRO_FLIP_VERTICAL;
    /* FIXME allegro has no diagonal flip */
    return res;
}

int TileMap::gid_clear_flags(unsigned int gid)
{
    return gid & TMX_FLIP_BITS_REMOVAL;
}

void TileMap::draw_layer(tmx_map *map, tmx_layer *layer)
{
    unsigned long x, y; // The map coordinates
    unsigned int sx, sy, sw, sh, flags; // Individual tile coordinates
    float op; // Tile opacity value

    tmx_tileset *ts;
    ALLEGRO_BITMAP *tileset; /* Owned by the tmx library */

    op = layer->opacity;

    al_hold_bitmap_drawing(true);
    for (y = 0; y < map->height; y++)
    {
        for (x = 0; x < map->width; x++)
        {
            ts = tmx_get_tileset(map, layer->content.gids[(y*map->width) + x], &sx, &sy);
            if (ts)
            {
                sw = ts->tile_width;
                sh = ts->tile_height;

                tileset = (ALLEGRO_BITMAP*)ts->image->resource_image;
                flags = gid_extract_flags(layer->content.gids[(y*map->width) + x]);

                al_draw_tinted_bitmap_region(tileset, al_map_rgba_f(op, op, op, op),
                    sx, sy, sw, sh, x*ts->tile_width, y*ts->tile_height, flags);
            }
        }
    }
    al_hold_bitmap_drawing(false);
}

void TileMap::renderFullMap()
{
    tmx_layer *layers = map->ly_head;

    if (map->orient != O_ORT)
    {
        std::cerr << "Error: I only render Ortogonal maps!" << std::endl;
        return;
    }

    al_set_target_bitmap(fullMap);
    al_clear_to_color(int_to_al_color(map->backgroundcolor));

    while (layers)
    {
        identLayer(layers);
        layers = layers->next;
    }

    al_set_target_backbuffer(al_get_current_display());
}

tmx_layer *TileMap::getLayerByName(std::string name)
{
    tmx_layer *currLayer = map->ly_head;
    std::string layerName = currLayer->name;

    while (currLayer)
    {
        if (layerName == name)
        {
            return currLayer;
        } else
        {
            currLayer = currLayer->next;
            layerName = currLayer->name;
        }
    }

    std::cerr << "Error: Layer " << name << " not found." << std::endl;
    return nullptr;
}

void TileMap::readWalkProperty(int arrLength)
{
    tmx_layer *layer = map->ly_head;

    while (layer)
    {
        if (layer->type == L_LAYER)
        {
            for (int i = 0; i < arrLength; i++)
            {
                tmx_tile *tile = tmx_get_tile(map, layer->content.gids[i]);

                if (tile != nullptr)
                {
                    tmx_property *props = tile->properties;
                    while (props)
                    {
                        std::string name = props->name;
                        if (name == "canWalk")
                        {
                            walkTable[i] = atoi(props->value);
                        }
                        props = props->next;
                    }
                }
            }
        }

        layer = layer->next;
    }
}

// Decides how to render a layer. then renders it.
void TileMap::identLayer(tmx_layer *layer)
{
    switch (layer->type)
    {
        case L_OBJGR:
            draw_objects(layer->content.head, int_to_al_color(layer->color));
            break;
        case L_IMAGE:
            if (layer->opacity < 1.)
            {
                float op = layer->opacity;
                al_draw_tinted_bitmap((ALLEGRO_BITMAP*)layer->content.image->resource_image, al_map_rgba_f(op, op, op, op), 0, 0, 0); /* TODO: does not render at correct position */
            } else
            {
                al_draw_bitmap((ALLEGRO_BITMAP*)layer->content.image->resource_image, 0, 0, 0);
            }
            break;
        case L_LAYER:
            draw_layer(map, layer);
            break;
        default:
            std::cerr << "Warning: I just dropped an unknown layer: " << layer->name << std::endl;
            break;
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Andreas Sandberg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef DCXX_TYPES_HH
#define DCXX_TYPES_HH

#include <cmath>
#include <dcxx/utils.hh>

DCXX_BEGIN_NS_DC

/** One foot in metre */
#define DCXX_FOOT 0.3048

struct Duration {
    Duration(double val)
	: val(val) {}

    static Duration seconds(double val) {
	return Duration(val);
    }

    double seconds() const {
	return val;
    }

    static Duration minutes(double val) {
	return Duration(val * 60);
    }

    double minutes() const {
	return val / 60;
    }

    static Duration hours(double val) {
	return Duration(val * 60 * 60);
    }

    double hours() const {
	return val / 60 / 60;
    }

    operator double() { return val; }

    /** Duration in seconds */
    double val;
};

struct Length {
    Length(double val)
	: val(val) {}

    static Length metre(double val) {
	return Length(val);
    }

    double metre() const {
	return val;
    }

    static Length feet(double val) {
	return Length(DCXX_FOOT * val);
    }

    double feet() const {
	return val / DCXX_FOOT;
    }

    operator double() { return val; }

    /** Length, always in metre */
    double val;
};

DCXX_END_NS

#endif
<commit_msg>Add default constructors for Duration and Length that sets them to 0<commit_after>/*
 * Copyright (c) 2011, Andreas Sandberg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef DCXX_TYPES_HH
#define DCXX_TYPES_HH

#include <cmath>
#include <dcxx/utils.hh>

DCXX_BEGIN_NS_DC

/** One foot in metre */
#define DCXX_FOOT 0.3048

struct Duration {
    Duration()
	: val(0.0) {}
    Duration(double val)
	: val(val) {}

    static Duration seconds(double val) {
	return Duration(val);
    }

    double seconds() const {
	return val;
    }

    static Duration minutes(double val) {
	return Duration(val * 60);
    }

    double minutes() const {
	return val / 60;
    }

    static Duration hours(double val) {
	return Duration(val * 60 * 60);
    }

    double hours() const {
	return val / 60 / 60;
    }

    operator double() { return val; }

    /** Duration in seconds */
    double val;
};

struct Length {
    Length()
	: val(0.0) {}
    Length(double val)
	: val(val) {}

    static Length metre(double val) {
	return Length(val);
    }

    double metre() const {
	return val;
    }

    static Length feet(double val) {
	return Length(DCXX_FOOT * val);
    }

    double feet() const {
	return val / DCXX_FOOT;
    }

    operator double() { return val; }

    /** Length, always in metre */
    double val;
};

DCXX_END_NS

#endif
<|endoftext|>


<commit_before>
#include <SDL.h>
#include <SDL_audio.h>
#include <akAudioMixer.h>
#include <assert.h>
#include <signal.h>
#include <iostream>
#include "utils.h"

class SDLWav
{
public:
    SDLWav(const char* filename):
        m_audioBuf(nullptr),
        m_audioLen(0),
        m_spec()
    {
        SDL_LoadWAV(filename, &m_spec, &m_audioBuf, &m_audioLen);
        assert(m_spec.freq == 44100);
        assert(m_spec.format == AUDIO_S16);
        assert(m_spec.channels == 1);
        std::cout << filename << " has " << (m_audioLen >> 1) << " samples\n";
    }

    ~SDLWav()
    {
        if (m_audioBuf)
        {
            SDL_FreeWAV(m_audioBuf);
        }
    }

    explicit operator bool() const
    {
        return (m_audioBuf != nullptr && m_audioLen > 0);
    }

    const SDL_AudioSpec& GetSpec() const
    {
        return m_spec;
    }

    const int16_t* GetSamplePtr() const
    {
        return reinterpret_cast<const int16_t*>(m_audioBuf);
    }

    uint32_t GetNumSamples() const
    {
        assert((m_audioLen % 2) == 0);
        return (m_audioLen >> 1);
    }

private:
    Uint8* m_audioBuf;
    Uint32 m_audioLen;
    SDL_AudioSpec m_spec;
};

int mixerMain(SDL_AudioDeviceID audioDevice, const SDLWav& wav)
{
    akAudioMixer::AudioMixerConfig cfg;
    // mix ahead time needs to be dt at minimum,
    // but larger in most cases to catch misbehaving timers
    // which usually jump for 15-30 ms periodically
    cfg.mixAheadSeconds = 0.05f;
    akAudioMixer::AudioMixer* mixer = akAudioMixer::CreateAudioMixer(cfg);
    if (!mixer)
    {
        return -1;
    }

    akAudioMixer::AudioSource source;
    source.SetSource(wav.GetSamplePtr(), wav.GetNumSamples());
    mixer->AddSource(source);

    utils::RunLoop(0.01f, [&](double absoluteTime, float delta)
    {
        const uint32_t deltaSamples = static_cast<uint32_t>(round(delta * 44100.0f));
        akAudioMixer::AudioBuffer output = mixer->Update(deltaSamples);
        SDL_QueueAudio(audioDevice, output.samples, static_cast<Uint32>(output.numSamples*2));
        return (output.samples != nullptr) && (output.samples > 0);
    });

    akAudioMixer::FreeAudioMixer(mixer);
    return 0;
}

static void quit(int param)
{
    exit(1);
}

int main(int argc, const char* argv[])
{
    std::cout.sync_with_stdio(false);
    signal(SIGINT, &quit);
    utils::FixWorkingDirectory();
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_AudioSpec audioSpec;
    SDL_zero(audioSpec);
    audioSpec.freq = 44100;
    audioSpec.format = AUDIO_S16;
    audioSpec.channels = 1;
    audioSpec.samples = 4096;
    SDL_AudioDeviceID audioDevice = SDL_OpenAudioDevice(nullptr, false, &audioSpec, nullptr, 0);

    std::cout << "Drivers:\n";
    int numDrivers = SDL_GetNumAudioDrivers();
    for (int i = 0; i < numDrivers; ++i)
    {
        std::cout << SDL_GetAudioDriver(i) << "\n";
    }
    std::cout << "Devices:\n";
    int numDevices = SDL_GetNumAudioDevices(0);
    for (int i = 0; i < numDevices; ++i)
    {
        std::cout << SDL_GetAudioDeviceName(i, 0) << "\n";
    }

    SDLWav thunder("media/thunder2.wav");

    int ret = -1;
    while (audioDevice > 1 && thunder)
    {
        SDL_PauseAudioDevice(audioDevice, 0);
        ret = mixerMain(audioDevice, thunder);
        SDL_PauseAudioDevice(audioDevice, 1);
        getchar();
    }

    SDL_CloseAudioDevice(audioDevice);
    SDL_Quit();
    return ret;
}
<commit_msg>Increased mix ahead amount in AudioMixerTest<commit_after>
#include <SDL.h>
#include <SDL_audio.h>
#include <akAudioMixer.h>
#include <assert.h>
#include <signal.h>
#include <iostream>
#include "utils.h"

class SDLWav
{
public:
    SDLWav(const char* filename):
        m_audioBuf(nullptr),
        m_audioLen(0),
        m_spec()
    {
        SDL_LoadWAV(filename, &m_spec, &m_audioBuf, &m_audioLen);
        assert(m_spec.freq == 44100);
        assert(m_spec.format == AUDIO_S16);
        assert(m_spec.channels == 1);
        std::cout << filename << " has " << (m_audioLen >> 1) << " samples\n";
    }

    ~SDLWav()
    {
        if (m_audioBuf)
        {
            SDL_FreeWAV(m_audioBuf);
        }
    }

    explicit operator bool() const
    {
        return (m_audioBuf != nullptr && m_audioLen > 0);
    }

    const SDL_AudioSpec& GetSpec() const
    {
        return m_spec;
    }

    const int16_t* GetSamplePtr() const
    {
        return reinterpret_cast<const int16_t*>(m_audioBuf);
    }

    uint32_t GetNumSamples() const
    {
        assert((m_audioLen % 2) == 0);
        return (m_audioLen >> 1);
    }

private:
    Uint8* m_audioBuf;
    Uint32 m_audioLen;
    SDL_AudioSpec m_spec;
};

int mixerMain(SDL_AudioDeviceID audioDevice, const SDLWav& wav)
{
    akAudioMixer::AudioMixerConfig cfg;
    // mix ahead time needs to be dt at minimum,
    // but larger in most cases to catch misbehaving timers
    // which can jump for 15-30 ms periodically
    cfg.mixAheadSeconds = 0.1f;
    akAudioMixer::AudioMixer* mixer = akAudioMixer::CreateAudioMixer(cfg);
    if (!mixer)
    {
        return -1;
    }

    akAudioMixer::AudioSource source;
    source.SetSource(wav.GetSamplePtr(), wav.GetNumSamples());
    mixer->AddSource(source);

    utils::RunLoop(0.01f, [&](double absoluteTime, float delta)
    {
        const uint32_t deltaSamples = static_cast<uint32_t>(round(delta * 44100.0f));
        akAudioMixer::AudioBuffer output = mixer->Update(deltaSamples);
        SDL_QueueAudio(audioDevice, output.samples, static_cast<Uint32>(output.numSamples*2));
        return (output.samples != nullptr) && (output.samples > 0);
    });

    akAudioMixer::FreeAudioMixer(mixer);
    return 0;
}

static void quit(int param)
{
    exit(1);
}

int main(int argc, const char* argv[])
{
    std::cout.sync_with_stdio(false);
    signal(SIGINT, &quit);
    utils::FixWorkingDirectory();
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_AudioSpec audioSpec;
    SDL_zero(audioSpec);
    audioSpec.freq = 44100;
    audioSpec.format = AUDIO_S16;
    audioSpec.channels = 1;
    audioSpec.samples = 4096;
    SDL_AudioDeviceID audioDevice = SDL_OpenAudioDevice(nullptr, false, &audioSpec, nullptr, 0);

    std::cout << "Drivers:\n";
    int numDrivers = SDL_GetNumAudioDrivers();
    for (int i = 0; i < numDrivers; ++i)
    {
        std::cout << SDL_GetAudioDriver(i) << "\n";
    }
    std::cout << "Devices:\n";
    int numDevices = SDL_GetNumAudioDevices(0);
    for (int i = 0; i < numDevices; ++i)
    {
        std::cout << SDL_GetAudioDeviceName(i, 0) << "\n";
    }

    SDLWav thunder("media/thunder2.wav");

    int ret = -1;
    while (audioDevice > 1 && thunder)
    {
        SDL_PauseAudioDevice(audioDevice, 0);
        ret = mixerMain(audioDevice, thunder);
        SDL_PauseAudioDevice(audioDevice, 1);
        getchar();
    }

    SDL_CloseAudioDevice(audioDevice);
    SDL_Quit();
    return ret;
}
<|endoftext|>


<commit_before>// Copyright © 2014 Lénaïc Bagnères, hnc@singularity.fr

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef HNC_COLOR_HPP
#define HNC_COLOR_HPP

#include <iostream>
#include <iomanip>
#include <ios>
#include <string>

#include "int.hpp"
#include "to_string.hpp"
#include "algo/to_upper.hpp"

#include "serialization.hpp"

namespace hnc
{
	/**
	 * @brief hnc::color
	 *
	 * @code
	   #include <hnc/color.hpp>
	   @endcode
	 */
	class color
	{
	public:

		/// Red level
		hnc::uint8 r;

		/// Green level
		hnc::uint8 g;

		/// Blue level
		hnc::uint8 b;

		/// Alpha level (transparency)
		hnc::uint8 a;

		/// @brief Default constructor
		color() : r(0), g(0), b(0), a(255) { }

		/// @brief Constructor
		/// @param[in] r Red level
		/// @param[in] g Green level
		/// @param[in] b Blue level
		/// @param[in] a Alpha level (transparency)
		color
		(
			hnc::uint8 const & r,
			hnc::uint8 const & g,
			hnc::uint8 const & b,
			hnc::uint8 const & a = 255
		) :
			r(r), g(g), b(b), a(a)
		{ }

		/// @brief HTML code of the color
		/// @return HTML code of the color
		std::string html()
		{
			return hnc::algo::to_upper_copy
			(
				std::string("#") +
				hnc::to_string(r, std::setw(2), std::setfill('0'), std::hex) +
				hnc::to_string(g, std::setw(2), std::setfill('0'), std::hex) +
				hnc::to_string(b, std::setw(2), std::setfill('0'), std::hex)
			);
		}

		hnc_generate_serialize_method(r, g, b, a)
	};

	/// @brief Operator == between two hnc::color
	/// @param[in] a A hnc::color
	/// @param[in] b A hnc::color
	/// @return true if the hnc::color are equal, false otherwise
	inline bool operator==(hnc::color const & a, hnc::color const & b)
	{
		return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
	}

	/// @brief Operator != between two hnc::color
	/// @param[in] a A hnc::color
	/// @param[in] b A hnc::color
	/// @return true if the hnc::color are different, false otherwise
	inline bool operator!=(hnc::color const & a, hnc::color const & b)
	{
		return !(a == b);
	}

	/// @brief Operator << between a std::ostream and a hnc::color
	/// @param[in,out] o     Output stream
	/// @param[in]     color A hnc::color
	/// @return the output stream
	inline std::ostream & operator<<(std::ostream & o, hnc::color const & color)
	{
		o << "{ " << color.r << ", " << color.g << ", " << color.b << ", " << color.a << " }";
		return o;
	}
}

#endif
<commit_msg>Add hnc::color::black() and hnc::color::white()<commit_after>// Copyright © 2014 Lénaïc Bagnères, hnc@singularity.fr

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef HNC_COLOR_HPP
#define HNC_COLOR_HPP

#include <iostream>
#include <iomanip>
#include <ios>
#include <string>

#include "int.hpp"
#include "to_string.hpp"
#include "algo/to_upper.hpp"

#include "serialization.hpp"

namespace hnc
{
	/**
	 * @brief hnc::color
	 *
	 * @code
	   #include <hnc/color.hpp>
	   @endcode
	 */
	class color
	{
	public:

		/// Red level
		hnc::uint8 r;

		/// Green level
		hnc::uint8 g;

		/// Blue level
		hnc::uint8 b;

		/// Alpha level (transparency)
		hnc::uint8 a;

		/// @brief Default constructor
		color() : r(0), g(0), b(0), a(255) { }

		/// @brief Constructor
		/// @param[in] r Red level
		/// @param[in] g Green level
		/// @param[in] b Blue level
		/// @param[in] a Alpha level (transparency)
		color
		(
			hnc::uint8 const & r,
			hnc::uint8 const & g,
			hnc::uint8 const & b,
			hnc::uint8 const & a = 255
		) :
			r(r), g(g), b(b), a(a)
		{ }

		/// @brief HTML code of the color
		/// @return HTML code of the color
		std::string html()
		{
			return hnc::algo::to_upper_copy
			(
				std::string("#") +
				hnc::to_string(r, std::setw(2), std::setfill('0'), std::hex) +
				hnc::to_string(g, std::setw(2), std::setfill('0'), std::hex) +
				hnc::to_string(b, std::setw(2), std::setfill('0'), std::hex)
			);
		}

		hnc_generate_serialize_method(r, g, b, a)

		/// @brief Black color
		/// @return Black color
		static hnc::color black() { return { 0, 0, 0 }; }

		/// @brief White color
		/// @return White color
		static hnc::color white() { return { 255, 255, 255 }; }
	};

	/// @brief Operator == between two hnc::color
	/// @param[in] a A hnc::color
	/// @param[in] b A hnc::color
	/// @return true if the hnc::color are equal, false otherwise
	inline bool operator==(hnc::color const & a, hnc::color const & b)
	{
		return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
	}

	/// @brief Operator != between two hnc::color
	/// @param[in] a A hnc::color
	/// @param[in] b A hnc::color
	/// @return true if the hnc::color are different, false otherwise
	inline bool operator!=(hnc::color const & a, hnc::color const & b)
	{
		return !(a == b);
	}

	/// @brief Operator << between a std::ostream and a hnc::color
	/// @param[in,out] o     Output stream
	/// @param[in]     color A hnc::color
	/// @return the output stream
	inline std::ostream & operator<<(std::ostream & o, hnc::color const & color)
	{
		o << "{ " << color.r << ", " << color.g << ", " << color.b << ", " << color.a << " }";
		return o;
	}
}

#endif
<|endoftext|>