未来の私へ送るデザインパターン 3/24 [Adapter]

このシリーズは、この内容を忘れた未来のcacaponが読んだときに、
自力でそれを使ったプログラムが自作できることを目的として作られました~

こちらの記事は、以下を主に参考に作成しておりま…
したが、理解しにくい部分が多々出てきたので現在模索中です~

www.techscore.com

今回はGoF本を参考にしました~

オブジェクト指向における再利用のためのデザインパターン
エリック ガンマ ラルフ ジョンソン リチャード ヘルム ジョン ブリシディース
ソフトバンククリエイティブ
売り上げランキング: 18,655

残りは、cacaponの記憶の片隅にある情報がソース元になります~

また、2回書いていたのですが、書く量が多くて挫折しそうなので、
フォーマットを変えてみました~

またちょくちょく変えると思います~

Adapterってどんなやつ?

AdapterパターンはクラスAが「クラスBの何かを使いたい…でもできない!」
という時に使われるデザインパターンだそうです~

身近な例ですと、携帯の充電ケーブルがイメージしやすいですかね?
cacaponの充電器は、iPhoneなので、ケーブル自体はLightning端子?とUSB2.0?で出来ているモノを使用しています~
これだと、パソコンに刺して充電できますけど、電源プラグからは充電できませんよね?
電源プラグからも充電したい場合に使うのが、電源アダプターかと思います。

f:id:cacapon:20200214183158p:plain

こんな感じで、
使えないものを使えるようにするための装置、というかインターフェース?
の事をアダプターというらしいです。
これをオブジェクト指向で作成する場合でも使っちゃおうということですね~


アダプターパターンの実現方法は2種類あるそうです~
一つはクラスに適用する場合、もう一つがオブジェクトに適用する場合だそうです~

f:id:cacapon:20200214183222p:plain

GoF本によりますと、それぞれ特徴があってトレードオフがあるそうです~ 気になった部分だけ書くと…

  • クラスに適用する有場合は、具象クラスのAdapterにインターフェースを使えるようにする処理を任せるので、
    サブクラス全体に適用する場合はうまく行かないらしいです。 その代わり、オーバーライドするのは簡単らしいです~
  • オブジェクトに適用する場合は、Adapteeクラスのふるまいをオーバーライドするのが難しいそうです~ その代わり、サブクラスも含めた適用を行う場合は比較的簡単にできるっぽいです~

要はケースバイケースですかね?奥が深いです~


## pythonでの実装例

今回は、先に紹介した図のうち、
オブジェクトに適用する場合に沿った実装をしてみたいと思います~

具体例はこちら

f:id:cacapon:20200214183345p:plain

実装については下記リンクを参考に作り直しました~

pythonによるデザインパターン[Adapter] - Since I want to start “blog” that looks like men do, I do start. - Medium

from abc import ABCMeta, abstractmethod


def myiPhone():
    t = Cable()
    t.charge(plug='Power')


class Power():
    def __init__(self):
        pass

    def chargefromPower(self, plug):
        if plug == 'Power':
            print('電源から充電を開始します')
        else:
            print('plugが合わないので電源から充電ができませんでした')


class Adapter(metaclass=ABCMeta):
    @abstractmethod
    def charge(self):
        pass


class Cable(Adapter):
    def __init__(self):
        self.__Power = Power()

    def charge(self, plug):
        self.__Power.chargefromPower(plug)


if __name__ == '__main__':
    myiPhone()


疑問点

アダプターをかませない場合の処理ってどこにどう書けばいいんですかね?USBケーブルでしょうか??
今回だと、差し込み先を変数として渡すようにしてみたのですが、
USB端子の場合の処理をどこに書けばいいか分かりませんでした…

ん~まだまだ自在に扱えるまでには時間がかかりそうです~

未来の私へ送るデザインパターン 2/24 [iterator]

このシリーズは、この内容を忘れた未来のcacaponが読んだときに、
自力でそれを使ったプログラムが自作できることを目的として作られました~

