Движущиеся объекты на сетке в C++


У меня есть код, который работает, но очень плохо написано. Основной многословность, это только для проверки класс. Я хочу заставить объекты передвигаться по шахматной доске (координатной сетке). Я определил эти объекта в качестве транспортных средств. У них есть позиции (X,Y) на плоскости и направлении. Были вынуждены двигаться только на Север-Юг-Восток-Запад, возможных направлений может быть

  1. Север: (0, 1)
  2. Юг: (0, -1)
  3. Восток: (1, 0)
  4. Запад: (-1, 0)

Средствами можно осуществлять только шаг за шагом (х+1, Г), (Х, Y+1), где x, y-целые числа. Две машины не могут стоять в одном положении. Автомобиль сохраняет направление пока это возможно, что при обнаружении занимаемой должности.

Так что я должен создать функцию Void ход, по которому в качестве аргументов позиции соседних транспортных средств (Север Юг Восток Запад). Такая функция должна:

  1. Проверьте, если транспортное средство может сохранять свое направление и, если это возможно, обновить положение автомобиля с новой должностью;
  2. Если ячейка занята, перейти на другую сторону, проверить, если ячейка в этом направлении является бесплатным...
  3. Если каждая клетка вокруг автомобиля оккупирован, не дергайся.

The final situation in the main

Я написал код, который выполнить пункт 1, но у меня есть трудности с пункта 2. В частности, я не могу думать о умный способ, чтобы изменить направление автомобиля. Вот мой код до сих пор, это работает, но, безусловно, это не лучший способ делать то, что я хочу сделать:

 #include <iostream>
#include <cmath>

using namespace std;

class Vehicle {
private:
    int x, y;
    int vx, vy;
public:
    int getx() { return x;}
    int gety() { return y;}
    int getvx() { return vx;}
    int getvy() { return vy;}
void sety(int a) { y = a;}
void setx(int a) { x = a;}
void setvx(int a) { 
    if (a != 0) {   
        vx = a / abs(a);
    }else { vx = a;}
} 
void setvy(int a) { 
    if (a != 0) {   
        vy = a / abs(a);
    }else { vy = a;}
}

void move(Vehicle * v) {
    int big = 0;
    int per[8];
    per[0]=0;   // North
    per[1]=1;
    per[2]=0;   // South
    per[3]=-1;
    per[4]=1;   // West
    per[5]=0;
    per[6]=-1;  // East
    per[7]=0;   


    while(big<8) {
        int cont=0;
        for(int i=0; i<4; i++) {
            if (x+vx != v[i].getx() or y+vy != v[i].gety()) {
                cont ++;
            }
        }
        if(cont==4) {
            x = x + vx;
            y = y + vy;
            break;
        } else { 
            vx = per[big];
            vy = per[big+1];
            big = big + 2;
        }
    }
}

void print() {
    cout << "x: " << x << endl;
    cout << "y: " << y << endl;
    cout << "vx: " << vx << endl;
    cout << "vy: " << vy << endl;   
    cout << endl;
}

};

int main() {
Vehicle x;  
x.setx(0);
x.sety(0);
x.setvx(0);
x.setvy(1);
x.print();

Vehicle v[4];

v[0].setx(0);
v[0].sety(1);
v[1].setx(-1);
v[1].sety(0);
v[2].setx(0);
v[2].sety(-1);
v[3].setx(1);
v[3].sety(0);

for(int i = 0; i<4; i++) {
    v[i].setvx(0);
    v[i].setvy(1);
    v[i].print();
}

x.move(v);
x.print();

v[2].setx(0);
v[2].sety(-2);
v[2].print();

x.move(v);
x.print();


}


1705
4
задан 1 апреля 2018 в 01:04 Источник Поделиться
Комментарии
1 ответ

Первое, что нужно сделать, чтобы очистить код будет сделать

struct pos {
int x;
int y;
};

Это позволит упростить оставшуюся часть кода, что делает его легче рассуждать о логике.

Например, уже сейчас можно установить скорость транспортного средства (направление) в {1,1}, что ваша постановка задачи не позволяет.

Тогда вы должны также определить сравнение равенства для вашего местоположения.

Ваш move функция, кажется, жестко количество транспортных средств в игре. Вместо этого вы должны передать его std::vector<Vehicle> по ссылке, и использовать size().

После того как вы исправить эти вещи, логика move функция-это вполне нормально. Это квадратичный по сложности, но это нормально для нескольких автомобилей. Если вы когда-нибудь намерены увеличить количество машин на порядки, есть два способа улучшения кода:


  1. Предел мира, и сохранить таблицу, в которой вы отмечаете, если он занят или нет.

  2. Магазин автомобилей std::unordered_mapС их положение в качестве ключевых. Тогда вы можете посмотреть в постоянное время.


Редактировать: как предположил в комментарии ниже using namespace std не следует использовать. Есть несколько очень веских причин не использовать его, и единственная причина, чтобы использовать это "я ленивый". Посмотрите вокруг других ответов на комментарий код для рассуждений. Этот момент наступает примерно половину c++ вопросы.

5
ответ дан 1 апреля 2018 в 02:04 Источник Поделиться