11/30の課題について


11/30の課題


解答例(1)

class Kadai1130{
    public static void main(String [] args) throws Exception{
        System.out.println("Guess a Moo number I think.");
        BufferedReader b=new BufferedReader(new InputStreamReader(System.in));
        //乱数でMoo数を作る
        MooNumber kotae=new MooNumber();
        //解答数のカウンターの作成
        int count=0;
        for(;;){
            /*MooNumberを作成中にExceptionoが発生するかもしれないのでtryでくるむ*/
        try{
            //入力された文字列をMoo数に変換
        MooNumber kaitou=new MooNumber(b.readLine());
        //ここで解答数をカウント
        count++;
        //Bullを計算して表示
        System.out.print(kotae.getBull(kaitou)+"B");
        //Cowを計算して表示
        System.out.println(kotae.getCow(kaitou)+"C");
        //もし4Bullならループを抜ける
        if(kotae.getBull(kaitou)==4) break;     
        }
        catch(Exception e){
            System.out.println("Not a Moo number.");
        }
        }
        //解答回数とともに正解したことを告げる
        System.out.println("Correct answer in "+count);
    }
}

コメント

ほとんどの人がこれと同じようなコードを解答してくれました.

解答例(2)

// 名前:XX XXX
// 学生証番号:XXXXXX
// 説明:moo数を定義するクラスは作らずに、moo数をそのままStringとして扱い、
//Stringクラスのメソッドを用いてbull及びcowを求めた。

import java.util.Random;
import java.io.*;

class Kadai1130{
  public static void main(String [] args) throws Exception{
  
//乱数によるmoo数の作成
    String moo="",imput;
    int temp[]=new int[10],i,j,bull=0,cow=0;
    for(i=0;i< 10;i++){ temp[i]=i; }
     Random r=new Random();
       for(i=0;i< 4;i++){
         j=i+r.nextInt(10-i);
         moo+=temp[j];temp[j]=temp[i];
       }
      System.out.println("Guess a Moo number");

      BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
   toproop: for(int k=1;;k++){
        imput=d.readLine();
     //moo数であるかのチェック
        if(imput.length() != 4){
          System.out.println("Not a Moo Number");k--;continue;
        }
        boolean used[]=new boolean[10];
        bull=0;cow=0;
        for(i=0;i< 4;i++){
          int index="0123456789".indexOf(imput.charAt(i));
          if(index == -1 || used[index]){
              System.out.println("Not a Moo Number");k--;continue toproop;
          }
        // Moo積を求める
          j=moo.indexOf(imput.charAt(i));
          if(j==-1) ;
          else if(j!=i) cow++;
          else if(j==i) bull++;
        used[index]=true;
        }
        System.out.println(k+":"+bull+"B"+cow+"C");
          if(bull==4) {
            System.out.println("Correct answer in "+k);break;
          }
      }
  }
}

コメント

文字列表現にした結果短くなっていますね.ただ,長くなってもクラスにした方が 読みやすい気はします.

オプション課題

解答例(1)

////////////////////////////////////////////////////////////////////////////////
// プログラム名     : Option1130
// 作成者           : gXXXXX XXXX
// プログラムの説明 : Moo数当てのGUI版およびコンピュータの戦略
//                  : コンピュータプレイヤーのアルゴリズムについて
//                  : Foolish ランダムに返すだけ
//                  : Shibu1 いままでの回答とその結果から考えてありうる候補の中か
//                           ランダムに返す
//                  : Shibu2 一手先の局面を最悪の場合の残り候補数を基準に評価し、
//                           残り候補数がもっとも少なくなるものを返す
//                  : Shibu3 一手先の局面を残り候補数の期待値で評価し、期待値がも
//                           っとも小さくなるように返す
//                  : Shibu4 Shibu3の改良版.負けそうになったときの処理を追加
// コメント         : GUI部分はすぐできました(といってもあまり設計が美しくないです
//                    が  ルゴリズムのほうはShibu1で十分強い気が  。Shibu3
//                    で作って平均0.3回程しか改善されなかったのがやる気が  。がん
//                    ばってもあまり報われそうにないですね  。Shibu4は方針をかえて
//                    対戦相手を意識させてみましたが、効果があるのかないのか  。
//                    やっぱり二手以上先までよませないとこれ以上は改善されないの
//                    かなぁ  。
////////////////////////////////////////////////////////////////////////////////


