-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)您保持船舶坐标的方法非常尴尬,其中 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])) {
  ....
}

在它的核心,你有一些路要走。如果您开始解决问题,然后返回您可能遇到的特定问题,您将在这里得到更好的回应。在给出代码片段时尽量简洁,因为没有多少人会花很多时间通过整个课程来找到一两行给出的问题。

祝你好运!

---PS---

大约 3-4 年前,我用一些相当先进的 AI 编写了一款战舰游戏。我会在这里链接它:

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

首先,我为...蹩脚的代码道歉(我发誓我是一个年轻得多的程序员!)。如果您想查看它以获取提示,那很好。简要说明:

在它的核心,您需要创建某种形式的数据类型来存储他的命中。一旦“命中”得分,您将其推送到数据类型,我使用了Stack. 成功命中的炮弹将存储在堆栈中,直到船沉没。那时,它会从属于刚刚沉没的船的堆栈中删除镜头。如果堆栈上仍有射击,它知道在此过程中它已经击中了第二艘船并继续在该区域猜测。

为了实现这一点,它经历了几个阶段:

1)随机射击直到命中。

2)围绕那个镜头射击(使用随机(4)调用来获得N / S / E / W方向) - 继续这样做直到你获得第二个镜头

3)用两点创建一条“线”并沿着它开火,直到船沉没或......

4) 反转线,向另一个方向射击。

这会给您一个良好的合作开始吗?

于 2013-01-17T20:57:19.590 回答
0

有很多代码要看。所以现在我将给出一些我想到的一般性建议:

当计算机 AI 获得“命中”时,设置“全局”标志(更可能是类变量)并“记住”命中发生的位置。在接下来的回合中,以某种预定的顺序(比如北、南、东、西)猜测相邻的方格,直到找到另一个命中。然后设置另一个标志,并在下一轮猜测与第二次击中相同的方向。仅当找到所有三个命中时才应重置初始标志。这应该可以解决后续未命中导致计算机 AI 再次开始随机猜测的问题。

于 2013-01-17T20:39:49.243 回答