2017-04-27 67 views
-1

我正在创建一个简单的连接4游戏,我有我的minmax算法解决方案的问题。我想我有一个指针问题,并将表传递给minmax,并通过minmax传递给其他函数,特别是rmv和place,Dev ++在调试时需要指针,但函数被定义为获取变量。我认为minmax算法逻辑是可以的,所以问题是函数执行的问题(代码中有许多不明确的打印文件,因为debbuging只是删除它们)。Minmax算法和指针在C

  • 假设发生:计算机根据minmax逻辑进行移动。
  • 发生了什么:计算机始终位于0,而dev C++ pop对指针有一些警告。
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


#define R 7 
#define C 7 

int turn=0; 
char game_board[R][C]={}; 
int column_fill[C]={}; 

void print_table(); 
void set_table(); 
void set_column_fill(); 
void print_table_fill(); 

void human_plays(int player); 
void comp_plays(); 
int draw(int column_fill[C]); 
int win(char board[R][C]); 

int place(char (*board)[C] , int *column_fill , int col, int player); 
void rmv(char (*board)[C] , int *column_fill , int col); 

int minimax(char board[R][C],int column_fill, int depth, int player /*1:player or 2:com*/); 
int heuristic(char board[R][C]); 
int ai(char board[R][C],int column_fill[C], int depth); 



/* run this program using the console pauser or add your own getch, system("pause") or input loop */ 

int main(int argc, char *argv[]) { 
    int draw_val=0,win_val=0; 


    printf("Player: + Com: *\n\n"); 

    set_table(); 
    set_column_fill(); 
    //print_table_fill(); 
    print_table(); 
    turn++; 

    printf("\n ~Start~\n"); 

    while (draw_val!=1){ 

     if (turn%2==1){ 
      printf("Player's' turn\n"); 
      human_plays(1);  
      win_val = win(game_board); 
      if (win_val){ 
       printf("\n\nCongratulations, you Won!!!\n"); 
       print_table(); 
       break; 
      } 

     } 
     else{ 
      printf("\nCom turn\n"); 
      comp_plays(); 
      win_val = win(game_board); 
      if (win_val){ 
       printf("\n\nYou have lost!!! :("); 
       printf("\n"); 
       print_table(); 
       break; 
      } 
     } 

     printf("\n"); 
     print_table(); 


     turn++; 
     draw_val=draw(column_fill); 

    } 



    return 0; 
} 


void set_table(){ 
    int row,col; 


    for (row=0;row<R;row++){ 
     for (col=0;col<C;col++){ 
      game_board[row][col] = '-'; 
     } 

    } 
} 

void set_column_fill(){ 
    int col; 

    for (col=0;col<C;col++){ 
     column_fill[col] = R; 
    } 
} 


void print_table(){ 
    int row,col; 

    printf(" turn: %d\n",turn); 

    for (row=0;row<R;row++){ 
     for (col=0;col<C;col++){ 
      printf("%c ",game_board[row][col]); 
     } 
     printf("\n"); 

    } 
} 

void print_table_fill(){ 
    int col; 

     for (col=0;col<C;col++){ 
      printf(" %d",column_fill[col]); 
     } 
     printf("\n"); 

} 



void human_plays(int player){ 
    int user_input, row; 

    //Handle two players from the same function 
    char choice='+'; 
    if (player != 1) choice = '*'; 

    //Ask user for input 
    printf("Enter a column(1-%d):",C); 
    scanf("%d",&user_input); 

    //Check if column exists 
    while (user_input < 1 || user_input > 7){ 
     printf("Enter a corrent column number:"); 
     scanf("%d",&user_input); 
    } 
    //Chsck if column is filled 
    while (column_fill[user_input-1] == 0){ 
     printf("Column is filled, enter again:\n"); 
     scanf("%d",&user_input); 
    } 
    //Do some magic! 
    user_input--; 
    place(game_board , column_fill ,user_input,player); 

    //Print something... 
    printf("\nPlayer places at row %d",user_input+1); 
} 

void comp_plays(){ 

// char cpu_mind[R][C]; //It's all in the mind... 
// int cpu_column_fill[C]; 
    int answer; 

// int row,col; 
// for (row=0 ; row < R ; row++){ 
//  for(col=0 ; col < C ; col++){ 
//  cpu_mind[row][col]= game_board[row][col]; 
//  } 
// } 
// 
// for(col=0 ; col < C ; col++){ 
//  cpu_column_fill[col] =column_fill[col]; 
//  } 

    answer = ai(game_board ,column_fill,5); 
    place(game_board,column_fill,answer,2); 
    printf("Com places at :%d",answer); 

} 



int draw(int column_fill[C]){ 
    int col; 

    for (col=0 ; col<C ; col++){ 
     if (column_fill[col] !=0) return 0; 
     } 
    return 1; 
} 