こちらの記事は、以下を主に参考に作成しております♪
残りは、cacaponの記憶の片隅にある情報がソース元になります~

www.techscore.com

iteratorとは?

iteratorは日本語だと「反復子」というそうです…
あんまり聞いたことがないです~

プログラマだとイメージつきやすいのはfor文の i変数ですかね?
繰り返すときにどんどん増えてくアレです~
日常生活だと…分からないなぁ…

参考URLだと、最もイメージしやすいデザインパターンがこれらしいので、
こちらから紹介されていました~

メリットとしては、 配列の中から情報の一覧を取得したり、検索を掛けたりする際、
中の構造に関係なく情報を取得できるそうです~
凄いですね~


例題

フッキー博士は未知の生物の研究者。
ある特徴を持つ生物に対し、「パチモン」と名づけ、
パチモンの生態をまとめた図鑑を作ることにしました。

協力者にお願いしていたパチモンの情報が5つ届いたので、
図鑑に情報を追加することにします。

届いた情報は以下の通りです。

  • 名前:マカフクサ 分類:しょくぶつパチモン
  • 名前:ヒグアナ 分類:イグアナパチモン
  • 名前:ヨロイガメ 分類:カメパチモン
  • 名前:マメッポー 分類:ハトパチモン
  • 名前:ネズット 分類:ネズミパチモン

図鑑に追加した後、
図鑑利用者が追加した情報の一覧を見れるようにしてください。

怒られないかなぁ…大丈夫かなぁ…


itaratorを使わないで作ったプログラム

こんな構成で作りました~ f:id:cacapon:20200207150915p:plain

# main.py

from user import User
from doctorfukkey import DoctorFukkey

DrFukkey = DoctorFukkey()
you = User()

DrFukkey.work()
you.lookpicturebook()
# doctorfukkey.py

from picturebook import PictureBook


class DoctorFukkey():
    def work(self):
        use = PictureBook()

        use.add_pachimon_info('マカフクサ', 'しょくぶつパチモン')
        use.add_pachimon_info('ヒグアナ', 'イグアナパチモン')
        use.add_pachimon_info('ヨロイガメ', 'カメパチモン')
        use.add_pachimon_info('マメッポー', 'ハトパチモン')
        use.add_pachimon_info('ネズット', 'ネズミパチモン')
# user.py
from pprint import pprint
from picturebook import PictureBook


class User():
    def lookpicturebook(self):
        use = PictureBook()
        pprint(use.show_pachimon_info())
# picturebook.py やむを得ずシングルトンを使用しています

class PictureBook():
    _instance = None
    _pachimon_info = {}

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._pachimon_info = {}

        return cls._instance

    def add_pachimon_info(self, name, classifying):
        PictureBook._pachimon_info[name] = classifying

    def show_pachimon_info(self):
        return PictureBook._pachimon_info


その後…

考えられるのはこんなところでしょうか?

  • 図鑑の登録形式が変わった。(Noの追加とか、体長、体重の追加など)
  • 一覧でなくで特定の条件のものを表示したい
  • キーワードから特定のパチモンを表示できる

…最初にDict型で作ってしまったせいか、あまりiteratorの恩恵がわかりにくいかもです…


itaratorを使って作ったプログラム

f:id:cacapon:20200207234658p:plain

こんな感じにするそうです。
ではやってみましょう~

# main.py

from concreteaggregate import ConcreteAggregate
from concreteiterator import ConcreteIterator

use = ConcreteAggregate()

use.add_pachimon_info('マカフクサ', 'しょくぶつパチモン')
use.add_pachimon_info('ヒグアナ', 'イグアナパチモン')
use.add_pachimon_info('ヨロイガメ', 'カメパチモン')
use.add_pachimon_info('マメッポー', 'ハトパチモン')
use.add_pachimon_info('ネズット', 'ネズミパチモン')


iterator = ConcreteIterator(use)

