Javaでサイコロ(六面体)のアクションを考えてみる

f:id:ts0818:20190504154644j:plain

『I, at any rate, am convinced that He does not throw dice.』

⇧ 『どんな条件であろうと、神様はサイコロを振らない、と私は確信している』とは、アルベルト・アインシュタイン の有名な言葉ですね。

どうもボクです。

幼少のころは、言葉を理解したり話したりするという面では問題がなかったが、言葉を出すのには時間を要した。一方で数学に関しては傑出した才能を示し、9歳のときにピタゴラスの定理の存在を知り、その定理の美しい証明を寝る間も惜しんで考え、そして自力で定理を証明した。12歳のときに叔父からユークリッド幾何学の本をもらい独習微分学と積分学も、この当時に独学で習得したといわれている。同じころ、医学生だったマックス・タルメイから天文学の存在を知らされ、同時に物理学に関心を示すようになったという。ただ、確率は生まれつき不得意で、このことがのちに統計力学量子力学を否定する素養となる。

アルベルト・アインシュタイン - Wikipedia

⇧  『確率』に関するコンプレックスが、先の言葉に現れているのかしら...とは言え、神童かつ天才であったことは間違いないですね。

アルベルト・アインシュタイン - Wikipedia

⇧  まじか~...そんだけ寝る時間もちゃんと取れてたなんて、本物の天才やん...

 

というわけで、今回は、サイコロ(六面体)のアクションについてのプログラミングを考えていきましょうということで。六面体以外の多面体のサイコロは考えないということで。

レッツトライ~。

 

サイコロは転がるものなので

まぁ、問題を見たほうが早いということで、

judge.u-aizu.ac.jp

⇧  上記サイト様で。

次の展開図から得られるサイコロを転がすシミュレーションを行うプログラムを作成してください。 

f:id:ts0818:20190504164312p:plain

サイコロの各面には図のとおりに 1 から 6 のラベルが割りあてられています。

入力としてサイコロの各面のラベルに対応する整数と、転がす命令の列が与えられるので、サイコロの上面の整数を出力してください。シミュレーションの初期状態は、図のとおりのラベルの位置でサイコロが置かれているものとします。

サイコロ 1 | プログラミング入門 | Aizu Online Judge

例えば、入力値が、「1 2 4 8 16 32」 とかの場合、

方位・上下 Top South East West North Bottom
サイコロの目(問題文) 1 2 3 4 5 6
サイコロの目(例) 1 2 4 8 16 32

初期状態は、こんな感じになるらしい。

つまり、アクション的には、

  • North(北)に転がす
  • East(西)に転がす
  • West(東)に転がす
  • South(南)に転がす

の4つが存在し、そのアクションごとに、「サイコロの目」と「方位・上下」の組み合わせを変化させないといけないと。

このうち、「南北」のどちらかに転がした場合「東西」は不動、「東西」のどちらかに転がした場合「南北」は不動となることが、問題文の画像から読み取れると。

 

実際にプログラミング

というわけで、実際にプログラミングしてみますか。

Eclipseを起動し、適当なJavaプロジェクト、クラスを作成。

f:id:ts0818:20190504193711p:plain

コーディングはこんな感じに。

Dice01.java

package dto;

public class Dice01 {
  private int number[];
  private int work[];

  public Dice01() {

  }

  public Dice01(String[] args) {
    number = new int[args.length];
    work = new int[args.length];
    // サイコロの初期化
    for (int i = 0; i < args.length; i++) {
      number[i] = Integer.parseInt(args[i]);
    }
  }

  public void rollDice(char action, int num) {
    for (int i = 0; i < num; i++) {
      this.work[i] = this.number[i];
    }

    switch (action) {
    case 'E':
      // West→Top, South→South, Top→East, Bottm→West, North→North, East→Bottom
      setNumber(work[3], work[1], work[0], work[5], work[4], work[2]);
      break;
    case 'N':
      // South→Top, Bottom→South, East→East, West→West, Top→Nouth, Nouth→Bottom
      setNumber(work[1], work[5], work[2], work[3], work[0], work[4]);
      break;
    case 'S':
      // North→Top, Top→South, East→East, West→West, Bottom→North, South→Bottom
      setNumber(work[4], work[0], work[2], work[3], work[5], work[1]);
      break;
    case 'W':
      // East→Top, South→South, Bottom→East, Top→West, North→North, West→Bottom
      setNumber(work[2], work[1], work[5], work[0], work[4], work[3]);
      break;
    default :
      break;
    }
  }

  public void setNumber(int n1, int n2, int n3, int n4, int n5, int n6) {
    this.number[0] = n1;
    this.number[1] = n2;
    this.number[2] = n3;
    this.number[3] = n4;
    this.number[4] = n5;
    this.number[5] = n6;
  }

  public int takeTopNumber() {
    return this.number[0];
  }
}

TestDice.java

package main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import dto.Dice01;

public class TestDice {

  public static void main(String[] args) {
    // TODO 自動生成されたメソッド・スタブ
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    try {
      String[] diceNumber = br.readLine().split("\\s");
      Dice01 dice01 = new Dice01(diceNumber);
      
      char[] order = (br.readLine()).toCharArray();
      for (int i = 0; i < order.length; i++) {
        dice01.rollDice(order[i], diceNumber.length);
      }
      System.out.println(dice01.takeTopNumber());
      
    } catch (IOException e) {
      // TODO 自動生成された catch ブロック
      e.printStackTrace();
    }
  }
}

そしたらば、実行で。

f:id:ts0818:20190504194220p:plain

入力値は、

Input

1行目に各面の整数が、図に示すラベルの順番に空白区切りで与えられます。

2行目に命令を表す1つの文字列が与えられます。命令はそれぞれ図に示す4方向を表す文字 ENSW を含む文字列です。

サイコロ 1 | プログラミング入門 | Aizu Online Judge

ということで、

f:id:ts0818:20190504194558p:plain

できました~。

六面体のサイコロでも、たいへんだというのに、多面体のサイコロは想像を絶しそうですね...32面体とかどんな感じになるのかしら...

神様はサイコロを振らないけれど、人間はサイコロを振りたがりますから~!残~念!

今回はこのへんで。