-2

テキストベースの戦艦ゲームを作成しており、プレイヤーはコンピューターと対戦します。ランダムな 3 ユニットの長さの船 3 隻がボード上に配置されます。最後の推測がヒットした場合、コンピューターが最後の推測がどこにあったかを推測できるようにしたいと考えています。(しかし、彼がヒットするまで同じ場所の周りを推測し続け、船全体または3ヒットを取得するまでその周りを推測し続けるように機能させたいです)それは少し機能します。ヒットした場合、コンピューターは最後の推測に近いものを推測しますが、その推測に失敗すると、再びランダムに推測し始めます。誰かが私を少し助けてくれますか?-getGuess()メソッドはAIを使ったものです-

/*
 * computer class to handle computers guesses/ etc
 * most methods are copied from player class, but slightly altered to account for variable names
 * Methods that havent been copied have comments
 */ 

public class Computer{
  static int firstCo, secondCo;
  static int[] guessedHits={7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
  //int array to store last guess
  static int[] lastGuess = new int[2];
  //int array to store current guess
  static int[] guess=new int[2];

  public static int[] computerShip1=new int[6];
  public static int[] computerShip2=new int[6];
  public static int[] computerShip3=new int[6];

  /*
   * method to choose random guess for computer - but make it guess around last guess if last guess was a hit
   * return guess coordinate numbers in an array
   */
  public static int[] getGuess(){
    int[] guess=new int[2];
    int firstCo, secCo;
    int ran; //random int between 0 and 1 - will help to make random choices for guesses
    if(isHit(lastGuess[0],lastGuess[1])){
      ran=(int)(Math.random()*2);
      //if ran is 0 and last guesses x coordinate was correct, set next guess to last x, and next y to last y +1
      if((ran==0 && lastGuess[0]==Player.playerShip1[0]) || (ran==0 && lastGuess[0]==Player.playerShip1[2]) || (ran==0 && lastGuess[0]==Player.playerShip1[4])){
        guess[0]=lastGuess[0];
        guess[1]=lastGuess[1]+1;
      //if ran is 1 and last guesses x coordinate was correct, set next guess to last x, and next y to last y -1
      }else if((ran==1 && lastGuess[0]==Player.playerShip1[0]) || (ran==1 && lastGuess[0]==Player.playerShip1[2]) || (ran==1 && lastGuess[0]==Player.playerShip1[4])){
        guess[0]=lastGuess[0];
        guess[1]=lastGuess[1]-1;
      //if ran is 0 and last guesses y coordinate was correct, set next guess to last y, and next x to last x +1
      }else if((ran==0 && lastGuess[1]==Player.playerShip1[1]) || (ran==0 && lastGuess[1]==Player.playerShip1[3]) || (ran==0 && lastGuess[1]==Player.playerShip1[5])){
        guess[0]=lastGuess[0]+1;
        guess[1]=lastGuess[1];
      //if ran is 1 and last guesses y coordinate was correct, set next guess to last y, and next x to last x -1
      }else if((ran==1 && lastGuess[1]==Player.playerShip1[1]) || (ran==1 && lastGuess[1]==Player.playerShip1[3]) || (ran==1 && lastGuess[1]==Player.playerShip1[5])){
        guess[0]=lastGuess[0]-1;
        guess[1]=lastGuess[1];
      }
    return guess;
    }else{
      guess[0]=(int)(Math.random()*7);
      guess[1]=(int)(Math.random()*7);
      return guess;
    }
  }

  public static boolean isHit(int firstC, int secC){
    for(int i=0; i<Player.playerShip1.length; i=i+2){
      if(firstC==Player.playerShip1[i] && secC==Player.playerShip1[i+1]){
        return true;
      }
      if(i==4){
        break;
      }
      }
    for(int i=0; i<Player.playerShip2.length; i=i+2){
      if(firstC==Player.playerShip2[i] && secC==Player.playerShip2[i+1]){
        return true;
      }
        if(i==4){
        break;
        }
      }

    for(int i=0; i<Player.playerShip3.length; i=i+2){
      if(firstC==Player.playerShip3[i] && secC==Player.playerShip3[i+1]){
        return true;
      }
      if(i==4){
        break;
      }
      }

    return false;
  }


  public static void addHits(int firstC, int secC){
    int index=-1;
    for(int i=0; i<guessedHits.length; i++){
      if(guessedHits[i]==7){
        index=i;
        break;
      }
    }
    guessedHits[index]=firstC;
    guessedHits[index+1]=secC;
  }


  public static void setComputerShips(){
   int randX, randY;
   int direction; //will be random int 0-1, determines direction ship will extend(up/down, left/right)

   randX=(int)(Math.random()*7);
   randY=(int)(Math.random()*7);
   direction=(int)(Math.random()*2);

   computerShip1[0]=randX;
   computerShip1[1]=randY;
   if(direction==0){//extend upwards or downwards 2 units(y values change, x stays the same)
    computerShip1[2]=randX;
    computerShip1[4]=randX;
    if(randY>3){//if y value is greater than 3, has to extend down or it wont fit
     computerShip1[3]=randY-1;
     computerShip1[5]=randY-2;
    }else if(randY<2){//if y value is less than 2, has to extend up or it wont fit
     computerShip1[3]=randY+1;
     computerShip1[5]=randY+2;
    }else{//if direction doesnt matter, just extend upwards
     computerShip1[3]=randY+1;
     computerShip1[5]=randY+2;
    }
   }else if(direction==1){//extends left or right 2 units(y values stay the same, x changes)
    computerShip1[3]=randY;
    computerShip1[5]=randY;
    if(randX>3){//if x is greater than 3, must extend left or it wont fit
     computerShip1[2]=randX-1;
     computerShip1[4]=randX-2;
    }else if(randX<2){//if x is less than 2, must extend right or it wont fit
     computerShip1[2]=randX+1;
     computerShip1[4]=randX+2;
    }else{//if direction doesnt matter, just extend right
     computerShip1[2]=randX+1;
     computerShip1[4]=randX+2;
    }
   }
   //do same for both other ships
   do{
   randX=(int)(Math.random()*7);
   randY=(int)(Math.random()*7);
   }while((randX==computerShip1[0] && randY==computerShip1[1])||(randX==computerShip1[2]&&randY==computerShip1[3])||(randX==computerShip1[4]&&randY==computerShip1[5]));
   direction=(int)(Math.random()*2);

   computerShip2[0]=randX;
   computerShip2[1]=randY;
   if(direction==0){
    computerShip2[2]=randX;
    computerShip2[4]=randX;
    if(randY>3){
     computerShip2[3]=randY-1;
     computerShip2[5]=randY-2;
    }else if(randY<2){
     computerShip2[3]=randY+1;
     computerShip2[5]=randY+2;
    }else{
     computerShip2[3]=randY+1;
     computerShip2[5]=randY+2;
    }
   }else if(direction==1){
    computerShip2[3]=randY;
    computerShip2[5]=randY;
    if(randX>3){
     computerShip2[2]=randX-1;
     computerShip2[4]=randX-2;
    }else if(randX<2){
     computerShip2[2]=randX+1;
     computerShip2[4]=randX+2;
    }else{
     computerShip2[2]=randX+1;
     computerShip2[4]=randX+2;
    }
   }
   do{
   randX=(int)(Math.random()*7);
   randY=(int)(Math.random()*7);
   }while((randX==computerShip1[0] && randY==computerShip1[1])||(randX==computerShip1[2]&&randY==computerShip1[3])||(randX==computerShip1[4]&&randY==computerShip1[5])||(randX==computerShip2[0] && randY==computerShip2[1])||(randX==computerShip2[2]&&randY==computerShip2[3])||(randX==computerShip2[4]&&randY==computerShip2[5]));
   direction=(int)(Math.random()*2);

   computerShip3[0]=randX;
   computerShip3[1]=randY;
   if(direction==0){
    computerShip3[2]=randX;
    computerShip3[4]=randX;
    if(randY>3){
     computerShip3[3]=randY-1;
     computerShip3[5]=randY-2;
    }else if(randY<2){
     computerShip3[3]=randY+1;
     computerShip3[5]=randY+2;
    }else{
     computerShip3[3]=randY+1;
     computerShip3[5]=randY+2;
    }
   }else if(direction==1){
    computerShip3[3]=randY;
    computerShip3[5]=randY;
    if(randX>3){
     computerShip3[2]=randX-1;
     computerShip3[4]=randX-2;
    }else if(randX<2){
     computerShip3[2]=randX+1;
     computerShip3[4]=randX+2;
    }else{
     computerShip3[2]=randX+1;
     computerShip3[4]=randX+2;
    }
   }
  }

  public static boolean hasWon(){
    if(guessedHits[17]!=7)
      return true;
    else
      return false;
  }
}
4

2 に答える 2

1

あなたのgetGuess()関数は、あなたが求めているものですよね?

1)同じ場所を2回推測することは決してありません。推測しようとしている座標がまだ推測されていないかどうかを判断するブール値を作成します。