while(iterator.hasnext()):
    print(iterator.next())

# iterator.py

from abc import ABCMeta, abstractmethod


class Iterator(metaclass=ABCMeta):
    @abstractmethod
    def hasnext(self):
        pass

    @abstractmethod
    def next(self):
        pass
# concreteiterator.py

from iterator import Iterator


class ConcreteIterator(Iterator):
    def __init__(self, concreteAggregate):
        self.__concreteaggregate = concreteAggregate
        self.__last = 0

    def next(self):
        info = self.__concreteaggregate.get_pachimon_info(self.__last)
        self.__last += 1
        return info

    def hasnext(self):
        if self.__last >= len(self.__concreteaggregate.show_pachimon_list()):
            return False
        return True
# aggregate.py

from abc import ABCMeta, abstractmethod

from iterator import Iterator


class Aggregate(metaclass=ABCMeta):
    def __init__(self):
        self.Iterator = Iterator()

    @abstractmethod
    def iterator(self):
        pass
# concreteaggregate.py

from aggregate import Aggregate
from concreteiterator import ConcreteIterator


class ConcreteAggregate(Aggregate):
    def __init__(self):
        self.__pachimon_info = []

    def add_pachimon_info(self, name, classflying):
        self.__pachimon_info.append([name, classflying])

    def get_pachimon_info(self, index):
        return self.__pachimon_info[index]

    def show_pachimon_list(self):
        return self.__pachimon_info

    def iterator(self):
        return ConcreteIterator(ConcreteAggregate())


その後...の対応例

今回は対応例が思いつかなかったので割愛します~

未来の私へ送るデザインパターン 1/24 [オブジェクト指向]

このシリーズは、この内容を忘れた未来のcacaponが読んだときに、
自力でそれを使ったプログラムが自作できることを目的として作られました~

こちらの記事は、以下を主に参考に作成しております♪
残りは、cacaponの記憶の片隅にある情報がソース元になります~

www.techscore.com

オブジェクト指向とは?

オブジェクト指向は、設計するときの考え方の一つです~
「設計図」から「オブジェクト」を作り出し、
「オブジェクト」同士のやり取りで処理を作っていくイメージになります~

設計図の事をクラスと言ったり、
オブジェクトの事をインスタンスということもあるので注意です~

メリットとしては、手続き型で設計したときと比べて
生産性が高いこと、再利用性が高いことが挙げられます~

なぜデザインパターンのついてのブログでオブジェクト指向をまとめているかというと、
デザインパターンオブジェクト指向の子どもみたいなものだからです~

オブジェクト指向のメリットは上述の通りですが、
一見オブジェクト指向で設計しても生産性とか再利用性が無いプログラムが続出しました~
(現にcacaponの作ったプログラムもその気が強いです…)

そんな人たちのために、4人の頭の良い方が、
「よくある問題をオブジェクト指向で設計する際の解答例を23個作ったぜ!」
って作られたのがデザインパターンなのです~

f:id:cacapon:20200130003111p:plain

例題

ボタンが押されると紙コップが出てくる機械を考えています~
それをプログラムで表現してみてください~
あ、従業員さんが補充できるように「補充出来る機能」も忘れずに~


オブジェクト指向を使わないで作ったプログラム

手続き型のやり方で作っていきたいと思います~
因みに、手続き型というのは、手順に沿って処理をやっていく形式の設計ですね~

def getRemainingPaperCup():
    # 残り個数が記載されているPaperCup.txtから残り個数を取得します。
    with open('PaperCup.txt', mode='r') as f:
        remainingcup = int(f.read())
    return remainingcup


def setRemainingPaperCup():
    # 残り個数をPaperCup.txtに保存します。
    with open('PaperCup.txt', mode='w') as f:
        f.write(str(haspapercup))


haspapercup = getRemainingPaperCup()
command = {
    '1': 'eject',
    '2': 'charge',
    '3': 'exit'
}


