Skip to content

Instantly share code, notes, and snippets.

@kazuhito-m
Last active August 29, 2015 14:12
Show Gist options
  • Save kazuhito-m/cdf14987f6884ca29b33 to your computer and use it in GitHub Desktop.
Save kazuhito-m/cdf14987f6884ca29b33 to your computer and use it in GitHub Desktop.
じゃんけんプログラム(Groovy版)
/*
* Special Thanks!
* 監修/コードレビュアー: @bufferings さん、 @megascus さん。 (ミウラはほぼアイディアだけ…トホホ)
*/
import org.junit.Test
/** じゃんけんの"手"を表わす定数群。 */
enum Sign {
pa, ty, gu;
}
/** じゃんけんの結果を表現する定数群。 */
enum Result {
drow, win, loss;
}
/**
* じゃんけんクラス。
*/
class Janken {
/**
* 3つの手からランダムに取り出す。
* @return グー、チョキ、パーのどれか。
*/
Sign randomHand() {
return Sign.values()[(new Random()).nextInt(Sign.values().length)]
}
/**
* じゃんけんの勝負。
* @param myHand 自分の手。
* @param enemyHand 相手の手。
* @return 勝敗値。
*/
Result janken(Sign myHand, Sign enemyHand) {
// enumのordinal(0から始まる定義順)を利用して計算で勝敗を出す。
// 手は 0:パー、1:チョキ、2:グーとなるため、(自分の手 引く 相手の手)をすると、 -2〜+2 の範囲の数値となる。
// 結果は 0:あいこ、1:勝ち、2:負けとなるため、
// -2(勝),-1(負),0(あいこ),1(勝),2(負) という数列を、 1,2,0,1,2 という数列に変換する必要がある。
// そこで、「3足して3で割った余り」という計算方法で、Resultのordinalに合わせる。
def len = Sign.values().length
int res = ((myHand.ordinal() - enemyHand.ordinal() + len) % len)
return Result.values()[res]
}
/**
* じゃんけんの勝負(片方の手が自動で決まるタイプ)。
* @param hand 手。
* @return 勝敗値。
*/
Result janken(Sign hand) {
janken(hand, randomHand())
}
}
/**
* じゃんけんクラスのテスト。
*/
class JankenTest {
Janken sut = new Janken();
@Test
void 手のenumは期待した通りの数値を返してくれるか() {
assert Sign.gu.ordinal() == 2
assert Sign.ty.ordinal() == 1
assert Sign.pa.ordinal() == 0
}
@Test
void 結果のenumは期待した通りの数値をかえしてくれるか() {
assert Result.drow.ordinal() == 0
assert Result.win.ordinal() == 1
assert Result.loss.ordinal() == 2
}
@Test
void ランダムに手を返す() {
// ランダムに返すもののテストなので、信頼性のため複数回回す。
1..1000.each {
assert Sign.values().contains(sut.randomHand())
}
}
@Test
void じゃんけんして自分が勝つパターン() {
def expect = Result.win
assert sut.janken(Sign.gu, Sign.ty) == expect
assert sut.janken(Sign.ty, Sign.pa) == expect
assert sut.janken(Sign.pa, Sign.gu) == expect
}
@Test
void じゃんけんして自分が負けるパターン() {
def expect = Result.loss
assert sut.janken(Sign.gu, Sign.pa) == expect
assert sut.janken(Sign.ty, Sign.gu) == expect
assert sut.janken(Sign.pa, Sign.ty) == expect
}
@Test
void じゃんけんしてあいこになるパターン() {
def expect = Result.drow
assert sut.janken(Sign.gu, Sign.gu) == expect
assert sut.janken(Sign.ty, Sign.ty) == expect
assert sut.janken(Sign.pa, Sign.pa) == expect
}
@Test
void 他者の手が自動的に出るようなじゃんけんが可能である() {
// ランダムに返すもののテストなので、信頼性のため複数回回す。
1..1000.each {
for (Sign s : Sign.values()) {
assert Result.values().contains(sut.janken(s)) // 計3000回か…。
}
}
}
}