2011-01-24 21 views
0

私はTicTacToeプログラムをやっていますが、唯一の欠けている部分は、ゲームを終了するか、再生するかをユーザーが選択できるようにすることです。私はゲームに "戻る"方法を見つけることができません。ゲームに戻るには?ゲームを終了した後

import java.io.*; 

public class Expierment 
{ 
     static char c1 [] = new char[10]; 
     static char c2 [] = new char[10]; 
     static char c3 [] = new char[10]; 
     static char p1; 
     static char p2; 
     static boolean gameOver = false; 
     public static void main(String args[]) 
     { 
      int counter = 0; 
      int p1Wins = 0; 
      int p2Wins = 0; 
      int r1 = 0; 
      int r2 = 0; 
      int r3 = 0; 
      int r4 = 0; 
      int r5 = 0; 
      int r6 = 0; 
      int r7 = 0; 
      int r8 = 0; 
      int r9 = 0; 
      int pick1 = 0; 
      int pick2 = 0; 
      int pick3 = 0; 
      int pick4 = 0; 
      int pick5 = 0; 
      int pick6 = 0; 
      int pick7 = 0; 
      int pick8 = 0; 
      int pick9 = 0; 
      char turn = 'X'; 
      int choice = menu(); 
      switch(choice) 
      { 
       case 1: 
        System.out.println("The game is called 'Tic-Tac-Toe', you should have known it. If you don't, search it.") ; 
       case 2: 
        gameOver = false; 
        break; 
       case 3: 
        System.out.println("\nSee you next time !!"); 
        return; 
       default: 
        System.out.println("\nYou hit the wrong key......\n"); 
        return; 
      }//end of switch 
      System.out.println("\nPlayer 1 initials ?"); 
      String n1 = GCS(); 
      p1 = n1.charAt(0); 
      System.out.println("\nPlayer 2 initials ?"); 
      String n2 = GCS(); 
      p2 = n2.charAt(0); 
      c1[2]='1'; 
      c2[2]='2'; 
      c3[2]='3'; 
      c1[1]='4'; 
      c2[1]='5'; 
      c3[1]='6'; 
      c1[0]='7'; 
      c2[0]='8'; 
      c3[0]='9'; 
     printBoard(); 
     while(gameOver!=true) 
     { 
      System.out.println("Which spot ?"); 
      int pick = Integer. parseInt(GCS()); 
       switch (pick) 
      { 
       case 1: 
        if (r1<1) 
       { 
        c1[2] = turn; 
        r1++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break;     
       case 2: 
        if (r2<1) 
       { 
        c2[2] = turn; 
        r2++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break;     
       case 3: 
        if (r3<1) 
       { 
        c3[2] = turn; 
        r3++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break; 
       case 4: 
        if (r4<1) 
       { 
        c1[1] = turn; 
        r4++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break; 
       case 5: 
        if (r5<1) 
       { 
        c2[1] = turn; 
        r5++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break; 
       case 6: 
        if (r6<1) 
       { 
        c3[1] = turn; 
        r6++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break; 
       case 7: 
        if (r7<1) 
       { 
        c1[0] = turn; 
        r7++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break; 
       case 8: 
        if (r8<1) 
       { 
        c2[0] = turn; 
        r8++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break; 
       case 9: 
        if (r9<1) 
       { 
        c3[0] = turn; 
        r9++; 
       } 
       else 
       { 
        System.out.println("That column is full, pick another.\n"); 
        continue; 
       } 
        break; 
       default: 
        System.out.println("Seriously?! Pick a possible spot.\n"); 
        continue; 
       }//end of switch 
      if (turn=='X') turn = 'O'; 
      else turn = 'X'; 
      printBoard(); 
      if (checkWinner()) 
      { 
       while(gameOver==true) 
       { 
        int Echoice = EGM(); 
        switch(Echoice) 
        { 
         case 1: 
          System.out.println("The game is called 'Tic-Tac-Toe', you should have known it. If you don't, search it.") ; 
         case 2: 
          gameOver = false; 
          menu(); 

          break; 
         case 3: 
          System.out.println("\nSee you next time !!"); 
          return; 
         default: 
          System.out.println("\nYou hit the wrong key......\n"); 
          return; 
        }//end of switch 
       }//end of while true 
       return; 
      } 
      counter ++; 
      if (counter==9) 
      { 
       System.out.println("\n\nYou tied.\n"); 
       return; 
      } 
     }//end of while not true 
    }//end of main 

    public static boolean checkWinner() 
    { 
      for (int k=0; k<2; k++) 
     { 
      if ((c1[k]!=' ')&&(c1[k]==c2[k])&&(c1[k]==c3[k])) 
      { 
       System.out.println("\nYo " + c1[k] + " is the winner!\n"); 
       gameOver=true; 
       return true; 
      }//checks column 1-3 horizontally 
     }//end of horizontal check 

     for (int m=0; m<2; m++) 
     { 
      if((c1[m]!=' ')&&(c1[m]==c1[m+1])&&(c1[m+1]==c1[m+2])&&(c1[m]==c1[m+2])) 
      { 
       System.out.println("\nYo " + c1[m] + " is the winner!\n"); 
       gameOver=true; 
       return true; 
      }//checks column 1 vertically 
      if((c2[m]!=' ')&&(c2[m]==c2[m+1])&&(c2[m+1]==c2[m+2])&&(c2[m]==c2[m+2])) 
      { 
       System.out.println("\nYo " + c2[m] + " is the winner!\n"); 
       gameOver=true; 
       return true; 
      }//checks column 2 vertically 
      if((c3[m]!=' ')&&(c3[m]==c3[m+1])&&(c3[m+1]==c3[m+2])&&(c3[m]==c1[m+2])) 
      { 
       System.out.println("\nYo " + c3[m] + " is the winner!\n"); 
       gameOver=true; 
       return true; 
      }//checks column 3 vertically 
       if ((c1[m]!=' ')&&(c1[m]==c2[m+1])&&(c1[m]==c3[m+2])) 
      { 
       System.out.println("\nYo " + c1[m] + " is the winner!\n"); 
       gameOver=true; 
       return true; 
      }//checks upward diagonal 
       if ((c3[m]!=' ')&&(c3[m]==c2[m+1])&&(c3[m]==c1[m+2])) 
      { 
       System.out.println("\nYo " + c1[m] + " is the winner!\n"); 
       gameOver=true; 
       return true; 
      } 
     }//end of vertical check 
       return false; 
    }//end of checkWinner 

    public static void printBoard() 
    { 
     System.out.println("_______"); 
     for (int j = 2; j > -1; j--) 
     { 
      System.out.println("|" + c1[j] + "|" + c2[j] + "|" + c3[j] + "|"); 
      System.out.println("-------"); 
     } 
    }//end of printBoard 

    public static int menu() 
    { 
     System.out.println("Tic-Tac-Toe ~ Main Menu\n\n1. Instructions\n2. Play a 1 player game"+"\n3. Exit\n"); 
     int selection = Integer.parseInt(GCS()); 
     return selection; 
    }//end of menu 

    public static int EGM() 
    { 
     System.out.println("Tic-Tac-Toe ~ End of Game Menu\n\n1. Instructions\n2. Play again"+"\n3. Exit\n"); 
     int Eselection = Integer.parseInt(GCS()); 
     return Eselection; 
    } 

    public static String GCS() 
    { 
     int noMoreInput=-1; 
     char enterKeyHit='\n'; 
     int InputChar; 
     StringBuffer InputBuffer = new StringBuffer(100); 

     try 
     { 
      InputChar=System.in.read(); 
      while(InputChar != noMoreInput) 
      { 
       if((char)InputChar !=enterKeyHit) 
       { 
        InputBuffer.append((char)InputChar); 
       } 
       else 
       { 
        InputBuffer.setLength(InputBuffer.length()-1); 
        break; 
       } 
       InputChar=System.in.read(); 
      } 
     } 
     catch (IOException IOX) 
     { 
      System.err.println(IOX); 
     } 
     return InputBuffer.toString(); 
     }//end of GCS 
}//end of public class 
+0

あなたの質問とは無関係に、このコードを書き換えて、 'pick1'、' pick2'、...、 'pick9'変数の必要性を排除することをお勧めします。これと同じような変数のコレクションを書くことが決まれば、 'int [] pick = new int [9]'のように配列を使ってほとんどいつでも書き換えることができます。これにより、すべての値に 'pick [0]'、...、 'pick [8]'としてアクセスすることができますが、もっと重要なのは、プログラムでインデックスを生成できることです。これは、あなたが時間をとって喜んでいるならば、 'switch'ステートメントをわずか数行のコードに圧縮することができます。 – templatetypedef

+0

フォーマットを修正してください –

+0

いくつかのヒントr1-r9、pick1-pick9は代わりに配列を使用し、csと同じものを文字列の配列に変更し、c [0] = "741"のように初期化します。 – hhafez

答えて

2

あなたは本当にmain機能のうち、そのコードの一部を取得する必要があります。

具体的には、私は多分、別の関数で、ゲーム全体のループを置くなど、ゲームをプレイして勝者をチェックするためのロジックが含まれているplayGame()を、と呼ばれ、いずれかの勝者を返すか、単に勝者とリターンを印刷したいです無効。

次に、メイン関数がplayGame()を呼び出してループを終了し、ループの最後に、再度再生したいかどうかをユーザーに確認します。

通常、各機能に1つの論理タスクを実行させます。あなたはcheckWinnerを動かすことでうまくやったが、他のコードのいくつかと同じようにする。

「ユーザーにもう一度再生を依頼する」のヘルプが必要な場合は、コメントを残してください。私はそれに対処するための編集を行います。

1
quick and dirty pseudo-code - not modular 

do {  
    //everything in your main goes here 
    . 
    . 
    .  
    playAgain = prompt the user 
} while(playAgain); 
0

もっと簡潔な主な方法では、はるかに明確になります。本当に素早く汚れた方法は、メインメソッドのすべてを新しいメソッドにコピーし、メインからメソッドを呼び出すだけです。ユーザーが新しいゲームを開始するときに選択します。

+0

を使用してください。それでは、第2ゲームの終了時はどうでしょう。 – Blackiey

+0

は本質的に目標をゲームループと似ています。 playGame()のように、値を初期化したり、ボードを印刷したりするメソッドがあります。メインから呼び出します。ゲームが終了したら、次に何をするかをユーザーに尋ねます。シンプルにするために、System.inから読み込んだScannerオブジェクトを使用することができます。プレイが再びプレイされると答えが返ってくると、gameGameにループバックしてやり直します。 2番目のゲームは、1番目のゲーム、3番目のゲームなどと変わりありません。playGame()を呼び出す限り、基本的に新鮮な状態になります。 – awestover89

1

do-whileメソッドよりも汚れています。最終的にスタックオーバーフローを引き起こします。

//your current main method 
boolean playAgain = prompt the user 
if(playAgain){ 
    main(args); 
} 
+1

+1の最も邪魔なコード。私はこの1つを読んだ後に洗濯のように感じる。 –

+0

これで十分です。 –

+0

@Amir Afghaniは私の2番目の文が言っていることではありませんか? – ILMTitan

1

現在のプログラムレイアウトでは、それを達成するための「クリーン」な方法はありません。ここではいくつかの建設的な批判です:

  • あなたの主な方法は、唯一のあなただけのmain方法でプログラムを初期化する必要があるブートストラップ

でなければなりません。したがって、方法をやってみてくださいものを試してみてください。あなたは今デザインはゲームメニューとゲームのメインループを同じメソッドの中に持っています。

あなたのゲームループは次のようになります。

while still playing 
    read input from user 
    if game is active 
     process game input 
     update game 
    else 
     process menu input 
     update menu 

この方法は、あなただけのメニューやゲームのgame is active状態を急がする必要があります。等。

あなたGCS方法であり、あまりにも複雑で、ただでそれを置き換える:

Scanner scanner = new Scanner();  // put this somewhere at the class level (so it is reusable) 
... 
String input = scanner.nextLine(); // put this somewhere in a method reading an input 
  • 変数虐待

多くの変数を初期化するのではなく、おそらく他のものと同様に配列を使用できます。具体的には、2次元配列を使用できます。

int grid[][] = new int[3][3]; 
// grid[0][0] points to the top-left cell, grid[2][2] points to the bottom right one 

または、すべてを格納するために単一のintを使用できます。あなたのグリッドをbit array

int grid = 0; // empty grid 
... 
// set player move 
grid |= (1 << (y*3)+x) << PLAYER_OFFSET; // PLAYER_OFFSET: 0=player 1, 16=player 2 
// reset (clear) player move 
grid &= ~((1 << (y*3)+x) << PLAYER_OFFSET); // ... 
// check if player move is set 
boolean isSet = (grid >> ((1 << (y*3)+x) << PLAYER_OFFSET)) && 1; // ... 

と表記する理由は何ですか? ...プレイヤーが勝利した場合、あなただけの勝利パターンに対して検証、for..loop空想やその他の複雑なアルゴリズムを必要としない確認するため:それ

int pattern = 273; // test for diagonal from [0,0] to [2,2], or bits "100 010 001" 
boolean isWinning = (grid && (pattern << PLAYER_OFFSET)) != 0; 

だそれ!


また、9から0を使用して、入力値がプレーヤーのその直感的ではないが同様に、グリッドセルを識別するために良いことができます。例えば、多くのゲーム(チェス、チェッカー、LOAなど)とアプリケーション(Excel、Calcなど)は、Algebraic chess notationシステムを使用しています。 xyの表記を変換するのは非常に簡単です。たとえば、

boolean cellPlayed = false; 
while (!cellPlayed) { 
    String cellStr = scanner.readLine().toLower(); // ex: "b2" for the center cell 
    try { 
     int gridx = cellStr.charAt(0) - 'a'; // ex: for "b2" should return 1 
     int gridy = cellStr.charAt(1) - '1'; // ex: for "b2" should return 1 

     grid(gridx][gridy] = playerValue;  // 1 for "player 1" and 2 for "player 2" 
     cellPlayed = true; 
    } catch (Exception e) { 
     System.out.println("Error! Invalid input"); 
    } 
} 

落胆しないでください。私たちはすべてどこかで始まります! :)