while(True):
    num = input('コマンドを入力してください \n1:カップを出す 2:カップを補充する 3:終了\n>>>')
    if command.get(num) == 'eject':
        if haspapercup == 0:
            print('紙コップがありません\n')
        else:
            haspapercup -= 1
            setRemainingPaperCup()
            print('紙コップを出しました')
            print('残り{}個です。'.format(haspapercup))
    elif command.get(num) == 'charge':
        try:
            chargecount = int(input('補充する数を1~100の間で設定してください\n>>>'))
        except ValueError:
            print('不正な入力です')
        else:
            if chargecount <= 0 or chargecount > 100:
                print('個数が正しくありません。最初からやり直してください')
            else:
                haspapercup += chargecount
                setRemainingPaperCup()
                print('紙コップを{}個補充しました'.format(chargecount))

        pass
    elif command.get(num) == 'exit':
        print('終了します')
        break
    else:
        print('入力エラーです、もう一度入力してください\n')


その後…

ちょっとごちゃごちゃしてますが、ちゃんと動いていそうです~
ただ、しばらくたつと紙コッププログラムを使っていた人たちから…

  • 紙コップを出す以外に、お湯付で紙コップを出す機能もつけたい
  • サービスエリアの紙コッププログラムは消費が激しいので、
    ここだけ1000個まで補充できるようにしてほしい
  • 当たりくじ付きの紙コップつけれない?

などなど、いっぱい改善案が出てきました~
ありがたいことなのですが、手続き型で作っていると、
それを元に作り直す手間が凄いことになりそうです~


オブジェクト指向を使って作ったプログラム

というわけで、オブジェクト指向っぽく作り直しました~
現時点でcacaponが理解している形がこのプログラムになります~

オブジェクト指向に沿って、紙コップマシンの設計図として
PaperCupMachineクラスを作成しました~
このクラスから生成する場合は、pythonの場合
objectname = ClassName()
という風に書くとオブジェクトが出来上がります~

設計図からオブジェクトを生成した後は、
従来通りコマンドで選択出来る形をとっていますが、…ここもオブジェクトにしていきたいところです~

class PaperCupMachine():
    def __init__(self):
        # 残り個数をPaperCup.txtから取得します。
        with open('PaperCup.txt', mode='r') as f:
            self.remainingcup = int(f.read())

        # 最大容量を設定します。
        self.maximumcapacity = 100

    def eject(self):
        # 紙コップを一個出します。
        if self.remainingcup == 0:
            print('紙コップがありません')
        else:
            self.remainingcup -= 1
            self._setRemainingPaperCup()
            print('紙コップを出しました')
            print('残り{}個です。'.format(self.remainingcup))

    def charge(self, chargecount):
        # 入力された個数をチャージします。
        if self._inputchecker(chargecount):
            print('不正な入力です')
            return

        if self._chargechecker(chargecount):
            return
        else:
            self.remainingcup += chargecount
            self._setRemainingPaperCup()
            print('紙コップを{}個補充しました'.format(chargecount))

    def _inputchecker(self, data):
        # inputしてはいけないint型以外の型入力ならTrueを返します。
        return not type(data) is int

    def _setRemainingPaperCup(self):
        # 残り個数をPaperCup.txtに保存します。
        with open('PaperCup.txt', mode='w') as f:
            f.write(str(self.remainingcup))

    def _chargechecker(self, chargecount):
        # 以下の場合、Trueを返します。
        # 追加した場合に最大容量を超える時
        # 与えられた追加個数が不正な値の場合True
        if chargecount < 0:
            print('入力値は最大容量以下の自然数でお願いします')
            return True
        if self.remainingcup + chargecount > self.maximumcapacity:
            print('容量を超えたため、入力を受け付け出来ませんでした')
            return True
        return False


papercupmachine_object = PaperCupMachine()

command = {
    '1': 'eject',
    '2': 'charge',
    '3': 'exit'
}

