2013-12-25 2 views
0

Я работаю над школьным проектом (мне разрешили сделать симуляцию на C++ для моего проекта Science Fair), и все идет хорошо (помимо другой ошибки с которыми я столкнулся) до сих пор. Чтобы полностью понять, что я делаю, я предлагаю вам быстро взглянуть на this page.Ошибка Seg от попытки доступа из диапазона диапазона, неизвестно почему

Хорошо. Ниже мой код. Когда вы пытаетесь запустить его, вы можете ясно видеть, что некоторые боты 'x и y cordinates находятся в негативах, что не должно происходить. Я трижды проверил все операции, и все выглядит хорошо для меня. Я использовал this, чтобы помочь мне понять расположение X и Y относительно массивов. Есть ли ясная проблема в моей ошибке? Я все еще привык к многомерным массивам, поэтому, пожалуйста, учтите это. Кроме того, я знаю, что большинство из них крайне неэффективно; его очистка будет сам по себе проектом. Спасибо и счастливые праздники!

* Мои проблемы исходят от функций moveBot, которые находятся в нижней части. Не похоже было, чтобы вы читали лишние части.

Обновленный код:

// NANORG SIMULATION 
// CREATED BY JACOB HARTMANN FOR THE SCIENCE FAIR (2013) 
// CODED IN C++ 

#include <iostream> 
#include <string> 
#include <stdlib.h> 
#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <cstdlib> 

#include "bot.h" 

using namespace std; 

signed int map [40][70]; //2D array x first, then y 
int mapBot [40][70]; //If bot is there, 1. If not, 0 This array keeps track if there is a bot in a location 
signed int currentTick = 0; //Signed just in case something goes wrong and goes into the -s 
int maxTick = 1000000; //Should always stay at 1mil 
signed int totalEnergy = 0; //For some reason, when I add this here, everything breaks. 

Bot bots[50]; 

void setupMap(); 
void tick(); 
void updateTickOutput(); 
void outputMapValue(int x, int y); 
void assignBotID(); 
void setupBot(); 
void moveBot(); 
void manualMoveBot(int botID); 
void mutateBot(int botID, int level, int sT); 
void ckLoc(int botIdent); 
void reassignLoc(int botID); 
void gatherEnergy(int botID); 

int main() { 
    cout << "  ----------------------" << endl; 
    cout << "  NANORG Simulation V1.3.1" << endl; 
    cout << "Created in C++ by Jacob Hartmann" << endl; 
    cout << "  ----------------------" << endl << endl; 
     srand (time(NULL)); 
    cout << "Setting up map.. (Step 1)" <<endl; 
    setupMap(); 
    cout << "Assigning botIDs.. (Step 2)" << endl; 
    assignBotID(); 
    cout << "Setting up bots.. (Step 3)" << endl; 
    setupBot(); 
    cout << "Starting ticks.. (Step 4)" << endl; 
    tick(); 
// outputMapValue(5,5); 
// mutateBot(5, 2); //Just to test 
/* cout << endl << "X before: " << bots[5].x_cord << " Y before: " << bots[5].y_cord << endl; 
    moveBot(5); 
     cout << "X after: " << bots[5].x_cord << " Y after: " << bots[5].y_cord << endl; 
    cout << "Energy before: " << bots[5].energy <<endl; 
    gatherEnergy(5); 
    cout << "Energy after: " << bots[5].energy << endl; */ //DEBUG 
    return 0; 
} 

void setupMap(){ 
// srand (time(NULL)); //Not a good idea to put it here 
    for(int i = 0; i < 40; i++){ 
     for(int j = 0; j < 70; j++){ // We add one extra (70) so it fills the entire array. Same for above 
      map[i][j] = rand() % 2 + 1; // 1==normal 2==toxic 
     } 
    } 
// outputMapValue(5,4); //Debugging purposes 
// outputMapValue(7,9); 
    cout << "Map setup - \033[0;32mSuccessful" << "\033[0m" << endl; 
} 

void outputMapValue(int x, int y){ 
    cout << "The chunk value at (" << x+1 << ", " << y+1 << ") is: "; 
    cout << map[x][y]; //Outputting the value of (x,y) 
    if(map[x][y]==1){ //If (x,y) is == 1, the chunk is fine to eat 
     cout << " | Chunk is not toxic." << endl; 
    } 
    if(map[x][y]==2){ 
     cout << " | Chunk is toxic." << endl; 
    } 
} 

void updateTickOutput() { 
     //cout << "Map Size (x,y): " << " " << mapsizeX << "," << mapsizeY << endl;  This function used to just refresh everything, including map size, which really isn't needed.   cout << "Current Tick: " << currentTick << " " << "Max Tick: " << maxTick << endl; //Just outputting currentTick and maxTick 
    cout << "Score: " << totalEnergy << endl; 
} 

