LoginSignup
1
1

More than 5 years have passed since last update.

パラメーター用のクラス

Last updated at Posted at 2017-08-11

経緯とか書くと長くなるのでまずはコードから

PossibleChangeStatus.hpp
#ifndef __POSSIBLECHANGESTATUS_HPP__
#define __POSSIBLECHANGESTATUS_HPP__
#ifdef _MINWINDEF_ // Windows.h等がこのヘッダーより先にincludeされるとダメなのでundefする
#undef max
#undef min
#endif
#include <type_traits>
#include <algorithm>

inline float ChangeTwoDigits(const double Data) {
    return static_cast<float>(static_cast<int>((Data + 0.005) * 100)) / 100;
}

//C++17
template<typename T>
const T& clamp(const T& v, const T& lo, const T& hi) {
    return assert( !comp(hi, lo) ),
        (v < lo) ? lo : (hi < v) ? hi : v;
}

template<class T> class PossibleChangeStatus {
private:
    T MinStatus;
public:
    //public member variable
    T CurrentStatus, MaxStatus;

    PossibleChangeStatus() = default;
    PossibleChangeStatus(const PossibleChangeStatus&) = default;
    PossibleChangeStatus& operator=(const PossibleChangeStatus&) = default;
    PossibleChangeStatus(const T Max) : PossibleChangeStatus(Max, Max) {}
    PossibleChangeStatus(const T Current, const T Max, const T Min = 0)
        : MinStatus(Min), CurrentStatus(Current), MaxStatus(Max) {}


    //public member function
    PossibleChangeStatus operator+(const T Num) {
        return {
            clamp(this->CurrentStatus + Num, this->MinStatus, this->MaxStatus),
            this->MaxStatus, this->MinStatus
        };
    }
    PossibleChangeStatus operator-(const T Num) {
        return {
            clamp(this->CurrentStatus - Num, this->MinStatus, this->MaxStatus),
            this->MaxStatus, this->MinStatus
        };
    }
    PossibleChangeStatus operator*(const T Num) {
        return {
            clamp(this->CurrentStatus * Num, this->MinStatus, this->MaxStatus),
            this->MaxStatus, this->MinStatus
        };
    }
    PossibleChangeStatus operator/(const T Num) {
        return {
            clamp(this->CurrentStatus / Num, this->MinStatus, this->MaxStatus),
            this->MaxStatus, this->MinStatus
        };
    }
    PossibleChangeStatus& operator += (const T Num) {
        this->CurrentStatus = clamp(this->CurrentStatus + Num, this->MinStatus, this->MaxStatus);
        return *this;
    }
    PossibleChangeStatus& operator -= (const T Num) {
        this->CurrentStatus = clamp(this->CurrentStatus - Num, this->MinStatus, this->MaxStatus);
        return *this;
    }
    PossibleChangeStatus& operator *= (const T Num) {
        this->CurrentStatus = clamp(this->CurrentStatus * Num, this->MinStatus, this->MaxStatus);
        return *this;
    }
    PossibleChangeStatus& operator /= (const T Num) {
        this->CurrentStatus = clamp(this->CurrentStatus / Num, this->MinStatus, this->MaxStatus);
        return *this;
    }
    PossibleChangeStatus& operator++() {
        this->CurrentStatus = std::min(this->CurrentStatus + 1, this->MaxStatus);
        return *this;
    }
    PossibleChangeStatus operator++(int) {
        const auto re = *this;
        ++(*this);
        return re;
    }
    PossibleChangeStatus& operator--() {
        this->CurrentStatus = std::max(this->CurrentStatus - 1, this->MinStatus);
        return *this;
    }
    PossibleChangeStatus operator--(int) {
        const auto re = *this;
        --(*this);
        return re;
    }
    T& operator * () { return this->CurrentStatus; }
    const T& operator * () const { return this->CurrentStatus; }
    T& get() { return this->CurrentStatus; }
    const T& get() const { return this->CurrentStatus; }
    bool operator< (const T CompareNum) const { return this->CurrentStatus < CompareNum; }
    bool operator<= (const T CompareNum) const { return this->CurrentStatus <= CompareNum; }
    bool operator> (const T CompareNum) const { return this->CurrentStatus > CompareNum; }
    bool operator>= (const T CompareNum) const { return this->CurrentStatus >= CompareNum; }
    bool IsMin() const { return this->CurrentStatus == this->MinStatus; }
    bool IsMax() const { return this->CurrentStatus == this->MaxStatus; }
    float GetProportion() const { return ChangeTwoDigits(static_cast<double>(this->CurrentStatus) / static_cast<double>(this->MaxStatus - this->MinStatus)); }
};
template<typename T>
inline bool operator==(T l, const PossibleChangeStatus<T>& r) { return l == r.CurrentStatus; }
template<typename T>
inline bool operator==(const PossibleChangeStatus<T>& l, T r) { return r == l; }
template<typename T>
inline bool operator!=(T l, const PossibleChangeStatus<T>& r) { return !(l == r); }
template<typename T>
inline bool operator!=(const PossibleChangeStatus<T>& l, T r) { return r != l; }

#endif

このクラス作った環境がVisual Studio Professional 2013だった関係もありますが、一応constexprの使用は控えてありますので、C++11以前でも一応使える(?)ようになってます。(yumetodo氏みたく企画書読んだり大学の単位を捧げたりするほどC++やってないのでC++いくつまで使えるのかは知りません)

さて、作った経緯なんですが、現在公開中の未完成作品モンスター討伐ゲーム アンチ核家族化のパラメーターを管理するにあたり、Statusというクラスがこんなことになってまして…

Status.h
#include <string>

class Status {
public:
    Status(std::vector<status_data> arr, int i, bool is_player_setting);
    std::string name;
    int hp, max_hp, mp, max_mp, attack, defence, magic_attack, magic_defence, speed, graph_handle;
    bool is_male;
};

変数定義もちょっと多いし、計算部分に毎度毎度std::maxとstd::min書くのがめちゃくちゃめんどくなりまして…。
特に敵からの範囲攻撃、味方による範囲回復になると各キャラのHP変更するだけで3個も書かないといけなくて…。

まあそれがあまりにめんどくて、このクラスを作ったわけです。
これならGetProportion関数使えばHPゲージの実装も楽ですし、Minimize関数使えば死亡判定可能ですし、Less関数使えばパラメーター表示色変更も実装できちゃいます。

追記1

このクラスを他のキャラクター情報管理に使用するクラスと共にMITライセンスでGitHubに公開開始しました。
当該リポジトリはこちら
2017年8月23日現在、動作を完全に保証できるコンパイル環境は以下の通りです。

  • Microsoft Visual Studio 2013(PossibleChangeStatusクラスのみ)
  • Microsoft Visual Studio 2015
  • Microsoft Visual Studio 2017
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1