int win(char board[R][C]){ 
    int row , col; 
    char mark; 

    //Check Horizontal 
    for (row=0 ; row < R ; row++){ 
     for(col=0 ; col < C-3 ; col++){ 
      //mark = board[row][col]; 
      if (board[row][col] == '-') continue; //pass if scan find "-" to avoid win result on empty cells 

      if (board[row][col+1] == board[row][col] && board[row][col+2]== board[row][col] && board[row][col+3] == board[row][col]){ 
       if (board[row][col] == '+') return 1; 
       else return 2; 
      } 
     } 
    } 

    //Check Verical 
    for (row=0 ; row < R-3 ; row++){ 
     for(col=0 ; col < C ; col++){ 
      mark = board[row][col]; 
      if (mark == '-') continue; 
      if (board[row+1][col] == mark && board[row+2][col]== mark && board[row+3][col] == mark){ 
       if (mark == '+') return 1; 
       else return 2; 
      } 
     } 
    } 


    //Check linear (/) 
    for (row=0 ; row < R - 3 ; row++){ 
     for (col=0 ; col < C - 3 ; col ++){ 
     mark = board[row][col]; 
     if (mark == '-') continue; 
     if (board[row+1][col+1] == mark && board[row+2][col+2]== mark && board[row+3][col+3] == mark){ 
       if (mark == '+') return 1; 
       else return 2; 
      } 
     } 
    } 


    //Check other linear (\) 
    for (row=0 ; row < R-3 ; row++){ 
     for (col=3 ; col < C ; col ++){ 
     mark = board[row][col]; 
     if (mark == '-') continue; 
     if (board[row+1][col-1] == mark && board[row+2][col-2]== mark && board[row+3][col-3] == mark){ 
       if (mark == '+') return 1; 
       else return 2; 
      } 
     } 
    } 

    return 0; 
} 


int place(char (*board)[C] , int *column_fill , int col, int player){ 

    int row = --column_fill[col]; 

    board[row][col] = (player==1) ? '+' : '*'; 

    return 0; 
} 

void rmv(char (*board)[C] , int *column_fill , int col){ 

    int row = column_fill[col]++; 
    board[row][col]= '-'; 

} 


int heuristic(char board[R][C]) { 
    int result = 0; 
    int row, col; 

    char mark; 

    //Check Horizontal 
    for (row=0 ; row < R ; row++){ 
     for(col=0 ; col < C-3 ; col++){ 
      mark = board[row][col]; 
      if (mark == '-') continue; //pass if scan find "-" to avoid win result on empty cells 

      if (board[row][col+1] == mark && board[row][col+2]== mark && board[row][col+3] == mark){ 
       if (mark == '+') result-- ; 
       else result++; 
      } 
     } 
    } 

    //Check Verical 
    for (row=0 ; row < R - 3 ; row++){ 
     for(col=0 ; col < C ; col++){ 
      mark = board[row][col]; 
      if (mark == '-') continue; 
      if (board[row+1][col] == mark && board[row+2][col]== mark && board[row+3][col] == mark){ 
       if (mark == '+') result--; 
       else result++; 
      } 
     } 
    } 
    return result; 
} 

int minimax(char board[R][C],int column_fill, int depth, int player /*1:player or 2:com*/){ 
    int win_val; 
    int col, best; 
    int n=-10000-1; 

    printf("board %c ",board[0][0]); 

    win_val =draw(column_fill); 
    if (win_val) return 0; //draw 

    //printf("col fill \n\n\n\n\%d" ,column_fill[1]); 

    win_val = win(board); 
    if (win_val){ 
     if (win_val == player) return 10000 ; 
     else return -10000; 
    } 

    if(depth==0) 
     return ((player==1) ? heuristic(board) : -heuristic(board)); 

    best = -10000; 


    for(col=0; col<C; col++){ //check every move 
     if(board[0][col]=='-') { //make sure column isn't empty 
      //put(board, row, turn); 
      place(board ,column_fill , col, player); 
      n = minimax(board,column_fill, depth-1, 3-player); 
      if(player==1) { 
       if(-n>best) best = -n; 
      } else { //player==2 
       if(-n>best) best = -n; 
      } 
      //rmv(s, i); 
      rmv(board ,column_fill , col); 
     } 
     printf("best: %d\n",best); 
    } 

    return best; 
} 

int ai(char board[R][C],int column_fill[C], int depth) { 
    int col, move; 
    int n; 
    int val =-10000-1; 
    move = -2;//debug 

    printf("n\n\%c\n\n",board[0][0]); 

    for(col=0; col<C; col++){ 
     printf("ai: %d",col); 
     if(board[0][col]=='-') { 
      //put(s, i, 2); 
      place(board,column_fill, col,2); 
      n = minimax(board,column_fill, depth, 2); 
      printf("\n n: %d",n); 
      if(-n>val) { 
       val = -n; 
       move = col; 
      } 
      rmv(board,column_fill, col); 
     } 
    } 
    printf("\n\n %d \n",move); 

    return move; 
} 
+1

请查看关于创建[最小完整可验证示例]的指导页面(http:// stackoverflow .com/help/mcve)你的代码示例甚至没有包含你说你有问题的功能。 – JeremyP

+0

对不起,编辑切断了我的代码。 –

+0

现在您的示例已完成,请考虑将其做成最小化。此外,如果您告诉我们实际发生了什么问题,会发生什么情况:发生了什么以及应该发生什么。 – JeremyP

回答

0

我发现的bug,我已经忘记了在column_fill添加[]在最小 - 最大功能分配

minmax(...,column_fill,...){...}

应该是:

minmax(...,column_fill[C],...){...}