import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;

// Moo数を表すクラス
class MooNumber{
  // 4桁の10進表現に対応した配列
  int digits[]=new int[4];
  private static Random r=new Random();
  // 乱数でのMOO数の生成
  // 0123456789を並び替えて最初の4桁
  MooNumber(){
    int tmpDigits[]=new int[10];
    int i;
    // tmpDigitsに 0123456789を入れる
    for(i=0;i< 10;i++){
      tmpDigits[i]=i;
    }

    // 0 と 0-9(の範囲の乱数を添字とする tmpDigitsの要素)を,
    // 1と1-9を, 2と2-9を,3と3-9を入れ換える
    for(i=0;i< 4;i++){
      int j=i+r.nextInt(10-i);
      digits[i]=tmpDigits[j];
      tmpDigits[j]=tmpDigits[i];
    }
  }
  // 文字列から対応するMoo数を作る
  MooNumber(String str) throws Exception{
    if(str.length() != 4){
      throw new Exception("Not a Moo Number");
    }
    // 同じ数字が2回使われないかどうかのチェック
    boolean used[]=new boolean[10];
    for(int i=0;i< 4;i++){
      // strのi番目の文字が 0-9にあてはまるか?
      int index="0123456789".indexOf(str.charAt(i));
      // 0-9以外の文字か,index番目の数字が既に使われた時
      if(index == -1 || used[index]){
        throw new Exception("Not a Moo Number");
      }
      // index番目の数字が使われた
      used[index]=true;
      // インスタンス変数 digitのi桁目をindexにする.
      digits[i]=index;
    }
  }
  // 別のMoo数との間のbullを数える
  int getBull(MooNumber m){
    int bull=0;
    for(int i=0;i< 4;i++)
      if(digits[i]==m.digits[i])
        bull++;
    return bull;
  }
  // 別のMoo数との間のcowを数える
  int getCow(MooNumber m){
    int cow=0;
    for(int i=0;i< 4;i++)
      for(int j=0;j< 4;j++)
        if(i!=j && digits[i]==m.digits[j]){
          cow++;
          break;
        }
    return cow;
  }
  // デバッグ用など表示に使う.
  public String toString(){
    return ""+digits[0]+""+digits[1]+""+digits[2]+""+digits[3];
  }
}

//プレイヤー基底クラス
abstract class Player{
  protected MooNumber answerMooNumber;
  public Player(){
    answerMooNumber=new MooNumber();
  }
  public int getBull(MooNumber m){
    return answerMooNumber.getBull(m);
  }
  public int getCow(MooNumber m){
    return answerMooNumber.getCow(m);
  }
  abstract public MooNumber answer(int lastBull,int lastCow);
}

//ランダムに答えるだけのプレイヤー:一人プレイのお相手として
class FoolishPlayer extends Player{
  public MooNumber answer(int lastBull,int lastCow){
    return new MooNumber();
  }
}

//Playerクラス:Shibu1
//最も基本的?なプレイヤー、必要最小限のことしかしてない  
//なのに意外と強いかも  
//このアルゴリズムから乱数の要素を廃し5040のパターン全てに対して実行した結果:
//平均回答回数:5.56031746031746
//最小回答回数:1
//最大回答回数: 9
class Shibu1 extends Player{
  protected Vector numberList;
  protected boolean ifFirstTry=true;
  protected MooNumber lastAnswer;
  protected static Random r=new Random();