void tick() { 
     while(true){ 
       if(currentTick <= maxTick){ 
         currentTick += 1; 
      moveBot(); 
/*   if(currentTick >= 900000){ //If currentTick is over 900,000: we will begin to output individual ticks. Anything less and we get a seg fault. 
       updateTickOutput(); //See above 
      }*/ 
//   cout << "tick!";  This was for debugging, before I made the updateTickOutput() function to make sure that the program actually ticked 
     } 
      else if(currentTick == maxTick){ 
         cout << endl << "Done!" << endl; //Report that we are finished with the simulation. 
//   assignBotID(); //Make sure every bot has the proper ID. Moved to main() 
         break; //Kill the loop 
       } 
//    updateTickOutput(); //No real need for this, anymore. 
     } 
} 


void setupBot(){ 
    srand(time(NULL)); 
    for(int botNumber=0;botNumber <= 50; botNumber++){ 
//   cout << "debug (botNumber): " << botNumber << endl; //Debug feature 
      bots[botNumber].x_cord = rand() % 39 + 1; 
//   cout << "debug (bot x cord): " << bots[botNumber].x_cord << endl; //Debug feature 
      int bufferX = bots[botNumber].x_cord; 
      bots[botNumber].y_cord = rand() % 69 + 1; 
//   cout << "debug (bot y cord): " << bots[botNumber].y_cord << endl; //Debug feature 
      int bufferY = bots[botNumber].y_cord; 
      if(mapBot[bufferX][bufferY] == 1){ 
       cout << endl <<"A bot already is here!" << endl; 
       reassignLoc(botNumber); 
      } 
      else{ 
       mapBot[bufferX][bufferY] = 1; //Take the bot's cords and make sure everyone knows that a bot is there. 
//    cout<< "debug (map location):"<<mapBot[bufferX][bufferY] << endl ; Just a nice debug feature 
      } 
     // if(botNumber==5){ 
     //  cout << "bot 5 assigned"; //I broke this entire function a while back and I used this to test if I was assigning bots correctly. 
     // } 
    } 

/* cout << endl << "X: " << bots[5].x_cord+1 << endl; //Just some debugging stuff below 
    cout << "Y: " << bots[5].y_cord+1 << endl; 
    // cout << "The value at " << mapBot[bots[5].x_cord]<<","<< mapBot[bots[5].y_cord]<<" is: " << mapBot[bots[5].x_cord][bots[5].y_cord]; //This is a very messed up debug feature, but it still works. 

     cout << endl << "X: " << bots[6].x_cord+1 << endl; 
     cout << "Y: " << bots[6].y_cord+1 << endl; 
    cout << mapBot[6][6]; 
*/ 
    cout << "Bot setup - \033[0;32mSuccessful" << "\033[0m" << endl; 
} 

void assignBotID(){ 
    for(int i = 0; i < 50; ++i){ 
     bots[i].id = i + 1; 
    } 

/* int botNumber = 0; 
    string botName = "Bot"; 
    string finalName; 

    string buffer; 

    while(botNumber <50){ 
     if(botNumber < 50){ 
      botNumber = botNumber + 1; 
      buffer = to_string(botNumber); 
      finalName = botName + buffer; 
      //finalName.id = botNumber; A very very broken line. 
      bots[botNumber].id = botNumber; 
//   cout << finalName << ":"<< bots[botNumber].id << endl; A super awesome debugging output to make sure the bot's id is correct 
     } 
     else if((botNumber = 51)){ //Redundancy :) 
      break; 
     } 
    }*/ 
} 

void mutateBot(int botID, int level, int sT){ 
    if((sT=2)){ 
     bots[botID].mutationLevel = bots[botID].mutationLevel + level; 
    } 
    else if((sT=1)){ 
     bots[botID].mutationLevel = bots[botID].mutationLevel - level; 
    } 
// cout << botID << ":" << bots[botID].mutationLevel << endl; //Just a quick debugging feature to make sure it worked 
} 

void ckLoc(int botIdent){ 
    int bufferX; 
    int bufferY; 
    bufferX = bots[botIdent].x_cord; //Just set the buffers. Uses a bit more memory, but that is okay. 
    bufferY = bots[botIdent].y_cord; 
// cout << bufferX << endl << bufferY; 
    if(mapBot[bufferX][bufferY] ==1){ 
     cout << "Bot lives here!"; 
     reassignLoc(botIdent); 
    } 
} 

void reassignLoc(int botID){ 
    bots[botID].x_cord = rand() % 39 + 1; 
    bots[botID].y_cord = rand() % 69 + 1; 
    ckLoc(botID); 
} 