while(True):
    in_data = input('コマンドを入力してください \n1:カップを出す 2:カップを補充する 3:終了\n>>>')

    if command.get(in_data) == 'eject':
        papercupmachine_object.eject()
    elif command.get(in_data) == 'charge':
        try:
            chargecount = int(input('補充する数を入力してください。\n>>>'))
        except ValueError:
            print('補充する数が正しくありません。')
        else:
            papercupmachine_object.charge(chargecount)
    elif command.get(in_data) == 'exit':
        print('終了します')
        break
    else:
        print('入力エラーです、もう一度入力してください\n')


その後...の対応例

  1. 紙コップを出す以外に、お湯で紙コップを出す機能もつけたい
    →クラスの中に def で機能追加することができます~
  2. サービスエリアの紙コッププログラムは消費が激しいので、
    ここだけ1000個まで補充できるようにしてほしい
    →紙コップマシン自体が容量を管理しているので、容量を変更することで対応します~
  3. 当たりくじ付きの紙コップつけれない?
    →これは 従来のeject機能に当たりくじ機能を追加すると出来そうです。
import random


class PaperCupMachine():
    def __init__(self):
        # 残り個数をPaperCup.txtから取得します。
        with open('PaperCup.txt', mode='r') as f:
            self.remainingcup = int(f.read())

        # 最大容量を設定します。
        self.maximumcapacity = 100

    def eject_hotwater(self):
        print('こちらの形式はお湯を出せません。')

    def eject(self):
        # 紙コップを一個出します。
        if self.remainingcup == 0:
            print('紙コップがありません')
            return False  # 失敗
        else:
            self.remainingcup -= 1
            self._setRemainingPaperCup()
            print('紙コップを出しました')
            print('残り{}個です。'.format(self.remainingcup))
            return True

    def charge(self, chargecount):
        # 入力された個数をチャージします。
        if self._inputchecker(chargecount):
            print('不正な入力です')
            return  # 成功

        if self._chargechecker(chargecount):
            return
        else:
            self.remainingcup += chargecount
            self._setRemainingPaperCup()
            print('紙コップを{}個補充しました'.format(chargecount))

    def _inputchecker(self, data):
        # inputしてはいけないint型以外の型入力ならTrueを返します。
        return not type(data) is int

    def _setRemainingPaperCup(self):
        # 残り個数をPaperCup.txtに保存します。
        with open('PaperCup.txt', mode='w') as f:
            f.write(str(self.remainingcup))

    def _chargechecker(self, chargecount):
        # 以下の場合、Trueを返します。
        # 追加した場合に最大容量を超える時
        # 与えられた追加個数が不正な値の場合True
        if chargecount < 0:
            print('入力値は最大容量以下の自然数でお願いします')
            return True
        if self.remainingcup + chargecount > self.maximumcapacity:
            print('容量を超えたため、入力を受け付け出来ませんでした')
            return True
        return False


class PaperCupMachineVersionHotWater(PaperCupMachine):
    def eject_hotwater(self):
        # 紙コップを出した後、お湯を入れます。
        super().eject()
        print('お湯を入れました')


class PaperCupMachineVersionBigCapacity(PaperCupMachine):
    def __init__(self):
        super().__init__()
        self.maximumcapacity = 1000


class PaperCupMachineVersionRuckyCup(PaperCupMachine):
    def eject(self):
        # ランダムで当たりくじが出ます。
        if not super().eject():  # 紙コップを出すのが失敗したら
            # 終了する
            return
        if random.random() < 0.1:  # とりあえず10%
            print('当たりが出ました!おめでとう!')


papercupmachine_object = PaperCupMachineVersionRuckyCup()  # 生成するマシンは選択する。

command = {
    '1': 'eject',
    '2': 'charge',
    '3': 'ejecthotwator',
    '4': 'exit'
}