  //回答関数
  //残りの候補から適当に返す
  protected MooNumber search(){
    return (MooNumber)numberList.get(r.nextInt(numberList.size()));
  }
  public Shibu1(){
    super();
    //すべての可能性を網羅したリストを作成しておく
    numberList=new Vector();
    try{
      for(int i=0;i< 10;i++){
        for(int j=0;j< 10;j++){
          for(int k=0;k< 10;k++){
            for(int l=0;l< 10;l++){
              if(i!=j && i!=k && i!=l && j!=k && j!=l && k!=l){
                numberList.add(new MooNumber(""+i+""+j+""+k+""+l));
              }
            }
          }
        }
      }
      ifFirstTry=true;
    }
    //エラーは出るはずない
    catch(Exception e){
    }
  }
  public MooNumber answer(int lastBull,int lastCow){
    if(ifFirstTry){
      //最初は適当に候補を返す
      //"0123"でもいいが、回答パターンが固定化すると人間に裏をかかれる?
      ifFirstTry=false;
      return lastAnswer=(MooNumber)numberList.get(r.nextInt(numberList.size()));
    }
    else{
      //前回の回答,Bull,Cowから考えてありえない候補を消す
      for(int i=0;i< numberList.size();){
        MooNumber temp=(MooNumber)(numberList.get(i));
        if(lastBull!=temp.getBull(lastAnswer) || lastCow!=temp.getCow(lastAnswer)){
          numberList.remove(i);
        }
        else{
          i++;
        }
      }
      //sarch関数に基づいて回答
      return lastAnswer=search();
    }
  }
}

//Playerクラス:Shibu2
//Shibu1のsearch関数で一手先の局面をよませたもの
//局面の評価には最悪のパターンの残り候補の数を使用
//このアルゴリズムから乱数の要素を廃し5040のパターン全てに対して実行した結果:
//平均回答回数:5.384722222222222
//最小回答回数:1
//最大回答回数: 7
class Shibu2 extends Shibu1{
  protected Vector allNumberList;
  public Shibu2(){
    super();
    allNumberList=(Vector)numberList.clone();
  }

  protected MooNumber search(){
    int bull,cow;
    int[][] nBullCow=new int[5][5];
    int minMax=10000;
    int max;
    int minIndex=0;
    MooNumber number,number2;
    Vector numberList2;
    boolean ifList2=false;

    //まずは的中もありうる候補の中から探す
    for(int i=0;i< numberList.size();i++){
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          nBullCow[k][l]=0;
        }
      }
      //回答としてnumberを選んだ場合
      number=(MooNumber)numberList.get(i);
      //各[bull][cow]の繰り返しが何回出現するか
      for(int l=0;l< numberList.size();l++){
        number2=(MooNumber)numberList.get(l);
        bull=number.getBull(number2);
        cow=number.getCow(number2);
        nBullCow[bull][cow]++;
      }
      max=0;
      //もっとも出現回数が多い(つまり最も絞り込めていない)組み合わせを記録
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          if(max< nBullCow[k][l]) max=nBullCow[k][l];
        }
      }

      //maxが小さくなるほど良い回答
      if(max< minMax){
        minMax=max;
        minIndex=i;
      }
    }

    //的中しないかもしれないものも探す
    numberList2=(Vector)allNumberList.clone();
    for(int i=0;i< numberList.size();i++){
      numberList2.remove(numberList.get(i));
    }
    for(int i=0;i< numberList2.size();i++){
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          nBullCow[k][l]=0;
        }
      }
      //回答としてnumberを選んだ場合
      number=(MooNumber)numberList2.get(i);
      //各[bull][cow]の繰り返しが何回出現するか
      for(int l=0;l< numberList.size();l++){
        number2=(MooNumber)numberList.get(l);
        bull=number.getBull(number2);
        cow=number.getCow(number2);
        nBullCow[bull][cow]++;
      }
      max=0;
      //もっとも出現回数が多い(つまり最も絞り込めていない)組み合わせを記録
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          if(max< nBullCow[k][l]) max=nBullCow[k][l];
        }
      }

      //maxが小さくなるほど良い回答
      if(max< minMax){
        minMax=max;
        minIndex=i;
        ifList2=true;
      }

    }
    if(ifList2){
      return (MooNumber)numberList2.get(minIndex);
    }
    else{
      return (MooNumber)numberList.get(minIndex);
    }
  }
}