void moveBot(){ 
    for(int botID=1;botID<=50;botID++){ 
     int direction = 0; 
    // int bufX = bots[botID].x_cord; 
    // int bufY = bots[botID].y_cord; 
     direction = rand() % 4 + 1; 
     if(direction == 1){ //NORTH 
      if(bots[botID].y_cord==0 || mapBot[bots[botID].x_cord][bots[botID].y_cord=-1] == 1){ 
       //cout << "error moving bot - N "; 
       manualMoveBot(botID); 
      } 
      else{ 
       //cout << "BufferY: " << bufferY; 
       bots[botID].y_cord -= 1; 
        gatherEnergy(botID); 
      } 
     } 
     else if(direction == 2){ //EAST 
      if(bots[botID].x_cord == 39 || mapBot[bots[botID].x_cord+=1][bots[botID].y_cord] == 1){ 
       //cout << "error moving bot - E"; 
       manualMoveBot(botID); 
      } 
      else{ 
       bots[botID].x_cord += 1; 
        gatherEnergy(botID); 
      } 
     } 
      else if(direction == 3){ //SOUTH 
        if(bots[botID].y_cord == 69 || mapBot[bots[botID].x_cord][bots[botID].y_cord+=1] == 1){ 
          //cout << "error moving bot - S "; 
          manualMoveBot(botID); 
        } 
        else{ 
          bots[botID].y_cord += 1; 
        gatherEnergy(botID); 
        } 
      } 
      else if(direction == 4){ //WEST 
        if(bots[botID].x_cord == 0 or mapBot[bots[botID].x_cord=-1][bots[botID].y_cord] == 1){ 
          //cout << "error moving bot - W"; 
          manualMoveBot(botID); 
        } 
        else{ 
          bots[botID].x_cord -= 1; 
        gatherEnergy(botID); 
        } 
      } 
// gatherEnergy(botID); //Moved this to indivdual (spelling) stuff above. Just in case :) 
// cout << endl << "Direction: " << direction << endl; //Debug 
    } 
} 

void manualMoveBot(int botID){ 
       int direction = 0; 
//    int bufX = bots[botID].x_cord; 
//    int bufY = bots[botID].y_cord; 
       direction = rand() % 4 + 1; 
       if(direction == 1){ //NORTH 
         if(bots[botID].y_cord==0 || mapBot[bots[botID].x_cord][bots[botID].y_cord-1] == 1){ 
           //cout << "error moving bot - N "; 
           manualMoveBot(botID); 
         } 
         else{ 
           //cout << "BufferY: " << bufferY; 
           bots[botID].y_cord -= 1; 
           gatherEnergy(botID); 
         } 
       } 
       else if(direction == 2){ //EAST 
         if(bots[botID].x_cord == 39 || mapBot[bots[botID].x_cord+1][bots[botID].y_cord] == 1){ 
           //cout << "error moving bot - E"; 
           manualMoveBot(botID); 
         } 
         else{ 
           bots[botID].x_cord += 1; 
           gatherEnergy(botID); 
         } 
       } 
       else if(direction == 3){ //SOUTH 
         if(bots[botID].y_cord == 69 || mapBot[bots[botID].x_cord][bots[botID].y_cord+1] == 1){ 
           //cout << "error moving bot - S "; 
           manualMoveBot(botID); 
         } 
         else{ 
           bots[botID].y_cord -= 1; 
           gatherEnergy(botID); 
         } 
       } 
       else if(direction == 4){ //WEST 
         if(bots[botID].x_cord == 0 or mapBot[bots[botID].x_cord-1][bots[botID].y_cord] == 1){ 
           //cout << "error moving bot - W"; 
           manualMoveBot(botID); 
         } 
         else{ 
           bots[botID].x_cord += 1; 
           gatherEnergy(botID); 
     } 
    } 
} 

void gatherEnergy(int botID){ 
// int mV = map[bufferX][bufferY]; //Eeeeh, doesn't work here 
    int x = bots[botID].x_cord; 
    int y = bots[botID].y_cord; 
// cout << "id: " << botID << endl; 
// cout << "x: " << x; 
// cout << endl << "y: " << y << endl; 
    if(1==map[x][y]){ //Good chunk 
     bots[botID].energy += 2000; 
     totalEnergy += 2000; 
    // cout << totalEnergy << endl; //Debug 
    } 
    else if(2==map[x][y]){ //Bad chunk (toxic) 
     mutateBot(botID, 1, 2); 
    } 
} 
+4

'map [39]' вне пределов. 'map' имеет 39 элементов. – chris

+0