while(True):
    in_data = input('コマンドを入力してください \n1:カップを出す 2:カップを補充する 3:お湯を出す 4:終了\n>>>')

    if command.get(in_data) == 'eject':
        papercupmachine_object.eject()
    elif command.get(in_data) == 'charge':
        try:
            chargecount = int(input('補充する数を入力してください。\n>>>'))
        except ValueError:
            print('補充する数が正しくありません。')
        else:
            papercupmachine_object.charge(chargecount)
    elif command.get(in_data) == 'ejecthotwator':
        papercupmachine_object.eject_hotwater()
    elif command.get(in_data) == 'exit':
        print('終了します')
        break
    else:
        print('入力エラーです、もう一度入力してください\n')

機能を実現するために使用したのは、「継承」という機能になります~
元の機能を引き継いで、新しく機能を追加したり、同じ名前の機能を上書きしたり※することができます♪

  • class PaperCupMachineVersionHotWater(PaperCupMachine):
  • class PaperCupMachineVersionBigCapacity(PaperCupMachine):
  • class PaperCupMachineVersionRuckyCup(PaperCupMachine):

が、継承して新しく作ったクラスですね~
地味に元のクラスをいじったり、選択コマンドを増やしたりもしてはいるのですが、
大元はほぼ変えずに新しく作れるのが、きっと生産性が高い、再利用性が高い
といわれる所以なのではないかと思います~

※…オーバーライドっていうらしいです~

cacaponのメモ

  • 公開している機能を継承先のクラスで追加したときは、
    継承元のクラスにも同名の機能を追加したほうが良さそう~
    例えば、PaperCupMachineオブジェクトでお湯を出そうとすると、
    機能がないためにエラーになりました~
    空の機能でもいいから作っておくと、操作側をいじらなくて済みます~

  • 継承先で同名の機能を定義すると、元の内容が無くなるっぽいです~
    例えば、BigCapacityでsuper().__init__()しないと、
    self.remainingcupが定義されていないためエラーになった。

  • 当たり付を実装するうえで、紙コップが出ない時は当たりくじが出ないようにしたかったのですが…
    ejectで紙コップが出ない場合でも、次の当たりくじ判定処理が動いてしまいました~ 対応策として、継承元クラスをいじって成功失敗判定を返すようにしたけど、
    作りとして微妙と感じています~ もっと良いやり方ないかなぁ…

  • 個数の管理をPaperCup.txtありきな形式なため、
    保存している形式が変わったり、不正な値が保存されてしまっているとうまく動きません~
    確認であったのは、BigCapacityから通常に戻した場合に、個数がそのままになっておりました…
    オブジェクト毎に値を保持できるようにしたりできるといいなぁ…

というわけで、デザインパターンを学ぶ前のcacaponはこんな感じになりました~
24回終わった後にはメモした疑問などは解決出来ていたらいいなぁと思います~

干渉計を作ってみました。

この前本屋さんに言ったら、量子コンピュータなる本がありまして、
興味があったので買ってみました~

 

量子コンピュータ―超並列計算のからくり (ブルーバックス)
まだ、読んでいる最中なのですが、
その中に干渉計なる実験装置が出てきました。
なんでも、量子力学の測定などで使われる装置みたいなのです。
(量子コンピュータを理解するのに、元になる量子力学の知識が必要とのことで、前半は量子力学の大事な概念の説明が主な内容になっておりました。)

図で描くとこんな感じでしょうか?
 

f:id:cacapon:20200124232323p:plain


指向性のある光を半透鏡という半分通して、半分反射する鏡を置き、
光を分断します。
その後、鏡で反射し合わせてまた半透鏡を使って光を重ねます。

こうすると、不思議なことに、まぶしい側と暗い側ができるんですって。
いつか実際に実験してみてみたいですね~

さて、この干渉計を見ていたら、ぴんと来てしまったのです。
コレなら依然できなかったアレで表現できるのではないかと…
 
という訳で、作っちゃいました。
 

f:id:cacapon:20200124231005g:plain

例のあれで作ったシミュレーション
 
