使用minimax算法的Nim游戏

时间:2015-05-19 11:32:17

标签: c algorithm artificial-intelligence minimax

我写了一个Nim游戏。游戏开始,计算机(MAX)始终是第一步。每个玩家必须使用1或K(已定义)立方体。获胜者是获得最后一个立方体的玩家。这是我的代码:

#define M 13
#define K 4

char player[3] = "MAX";

struct Node{
    int cubesRemaining;
    struct Node *left;
    struct Node *right;
}; 

int minimum(int a, int b){
    if (a < b){
        return a;
    }
    else{
        return b;
    }
}

int maximum(int a, int b){
    if (a > b){
        return a;
    }
    else{
        return b;
    }
}

char switchPlayer(){
    if (strcmp(player, "MAX") == 0){
        strcpy(player, "MIN");
    }
    else{
        strcpy(player, "MAX");
    }
}

struct Node *buildGameTree(int ncubes){
    struct Node *cube = calloc(1, sizeof(struct Node));
    cube->cubesRemaining = ncubes;

    if (cube->cubesRemaining >= 1){
        cube->left = buildGameTree(ncubes - 1);
        switchPlayer();
    }
    if (cube->cubesRemaining >= M){
        cube->right = buildGameTree(ncubes - K);
        switchPlayer();
    }

    return (cube);
}

int computeMinimax(struct Node *n){
    int value;

    if (n->cubesRemaining == 0){
        if (strcmp(player, "MIN") == 0){
            return 1;
        }
        else{
            return -1;
        }
    }
    else{
        if (strcmp(player, "MIN") == 0){
            value = minimum(-1, computeMinimax(n->left));
            if (n->right != NULL){
                value = minimum(value, computeMinimax(n->right));
            }
        }
        else{
            value = maximum(1, computeMinimax(n->left));
            if (n->right != NULL){
                value = maximum(value, computeMinimax(n->right));
            }
        }
    }

    return value;

} 

main(){
    struct Node *root = buildGameTree(M);

    printf("WELCOME TO THE GAME\n");

    while (true){
        int takenCubes = 0;
        int v1,v2;

        v1 = computeMinimax(root->left);
        if (root->right != NULL){
            v2 = computeMinimax(root->right);
        }
        else{
            v2 = 2;
        }

        if (v1 < v2){
            takenCubes = 1;
        }
        else{
            takenCubes = K;
        }


        if (takenCubes == 1){
            root = root->left;
        }
        if (takenCubes == K){
            root = root->right;
        }

        printf("MAX player(PC) takes %d cubes, remaining %d cubes\n", takenCubes, root->cubesRemaining);

        if (root->cubesRemaining == 0){
            printf("MAX player(PC) wins the game!");
            break;
        }


        do{
            printf("How many cubes do you want? ");

            takenCubes = scanf("%d", &takenCubes);

            if (takenCubes >= 1 && takenCubes <= K && root->cubesRemaining - takenCubes >= 0){
                break;
            }

            printf("That's an illegal move. Choose 1 or %d matches.", K);

        } while (true);

        if (takenCubes == 1){
            root = root->left;
        }
        if (takenCubes == K){
            root = root->right;
        }

        printf("MIN player(human) takes %d cubes, leaving %d\n", takenCubes, root->cubesRemaining);

        if (root->cubesRemaining == 0){
            printf("MIN player(human) wins the game!");
            break;
        }
    }
}

我认为我的功能正常,但我认为我的主要功能有问题。程序总是启动,计算机(MAX播放器)占用4个立方体(我认为这是最好的动作)。但是从这一步开始,当我输入1或4个立方体时,人类和计算机总是需要1个立方体。我不明白我错在哪里。

0 个答案:

没有答案