//Playerクラス:Shibu3
//Shibu1のsearch関数で一手先の局面をよませたもの
//こちらは局面の評価に残り候補数の期待値を使用
//このアルゴリズムから乱数の要素を廃し5040のパターン全てに対して実行した結果:
//平均回答回数:5.270039682539682
//最小回答回数:1
//最大回答回数: 7
class Shibu3 extends Shibu2{
  protected MooNumber search(){
    int bull,cow;
    int[][] nBullCow=new int[5][5];
    double expectancy;
    double minExpectancy=10000;
    int minIndex=0;
    MooNumber number,number2;
    Vector numberList2;
    boolean ifList2=false;

    //まずは的中もありうる候補の中から探す
    for(int i=0;i< numberList.size();i++){
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          nBullCow[k][l]=0;
        }
      }
      //回答としてnumberを選んだ場合
      number=(MooNumber)numberList.get(i);
      //各[bull][cow]の繰り返しが何回出現するか
      for(int l=0;l< numberList.size();l++){
        number2=(MooNumber)numberList.get(l);
        bull=number.getBull(number2);
        cow=number.getCow(number2);
        nBullCow[bull][cow]++;
      }
      expectancy=0;
      //絞り込める候補の数の期待値を計算
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          expectancy+=(double)nBullCow[k][l]*(double)nBullCow[k][l]/(double)numberList.size();
        }
      }

      //expectancyが小さくなるほど良い回答
      if(expectancy< minExpectancy){
        minExpectancy=expectancy;
        minIndex=i;
      }
    }
    //的中しないかもしれないものも探す
    numberList2=(Vector)allNumberList.clone();
    for(int i=0;i< numberList.size();i++){
      numberList2.remove(numberList.get(i));
    }
    for(int i=0;i< numberList2.size();i++){
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          nBullCow[k][l]=0;
        }
      }
      //回答としてnumberを選んだ場合
      number=(MooNumber)numberList2.get(i);
      //各[bull][cow]の繰り返しが何回出現するか
      for(int l=0;l< numberList.size();l++){
        number2=(MooNumber)numberList.get(l);
        bull=number.getBull(number2);
        cow=number.getCow(number2);
        nBullCow[bull][cow]++;
      }
      expectancy=0;
      //絞り込める候補の数の期待値を計算
      for(int k=0;k< 5;k++){
        for(int l=0;l< 5;l++){
          expectancy+=(double)nBullCow[k][l]*(double)nBullCow[k][l]/(double)numberList.size();
        }
      }
      //expectancyが小さくなるほど良い回答
      if(expectancy< minExpectancy){
        minExpectancy=expectancy;
        minIndex=i;
        ifList2=true;
      }

    }

    if(ifList2){
      return (MooNumber)numberList2.get(minIndex);
    }
    else{
      return (MooNumber)numberList.get(minIndex);
    }
  }
}

