Java中的两个角硬币游戏

时间:2019-01-09 19:40:53

标签: java backtracking recursive-backtracking

2个角硬币游戏接收一个数组。游戏的目标是最大程度地累积点数(数组中元素的值)。您只能从数组的两个角取点。

游戏有两个条件:

1)第一个玩家(同伴)永远不会输(他会赢或平局),也不一定会选择最大优势。

2)第二个玩家(塔玛拉)将始终在最高角处得分。

我的输出:

amir took 16
tamara took 23
amira took 30
tamara took 15
amir took 19
tamara took 21
amir took 14
tamara took 13
Final Score:
amir total 79
tamara total 72

预期输出:

Amir took 16
Tamara took 23
Amir took 30
Tamara took 15
Amir took 19
Tamara took 21
Amir took 13
Tamara took 14
Final Score:
Amir total 78
Tamara total 73

问题:

-amir将选择16,因此tamara必须选择23,因此在下一回合中,他将选择30(因为tamara始终选择最大的角)。

-amir会在最后一轮选择13,而不是14,因为他已经赢了,所以他不在乎积分/硬币价值。

阿米尔之所以选择13而没有选择14的原因: 1.因为塔玛拉总是会选择最大的“结局” 2.因为他不会输掉这场比赛(65 vs 59),所以他会选择13而不是14-这是策略-只是不会输掉(可以打平并赢得比赛)他可以计划自己的所有举动,因为他可以从乞讨中看到阵列,并且他不想以更少的举动来放松这场比赛

-amir从第一回合就知道下一步是什么,因为他不会输掉这场比赛(他可以以赢家的身份完成比赛,也可以以相同的tamara得分完成比赛)

-Amir可以预先计算游戏的完整动作树,以及Tamar如何响应每个动作,然后他如何响应每个动作。这种解决方案的问题可能是一棵大树(阿米尔和塔玛拉可以玩的不同游戏数量为2 ^ K-如果K更大,那么功能强大的计算机将花费数万亿年)。 因此,在该游戏中需要诸如此类的有效解决方案。并要求阿米尔采取一些行动为自己制定策略

数组:

int[] array1 = {16,23,30,14,13,21,19,15};
TEST.coingame(array1);
System.out.println();

我的代码:

public static void coingame(int[] arr)
{ 
   int n = arr.length;  
   int i = 0, j = n-1,p1=0,p2=0,totalP2=0,totalP1=0; 

   while(j > i){

      if(arr[j]+arr[j-1]>arr[i]+arr[i+1]){
      p1 = arr[j];--j;
         if(arr[j]>arr[i]){
            p2=arr[j];--j;
         }else{  
            p2=arr[i];++i;
         } 
      }else{ 
         p1 = arr[i];++i;
         if(arr[j]>arr[i]){
            p2=arr[j];--j;
         }else{  
            p2=arr[i];++i;
         } 
      }

      System.out.println ("amir took "+p1);totalP1+=p1;
      System.out.println ("tamara took "+p2);totalP2+=p2;
   }

   System.out.println ("Final Score:");
   System.out.println ("amir total "+totalP1);
   System.out.println ("tamara total "+totalP2);
} 

编辑:(Akshay Batra的答案)

public static int[] pickByAmir(int[] coins, int amirTook, int tamaraTook, int start, int end) {
    if(start>end) {
        int[] res = new int[2];
        res[0] = amirTook;
        res[1] = tamaraTook;
        return res;
    }
    int[] a = new int[2];
    a[0] = amirTook;
    a[1] = tamaraTook;
    if(coins.length==0)
        return a;
    amirTook = coins[start];
    coins = pickByTamara(coins, ++start , end);
    tamaraTook = coins[start];
    a = pickByAmir(coins, amirTook+a[0], tamaraTook+a[1], ++start, end);
    int[] b = new int[2];
    b[0] = amirTook;
    b[1] = tamaraTook;
    if(a[0]<a[1]){
        amirTook = coins[end];
        coins = pickByTamara(coins, start, --end);
        b = pickByAmir(coins, amirTook+b[0], tamaraTook+b[1], ++start, end);

        if(a[0]<b[0])
            return b;
    }
        System.out.println ("Amir took "+amirTook);
        System.out.println ("Tamara took "+tamaraTook);
    return a;
}
public static int[] pickByTamara(int[] coins, int start, int end){
    return coins[start] > coins[end] ? coins : swapArray(coins, start, end);
}

public static int[] swapArray(int[] coins, int start, int end) {
    int temp = coins[start];
    coins[start] = coins[end];
    coins[end] = temp;
    return coins;
}

public static void coingame(int[] arr) {
    int[] a = pickByAmir(arr, 0, 0, 0, arr.length-1);
    System.out.println ("Final Score: ");
    System.out.println ("Amir total: "+a[0]);
    System.out.println ("Tamara total: "+a[1]);
    }

1 个答案:

答案 0 :(得分:1)

此代码可与您的输入配合使用,并在不同的输入下进行尝试,看看是否中断(如果这样做),可以优化您的解决方案

通过调用方方法int[] a = pickByAmir(array1, 0, 0, 0, array1.length-1);

调用

a[0]将有amir的总数,而a[1]将具有tamara的总数。

int[] pickByAmir(int[] coins, int amirTook, int tamaraTook, int start, int end) {
    if(start>end) {
        int[] res = new int[2];
        res[0] = amirTook;
        res[1] = tamaraTook;
        return res;
    }
    int[] a = new int[2];
    a[0] = amirTook;
    a[1] = tamaraTook;
    if(coins.length==0)
        return a;
    amirTook = coins[start];
    coins = pickByTamara(coins, ++start , end);
    tamaraTook = coins[start];
    a = pickByAmir(coins, amirTook+a[0], tamaraTook+a[1], ++start, end);
    int[] b = new int[2];
    b[0] = amirTook;
    b[1] = tamaraTook;
    if(a[0]<a[1]){
        amirTook = coins[end];
        coins = pickByTamara(coins, start, --end);
        b = pickByAmir(coins, amirTook+b[0], tamaraTook+b[1], ++start, end);
        if(a[0]<b[0])
            return b;
    }
    return a;
}
int[] pickByTamara(int[] coins, int start, int end){
    return coins[start] > coins[end] ? coins : swapArray(coins, start, end);
}

int[] swapArray(int[] coins, int start, int end) {
    int temp = coins[start];
    coins[start] = coins[end];
    coins[end] = temp;
    return coins;
}

好运