Java Mid Basic〜数秘術から社会人基礎力のロジック〜

今回は、数秘術の数字を算出する処理を実装します。
参照するのは、こちらの本です。

数秘術の数字

この本によるとまずは「ネームチャート」を作るのがはじめの一歩のようです。「〜ようです」というのは明示的に書いてないのでこのような書き方をしています。

ネームチャート

早い話が、名前をローマ字(アルファベット)にして母音と子音を出し、それに数字を割り振ったものです。
具体的には「Nanashino Takunoji」であれば下のようになります。

Nanashino -> 
母音[ 1, 1, 9, 6] "aaio";= 1+1+9+6=17=>1+7=「8」
子音[5, 5, 1, 8, 5]"Nnshn"= 5+5+1+8+5=24=>2+4=「6」
合計する=>8+6=14=>1+4=「5」

Takunoji -> 
母音[ 1, 3, 6, 9] "auoi";= 1+3+6+9=18=>1+8=「9」
子音[ 2, 2, 5, 1]"Tknj"= 2+2+5+1=10=>「1」
合計する=>9+1=10=>「0」

苗字の部分の計算、名前を計算して結果を出します。
ちなみに最後に算出している数字は「人格数」にあたります。

ロジックにする

「ロジック」と聞いて「は?」となる人のために記載しますが、早い話が、入力に対して想定通りの結果を返せる「処理」のことです。
今回の場合は。。。
入力:「名前(フルネーム)」のアルファベットが入ります。
出力:上で示したように「人格数」となりそうですが、そうではなく、母音と子音の"["と"]"で囲まれた数字を出力として欲しいのです。
この出力結果が「人格数」になると他の「運命数」は「生年月日」なので違いますが、「ハート数」などが算出できません。

いざロジック

初めに上に示したものを作成します。入力が「名前」出力が「母音と子音の数字配列」です。
しかし、Javaのメソッドの返り値は1つだけなので文字列に区切りもの「,(カンマ)」をつけて分けます。。。
いや、面倒なので配列にしてしまいましょう。コードにすると次のようになるのですが、今回は処理の仕様が決まっているので「テストケースから作成します。→「テスト駆動型開発」というやつです。
作成したテストコードもあります。

でわでわ。。。



Java Mid Basic 〜数秘術から社会人基礎力のロジック〜

イントロダクション

前回までに、占い(数秘術)と社会人基礎力の調査を行い、占いから社会人基礎力のパラメータを算出する方法を作成しました。
今度は、それをプログラムで実装しようというわけです。

設計

数秘術の数字の算出方法は占いの手順をそのまま行うので良いのですが、各数字(人格数、運命数。。。)から「社会人基礎力」の算出に関しては、理論も何もないので「直感」で割り振りました。下のような感じになります。詳細は前回の記事に記載しております。

<社会人基礎力>
1:「目的」
2:「学び」
3:「統合」
<ルール>
「人格数」: 1:「目的」と2:「学び」に割り振る
「運命数」: 3:「統合」に割り振る
「ハート数」: 1:「目的」に割り振る
「意思数」: 2:「学び」に割り振る
「成熟数」: 3:「統合」に割り振る

処理手順について

処理手順は前回の記事に記載した、算出方法がそのまま適用されます。
つまり、以下のような手順になります。

手順

  1. 数秘術で各数字(人格数など)を算出
  2. 社会人基礎力への変換表に付け合わせて値を割り振る

しかし、この手順ではプログラムに落とすことができません。視点が人間目線なので機械のレベルまで掘り下げてやる必要があります。
人間目線(高レベル)→機械目線(低レベル)というようなイメージです。そして、世間でよく言われている「高レベルAPI」という言葉は人間目線に近いAPIという意味です。逆にいうと細かい部分の操作ができません(笑)

レベルを下げる

初めの手順ではレベルが高い位置にあるので、これを下げて機械レベル(PCレベル)に近づけていきます。
上の手順を「PC操作でやろうとした時にどのように操作するか?」を考えます。そうすると下のようになると思います。

  1. 数秘術で算出するのに必要な「名前」と「生年月日」を入力する(名前はローマ字 or アルファベット)
  2. 入力されたアルファベット(ローマ字を含む)より、数秘術の計算を行う
  3. 各数字(人格数など)を算出し、社会人基礎力のマップに照らし合わせて、各項目に対しカウントアップ(割り振り)を行う

