最小 - 最大算法

时间:2016-02-27 12:47:54

标签: c memory-leaks minimax

我对编程完全陌生,我一个月前刚刚完全随机地尝试编写我自己的国际象棋引擎(我的目标是创造最能让自己最好的东西。迷人。)所以请尽量用你的答案尽可能清楚,并在我缺乏解释时请求澄清。

目前我的引擎可以在我的1.8Ghz处理器上分析大约每秒0.5到80万个位置,任何想法都会受到欢迎,但无论如何我觉得让我的引擎更快的唯一方法就是尝试按固定顺序移动,以便从搜索中排除不良移动。 为了做到这一点,我将代码从传递int变量转换为传递int指针。我的想法只是坚持得分产生它的举动。代码仍然有效,但规模不断扩大。我用Google搜索并尝试了一些内存泄漏工具,但它们只告诉我泄漏的内存已分配到哪里,我已经知道了,但不知道它的地址丢失了。

我已经想过,如果我只是发布我的代码,那么有经验的人可能会立即发现泄漏。 现在,我已经上网寻求帮助,我发现我的代码在逻辑上等同于一个已经存在数十年的算法,该算法以alpha beta修剪的minimax名称存在。凉。

int evaluate(int *board, int capture) { ... return board evaluation; }

int *Black(int *board, int depth, int *max, int *min) {
    if (depth == 0) {
        temp = malloc(20 * sizeof(int)); //eventually i will store
    }                 
    minlocal = malloc(20 * sizeof(int)); //moves next to the score
    *minlocal = *min;  //this is what i came up with so that min/max        
                       //of a higher function call doesn't get changed
    for (all moves) {
        if (depth > 0) {
            temp = whitemove(board, depth - 1, max, minlocal);
        } else {
            *temp = evaluate(board, capture);
        }
        if (*temp <= *max) {
            ;free(minlocal);
            return temp;
        }
        if (*temp < *minlocal) {
            *minlocal = *temp;
        }
        if (depth > 0) {
            free(temp);
        }
    }
    if (depth = 0) {    //<====== silly bug!
        free(temp);
    }
    return minlocal;
}

int *whitemove(int *board, int depth, int *max, int *min) {
    temp = malloc(20 * sizeof(int));
    maxlocal = malloc(20 * sizeof(int));
    *temp = -30000;
    *maxlocal = *max;
    for (all moves) {
        v = blackmove(board, depth - 1, maxlocal, min);
        if (*v > *temp) {
            free(temp);
            temp = v;
        } else {
            free(v);
        }
        if (*temp > *maxlocal) {
            *maxlocal = *temp;
        }
        if (*temp >= *min) {
            free(maxlocal);
            return temp;
        }
    }
    free(maxlocal);
    return temp;
}

阅读代码你可能已经注意到我的东西只能打白,深度只能是偶数,这对我来说并不重要。

据我所知,这种方法可能绝对是愚蠢的,但它似乎没有比以前慢,它应该能够存储游戏线而不是简单的第一步。任何关于替代品的意见也是受欢迎的。

2 个答案:

答案 0 :(得分:1)

你似乎在很短的时间内就掌握了很好的编程技巧。

然而,您仍然需要改进您的风格:演示文稿非常重要,因为它有助于避免许多愚蠢的错误,并使您的代码对其他程序员和您自己更具可读性。

还要使用编译器可以使用适当的标志生成的所有警告,例如gcc -Wall -Wextra

Black函数末尾有一个愚蠢的错误:

if (depth = 0)

显然应该阅读

 if (depth == 0)

这是你永远不会释放记忆的地方。

可能有其他地方丢失了已分配块的跟踪,以及不需要分配的地方,如果您不需要将其返回给调用者,则使用本地数组要快得多。将指向本地数组的指针作为目标数组传递也可以减少内存分配量。

答案 1 :(得分:1)

通常,当您在C中编写代码时,无论何时分配内存,都需要记住,在比较中使用double equals运算符需要正确free。在我们的例子中,你有一个名为temp的变量,它将使用已分配的内存,并在whitemoveBlack的每次初始化时为你分配新的内存,而不是free以前分配的内存,仍然分配,但你不再参考它。

答案如上,下面我会给你一些建议:

很高兴你发明了alpha-beta修剪而没有了解它,但你需要优雅地实现它。例如,您有一个whitemove和一个Black函数。为什么将Black命名为“黑色”而不是一致并将其命名为“blackmove”?此外,在编写函数时,需要尽可能地解决问题。白色的举动与黑色有什么不同?

  • 他们试图最大化对不同方向的评估
  • 他们能够以不同的方式移动

现在,如果考虑到这一点,您可以将这两个函数编写为单个函数。您不需要返回大内存块,因为这不是我们想要从国际象棋引擎中获知的内容。您需要返回评估和移动。您可以使用单个数组存储最佳变体,使用另一个数组存储当前变体。每当你发现一个更好的变化然后被认为是最好的,然后替换它。但避免内存泄漏:)