Я работаю над школьным проектом (мне разрешили сделать симуляцию на 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);
}
}
'map [39]' вне пределов. 'map' имеет 39 элементов. – chris
Крис, я думал, что 0 подсчитано в сторону «карты», так что общее количество значений будет 40; Я полностью не понимаю массивы? –
@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