そう、この前全然分からなかったMachinationですね(笑)
レーザーポインターから無数の光子を飛ばして、
光がどっちに到達するかをシミュレーションすることが出来ました♪

初めてまともに使えたのではないでしょうか…

量子を一つ一つ飛ばすこともできますよ~
 

f:id:cacapon:20200124233103g:plain

ただ、これをブログを書いた後に本を見直したのですが、
なんと、干渉計の距離を正しく設定すると、
必ず同じ側が強い光になるそうなんです。

今度はそれを踏まえて、正しいシミュレーションができるようになりたいですね~

Machinationを使ってみて分からなかった話

この前の休みの日にMachinationというツールを使ってみたのですが、全然分からなかったのでその時のお話を書こうかなと思います〜

 

Machinationというのは…

cacaponも上手く説明出来ないんですけど、

ゲームの一部分を図式化して、

それをシミュレーション出来るツールの様なのです。

 

サンプルとしてあったのは、

ソシャゲの宝箱ドロップを表現したものでした〜

 

仕様はこんな感じでした〜

・ステージをクリアすると確率で鍵が貰える

・更に高スコアだと確率で宝箱が貰える

・宝箱と鍵を消費するとアイテムが貰える

・アイテムは確率で何が出るか決まってる

 

これを図式していくと、

・1クリア時に鍵と宝箱が何個手に入るか?

・アイテムはどんな割合で手に入るか?

 

などを、Machination内で完結した形で

シミュレーション出来るのですよ〜

 

これが出来ると…

入手アイテムの偏りとかが分かったり、

鍵、宝箱のドロップ率が適正か分かったり

などなどそういうのを検証できるので、

便利なのは分かりました〜

 

ただ、cacaponが分かったのはここまでで、

いざ自分で作ってみようとすると全然分からなくなっちゃうのです…

 

cacaponが分からなく感じるのは、

①シミュレーションに落とし込む粒度がどんなものか分からない

②表現方法が分からない

 

大きく分けて2つです〜

 

まず①ですが、休みの日にチャレンジした時はゲーム&ウォッチのBallを表現しようと思ってたのですよ〜

Ballというのは簡単に言うとお手玉のゲームですね〜

 

ゲームの仕様をcacaponなりにまとめると…

・2つか3つのお手玉がある

お手玉は一定方向に動いている

・左右にあるボタンで腕を動かせる

お手玉をキャッチすると1点

 キャッチ後はお手玉の動きが逆になる

・落としたらゲームオーバー

 

という感じなのですが、

これをMachinationに落とし込む時に、

何を落とし込めば良いか分からないんです〜

 

ものが簡単過ぎるのか、

切り分けが出来てないだけか、

はたまた両方なのか分かりませんが、

少なくともこの前考えた時には出来ませんでした〜

 

②に関しては文法に慣れてないせいですかね〜

UE4でも似たような事書いた覚えありますけど、やっぱ慣れないツールは大体同じ感想を抱きますね〜

コードだと表現出来るのに、

ブループリントだと〜とか

図だと〜とか

cacaponは多い気がします〜

 

…という訳でしっくりしないまま終わってしまったcacaponでした〜

Machination自体は良いツールだとは思うのですが、いかんせん表現のコツがまだ掴めずcacaponには難しく感じます〜

早く慣れたいですね〜

 

物にもよるけど、大体の秘密は秘密のままが一番

最近日本人として日本の起源について知らないのはまずいなぁと思いまして、「古事記」と「日本書紀」を読み始めたcacaponです〜

 

読んでて思ったのですが…

 

「押すなよ? 押すなよ?」で熱湯風呂に突っ込まれる某芸人さんのような事って昔からやっていたんだなぁと思いました〜

 

例えば…

 

伊弉冉尊 「開けるな?絶対に開けるなよ?」

伊弉諾尊が開ける

 

豊玉毘売 「開けるな?絶対に開けるなよ?」

→山幸が開ける

 

上の二つは古事記の上の巻の話です〜

それ以外の昔話でも…

 

