Problems using vectors for a negamax algorithm c++ -


ok, first time asking own question on stack overflow, hope in right place, here goes:

i trying write program can total solve of game abalone - @ least in theory, if there isn't computational power it. using vectors hold board positions, , use max_size indicate length of longest diagonal on board. code appears work correctly board sides length 2 (meaning max_size of 3), returning -2 player 1 win, 0 draw, , 2 player 2 win, throws error when try increase max_size.

i think problem occurring in legality_check() function, can't figure out where. appreciated! include entirety of code can compile , run (hope that's ok), tell think problem is.

#include <vector> #include <iostream> #include <future> #include <map> #include <string> const int max_depth = 100; const int max_size = 3; const int winning_score = 2; std::vector<std::vector<int>> starting_vector(max_size, std::vector<int>(max_size)); std::map<std::vector<std::vector<int>>, std::vector<int>> positions_checked;  //checks legality of specified move , performs move if legal std::vector<std::vector<int>> legality_check(std::vector<std::vector<int>> initial_pos, int posr, int posc, int direction) {     std::vector<std::vector<int>> new_pos(initial_pos);     int start_posr = posr;     int start_posc = posc;     //weight keeps track of weight of 2 players separately , adds them @ end     //the result of addition (mod 10) gives function result should return     int weight[2] = {0, 0};     //keeps track of when color of marbles changes opponents     bool player_changed = false;     //the color of marble in starting position     int color;     //how program have row , column increment each iteration.     int row_move;     int column_move;     int score = 0;     int buffer = 0;     if (posc >= max_size)     {         buffer = posc - max_size + 1;     }     else     {         buffer = 0;     }     bool out_of_bounds = false; //not ((posr>buffer , posc>=0) , (posr<(signed)initial_pos.size() , posc<(signed)initial_pos[posr].size()));       //calculates row_move , column_move. follow below pattern:     //direction 0: [posr][posc+1] each time     //direction 1: [posr-1][posc] each time     //direction 2: [posr-1][posc-1] each time     //direction 3: [posr][posc-1] each time     //direction 4: [posr+1][posc] each time     //direction 5: [posr+1][posc+1] each time     switch (direction)     {     case 0:     {         row_move = 0;         column_move = 1;         break;     }     case 1:     {         row_move = -1;         column_move = 0;         break;     }     case 2:     {         row_move = -1;         column_move = -1;         break;     }     case 3:     {         row_move = 0;         column_move = -1;         break;     }     case 4:     {         row_move = 1;         column_move = 0;         break;     }     case 5:     {         row_move = 1;         column_move = 1;         break;     }     //if not 1 of above directions, bad function call , illegal move     default: return initial_pos;     }     //stores color of starting position marble     color = initial_pos[posr][posc];     if (color == 0)     {         return initial_pos;     }     //while not out of bounds of board or not on empty square     while (not out_of_bounds , initial_pos[posr][posc] != 0)     {         //if current position's marble not same color, marbles of other player         if (initial_pos[posr][posc] != color)         {             player_changed = true;         }         //if 2 marble colors have been checked, , see original color again, illegal move         if (player_changed)         {             if (initial_pos[posr][posc] == color)             {                 return initial_pos;             }             //otherwise, add marble's weight player total             weight[1] = (weight[1] + initial_pos[posr][posc]) % (max_size + 1);         }         else         {             //add marble's weight player total             weight[0] = (weight[0] + initial_pos[posr][posc]) % (max_size + 1);         }         posr += row_move;         posc += column_move;         if (posc >= max_size)         {             buffer = posc - max_size + 1;         }         else         {             buffer = 0;         }         out_of_bounds = not ((posr > buffer , posc >= 0) , (posr < (signed)initial_pos.size() , posc < (signed)initial_pos[posr].size()));     }     if (out_of_bounds)     {         score = 1;         posr -= row_move;         posc -= column_move;     }     weight[0] = weight[0] / color;     //the formula (color*max_size)%(max_size+1) switches value of color opposing players values due how     //chose numbers represent each color (1 1 player, max_size other player)     weight[1] = weight[1] / ((color * max_size) % (max_size + 1));     int final_weight = weight[0] - weight[1];     if (weight[0] <= 3 , final_weight > 0)     {          while (posr != start_posr , posc != start_posc)         {             new_pos[posr][posc] = new_pos[posr - row_move][posc - column_move];             posr -= row_move;             posc -= column_move;         }         new_pos[start_posr][start_posc] = 0;          if (positions_checked.count(new_pos) == 0)         {             positions_checked[new_pos] = std::vector<int>(3, 0);          }         if (color == 1)         {             //positions_checked[new_pos][0]+=score+positions_checked[initial_pos][0]; ???              positions_checked[new_pos][0] += score;           }         else         {             //positions_checked[new_pos][1]+=score+positions_checked[initial_pos][1]; ???             positions_checked[new_pos][1] += score;          }          return new_pos;      }     else     {         return initial_pos;     } } int negamax(std::vector<std::vector<int>> initial_pos, int depth, int color, bool prev_move) {     int best_value=-10000;     int value;     int score=0;     int buffer=0;     bool loop_entered=false;       if(color==1)     {         score=positions_checked[initial_pos][1];      }     else     {         score=positions_checked[initial_pos][0];     }      //implement position repetition check later     if(depth==0 or score>=winning_score)     {         return -score;     }     else     {          for(int column=0; column < (signed)initial_pos.size(); ++column)         {             if(column>=max_size)             {                 buffer=column-max_size+1;             }             else             {                 buffer=0;             }             for(int row = buffer; row < (signed)initial_pos[column].size(); ++row)             {                 if(initial_pos[column][row]==color)                 {                     bool found_legal_move=false;                      for(int direction=0; direction!=6; direction++)                     {                         std::vector<std::vector<int>> new_pos = legality_check(initial_pos, column, row, direction);                         if(max_size==3)                         {                             new_pos[0][max_size+2]=(color*max_size)%(max_size+1);                         }                         else                         {                             new_pos[0][max_size]=(color*max_size)%(max_size+1);                         }                         if(new_pos != initial_pos && positions_checked[new_pos][2]==0)                         {                             found_legal_move=true;                             positions_checked[new_pos][2]=1;                              value = negamax(new_pos, depth-1, (color*max_size)%(max_size+1),true);                              //color 1: score 2. return 2. color 2 receives 2. becomes -2.                              //color1: score -1. return -1. color 2 receives -1. becomes 1. returns 1.                             //color1 receives 1. becomes -1.;                             //color1 receives -1. becomes 1.                             best_value = std::max(best_value, value);                            }                     }                     if((not found_legal_move) , prev_move)                     {                             value = negamax(initial_pos, depth-1, (color*max_size)%(max_size+1), false);                             best_value = std::max(best_value, value);                     }                     else if((not found_legal_move) , (not prev_move))                     {                         return 0; //stalemate, neither player has legal move, draw                     }                     loop_entered=true;                 }             }         }         if(loop_entered==false)         {             //if color has no marbles, opponent has won             return winning_score;         }      }     return best_value*-1;  }  int main() {      starting_vector[(max_size-1)/2].resize(max_size);     starting_vector[0].resize(max_size);     starting_vector[0][0] = 1;     starting_vector[0][1] = 1;     starting_vector[1][0] = 1;     starting_vector[1][1] = 1;     starting_vector[1][2] = 0;     starting_vector[2][0] = max_size;     starting_vector[2][1] = max_size;     starting_vector[0][max_size+2]=1;     positions_checked[starting_vector] = std::vector<int>(3,0);     std::cout << starting_vector.size() << " " << starting_vector[0].size() << std::endl;     std::cout<<starting_vector[0][0] << " " << starting_vector[0][1] << " " << starting_vector[1][0]                                      << " " << starting_vector[1][1] << " " << starting_vector[1][2]                                      << " " << starting_vector[2][0] << " " << starting_vector[2][1]                                      << std::endl;      std::vector<std::vector<int>> new_vector(legality_check(starting_vector, 0, 0, 1));     std::cout<<new_vector[0][0] << " " << new_vector[0][1] << " " << new_vector[1][0]                                      << " " << new_vector[1][1] << " " << new_vector[1][2]                                      << " " << new_vector[2][0] << " " << new_vector[2][1]                                      << std::endl;      std::cout<<starting_vector[0][0] << " " << starting_vector[0][1] << " " << starting_vector[1][0]                                      << " " << starting_vector[1][1] << " " << starting_vector[1][2]                                      << " " << starting_vector[2][0] << " " << starting_vector[2][1]                                      << std::endl;     std::cout<<new_vector[0][2] << std::endl;     std::cout<<negamax(starting_vector, max_depth, 1,true)<< " returned successfully" << std::endl;     return 0; } 