以上のような手順になります。

プログラムにすると

大雑把に下のような形になります。もちろん他にも方法はありますし、このサンプルが気に入らなければ他のやり方でも結構です。むしろアイディアを聞かせて欲しいくらいです(笑)

とりあえずは、このような形でプログラムを作成していけばゴールにはたどり着けるであろうというものです。

関連ページが下の方にあるのでよかったらどうぞ。


public class CreatePlayerParam implements CommandIF {

    /** 
     * CommandIFを実装する、コマンドクラス。
     * 
     * @see jp.zenryoku.sample.lv3.refactor.CommandIF#execute()
     */
    @Override
    public void execute() {
        // 標準入力
        Scanner input = new Scanner(System.in);
        System.out.println("あなたの名前をローマ字(ヘボン式)で入力してください: ");
        // 入力された文字列
        String inStr = input.nextLine();

        // 母音を切り取る
        String boIn = cutOffBoin(inStr);
        // 子音
        String shiIn = inStr;
        // 人格数
        int jinkakuSu = getJinkakuSu(boIn, shiIn);
        // 運命数
        int unmeSu = getUnmeSu(boIn, shiIn);
        // ハート数
        int heartSu = getHeartSu(boIn, shiIn);
        // 意思数
        int ishiSu = getIshiSu(boIn, shiIn);
        // 成熟数
        int seijukuSu = getSeijukuSu(boIn, shiIn);
        /* 社会人基礎力の算出 */
    }

    public String cutOffBoin(String inStr) {
        // 未実装
        return null;
    }

    public int getJinkakuSu(String boIn, String shiIn) {
        // 未実装
        return 0;
    }

    public int getUnmeSu(String boIn, String shiIn) {
        // 未実装
        return 0;
    }

    public int getHeartSu(String boIn, String shiIn) {
        // 未実装
        return 0;
    }

    public int getIshiSu(String boIn, String shiIn) {
        // 未実装
        return 0;
    }

