为项目制作Nim游戏

时间:2017-11-05 03:23:55

标签: java

玩智能电脑时遇到3个问题。

  • "Computer will take " + num中,num应该等于计算机占用的数量,但目前,它只是给了我拍摄后剩余的数量。
  • 当我击中4个弹珠时,计算机应该只拿一两个,但它决定它不能那样做,只是以某种方式赢得游戏。
  • 我不确定如何编写一个要求。我不知道如果它是一个小于2减1的幂的随机合法移动部分。
      

    在智能模式下,计算机会取出足够的弹珠来制作尺寸   桩的功率为2减1.这总是合法的举动,   除非当前桩的尺寸小于1的力量   二,所以在这种情况下,让它创造一个随机的合法行动。


Random rand = new Random();
int marbles = rand.nextInt(100) + 10;
int compMode = rand.nextInt(2) + 0; 
int takeaway = marbles;
boolean turn = rand.nextBoolean();

if (compMode == 1) {
  System.out.println("*** The computer is playing dumb.");
}
else {
  System.out.println("*** The computer is playing smart.");
}
System.out.println();
System.out.println("*** There are " + marbles + " marbles in the pile.");

while (marbles > 1) {
  if (turn == true){
    int ifBad = 0;
    while (ifBad == 0){
      System.out.print("How many do you want to take (1-" + marbles + ")");
      takeaway = scan.nextInt();
      int bad = marbles/2;
      if (takeaway > bad){
        System.out.println("Took too many marbles, try again");
      }
      else {
        ifBad++;
      }
    }
    marbles -= takeaway;
    System.out.println("*** There are " + marbles + " marbles in the pile.");
    turn = false;
  }
  if (turn == false){
    if (compMode == 1){
      marbles = getStupidMove(marbles, rand);
      System.out.println ("*** There are " + marbles + " marbles in the pile.");
    }
    else{
      marbles = getSmartMove(marbles); 
      System.out.println ("*** There are " + marbles + " marbles in the pile.");
    }
    turn = true;
  }
  if (marbles <= 1)
  {
    if (turn = false)
    {
      System.out.println ("Human Wins!");
    }  
    else
    {
      System.out.println ("Computer wins :(");
    }  
  }
}


public static int getSmartMove(int num){
  int power = 2;        
  while (power < num) 
  { 
    power *=2;
  }
  power /= 2;
  num = power-1;
  System.out.println("Computer will take " + num);

  return num;
}


public static int getStupidMove(int marbles, Random rand){
  int good = marbles/2;
  int take;
  if (marbles == 1){
    take = 1;
  }
  else {
    take = rand.nextInt(good) + 1;
    marbles -= take;
  }
  System.out.println("Computer will take " + take);
  return marbles; 
}

1 个答案:

答案 0 :(得分:0)

使用原始代码,可以通过从新的大理石中减去旧的大理石来确定取走的数字。因此,旧金额应存储在某处,或者新金额应存储为新变量。

int numNew = power-1;
System.out.println("Computer will take " + (num - numNew));
return numNew;

但是,检索2的最高功率的代码可以简化为一个函数Integer.highestOneBit。它找到只有一个位集的最接近的整数(小于或等于给定值)。如果它只设置了一个位,则表示它是2的幂。

int numNew = Integer.highestOneBit(num) - 1;

要确定整数是否为2的幂,可以使用Integer.bitCount计算设置的位数。同样,如果只设置了一个位,则它是2的幂。

由于检查需要小于2的幂,因此应计算比当前量高1的位数。如果num + 1是2的幂,则表示num比2的幂小1。

if (Integer.bitCount(num + 1) == 1) {
    // Do some valid move.
    return getStupidMove(num, rand);
}

我不熟悉游戏规则,但似乎有效的举动是夺走不到目前弹珠数量一半的任何东西。这似乎已在getStupidMove中实现,因此可以返回。

当它击中剩下的4个弹珠时,它会成功地将弹珠降低到3,因为4是2的最接近的力量,3是比它少一个。但是,与说明相矛盾,你说它应该采取一两个。如果您想要这种行为,可以添加一个检查,当时大理石是4并定义不同的行为。