ok, that's lot of code, here's what's happening. run code , gives me "* error in './abalone.exe':free(): invalid next size (fast): 0x0000000001c8f0b0 *" aborted (core dumped). error, , might wrong on this, seems occurring after last cout returns - line before return in int main(), doesn't make sense, since program outputs 6 lines, , have 6 couts. confusing me, since code after last cout return.

also, wasn't segmentation fault, had gotten code mixed other code working on, sorry that.

i did backtrace gdb , got after program threw exception:

*** error in '/abalone.exe': free(): invalid next size (fast): 0x000000000060b0b0 ***  program received signal sigabrt, aborted. 0x00007ffff7313cc9 in __gi_raise (sig=sig@entry=6)     @ ../nptl/sysdeps/unix/sysv/linux/raise.c:56 56      ../nptl/sysdeps/unix/sysv/linux/raise.c: no such file or directory. (gdb) bt #0  0x00007ffff7313cc9 in __gi_raise (sig=sig@entry=6)     @ ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1  0x00007ffff73170d8 in __gi_abort () @ abort.c:89 #2  0x00007ffff7350394 in __libc_message (do_abort=do_abort@entry=1,     fmt=fmt@entry=0x7ffff745eb28 "*** error in `%s': %s: 0x%s ***\n")     @ ../sysdeps/posix/libc_fatal.c:175 #3  0x00007ffff735c66e in malloc_printerr (ptr=<optimized out>,     str=0x7ffff745ecc8 "free(): invalid next size (fast)", action=1)     @ malloc.c:4996 #4  _int_free (av=<optimized out>, p=<optimized out>, have_lock=0)     @ malloc.c:3840 #5  0x000000000040457c in __gnu_cxx::new_allocator<int>::deallocate(int*, unsign ed long) () #6  0x0000000000403694 in std::_vector_base<int, std::allocator<int> >::_m_deall ocate(int*, unsigned long) () #7  0x0000000000402b25 in std::_vector_base<int, std::allocator<int> >::~_vector _base() () #8  0x00000000004023f9 in std::vector<int, std::allocator<int> >::~vector() () #9  0x0000000000405191 in void std::_destroy<std::vector<int, std::allocator<int > > >(std::vector<int, std::allocator<int> >*) () #10 0x00000000004047cf in void std::_destroy_aux<false>::__destroy<std::vector<i nt, std::allocator<int> >*>(std::vector<int, std::allocator<int> >*, std::vector <int, std::allocator<int> >*) () #11 0x00000000004039a0 in void std::_destroy<std::vector<int, std::allocator<int ---type <return> continue, or q <return> quit--- 

is there more information need give guys me?

ok, using method lux32 , vsoftco recommended me let me figure out error occurring , how fix it. line in int main() starting_vector[0][max_size+2]=1; trying set value out of bounds of vector, result in undefined behavior. needed used starting_vector[0].push_back(1). increases size of starting_vector 1 , sets location 1, needed do. thank everybody!


Comments

Popular posts from this blog

cakephp - simple blog with croogo -

How to group boxplot outliers in gnuplot -

bash - Performing variable substitution in a string -