//Playerクラス:Shibu1
//Shibu3の改良版
//負けるかもと思ったときの処理を追加
//7000回ほどShibu3と対戦させてみたが強くなっているようには感じられなかった  
//平均回答回数自体は大きくなってるだろうからかなぁ  
class Shibu4 extends Shibu3{
  protected Vector enemyList;
  protected int tryNumber=1;//何回目の回答か
  public Shibu4(){
    super();
    enemyList=(Vector)numberList.clone();
  }
  public int getBull(MooNumber m){
    int bull=answerMooNumber.getBull(m);
    int cow=answerMooNumber.getCow(m);
    //相手の残り候補を考えてあげる?
    for(int i=0;i< enemyList.size();){
      MooNumber temp=(MooNumber)(enemyList.get(i));
      if(bull!=temp.getBull(lastAnswer) || cow!=temp.getCow(lastAnswer)){
        enemyList.remove(i);
      }
      else{
        i++;
      }
    }
    return bull;
  }
  protected MooNumber search(){
    int bull,cow;
    int[][] nBullCow=new int[5][5];
    double expectancy;
    double minExpectancy=10000;
    int minIndex=0;
    MooNumber number,number2;
    Vector numberList2;
    boolean ifList2=false;

    //まずは的中もありうる候補の中から探す
    for(int i=0;i< numberList.size();i++){
      for(int k=0;k<5;k++){
        for(int l=0;l<5;l++){
          nBullCow[k][l]=0;
        }
      }
      //回答としてnumberを選んだ場合
      number=(MooNumber)numberList.get(i);
      //各[bull][cow]の繰り返しが何回出現するか
      for(int l=0;l< numberList.size();l++){
        number2=(MooNumber)numberList.get(l);
        bull=number.getBull(number2);
        cow=number.getCow(number2);
        nBullCow[bull][cow]++;
      }
      expectancy=0;
      //次に絞り込める候補の数の期待値を計算
      for(int k=0;k<5;k++){
        for(int l=0;l<5;l++){
          expectancy+=(double)nBullCow[k][l]*(double)nBullCow[k][l]/(double)numberList.size();
        }
      }
      //expectancyが小さくなるほど良い回答
      if(expectancy< minExpectancy){
        minExpectancy=expectancy;
        minIndex=i;
      }
    }
    //そろそろ負けるかも  
    //的中の可能性がないものなど答えている余裕はない
    //5回目で勝負がつくことが多い->5回を基準にするとよい?
    tryNumber++;
    if((enemyList.size()< numberList.size() && tryNumber>4) ||
       (enemyList.size()==numberList.size() && tryNumber>5)){
      return (MooNumber)numberList.get(minIndex);
    }
    //的中しないかもしれないものも探す
    numberList2=(Vector)allNumberList.clone();
    for(int i=0;i< numberList.size();i++){
      numberList2.remove(numberList.get(i));
    }
    for(int i=0;i< numberList2.size();i++){
      for(int k=0;k<5;k++){
        for(int l=0;l<5;l++){
          nBullCow[k][l]=0;
        }
      }
      //回答としてnumberを選んだ場合
      number=(MooNumber)numberList2.get(i);
      //各[bull][cow]の繰り返しが何回出現するか
      for(int l=0;l< numberList.size();l++){
        number2=(MooNumber)numberList.get(l);
        bull=number.getBull(number2);
        cow=number.getCow(number2);
        nBullCow[bull][cow]++;
      }
      expectancy=0;
      //次に絞り込める候補の数の期待値を計算
      for(int k=0;k<5;k++){
        for(int l=0;l<5;l++){
          expectancy+=(double)nBullCow[k][l]*(double)nBullCow[k][l]/(double)numberList.size();
        }
      }

      //expectancyが小さくなるほど良い回答
      if(expectancy< minExpectancy){
        minExpectancy=expectancy;
        minIndex=i;
        ifList2=true;
      }

    }
    if(ifList2){
      return (MooNumber)numberList2.get(minIndex);
    }
    else{
      return (MooNumber)numberList.get(minIndex);
    }
  }
}
//人間用:一応作ったけど  .全体の設計が良くないかも  .
class HumanPlayer extends Player{
  public MooNumber answer(int lastBull,int lastCow){
    return new MooNumber();
  }
  public void setNumber(MooNumber m){
    answerMooNumber=m;
  }
}

//ここからメインクラス
class Option1130 extends Frame{
  //各種コンポーネント
  private Button startButton,speedButton;
  private Choice[] playerChoice=new Choice[2];
  private TextArea logArea;
  private Button[] numberButton=new Button[10];
  private Button okButton,clearButton;
  private TextField inputField;
  //数字ボタンの押せる・押せない
  private boolean[] stateOfNumberButton=new boolean[10];
  //ゲームのメイン変数
  private Player[] player=new Player[2];
  private int turn=0;
  private int[] lastBull=new int[2];
  private int[] lastCow=new int[2];
  //人間の入力に関する変数
  private MooNumber inputMooNumber;
  private boolean firstInput;
  //タイマー処理用変数
  private Timer timer;
  private boolean ifTimerAction=false;
  private int timerCount=0;
  private boolean ifSpeedUp=false;
  private boolean ifProceeding=false;

