Edited at

サイコロの回転をシミュレート(AOJ ITP1_11_A)

More than 3 years have passed since last update.

AOJ ITP1_11_Aをやっていて結構困ったので備忘録的に書いておく。

問題はページに飛んで各自で見ていただきたい。


できるようにすべきこと

・方角を与えてサイコロを回転させる

・上面の数値を返す


実現に向けて最初にやろうとしたこと

・各面の数値をメンバ配列に入れておく

・上面になっている面の番号を変数に記録しておく(最初は1)

(各面には数字とは別に一意な番号が振ってある)


いざ回転

回転させる際は、現在の上面の番号と移動の方角から次の上面の番号を求める。

⇒だめでした

回転の仕方によって番号の推移が違うことが判明。

S方向に転がしていって6を上面にしたときと、E方向に転がしていって6を上面にしたときでは番号の配置(ひいては面の配置)が違う。

動き方によって処理を変えないといけない?


ブレークスルー

「上の面が何番かを記録しておく」のではなく、「回転するたびに数字を全部回転に合わせて実際に動かす」。

(最初に考えた方法よりもむしろプリミティブ。でもこっちの方が正しい)

コードも載せておく。

2015/07/12 他の記事を書くにあたり少し修正。

(operator[]()の追加、top()の削除)

class dice{

public:
explicit dice(int in[6]){
for(int i=0;i<6;i++){
v[i]=in[i];
}
}
void mov(const char c){
int buf;
switch(c){
case 'N':{
buf = v[0];
v[0] = v[1];
v[1] = v[5];
v[5] = v[4];
v[4] = buf;
break;
}
case 'E':{
buf = v[0];
v[0] = v[3];
v[3] = v[5];
v[5] = v[2];
v[2] = buf;
break;
}
case 'W':{
buf = v[0];
v[0] = v[2];
v[2] = v[5];
v[5] = v[3];
v[3] = buf;
break;
}
case 'S':{
buf = v[0];
v[0] = v[4];
v[4] = v[5];
v[5] = v[1];
v[1] = buf;
break;
}
}
}
int operator[](size_t i){return v[i];}
private:
int v[6];
};

上面の数字を得るにはdiceオブジェクトdについて、d[0]を呼べばよい。


課題

・方角ごとに処理を書くのはめんどい。

(何かのコンテナで解決できないだろうか)


続編

サイコロの配置に関する問題を乱数を使って解く(AOJ ITP1_11_B/C)