Крис, я думал, что 0 подсчитано в сторону «карты», так что общее количество значений будет 40; Я полностью не понимаю массивы? –

+2

@JacobHartmann 'Карта [39] [69]' - массив массивов 'ints', где доступ начинается с элемента 0. ie 'Map [0]', 'Map [1]', ..., 'Map [ 38] '- это 39 элементов. Как справедливо сказал Крис, ** 'map [39]' выходит за пределы **. Быстрое исправление будет «Карта [40] [70]», предполагая, что вы также были неверны для распределения для вспомогательных массивов. Поскольку вы делаете C++, я рекомендую использовать контейнеры C++, такие как 'std :: vector' и' std :: array' ('C++ 11') вместо – woosah

ответ

1

У вас есть несколько проблем.

Основным является то, что индексы массива:
так для Bot bots[50]; действительные индексы [0; 49].
Для map, согласно опротестовать это должно быть int mapBot [40][70];
, так что вы можете получить доступ к элементу, начиная с mapBot[0][0] к mapBot[39][69].

Вы смешиваете = и == в некотором сравнении.
= выполняет задание, когда == сделать сравнение. Я вижу, что вы добавляете дополнительные скобки для удаления предупреждения. Вы должны прочитать или понять более тщательно предупреждающие сообщения. так else if((currentTick = maxTick)){ в tick например, должно быть else if (currentTick == maxTick) {.
То же самое в mutateBot ...

В AssigningBotID, вы увеличиваем индекс перед обращением массива и делать резервные проверки. Ниже достаточно:

void assignBotID() { 
    for (int i = 0; i < 50; ++i) { 
     bots[i].id = i /* + 1 */; // uncomment if id should be [1; 50] 

     // A super awesome debugging output to make sure the bot's id is correct 
     //std::cout << "Bot" << i << ":"<< bots[i].id << endl; 
    } 
} 

в manualMoveBot Ваш тест может изменить положение, так как вы используете +=: mapBot[bots[botID].x_cord += 1][bots[botID].y_cord] == 1 должен быть mapBot[bots[botID].x_cord + 1][bots[botID].y_cord] == 1

Ваша логика забудьте обновить mapBot: старое место должно быть установлено в 0 , новое место должно быть установлено на 1. Обратите внимание, что при инициализации он не всегда устанавливается ни ...

EDIT: Вы должны вызывать только srand (time(NULL)); один раз (один в main())

setupBot() должно быть что-то вроде (и так reassignLoc и ckLoc могут быть удалены):

void setupBot() { 
    for (int i = 0; i < 50; ++i) { 
     int x, y; 
     do { 
      x = rand() % 40; // [0; 39] 
      y = rand() % 70; // [0; 69] 
     while (mapBot[x][y] == 1); 

     bots[i].x_cord = x; 
     bots[i].y_cord = y; 
     mapBot[x][y] = 1; 
    } 
    cout << "Bot setup - \033[0;32mSuccessful" << "\033[0m" << endl; 
} 

mutateBot не будет исправлено: заменить = на == для сравнения.

void moveBot() { 
    for (int i = 0; i < 50; ++i) { 
     manualMoveBot(botID); 
    } 
} 

void manualMoveBot(int botID) { 
    const int oldX = bots[botID].x_cord; 
    const int oldY = bots[botID].y_cord; 
    int newX = oldX; 
    int newY = oldY; 
    int direction = rand() % 4 + 1; 

    if (direction == 1) { // NORTH 
     newY = oldY - 1; 
    } else if (direction == 2) { // EAST 
     newX = oldX + 1; 
    } else if (direction == 3) { // SOUTH 
     newY = oldY + 1; 
    } else if (direction == 4) { // WEST 
     newX = oldX - 1; 
    } 

    if (newX < 0 || 40 <= newX 
     || newY < 0 || 70 <= newY 
     || mapBot[newX][newY] == 1) { 
     cout << "error moving bot"; 
#if 0 
     // if this code is active, we may have infinite loop 
     // when bot is completely surrounded. 
     manualMoveBot(int botID); 
#endif 
     return; 
    } 
    bots[botID].x_cord = newX; 
    bots[botID].y_cord = newY; 
    mapBot[newX][newY] = 1; 
    mapBot[oldX][oldY] = 0; 
    gatherEnergy(botID); 
} 
+0

Я сделал то, что вы сказали, и я все равно получаю seg. неисправность. GDB: «Программный сигнал SIGSEGV, ошибка сегментации. 0x00007ffff725124d в __random() at random.c: 297 297 random.c: Нет такого файла или каталога. ' –

+0

@JacobHartmann: вам нужно будет указать фиксированный код. – Jarod42

+0

Могу ли я сделать это в комментариях? –

Смежные вопросы