  //各種コンポーネントを初期化する関数
  public void initComponent(){
    startButton.setEnabled(true);
    for(int i=0;i<10;i++){
      numberButton[i].setEnabled(false);
      stateOfNumberButton[i]=false;
    }
    okButton.setEnabled(false);
    clearButton.setEnabled(false);

    logArea.append("ゲームを開始するには Start Gameボタンを押してください.\n");
  }

  //メイン処理関数
  //OKボタンでMooNuberが入力されたとき及びタイマー処理から呼ばれる
  //ifProceeding=trueのとき(処理中)は呼ばないで!
  public void action(){
    ifProceeding=true;
    if(firstInput){
      firstInput=false;
      lastBull[0]=lastBull[1]=lastCow[0]=lastCow[1]=-1;
      if(player[0] instanceof HumanPlayer){
        ((HumanPlayer)player[0]).setNumber(inputMooNumber);
        logArea.append("Player AのMoo数を"+inputMooNumber+"に設定しました.\n");
      }
    }
    else{
      MooNumber[] answer=new MooNumber[2];
      //プレイヤーに回答させる
      if(player[0] instanceof HumanPlayer){
        answer[0]=inputMooNumber;
      }
      else{
        answer[0]=player[0].answer(lastBull[0],lastCow[0]);
      }
      answer[1]=player[1].answer(lastBull[1],lastCow[1]);
      //それぞれBull,Cowを求めて表示
      lastBull[0]=player[1].getBull(answer[0]);
      lastCow[0]=player[1].getCow(answer[0]);
      lastBull[1]=player[0].getBull(answer[1]);
      lastCow[1]=player[0].getCow(answer[1]);
      logArea.append("Player A:Answer="+answer[0]+" Bull:"+lastBull[0]+" Cow:"+lastCow[0]+"\n");
      logArea.append("Player B:Answer="+answer[1]+" Bull:"+lastBull[1]+" Cow:"+lastCow[1]+"\n");
      //終了判定
      if(lastBull[0]==4 && lastBull[1]==4){
        logArea.append("turn"+turn+"で引き分けです.\n");
        initComponent();
        return;
      }
      else if(lastBull[0]==4){
        logArea.append("turn"+turn+"でPlayer Aの勝ちです.\n");
        initComponent();
        return;
      }
      else if(lastBull[1]==4){
        logArea.append("turn"+turn+"でPlayer Bの勝ちです.\n");
        initComponent();
        return;
      }
    }
    //終了していないとき
    //次のターン数を表示
    logArea.append("\nturn "+(++turn)+":\n");
    if(player[0] instanceof HumanPlayer){
      logArea.append("Player Aの回答を入力してください. > ");
    }
    ifProceeding=false;
  }