    public int getSeijukuSu(String boIn, String shiIn) {
        // 未実装
        return 0;
    }
}```
以前作成したCommandIFを使用して、このクラスをロードしてパラメータを算出するような実装にしようと思っているので。このクラスのみを作成すれば、今まで作成していたコンソールアプリに組み込むことができます。詳細は上記のリンクを参照してください。

CommandIF(インタフェース)を使用したポリモーフィズムの実行動画があります。


でわでわ。。。

関連ページ

Java Mid Basic テキストRPG 〜数秘術から社会人基礎力を算出〜

イントロダクション

前回は、数秘術についてどんなものか調べました。
今回は「社会人基礎力」を算出する、ルールを作成します。
詳細な内容に関してはこちらの記事に記載しました。
大雑把に、数秘術の書く値が、それぞれどのような意味を持ち、それに対して関連付ける値はどのようなものが良いか?を考えるための材料を揃えた次第です。調査自体はなかなか面白かったし、女性には喜ばれますね。ちょっとだけ相談しました。→「占いって興味ありますか?」的なことを聞きました。
そして、まとめたものが、以下のような表になります。


1:「目的」=>「前に踏み出す力」のために必要とされる

主体性:1、7、9
働きかけ力:3、7、9
実行力:1、5、8

2:「学び」=>「考え抜く力」のために必要とされる

課題発見力:2、4、8
計画力:2、5、8
創造力:1、2、9
3:「統合」=>「チームで働く力」のために必要とされる

発信力:1、4、9
傾聴力:1、7、0
柔軟性:4、6、9
情報把握力:1、7、0
規律性:4、6、0
ストレスコントロール力:1、5、9


算出手順

[Step1]
まずは数秘術にて、以下の数値を算出します。詳細はこちら

  1. 「人格数」: 名前の合計
  2. 「運命数」: 生年月日の合計
  3. 「ハート数」: 母音の合計
  4. 「意思数」: 子音の合計
  5. 「成熟数」: 人格数 + 運命数
  6. 「特性数」:用途未定
  7. 「欠落数」:用途未定

そして、それぞれに算出した値を上記の表に割り当てます。

<例>
「人格数」: 名前の合計=1
「運命数」: 生年月日の合計=2
「ハート数」: 母音の合計=3
「意思数」: 子音の合計=4
「成熟数」: 人格数 + 運命数=3
のような結果が出た人であれば、上記の表と以下のルールより
<ルール>
「人格数」: 1:「目的」と2:「学び」に割り振る
「運命数」: 3:「統合」に割り振る
「ハート数」: 1:「目的」に割り振る
「意思数」: 2:「学び」に割り振る
「成熟数」: 3:「統合」に割り振る

主体性:1
働きかけ力:1
実行力:1
課題発見力:1
計画力:
創造力:1
発信力:1
傾聴力:1
柔軟性:
情報把握力:
規律性:
ストレスコントロール力:

のようになります。これは「先天的に持っている」という程のデータになるのと、ゲームで使用するパラメータなので「なんか点数低くね?」とか思わないでください。。。

でわでわ。。。

関連ページ

  1. テキストRPGを作る〜数秘術の概要まとめ〜
  2. Java Mid Basic〜リファクタリングLv2 処理の整理とクラス分け(準備編)〜
  3. Java Mid Basic 〜Lv3_2_Javaの基本(リファクタリングLv2)ゲームループ付き
  4. Java Mid Basic〜リファクタリングLv2 Mainメソッドを作る〜
  5. Java Mid Basic〜リファクタリングLv2 プロパティファイルで無修正ものを作る〜
  6. Java Mid Basic 〜仕様作成、数秘術から社会人基礎力〜


Java Mid Basic 〜仕様作成、数秘術から社会人基礎力〜

イントロダクション

こちらのサイトを見つけました、内容は、「社会人基礎力」について項目を挙げ、各内容について記載している記事です。丁度、ゲームのパラメータに悩んでいたところヒトとしてのパラメータ的なものがあったので、参考にしたました。
使用するのは以下のものです。

<数秘術>; 下のリンクは広告です。

経済産業省提唱「社会人基礎力

換算する値

以下の項目が、「社会人基礎力」で挙げられている項目です。12個あります。カテゴリとしては、1〜3=①, 4〜6=②, 7〜12=③の様に分けます。

<パラメータ>

  1. 主体性: 1, 7, 9
  1. 働きかけ力:3, 7, 9
  1. 実行力:1, 5, 8
  1. 課題発見力:2, 4, 8
  1. 計画力:2, 5, 8
  1. 創造力:1, 2, 9
  1. 発信力:1, 4, 9
  1. 傾聴力:1, 7, 0
  1. 柔軟性:4, 6, 9
  1. 規律性:4, 6, 0
  1. ストレスコントロール:1, 5, 9
  1. 状態把握力:1, 7, 0

これらの項目に値を設定するのですが、結論から言うと計測不能なので直感で割振りました。数秘術で算出した以下の項目を使います。

数秘術の値

  • 人格数=①と②に割り振る
  • 運命数=③に割り振る
  • ハート数=①
  • 意思数=②
  • 成熟数=③
  • 特性数=保有属性
  • 欠落数=弱点属性

上の値は、<パラメータ>の表にある数字部をカウントする形で算出します。

人格数が9の人は、表の番号1, 2, 6に一点加算するといった形で計算していきます。

数字について

数字; 属性 / 星; 神様
1: 火 / 太陽; ヘリオス, アポロン )
2: 水 / 月; セレネー, アルテミス
3: 風 / 土星; クロノス, サトゥルヌス
4: 地 / 地球: ガイア
5: (エーテル)風 / 水星; ヘルメス
6:地/ 金星; アプロディーテー, ヴィーナス)
7: 風 / 海王星; ネプチューン, ポセイドン
8: 水 / 土星; クロノス, サトゥルヌス
9: 火 / 火星; アレス

これらの数字は、「特製数」と「欠落数」に対応させようと考えております。

特性数

1、3、4が特性数の場合→火、風、地の属性を持ちます。そして、ネームチャートに出て来た数字の数をレベルにします。つまり「A」が2回、「C」が1回、「D」が3回出てくるような人は火=Lv2, 風=Lv1, 地=Lv3となります。

欠落数

逆に2、5、8が欠落数の場合は水、(エーテル)風が弱点になり、2と8は属性が「水」なので水が致命的な弱点になります。

とりあえず

現状ではこんな感じの仕様でゲーム作成を行おうと思います。

でわでわ。。。



Java Mid Basic〜Lv3_4_リファクタリングLv2 プロパティファイルで無修正ものを作る〜

イントロダクション

前回は、メインメソッドの修正を行わないでのコマンド追加実装をやりました。
具体的には、コンストラクタに作成した、クラスをマップに登録する処理を追加します(1行)。。。
しかし。これもなんだかんだとクラスの修正をしているのでイマイチです。なので

今回は、プロパティファイルを使用します。このファイルは「キー=値」のように記述しているファイルのことで次のような形で作成します。
具体的には、キーをコマンドとして扱い、値を取得するクラスの完全クラス名として記述します。

# キー=値
hello=jp.zenryoku.XXX.HelloCls

目的は、コマンドを入力したら対象のクラスを取得するためです。
<プロパティファイルの扱い>

メインクラスを無修正ものにする

この方向でコマンドを追加する方法を実践したいと思います。その方法は以下の手順で行います。

  1. プロパティファイルにキーとクラスの完全名をセットにして登録する
  2. クラスの完全名からクラスのインスタンスを取得して実行するようにする

上記のような形になります。「よくわからん。。。」と思った方、詳細を下に記載します。

修正のいらない実装

修正をしなくても「クラスを追加」もしくは、「新しい機能の実装を追加」するためには「依存関係を分断」してやる必要があります。

世間巷では「依存関係の分断」なんて言葉が一時流行りました。これは下のようなプログラムコードがあったとしましょう。

無修正Lv1

MyCls main = new MyCls();
String param = "hello";
main.execute(param);

上のようなコードの場合は、「MyCls」をコード上で「new」しているので、「MyCls」を変更して別のクラスを使用したい時にはこのコードを書き換える必要があります。

無修正Lv2

しかし、下のようにプログラムを書き換えてやれば、「getMyCls」の中身を修正すればよく、下のコードは修正しなくてよくなります。

MyIF main = getMyCls();
String param = "hello";
main.execute(param);

無修正Lv3

上のコードを応用していくと、次のように書くことも可能です。これはjava.lang.refrectionというパッケージを使ったやり方です。

Class<? extends MyIF> cls = Class.forName("完全クラス名");
MyIF main = (MyIF) cls.getInstance();
String param = "hello";
main.execute(param);

上のように書けば、「完全クラス名」を動的に渡してやれば目的のクラスのインスタンス(オブジェクト)が取得できます。具体的には完全クラス名をメソッドの引数に渡してやる方法です。次のようなコードも使えます。

public MyIF getMyIF(String perfectClsName) {
    Class<? extends MyIF> cls = Class.forName("完全クラス名");
    MyIF main = (MyIF) cls.getInstance();
    return main;
}

public void sample() {
    MyIF main = getMyIF("jp.zenryoku.XXX.HelloCls");
    String param = "hello";
    main.execute(param);
}

ちょっと、わかりずらいかもしれませんが、このように書くとプログラムを修正しなくても目的を果たすことができます。
※目的は、対象のインスタンスを取得するということです。

はじめは「MyCls main = new MyCls()」と書いていたものを書き換えて無修正ものにしました。
このようにプログラムコードを修正しなくても使いたいオブジェクト(インスタンス)を動的に取得できるようにすることを「依存関係の分断」といいます。

ちなみに、Springframeworkというフレームワークではこの「依存関係の分断」をDI(Dependency Injection)という形で実現しています。

依存関係の分断

依存関係とは「関連性がある」ということ、つまり「関連性がある=片方を修正したら、もう片方も修正する必要がある」という関係が出来上がっていることです。
よく世間では「依存関係の注入」などという言葉で言いますが、実際どういうことか?に関して触れていることが少ないように感じています。
実装方法に関してはいろんな記事があり、わかりやすく説明がされていると思います。

つまり

依存関係を分断しようということです。具体的には下のように考えます。

  1. 新しい機能を追加するときには今実装している部分を修正したくない
  2. 新しく機能を追加するのと、実装中のクラスを修正しない方法は?

大雑把に、上のように考えます。サンプルとして今回のサンプルアプリを参考にして考えてみます。
現状の実装はGitにあるソースを見てもらうと一目瞭然です、一部抜粋して以下に示します。(メインメソッドのみ抜粋)

public static void main(String[] args) {
    // コマンドの用意
    cmdMap = new HashMap<String, CommandIF>();
    cmdMap.put("hello", new HelloCommand());
    cmdMap.put("ready", new ReadyCommand());
    // 標準入力
    Scanner input = new Scanner(System.in);

    while(true) {
        System.out.println("入力してください: ");
        String inStr = input.nextLine();
        CommandIF cmd = cmdMap.get(inStr);
        if (cmd != null) {
            cmd.execute();
        }
        if ("bye".equals(inStr)) {
            System.out.println("Good Byw");
            break;
        }
    }
}

動きは下の動画のようになります。

この状態では、Mapにコマンドクラスを追加してやれば新しい機能を追加できます。なので修正するポイントはコンストラクタのみになります。

この際だから。。。

そう、「ここまできたら最後までいけ!」と思うのが人情(自分だけでしょうか?(笑))、なのでやってしまいましょう。

<実装手順>

  1. コンストラクタでMapにコマンドクラスを追加するのをやめる
  2. その代わりにプロパティファイルを使用する
  3. プロパティファイルから完全クラス名を取得し、インスタンスを生成
  4. 生成したインスタンスのメソッドを実行する

このようにしてやれば、メインクラスの修正はいりません。
<追加するもの>
・プロパティファイル
・プロパティファイルのロード処理
・同様に値の取得処理

<CommandList.properties>

 hello=jp.zenryoku.sample.lv3.refactor.cmd.HelloCommand
ready=jp.zenryoku.sample.lv3.refactor.cmd.ReadyCommand
</pre>
<pre>/** プロパティファイル取得 */
public void loadPropertyFile() {
    prop = new Properties();
    try {
        // resources/
        prop.load(getClass().getResourceAsStream("/CommandList.properties"));
    } catch (IOException e) {
        e.printStackTrace();
        // エラーコード-1をセットしてプログラム終了
        System.exit(-1);
    }
}

プロパティファイルからインスタンスの取得

public CommandIF getCommandIF(String key) {
    // 完全クラス名を取得する
    String fullClassName = prop.getProperty(key);
    if (fullClassName == null || "".equals(fullClassName)) {
        return null;
    }
    CommandIF cmd = null;
    try {
        @SuppressWarnings("unchecked")
        Class<CommandIF> cmdCls = (Class<CommandIF>) Class.forName(fullClassName);
        cmd = cmdCls.newInstance();
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        System.exit(-1);
    }
    return cmd;
}

このように、メインメソッドの修正を行わなくてもCommandIFを実装したクラスの数だけコマンドに対する実行処理を作成することができます。

その代わり、プロパティファイルにキーと値を追加する必要がありますが。。。しかしコードを修正するとテストを行う必要があるので格段に余計な手間と時間を省くことができます。

まさに「無修正」

できた時間を使用して、心と体のリフレッシュ及び、楽しい時間を過ごす。。。これが平和への第一歩だと思います。
このように、時間を大切に使わないと、昔の不況時代のように「寝る暇がない!」とか「今日も漫画喫茶でお泊まり!」とか。。。おおよそ人間の尊厳が無いような、不幸なことになってしまうので、日々精進を重ねることが大切だと思います。。。趣味にしてしまうのが一番手っ取り早いという噂もあるとか無いとか(笑)

でわでわ。。。