Как сделать такой цикл?

svk

1,185
3
Надо проверить соседние блоки, а затем соседние блоки соседних блоков. (Что-то вроде определения герметичности помещения)
 
WTF? :D
Вот тебе код, который проверит, если соседний блок - губка и сосед губки - торт, то заменит данный блок на кактус:
Код:
if (world.getBlock(X + 1, Y, Z) == Blocks.sponge) {
    if (world.getBlock(X + 2, Y, Z) == Blocks.cake) {
        world.setBlock(X, Y, Z, Blocks.cactus)
    }
}
 
Всё, кажись понял. Я ведь пытался всё это в условиях итерации сделать, а там добавлять елементы в список нельзя.

Но можно ведь while сделать... Щас попробую...
 
Вот такое вот страшилище получилось:
Код:
package com.svk.atmosphereSound.events;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

import com.svk.atmosphereSound.base.ModInfo;
import com.svk.atmosphereSound.utils.UtilRegion;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;

public class EventSpectatorSound 
{
    private ArrayList<int[]> inTurnBlocks = new ArrayList();
    private ArrayList<int[]> inCheckedBlocks = new ArrayList();
    private ArrayList<int[]> confirmedBlocks = new ArrayList();

    private int tick = 0;

    @SubscribeEvent
    public void TickEvent(TickEvent.PlayerTickEvent e) 
    {        
        EntityPlayer player = e.player;
        World world = player.worldObj;
        if(!world.isRemote)
        {
            tick++;
            if(tick == (20*7)*2)
            {    
                int x = (int) player.posX;
                int y = (int) player.posY;
                int z = (int) player.posZ;

                if(world.canBlockSeeTheSky(x, y, z))
                {
                    confirmedBlocks.add(new int[]{x, y, z});
                }
                else
                {
                    inTurnBlocks.add(new int[]{x, y, z});
                }

                inTurnCheck(world, new int[]{x, y, z});

                inTurnBlocks = new ArrayList();
                confirmedBlocks = new ArrayList();
                inCheckedBlocks = new ArrayList();
                tick = 0;
            }
        }
    }

    private void inTurnCheck(World world, int[] startCoords)
    {
        int currentY = startCoords[1];

        while(inTurnBlocks.size() != 0)
        {
            int[] blockCoords = inTurnBlocks.get(0);
            
            addBlockCoordsToList(world, new int[]{blockCoords[0]+1, currentY, blockCoords[2]});
            addBlockCoordsToList(world, new int[]{blockCoords[0]-1, currentY, blockCoords[2]});
            addBlockCoordsToList(world, new int[]{blockCoords[0], currentY, blockCoords[2]+1});
            addBlockCoordsToList(world, new int[]{blockCoords[0], currentY, blockCoords[2]-1});

            inCheckedBlocks.add(blockCoords);
            inTurnBlocks.remove(0);
        }
    }

    private void addBlockCoordsToList(World world, int[] blockCoords)
    {
        if(world.isAirBlock(blockCoords[0], blockCoords[1], blockCoords[2]))
        {
            for(int[] i : inCheckedBlocks)
            {
                if(Arrays.equals(i, blockCoords))
                {
                    return;
                }
            }

            if(!world.canBlockSeeTheSky(blockCoords[0], blockCoords[1], blockCoords[2]))
            {
                inTurnBlocks.add(blockCoords);
            }
            else
            {
                confirmedBlocks.add(blockCoords);
            }
        }
    }
}

Для герметичности сойдёт, но не для меня.

Потом буду делать проверку на количество "кучи" блоков которые видят небо.
(Что-бы при дырке в потолке не проигрывался звук ветра).

И затем буду думать над сканированием краёв дыры, для поиска средней точки дыры и проигрывать там звук.
[merge_posts_bbcode]Добавлено: 15.02.2016 20:23:16[/merge_posts_bbcode]

А, ну ещё и ограничитель приделать, что-бы не сканировало излишнею территорию.
 
Agravaine написал(а):
А рекурсия для кого?
Ну это когда метод вызывается внутри самого себя. Но тогда скан будет по цепочке, а так, в том порядке, в котором добавлялось. В итоге выйдет так, что скан происходит почти равномерно во все стороны.
 
Как минимум рекурсия может потребовать немного больше памяти под стек возвратов. Есть еще причины для снижения быстродействия. Хорошие компиляторы сами разворачивают рекурсию в цикл когда это возможно. Как это происходит в джаве я не знаю.
 
Назад
Сверху