鶴の恩返し 「開けるな?絶対に開けるなよ?」

→若者が開ける

 

雪女 「言うなよ?絶対に言うなよ?」

→違う女にバラす(その人は変装している雪女さんですけど)

 

……

 

なんでしょうね?

日本人のSaGa…もとい性何ですかね?

 

分からない事を分かるようになりたい…

というのは人として持っている欲求の一つなのかなとは思います〜

そのおかげで、今は便利な道具がいっぱい出来ました〜 先人の皆様には本当に感謝です〜

 

ですが、それを対人に発揮してしまうと大体悲惨な目に遭います〜

昔話だと男側は大体嫁さんや彼女さんに逃げられてますね〜

因果応報な気はしますのであまり弁護できないですけど〜

 

女性側は…最愛の人に裏切られて相当辛いんだろうなと思いました。

男尊女卑が強かった時代で、これだけのメッセージ性があるのは相当強い思いだったのではとcacaponは思います。

 

まあ、秘密の内容が人を裏切るような秘密だったら秘密を暴くべきなのでしょうが…

そうでないなら秘密を秘密のままにしておくのも人間関係を円滑にする秘訣なのかもしれません〜

 

 

 

心の電池切れをどうにかしたいcacaponの年末年始奮闘?記

 

あけましておめでとうございます。

今年もよろしくお願いします~

 

さて、年末年始は皆さんどのようにお過ごしでしたでしょうか?
cacaponは仕事終わってからスイッチが切れてしまったみたいで、
年末終わりにこれしようかなと思っていたことがあまりできませんでした~

cacaponは、これを心の電池切れと勝手に呼んでいます。
頭では何かしたいと考えても、いざ行動に移せないんですよね…
cacaponとしてはどうにかしたいんですけど、
ここ最近の一番の悩みですね~

とりあえず思ったのが、
電池が切れたなら充電する方法があるはず。
充電する方法が何か分からないけど探してみようということで、
色々なことをしてみました~

まずは、一日ゴロゴロしてみました。
単純に疲れがたまっているだけなら、
ゴロゴロして疲れが取れれば回復するかな?と思いやってみました~

結果としては逆効果でやればやるほど日増しに気が滅入ってしまいました…
これはアカンですね。
それとゴロゴロついでにネット小説読みまくっていたのですが、
ネット小説の読みすぎは、cacaponの心の電池を消耗しますね~
趣味もほどほどが肝心かもしれません~

その次にやったのは散歩をする事でした。
外の空気を吸って青い空の下、体を動かすのは良かったように思います♪
少し良くなったかなぁと思ったんですけど…
まだ動ける感じにはなりませんでした~

でも、二時間歩きっぱなしはやりすぎました。
今は近場をてくてく歩くくらいにしています~

その次やったのは自分との対話ですかね?
朝起きた時に、思ったことをとりあえず書き綴ってみる。
散歩のときにふと思ったことを書いてみる。
そんな感じでどちらかというと理性ではなさそうな部分を
拾ってみることをやってみました。
これならノートとペンがあればできますし、結構お手軽だと思います~

結果としては心の充電にはなりませんでしたけど、
自分が今何にアンテナが向いているのか少しわかった気がします~
因みに、cacaponのトレンドは「シンプル」と「自分の世界」でした~

問題は、cacaponが続けるのが苦手な所ですかね?
2日くらいは出来たんですけど、3日目からめんどくさくなってきました…
これが三日坊主ってやつですかね?2日かな?


んで、もやもやしたまま今日まで来てしまいましたが、
結局解決はしていないです~
ブログ書きはとりあえず今日中までは出来ましたけど…
どちらかというと「あ、やるの忘れてた!」から何とか仕上げたみたいな感じになってしまって、cacaponの心情としてはちょっと違うんですよね…

ん~ 年始早々これ大丈夫か?って感じのcacaponですが、
まあ、なるようにはなるのかなと思うので出来ることを試してみたいと思います~