Skip to content

Commit

Permalink
perfomance: заменяет двухмерный массив матрицы мира на одномерный
Browse files Browse the repository at this point in the history
    Доступ к элементам одномерного массива намного быстрее чем к
    элементам многомерного. Скорость пересчета увеличилась примерно на 20%.
  • Loading branch information
xlam committed Sep 4, 2018
1 parent 0c8fe33 commit 8129e74
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 63 deletions.
87 changes: 48 additions & 39 deletions ru/cyberbiology/test/Bot.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ int fullAroud(Bot bot) {
int xt = xFromVektorR(bot, i);
int yt = yFromVektorR(bot, i);
if ((yt >= 0) && (yt < world.height)) {
if (world.matrix[xt][yt] == null) {
if (world.getBot(xt, yt) == null) {
return 2;
}
}
Expand All @@ -392,7 +392,7 @@ int findEmptyDirection(Bot bot) {
int xt = xFromVektorR(bot, i);
int yt = yFromVektorR(bot, i);
if ((yt >= 0) && (yt < world.height)) {
if (world.matrix[xt][yt] == null) {
if (world.getBot(xt, yt) == null) {
return i;
}
}
Expand Down Expand Up @@ -511,8 +511,8 @@ int isMulti(Bot bot) {
* @param yt новые координаты y
*/
void moveBot(Bot bot, int xt, int yt) {
world.matrix[xt][yt] = bot;
world.matrix[bot.x][bot.y] = null;
world.matrix[world.width * yt + xt] = bot;
world.clearBot(bot.x, bot.y);
bot.x = xt;
bot.y = yt;
}
Expand Down Expand Up @@ -540,7 +540,7 @@ public void deleteBot(Bot bot) {
this.world.pestGenes -= bot.pest;
}
}
world.matrix[bot.x][bot.y] = null; // удаление бота с карты
world.clearBot(bot.x, bot.y); // удаление бота с карты
}


Expand Down Expand Up @@ -621,15 +621,16 @@ public int botMove(Bot bot, int direction, int ra) { // ссылка на бот
if ((yt < 0) || (yt >= world.height)) { // если там ... стена
return 3; // то возвращаем 3
}
if (world.matrix[xt][yt] == null) { // если клетка была пустая,
Bot bot2 = world.getBot(xt, yt);
if (bot2 == null) { // если клетка была пустая,
moveBot(bot, xt, yt); // то перемещаем бота
return 2; // и функция возвращает 2
}
// осталось 2 варианта: ограника или бот
if (world.matrix[xt][yt].alive <= LV_ORGANIC_SINK) { // если на клетке находится органика
if (bot2.alive <= LV_ORGANIC_SINK) { // если на клетке находится органика
return 4; // то возвращаем 4
}
if (isRelative(bot, world.matrix[xt][yt]) == 1) { // если на клетке родня
if (isRelative(bot, bot2) == 1) { // если на клетке родня
return 6; // то возвращаем 6
}
return 5; // остался только один вариант - на клетке какой-то бот возвращаем 5
Expand Down Expand Up @@ -658,25 +659,26 @@ int botEat(Bot bot, int direction, int ra) { // на входе ссылка н
if ((yt < 0) || (yt >= world.height)) { // если там стена возвращаем 3
return 3;
}
if (world.matrix[xt][yt] == null) { // если клетка пустая возвращаем 2
Bot bot2 = world.getBot(xt, yt);
if (bot2 == null) { // если клетка пустая возвращаем 2
return 2;
}
// осталось 2 варианта: ограника или бот
else if (world.matrix[xt][yt].alive <= LV_ORGANIC_SINK) { // если там оказалась органика
deleteBot(world.matrix[xt][yt]); // то удаляем её из списков
else if (bot2.alive <= LV_ORGANIC_SINK) { // если там оказалась органика
deleteBot(bot2); // то удаляем её из списков
bot.health = bot.health + 100; //здоровье увеличилось на 100
goRed(this, 100); // бот покраснел
return 4; // возвращаем 4
}
//--------- дошли до сюда, значит впереди живой бот -------------------
int min0 = bot.mineral; // определим количество минералов у бота
int min1 = world.matrix[xt][yt].mineral; // определим количество минералов у потенциального обеда
int hl = world.matrix[xt][yt].health; // определим энергию у потенциального обеда
int min1 = bot2.mineral; // определим количество минералов у потенциального обеда
int hl = bot2.health; // определим энергию у потенциального обеда
// если у бота минералов больше
if (min0 >= min1) {
bot.mineral = min0 - min1; // количество минералов у бота уменьшается на количество минералов у жертвы
// типа, стесал свои зубы о панцирь жертвы
deleteBot(world.matrix[xt][yt]); // удаляем жертву из списков
deleteBot(bot2); // удаляем жертву из списков
int cl = 100 + (hl / 2); // количество энергии у бота прибавляется на 100+(половина от энергии жертвы)
bot.health = bot.health + cl;
goRed(this, cl); // бот краснеет
Expand All @@ -685,11 +687,11 @@ else if (world.matrix[xt][yt].alive <= LV_ORGANIC_SINK) { // если там
//если у жертвы минералов больше ----------------------
bot.mineral = 0; // то бот израсходовал все свои минералы на преодоление защиты
min1 = min1 - min0; // у жертвы количество минералов тоже уменьшилось
world.matrix[xt][yt].mineral = min1 - min0; // перезаписали минералы жертве =========================ЗАПЛАТКА!!!!!!!!!!!!
bot2.mineral = min1 - min0; // перезаписали минералы жертве =========================ЗАПЛАТКА!!!!!!!!!!!!
//------ если здоровья в 2 раза больше, чем минералов у жертвы ------
//------ то здоровьем проламываем минералы ---------------------------
if (bot.health >= 2 * min1) {
deleteBot(world.matrix[xt][yt]); // удаляем жертву из списков
deleteBot(bot2); // удаляем жертву из списков
int cl = 100 + (hl / 2) - 2 * min1; // вычисляем, сколько энергии смог получить бот
bot.health = bot.health + cl;
if (cl < 0) { cl = 0; } //========================================================================================ЗАПЛАТКА!!!!!!!!!!! - энергия не должна быть отрицательной
Expand All @@ -698,7 +700,7 @@ else if (world.matrix[xt][yt].alive <= LV_ORGANIC_SINK) { // если там
return 5; // возвращаем 5
}
//--- если здоровья меньше, чем (минералов у жертвы)*2, то бот погибает от жертвы
world.matrix[xt][yt].mineral = min1 - (bot.health / 2); // у жертвы минералы истраченны
bot2.mineral = min1 - (bot.health / 2); // у жертвы минералы истраченны
bot.health = 0; // здоровье уходит в ноль
return 5; // возвращаем 5
}
Expand All @@ -724,11 +726,13 @@ int botSeeBots(Bot bot, int direction, int ra) { // на входе ссылка
}
if (yt < 0 || yt >= world.height) { // если там стена возвращаем 3
return 3;
} else if (world.matrix[xt][yt] == null) { // если клетка пустая возвращаем 2
}
Bot bot2 = world.getBot(xt, yt);
if (bot2 == null) { // если клетка пустая возвращаем 2
return 2;
} else if (world.matrix[xt][yt].alive <= LV_ORGANIC_SINK) { // если органика возвращаем 4
} else if (bot2.alive <= LV_ORGANIC_SINK) { // если органика возвращаем 4
return 4;
} else if (isRelative(bot, world.matrix[xt][yt]) == 1) { // если родня, то возвращаем 6
} else if (isRelative(bot, bot2) == 1) { // если родня, то возвращаем 6
return 6;
} else { // если какой-то бот, то возвращаем 5
return 5;
Expand All @@ -744,8 +748,9 @@ int botSeeBots(Bot bot, int direction, int ra) { // на входе ссылка
void botGenAttack(Bot bot) { // вычисляем кто у нас перед ботом (используется только относительное направление вперед)
int xt = xFromVektorR(bot, 0);
int yt = yFromVektorR(bot, 0);
if ((yt >= 0) && (yt < world.height) && (world.matrix[xt][yt] != null)) {
if (world.matrix[xt][yt].alive == LV_ALIVE) { // если там живой бот
Bot bot2 = world.getBot(xt, yt);
if ((yt >= 0) && (yt < world.height) && (bot2 != null)) {
if (bot2.alive == LV_ALIVE) { // если там живой бот
bot.health = bot.health - 10; // то атакуюий бот теряет на атаку 10 энергии
if (bot.health > 0) {
bot.modifyMind();
Expand Down Expand Up @@ -781,25 +786,27 @@ int botCare(Bot bot, int direction, int ra) { // на входе ссылка н
}
if (yt < 0 || yt >= world.height) { // если там стена возвращаем 3
return 3;
} else if (world.matrix[xt][yt] == null) { // если клетка пустая возвращаем 2
}
Bot bot2 = world.getBot(xt, yt);
if (bot2 == null) { // если клетка пустая возвращаем 2
return 2;
} else if (world.matrix[xt][yt].alive <= LV_ORGANIC_SINK) { // если органика возвращаем 4
} else if (bot2.alive <= LV_ORGANIC_SINK) { // если органика возвращаем 4
return 4;
}
//------- если мы здесь, то в данном направлении живой ----------
int hlt0 = bot.health; // определим количество энергии и минералов
int hlt1 = world.matrix[xt][yt].health; // у бота и его соседа
int hlt1 = bot2.health; // у бота и его соседа
int min0 = bot.mineral;
int min1 = world.matrix[xt][yt].mineral;
int min1 = bot2.mineral;
if (hlt0 > hlt1) { // если у бота больше энергии, чем у соседа
int hlt = (hlt0 - hlt1) / 2; // то распределяем энергию поровну
bot.health = bot.health - hlt;
world.matrix[xt][yt].health = world.matrix[xt][yt].health + hlt;
bot2.health = bot2.health + hlt;
}
if (min0 > min1) { // если у бота больше минералов, чем у соседа
int min = (min0 - min1) / 2; // то распределяем их поровну
bot.mineral = bot.mineral - min;
world.matrix[xt][yt].mineral = world.matrix[xt][yt].mineral + min;
bot2.mineral = bot2.mineral + min;
}
return 5;
}
Expand All @@ -826,24 +833,26 @@ int botGive(Bot bot, int direction, int ra) // на входе ссылка на
}
if (yt < 0 || yt >= world.height) { // если там стена возвращаем 3
return 3;
} else if (world.matrix[xt][yt] == null) { // если клетка пустая возвращаем 2
}
Bot bot2 = world.getBot(xt, yt);
if (bot2 == null) { // если клетка пустая возвращаем 2
return 2;
} else if (world.matrix[xt][yt].alive <= LV_ORGANIC_SINK) { // если органика возвращаем 4
} else if (bot2.alive <= LV_ORGANIC_SINK) { // если органика возвращаем 4
return 4;
}
//------- если мы здесь, то в данном направлении живой ----------
int hlt0 = bot.health; // бот отдает четверть своей энергии
int hlt = hlt0 / 4;
bot.health = hlt0 - hlt;
world.matrix[xt][yt].health = world.matrix[xt][yt].health + hlt;
bot2.health = bot2.health + hlt;

int min0 = bot.mineral; // бот отдает четверть своих минералов
if (min0 > 3) { // только если их у него не меньше 4
int min = min0 / 4;
bot.mineral = min0 - min;
world.matrix[xt][yt].mineral = world.matrix[xt][yt].mineral + min;
if (world.matrix[xt][yt].mineral > 999) {
world.matrix[xt][yt].mineral = 999;
bot2.mineral = bot2.mineral + min;
if (bot2.mineral > 999) {
bot2.mineral = 999;
}
}
return 5;
Expand Down Expand Up @@ -910,7 +919,7 @@ private void botDouble(Bot bot) {

newbot.direction = (int) (Math.random() * 8); // направление, куда повернут новорожденный, генерируется случайно

world.matrix[xt][yt] = newbot; // отмечаем нового бота в массиве matrix
world.setBot(newbot); // отмечаем нового бота в массиве matrix
this.world.population++;
}

Expand Down Expand Up @@ -961,7 +970,7 @@ private void botMulti(Bot bot) {

newbot.direction = (int) (Math.random() * 8); // направление, куда повернут новорожденный, генерируется случайно

world.matrix[xt][yt] = newbot; // отмечаем нового бота в массиве matrix
world.setBot(newbot); // отмечаем нового бота в массиве matrix
this.world.population++;

if (nbot == null) { // если у бота-предка ссылка на следующего бота в многоклеточной цепочке пуста
Expand Down Expand Up @@ -1277,8 +1286,8 @@ public void pestAttack()
{
int xt = xFromVektorR(this, 0);
int yt = yFromVektorR(this, 0);
if ((yt >= 0) && (yt < world.height) && (world.matrix[xt][yt] != null)) {
Bot victim = world.matrix[xt][yt];
Bot victim;
if ((yt >= 0) && (yt < world.height) && ((victim = world.getBot(xt, yt)) != null)) {
// паразит атакует только живых и незараженных ботов
if (victim.alive == LV_ALIVE && victim.pest == 0) {
int healthDrain = victim.health > 100 ? 100 : victim.health;
Expand Down Expand Up @@ -1320,7 +1329,7 @@ public int imitate(int dir) {
if ((yt < 0) || (yt >= world.height)) { // если там стена возвращаем 3
return 3;
}
Bot bot = world.matrix[xt][yt];
Bot bot = world.getBot(xt, yt);
if (bot == null) { // если клетка пустая возвращаем 2
return 2;
}
Expand Down
36 changes: 21 additions & 15 deletions ru/cyberbiology/test/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class World implements IWorld
public int width;
public int height;

public Bot[][] matrix; // Матрица мира
public Bot[] matrix; // Матрица мира
public int generation;
public int population;
public int organic;
Expand Down Expand Up @@ -76,15 +76,20 @@ public void setSize(int width, int height)
{
this.width = width;
this.height = height;
this.matrix = new Bot[width][height];
this.matrix = new Bot[height * width];
}

@Override
public void setBot(Bot bot)
{
this.matrix[bot.x][bot.y] = bot;
matrix[width * bot.y + bot.x] = bot;
}

@Override
public void clearBot(int x, int y) {
matrix[width * y + x] = null;
}

public void paint()
{
window.paint();
Expand All @@ -103,7 +108,7 @@ void jumpBotsCmdAdress() {
if (started()) stop();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Bot bot = matrix[x][y];
Bot bot = getBot(x, y);
if (bot != null) {
if (bot.alive == bot.LV_ALIVE) {
bot.adr = (byte)(Math.random() * Bot.MIND_SIZE);
Expand Down Expand Up @@ -134,7 +139,7 @@ public void run() {
Bot bot;
for (int y=from; y<to; y++) {
for (int x=0; x<width; x++) {
bot = matrix[x][y];
bot = getBot(x, y);
if (bot != null) {
bot.step(); // выполняем шаг бота
if (recorder.isRecording()) {
Expand Down Expand Up @@ -226,28 +231,29 @@ public void generateAdam()
bot.mind[i] = 25;
}

matrix[bot.x][bot.y] = bot; // даём ссылку на бота в массиве world[]
setBot(bot); // даём ссылку на бота в массиве world[]

return;
}
public void restoreLinks()
{
Bot bot;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (matrix[x][y] != null)
bot = getBot(x, y);
if (bot != null)
{
if (matrix[x][y].alive == 3)
if (bot.alive == bot.LV_ALIVE)
{
Bot bot = matrix[x][y];
if(bot.mprevX>-1 && bot.mprevY>-1)
{
bot.mprev = matrix[bot.mprevX][bot.mprevY];
bot.mprev = getBot(bot.mprevX, bot.mprevY);
}
if(bot.mnextX>-1 && bot.mnextY>-1)
{
bot.mnext = matrix[bot.mnextX][bot.mnextY];
bot.mnext = getBot(bot.mnextX, bot.mnextY);
}
}
}
Expand All @@ -265,7 +271,7 @@ public void restoreStats() {
Bot bot;
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
bot = matrix[x][y];
bot = getBot(x, y);
if (bot == null || bot.alive == bot.LV_FREE) {
continue;
}
Expand Down Expand Up @@ -358,7 +364,7 @@ public boolean stopRecording()

public Bot getBot(int botX, int botY)
{
return this.matrix[botX][botY];
return this.matrix[width * botY + botX];
}

@Override
Expand Down Expand Up @@ -388,9 +394,9 @@ public void makeSnapShot()
this.recorder.makeSnapShot();
}
@Override
public Bot[][] getWorldArray()
public Bot[] getWorldArray()
{
return this.matrix;
return this.matrix;
}
public void openFile(File file)
{
Expand Down
4 changes: 3 additions & 1 deletion ru/cyberbiology/test/prototype/IWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ public interface IWorld

public void setBot(Bot bot);

public void clearBot(int x, int y);

public void paint();

public ProjectProperties getProperties();

public Bot[][] getWorldArray();
public Bot[] getWorldArray();

public void restoreLinks();

Expand Down
2 changes: 1 addition & 1 deletion ru/cyberbiology/test/prototype/view/View.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public Image paint(World world, JPanel canvas) {

for (int y = 0; y < world.height; y++) {
for (int x = 0; x < world.width; x++) {
Bot bot = world.matrix[x][y];
Bot bot = world.getBot(x, y);
Color color = getBotColor(bot);
g.setColor(color);
g.fillRect(x * World.BOTW, y * World.BOTH, World.BOTW, World.BOTH);
Expand Down
Loading

0 comments on commit 8129e74

Please sign in to comment.