プログラムdeタマゴ

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

おまけ:複数人数のじゃんけんプログラム

ググってみたら、意外にも数式だけで一気に勝利判定してしまうような記事は見当たらなかった。

というわけで、おまけで複数人数の時はどうするかです。
といっても、流石に今回は引き分けか、それとも勝負がついたかで処理が異なるので1度条件分岐せざるを得ませんが。(もししなくてすむ方法があったら誰かよろしく。ポリなんちゃらは禁止。)


まずはグーチョキパーそれぞれの値をどうするかを決めます。
今回は

  • グー  9(1001)
  • チョキ 2(0010)
  • パー  4(0100)

とします。4bit目は小細工のための飾りです。


まずは出された手の全部のor和をとります。
これで、何が出されていていて、何が出されていないのか、という情報が得られます。
例えば、全部出されていたら
1111(=15)
になりますし、グーかパーのみなら
1101(=13)
になります。チョキのみなら
0010
ですね。


次にこの値と、この値を右に1bitシフトした値と&をとります。
これで何が分かるかというと、自身のビットと左のビットが立っているビットが分かります。
例えば、1111なら111になります。1101なら、100になります。0010なら000ですね。
この結果が111か000なら引き分けになります。
一方、そうでないときは、ビットが立っている部分が表す手が勝利になります。
ですから、ある手が勝利になっているかどうかを調べるには、この値とその手の&をとってビットが立っているかを調べればいいのですね。


それらをまとめると以下の様になります。

public class Janken {
	static String[]
	              message1={"グー","チョキ","パー"},
	              message2={"負けました","勝ちました"};
	static int[] gcp={9,2,4};
	public static void main(String[] args) {
		int member = 3;
		int[] players = new int[member];
		int[] gcps = new int[member];

		int kekka=0;
		//手の決定
		StringBuilder str = new StringBuilder();
		for(int i=0;i<member;i++){
			int te,g_c_p;
			te = (int) (Math.random()*3);//手の決定
			g_c_p = gcp[te];//値の取り出し
			players[i] = te;
			gcps[i] = g_c_p;
			str.append(String.format("Player%dは%sを出しました。\n",i,message1[players[i]]));

			kekka |=g_c_p;
		}
		kekka = kekka & (kekka>>1);
		if(kekka==7 || kekka==0){
			str.append("  引き分けです\n");
		}else{
			for(int i=0;i<member;i++){
				str.append(String.format("  Player%dは%s\n",i,message2[Integer.bitCount(gcps[i]&kekka)]));
			}
		}
		System.out.println(str);
	}
}

実行結果の例
Player0はチョキを出しました。
Player1はチョキを出しました。
Player2はパーを出しました。
Player0は勝ちました
Player1は勝ちました
Player2は負けました




というわけで、複数人数のじゃんけんゲームを(ループを覗けば)引き分け判定をするための一回の条件分岐で作成することが出来ました。
あと、勝利結果を書く部分はInteger.bigCountを使っていますが、Cの様に比較の結果が0か1で返ってくる場合は、message2[(gcps[i]&kekka) !=0]とすればよりよいでしょうね。