算法以确保在硬币排列问题中获胜(或达成平局)。

huangapple 未分类评论47阅读模式
英文:

Algorithm for guaranteeing win (or draw) in row of coins problem

问题

以下是您提供的代码的翻译部分:

// 该方法选择两个硬币中较大的那一个,前提是较大硬币旁边的硬币能够在最坏情况下保证获胜 - 所有剩余的最大数字都被 Tamar 选走。
public static void win(int[] arr){
    int beginning = 0, end=arr.length-1, sumAmir = 0, sumTamar = 0;
    int[] arrClone = arr.clone();
    java.util.Arrays.sort (arrClone, beginning, end+1);
    while (beginning < end){
        if ((arr[end] >= arr[beginning] && !loses(arr, arrClone, end-1, sumAmir, sumTamar, beginning, end))
                || (arr[end] < arr[beginning] && loses(arr, arrClone, beginning+1, sumAmir, sumTamar, beginning, end))) {
            System.out.println("Amir took " + arr[end]);
            sumAmir += arr[end];
            end--;
        }
        else{
            System.out.println("Amir took " + arr[beginning]);
            sumAmir += arr[beginning];
            beginning++;
        }
        if (arr[beginning] > arr[end]){
            System.out.println("Tamar took " + arr[beginning]);
            sumTamar += arr[beginning];
            beginning++;
        }
        else{
            System.out.println("Tamar took " + arr[end]);
            sumTamar += arr[end];
            end--;
        }
    }
    System.out.println("Amir total " + sumAmir + "\nTamar total " + sumTamar);
}

private static boolean loses(int[] arr, int[] arrClone, int place, int sumAmir, int sumTamar, int beginning, int end) {
    int currPlace = arr[place];
    if (end - beginning == 1) {
        return false;
    }
    if (place == beginning + 1) {
        sumAmir += arr[beginning];
        beginning += 2;
    } else {
        sumAmir += arr[end];
        end -= 2;
    }

    // 对数组的最低和最高一半求和(排除已检查的二元组)
    int lowestValsSum = 0;
    int k = 0;
    int highestValsSum = 0;
    for (int i = beginning; i < (beginning+end)/2 + 1; i++) {
        k++;
        lowestValsSum += arrClone[i];
        highestValsSum += arrClone[end-k];
    }
    return sumAmir + highestValsSum < sumTamar + currPlace + lowestValsSum;
}

请注意,这只是您提供的代码的中文翻译,不包含额外的解释或讨论。如果您有任何问题或需要进一步的帮助,请随时提问。

英文:

In a row of n coins (>=0, n=even) each player (Amir and Tamar) must pick a coin from one of the EDGES of the row. Player with largest amount wins. Need to guarantee at least a draw for Amir. Amir goes first. My algorithm for this was Make Amir take the largest coin unless the IMMEDIATELY FOLLOWING coin guarantees a loss (i.e. if Amir takes all the highest possible remaining coins - he will STILL lose). Do you think this is right?
If so I would appreciate if you took a look at my code (Java) - getting random wins Amir/Tamar.

//This method takes the largest of the two coins providing the coin adjacent to the larger coin leaves a chance of winning assuming
//worse case scenario - all highest (remaining numbers) are picked by - Tamar.
public static void win(int[] arr){
    int beginning = 0, end=arr.length-1, sumAmir = 0, sumTamar = 0;
    int[] arrClone = arr.clone();
    java.util.Arrays.sort (arrClone, beginning, end+1);
    while (beginning&lt;end){
        if ((arr[end]&gt;=arr[beginning] &amp;&amp; !loses(arr,arrClone, end-1,sumAmir,sumTamar,beginning,end))
                || (arr[end]&lt;arr[beginning] &amp;&amp; loses(arr, arrClone,beginning+1,sumAmir,sumTamar,beginning,end))) {
            System.out.println (&quot;Amir took &quot; + arr[end]);
            sumAmir+=arr[end];
            end--;
        }
        else{
            System.out.println (&quot;Amir took &quot;+ arr[beginning]);
            sumAmir+=arr[beginning];
            beginning++;
        }
        if (arr[beginning]&gt; arr[end]){
            System.out.println (&quot;Tamar took &quot; + arr[beginning]) ;
            sumTamar+=arr[beginning];
            beginning++;
        }
        else{
            System.out.println (&quot;Tamar took &quot; + arr[end]) ;
            sumTamar+=arr[end];
            end--;
        }
    }
    System.out.println (&quot;Amir total &quot; + sumAmir + &quot;\nTamar total &quot; + sumTamar);
}
private static boolean loses(int[] arr,int[] arrClone, int place, int sumAmir, int sumTamar, int beginning, int end) {
    int currPlace =arr[place];
    if (end - beginning == 1) {
        return false;
    }
    if (place == beginning + 1) {
        sumAmir += arr[beginning];
        beginning += 2;
    } else {
        sumAmir += arr[end];
        end -= 2;
    }

    //Sums lowest &amp; highest halves of (sorted) array. (excluding checked duo)
    int lowestValsSum = 0;
    int k=0;
    int highestValsSum = 0;
    for (int i = beginning; i &lt; (beginning+end)/2 + 1; i++) {
        k++;
        lowestValsSum+=arrClone[i];
        highestValsSum+=arrClone[end-k];
    }
    return sumAmir + highestValsSum &lt; sumTamar + currPlace + lowestValsSum;
}

TX

答案1

得分: 0

你可以尝试为你的游戏实现极小化极大算法,以确保你的玩家进行最优游戏(无论是获胜还是平局)。

英文:

You can try to implement the minimax algorithm for your game to guarantee optimal play for your player(either win or draw).

huangapple
  • 本文由 发表于 2020年4月3日 21:42:41
  • 转载请务必保留本文链接:https://java.coder-hub.com/61013271.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定