プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

ジャンケンプログラムにポリモー…?何それおいしいの?

昨日の晩、私の先輩が突然、ジャンケンプログラムをJAVAでつくる課題が出たけどわからんから教えてとやってきました。
あ、先輩、ごちになりました(m __)m


まぁ、課題の言わんとしていることは分かるんですよ。言わんとしていることは。
だからセオリーに乗っ取って「これはね、インターフェースを宣言して、こうこうこうやってやるんだよ。これをポリモーフィズムというんだよ。」とやったわけです。



だが、ジャンケンプログラムを書くのにポリなんちゃらは必要ない。それどころか、条件分岐すらしない。
というわけで、ここで変態解法を載せておく。全国のジャンケンプログラム課題をJAVAで出されたみんな!これを提出したら殴られるぞ!

public class Janken {
	static int[] gcp={2,4,9};//順にグーチョキパーを表す値。
	static String[] message1= {
		"引き分けです",
		"あなたの勝ちです",
		"あなたの負けです"
	},
	message2={
		"グー",
		"チョキ",
		"パー"
	};
	
	public static void main(String[] args) {
		java.util.Scanner s = new java.util.Scanner(System.in);
		int you=-1,cpu=(int) (Math.random()*3);
		while(you <0 || you >= 3){
			you = s.nextInt();//入力ではぐー:0,チョキ1,パー2とする。
		}
		int y=gcp[you],c=gcp[cpu];
		System.out.printf("あなたは%sを、cpuは%sを選択しました。よって%s\n",message2[you],message2[cpu],
			message1[ Integer.bitCount((y*2|c^y)&14)-1 ]	//勝敗判定
		);
	}
}


実行結果例
2
あなたはパーを、cpuはグーを選択しました。よってあなたの勝ちです
1
あなたはチョキを、cpuはチョキを選択しました。よって引き分けです
0
あなたはグーを、cpuはパーを選択しました。よってあなたの負けです

肝となるのは

  • グー=2
  • チョキ=4
  • パー=9

という数値。


10進数で見ても意味は分からないのでビット列にします

数値 ビット列
グー 2 0010
チョキ 4 0100
パー 9 1001

ビット列の中でも赤くかこった部分が重要です。1bit目はちょこざいするための飾りです。
順に1bitずつたっているのが分かると思います。どこにビットがたっているかで手を決めているわけです。
さて、自分の手をX,相手の手をYとします。
この時

X×2 or Y exor X

という式を計算すると、上で赤くかこった部分のビット(2〜4bit)が

  • 引き分けなら1ビット
  • 勝ちなら2ビット
  • 負けなら3ビット

立っている状態になるのです。なんでそうなるかの証明は面倒くさいのでパス。



というわけで、2〜4ビットに何個ビットが立っているかを調べて(Integer.bitCountを利用)、配列から表示する結果を取り出せばジャンケンゲームの完成です。


配列オブジェクトのメソッド[int]で結果の表示を変更している、っていう風にむりやり見方を変えたら、まぁポリモーフィズムと言えなくもないけどさ…。Cでもできるこれはさすがにポリモーフィズムとはいわんでしょ。