  //コンストラクタ
  public Option1130(){

    super("Moo");

    //コンポーネント登録
    setLayout(null);
    Panel[] topPanel=new Panel[3];
    topPanel[0]=new Panel(null);
    topPanel[0].setBounds(5,50,495,50);
    topPanel[1]=new Panel();
    topPanel[1].setBounds(5,100,495,180);
    topPanel[2]=new Panel(new GridLayout(5,3));
    topPanel[2].setBounds(50,280,400,110);

    for(int i=0;i<3;i++) add(topPanel[i]);

    //topPanel[0](1段目)
    for(int i=0;i<2;i++){
      playerChoice[i]=new Choice();
      playerChoice[i].addItem("Foolish");
      playerChoice[i].addItem("Shibu1");
      playerChoice[i].addItem("Shibu2");
      playerChoice[i].addItem("Shibu3");
      playerChoice[i].addItem("Shibu4");
      //
      //新しくアルゴリズムを追加するときはここに処理を追加
      //
    }
    playerChoice[0].addItem("人間");//人間は必ずPlayer A

    Panel[] subPanel=new Panel[2];
    subPanel[0]=new Panel(new GridLayout(2,1));
    subPanel[0].add(new Label("Player A"));
    subPanel[0].add(playerChoice[0]);
    subPanel[1]=new Panel(new GridLayout(2,1));
    subPanel[1].add(new Label("Player B"));
    subPanel[1].add(playerChoice[1]);
    topPanel[0].add(subPanel[0]);
    topPanel[0].add(subPanel[1]);

    startButton=new Button("Start Game");
    topPanel[0].add(startButton);

    speedButton=new Button("Speed Up");
    topPanel[0].add(speedButton);

    subPanel[0].setBounds(10,0,100,40);
    subPanel[1].setBounds(385,0,100,40);
    startButton.setBounds(200,5,95,20);
    speedButton.setBounds(200,30,95,20);

    //topPanel[1](2段目)
    logArea=new TextArea("",10,50,TextArea.SCROLLBARS_VERTICAL_ONLY);
    logArea.setEditable(false);
    topPanel[1].add(logArea);

    //topPanel[2](3段目)
    topPanel[2].add(new Label(""));
    Label inputLabel=new Label("Moo数入力 ");
    inputLabel.setAlignment(Label.RIGHT);
    topPanel[2].add(inputLabel);

    inputField=new TextField(4);
    inputField.setEditable(false);
    topPanel[2].add(inputField);

    //テンキーの配列にするの面倒  
    for(int i=7;i<10;i++){
      numberButton[i]=new Button(Integer.toString(i));
      numberButton[i].setVisible(true);
      topPanel[2].add(numberButton[i]);
    }
    for(int i=4;i<7;i++){
      numberButton[i]=new Button(Integer.toString(i));
      numberButton[i].setVisible(true);
      topPanel[2].add(numberButton[i]);
    }
    for(int i=1;i<4;i++){
      numberButton[i]=new Button(Integer.toString(i));
      numberButton[i].setVisible(true);
      topPanel[2].add(numberButton[i]);
    }
    numberButton[0]=new Button(Integer.toString(0));
    numberButton[0].setVisible(true);
    topPanel[2].add(numberButton[0]);
    clearButton=new Button("Clear");
    clearButton.setVisible(true);
    topPanel[2].add(clearButton);
    okButton=new Button("OK");
    okButton.setVisible(true);
    topPanel[2].add(okButton);


    //コンポーネントイベント処理

    //数字ボタン0-9
    ActionListener numberButtonListener=new ActionListener(){
      public void actionPerformed(ActionEvent e){
        //現在の入力を読む
        String tempString=inputField.getText();
        for(int i=0;i<10;i++){
          //どのボタンが押されたか
          if(numberButton[i]==(Button)e.getSource()){
            //押されたボタンを押せなくして
            stateOfNumberButton[i]=false;
            //その数字を入力に追加
            inputField.setText(tempString+i);
            break;
          }
        }
        //4文字分入力していたら
        if((inputField.getText()).length()>=4){
          //全ての数字ボタンを押せなくして
          for(int i=0;i<10;i++){
            stateOfNumberButton[i]=false;
          }
          //OKボタンを押せるようにする
          okButton.setEnabled(true);
        }
        //数字ボタンの押せる・押せないを反映
        for(int i=0;i<10;i++){
          numberButton[i].setEnabled(stateOfNumberButton[i]);
        }
        //ClearボタンかOKボタンにフォーカスを移す
        clearButton.requestFocusInWindow();
        okButton.requestFocusInWindow();
      }
    };
    for(int i=0;i<10;i++){
      numberButton[i].addActionListener(numberButtonListener);
    }

    //OKボタン
    okButton.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        if(!ifProceeding){//念のため  
          //入力を読んでMooNumberに変換
          try{
            inputMooNumber=new MooNumber(inputField.getText());
          }
          //エラーは出るはずがない
          catch(Exception ee){
          }
          //clearボタンを押す
          (clearButton.getActionListeners())[0].actionPerformed(e);
          //logAreaに出力
          logArea.append(inputMooNumber.toString()+"\n");
          //メイン処理実行
          action();
        }
      }
    });

    //Clearボタン
    clearButton.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        //入力をクリアして
        inputField.setText("");
        //全ての数字ボタンを押せるようにし,
        for(int i=0;i<10;i++){
          stateOfNumberButton[i]=true;
          numberButton[i].setEnabled(stateOfNumberButton[i]);
        }
        //OKボタンは押せなくする
        okButton.setEnabled(false);
      }
    });

    //SpeedUpボタン
    speedButton.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        //Speedの切り替え処理
        if(ifSpeedUp){
          ifSpeedUp=false;
          speedButton.setLabel("SpeedUp");
        }
        else{
          ifSpeedUp=true;
          speedButton.setLabel("SpeedDown");
        }
      }
    });

    //GameStartボタン
    startButton.addActionListener(new ActionListener(){
      public void actionPerformed (ActionEvent e){
        String tempString;
        String output="";

        initComponent();

        for(int i=0;i<2;i++){
          //選択されたものを文字列で取得
          tempString=playerChoice[i].getSelectedItem();
          if(tempString.equals("人間")){
            player[i]=new HumanPlayer();
            output=output+"player"+(String.valueOf((char)('a'+i))).toUpperCase()+":"+"[人間] ";
          }
          else if(tempString.equals("Foolish")){
            player[i]=new FoolishPlayer();
            output=output+"player"+(String.valueOf((char)('a'+i))).toUpperCase()+":"+"[Foolish] ";
          }
          else if(tempString.equals("Shibu1")){
            player[i]=new Shibu1();
            output=output+"player"+(String.valueOf((char)('a'+i))).toUpperCase()+":"+"[Shibu1] ";
          }
          else if(tempString.equals("Shibu2")){
            player[i]=new Shibu2();
            output=output+"player"+(String.valueOf((char)('a'+i))).toUpperCase()+":"+"[Shibu2] ";
          }
          else if(tempString.equals("Shibu3")){
            player[i]=new Shibu3();
            output=output+"player"+(String.valueOf((char)('a'+i))).toUpperCase()+":"+"[Shibu3] ";
          }
          else if(tempString.equals("Shibu4")){
            player[i]=new Shibu4();
            output=output+"player"+(String.valueOf((char)('a'+i))).toUpperCase()+":"+"[Shibu4] ";
          }
          //
          //新しくアルゴリズムを追加するときはここに処理を追加
          //
        }
        output=output+"でゲームを開始します.\n";

        logArea.setText(output);
        turn=0;
        firstInput=true;
        ifProceeding=false;
        if(player[0] instanceof HumanPlayer){
          //人間の場合は初期設定を促す
          logArea.append("Player AのMoo数を設定してください. > ");
          //数字ボタンを押せるようにする
          for(int i=0;i<10;i++){
            numberButton[i].setEnabled(true);
            stateOfNumberButton[i]=true;
          }
          okButton.setEnabled(false);
          clearButton.setEnabled(true);
          //タイマーは使わない
          ifTimerAction=false;
        }
        else{
          //コンピュータ同士の場合はタイマーをオンに
          ifTimerAction=true;
          timerCount=0;
        }
      }

    });

    //タイマー処理
    //一定時間ごとにaction関数を呼び出す
    //900ミリ秒ごとまたは150ミリ秒ごと
    timer=new Timer(true);
    timer.schedule(new TimerTask(){
      public void run(){
        try{
          if(ifTimerAction && !ifProceeding && (timerCount>=6 || ifSpeedUp)){
            timerCount=0;
            action();
          }
          else{
            timerCount++;
          }
        }
        //メイン部分とのタイミングの関係でエラーが出たら無視
        catch(Exception e){
        }
      }
    },0,150);

    //メインフレームの設定
    setSize(500,400);
    setVisible(true);
    setResizable(false);
    addWindowListener(new WindowAdapter(){//ウィンドウイベント
      public void windowClosing(WindowEvent e) {//X印で終了
        System.exit(0);
      }
    });

    //最後に各種コンポーネント初期化
    initComponent();
  }
  public static void main(String [] args){
    Option1130 frame=new Option1130();
  }
}

コメント

大作ですね.平均回答回数の最小値は5.213であることが知られているので,Shibu3の5.27というのはかなり良い数字です.