2)船の座標を維持する方法は非常に厄介です。0,2,4はX座標で、1,3,5はY座標ですか。Ship座標を処理し、isHitのようにチェックするクラスを作成することをお勧めします。

public class Ship {
    int[] xCoords = new int[3];
    int[] yCoords = new int[3];

    public boolean isHit(int x, int y) {
      return (Arrays.asList(xCoords).contains(x) && Arrays.asList(yCoords).contains(y));
    }
}

次に、次のことができます。

if (Player.ship1.isHit(guess[0],guess[1])) {
  ....
}

その中心にあるのは、少し道のりです。問題に取り組み始めてから、特定の問題が発生した場合は、ここでより適切な応答が得られます。コードスニペットを提供するときは、できるだけ簡潔にするようにしてください。クラス全体を調べて1行か2行の問題を見つけるのに多くの時間を費やす人はあまりいないからです。

幸運を!

--- PS ---

私は約3〜4年前に、かなり高度なAIを使用して戦艦ゲームを作成しました。ここにリンクします:

https://github.com/GrahamBlanshard/AI-Battleship/blob/master/prograham/battleship/player/AIPlayer.java

最初に、私は...ラメコードをお詫びします(私ははるかに若いプログラマーでした、私は誓います!)。それを表示して、問題のないヒントを取得したい場合。簡単な説明:

その中心には、ヒットを保存する何らかの形式のデータ型を作成する必要があります。「ヒット」がスコアリングされたら、それをデータ型にプッシュします。私はを使用しましたStack。ヒットに成功したショットは、船が沈むまでスタックに保存されます。その時点で、沈んだばかりの船に属していたスタックからショットを削除します。スタックにまだショットがある場合は、そのプロセス中に2隻目の船に命中したことを認識し、そのエリアで推測を続けます。

これを達成するために、それは段階を経ます:

1)ヒットするまでランダムに撃ちます。

2)そのショットの周りを撃ちます(ランダム(4)呼び出しを使用してN / S / E / W方向を取得します)-2番目のショットを獲得するまでこれを続けます

3)2つのポイントで「線」を作成し、船が沈むまで、またはそれに沿って発射します。

4)ラインを逆にして、反対方向に撃ちます。

それはあなたに仕事をする良いスタートを与えますか?

于 2013-01-17T20:57:19.590 に答える
0

それは見なければならないたくさんのコードです。したがって、今のところ、頭に浮かぶいくつかの一般的な提案をします。

コンピューター AI が「ヒット」した場合、「グローバル」フラグ (クラス変数である可能性が高い) を設定し、ヒットが発生した場所を「記憶」します。次のターンでは、別のヒットが見つかるまで、あらかじめ決められた順序 (北、南、東、西など) で隣接するマスを推測します。次に、別のフラグを設定し、次のターンで 2 番目のヒットと同じ方向に推測します。初期フラグは、3 つのヒットがすべて見つかった場合にのみリセットする必要があります。これにより、その後のミスによってコンピューター AI が再びランダムに推測を開始するという問題が修正されるはずです。

于 2013-01-17T20:39:49.243 に答える