用较小的方块整齐地填充方块

时间:2014-05-12 02:19:01

标签: java

我正在开发一种游戏,其中世界被分成称为扇区的单元,玩家通过这些单元。这些扇区中的每一个都是不同的大小,每个扇区被划分为称为SubSectors的单元,这些单元可以是不同的大小并完全填充该扇区。我快速描绘了我希望这一代人如何工作:

tiles http://jsydie.com/artlib/misc/tiles.gif

编辑:我不是想画这样的随机图片。 SubSector对象(由上面的方块表示)知道它左上角的位置,以及它的大小。我试图将这些“正方形”拟合到父扇区对象大小的网格上。

我正在努力研究这些行业,但我不知道如何从这里开始下一步:

package world;

import java.util.ArrayList;
import java.util.Random;

public class Sector {

private static int size;
private static ArrayList<SubSector> sub;

public Sector(int par0) {
    size = par0;
    sub = this.generateSubs();
}

private ArrayList<SubSector> generateSubs() {
    ArrayList<SubSector> out = new ArrayList<SubSector>();

    int side = this.size;
    int spaces = side * side;

    boolean[][] available = new boolean[side][side];

    Random r = new Random();
    int subSide;
    int loc;
    SubSector a;
    boolean anyAvailable = true;

    while(anyAvailable) {
        subSide = r.nextInt(1+side)-1;
        System.out.println(subSide);
        a = new SubSector(subSide);
        loc = r.nextInt(4);
        System.out.println(loc);
        out.add(a);
        if(loc == 0) {
            for(int i=0; i<subSide; i++) {
                for(int j=0; j<subSide; j++) {
                    available[i][j] = false;
                }
            }
        }
        if(loc == 1) {
            for(int i=subSide; i>0; i--) {
                for(int j=0; j<subSide; j++) {
                    available[i][j] = false;
                }
            }
        }
        if(loc == 2) {
            for(int i=subSide; i>0; i--) {
                for(int j=subSide; j>0; j--) {
                    available[i][j] = false;
                }
            }
        }
        if(loc == 3) {
            for(int i=0; i<subSide; i++) {
                for(int j=subSide; j>0; j--) {
                    available[i][j] = false;
                }
            }
        }
        breakloop:
        for(int i=0; i<side; i++) {
            for(int j=0; j<side; j++) {
                if(available[i][j] == true) {
                anyAvailable = true;
                break breakloop;
                }
                else
                    anyAvailable = false;
            }
        }
    }


    return out;
}
}

我不知道如何检查SubSectors现在在剩余空间中可用的大小,然后创建一个并将其放在随机位置。

1 个答案:

答案 0 :(得分:0)

这是我为自己创建的内容,但它已针对您的方形子行业进行了修改。它包含一个类Sector,它在其空间上提供操作并管理其子扇区,即SubSector类。我把Javadoc留给了你。您可能希望添加坐标参数位于扇区空间内的检查。

public class Sector {

    private final int SIZE;
    private int[][] allocationTable;
    private Set<SubSector> subSectors = new HashSet<>();

    /**
     * Creates a new <code>Sector</code> of the specified size.
     * @param size the size of the sector
     */
    public Sector (int size) {

        SIZE = size;
        allocationTable = new int[SIZE][SIZE];
    }

    /**
     * Checks if a position in the grid is occupied by a {@link SubSector}.
     * @param x the x coordinate
     * @param y the y coordinate
     * @return <code>true</code> if the position is occupied, <code>false</code> otherwise
     */
    public boolean isAllocated(int x, int y) {

        return (allocationTable[x][y] != 0);
    }

    /**
     * Calculates the free space originating at the given coordinates. A {@link SubSector} of this
     * maximum size or less can be allocated in this space.
     * @param x the x coordinate origin of the space
     * @param y the y coordinate origin of the space
     * @return the length of contiguous non-allocated space
     */
    public int getNonAllocatedSpaceAt(int x, int y) {

        int space = Math.min(SIZE-x, SIZE-y);
        for (int i = x; i < space +x ; i++) {
            for (int j = y; j < space + y; j++) {
                if (isAllocated(i, j))
                    return Math.max(i - x, j - y);
            }
        }
        return space;
    }

    /**
     * Gets the {@link SubSector} containing the specified coordinate.
     * @param x the x coordinate
     * @param y the y coordinate
     * @return the <code>SubSecotr</code> to which this space is allocated. <code>null</code> if
     * the space is not allocated.
     */
    public SubSector getSubSectorAt(int x, int y) {

        for (SubSector s : subSectors)
            if (s.number == allocationTable[x][y])
                return s;
        return null;
    }

    /**
     * Gets the {@link SubSector} specified by its number designation.
     * @param subSector the number designation of the <code>SubSector</code>
     * @return the designated <code>SubSector</code>.  <code>null</code> if the <code>SubSector</code>
     * does not exist.
     */
    public SubSector getSubSector(int subSector) {

        for (SubSector s : subSectors)
            if (s.number == subSector)
                return s;
        return null;
    }

    /**
     * Allocates the specified coordinate space to the specified {@link SubSector} and creates a new
     * <code>SubSector</code>. The <code>SubSector</code> must not already exist.
     * @param x the x coordinate origin of the space
     * @param y the y coordinate origin of the space
     * @param size the length of contiguous space to be allocated
     * @param subSector the number designation of the <code>SubSector</code>
     * @return <code>true</code> if the space was allocated, <code>false</code> otherwise
     */
    public boolean allocate(int x, int y, int size, int subSector) {

        if (getNonAllocatedSpaceAt(x, y) < size || !subSectors.add(new SubSector(x, y, size, subSector)))
            return false;
        for (int i = x; i < size + x; i++) {
            for (int j = y; j < size + y; j++) {
                allocationTable[i][j] = subSector;
            }
        }
        return true;
    }

    /**
     * Frees the space occupied by the specified {@link SubSector} and removes it.
     * @param subSector the <code>SubSector</code> to be removed
     * @return <code>true</code> if the space was deallocated, <code>false</code> otherwise
     */
    public boolean deallocate(int subSector) {

        return remove(getSubSector(subSector));
    }

    /**
     * Frees the space occupied by the {@link SubSector} occupying the specified coordinates.
     * @param x the x coordinate
     * @param y the y coordinate
     * @return <code>true</code> if the space was deallocated, <code>false</code> otherwise
     */
    public boolean deallocate(int x, int y) {

        return remove(getSubSectorAt(x, y));
    }

    private boolean remove(SubSector sub) {

        if (!subSectors.remove(sub))
            return false;
        for (int i = sub.x; i < sub.size + sub.x; i++) {
            for (int j = sub.y; j < sub.size + sub.y; j++) {
                allocationTable[i][j] = 0;
            }
        }
        return true;
    }

    /**
     * Gets the allocation table for this <code>Sector</code>.
     * @return the allocation table for this <code>Sector</code>
     */
    public int[][] getAllocationTable() {

        return allocationTable;
    }

    /**
     * Gets the size of this <code>Sector</code>.
     * @return the size of this <code>Sector</code>
     */
    public int getSize() {

        return SIZE;
    }

    /**
     * Gets the (unsorted) {@link Set} of {@link SubSector}s in this <code>Sector</code>.
     * @return the <code>Set</code> of <code>SubSector</code>s in this <code>Sector</code>.
     */
    public Set<SubSector> getSubSectors() {

        return subSectors;
    }

    /**
     * A <code>SubSector</code> represents a square-shaped area in its parent {@link Sector}'s space.
     * A <code>SubSector</code> is designated (named) by a number and each parent <code>Sector</code>
     * can only contain one such <code>SubSector</code>.
     * A <code>SubSector</code> can only be created (and removed) by its parent <code>Sector</code>
     * and can never be modified (this prevents synchronizations issues with the allocation table),
     * however, its fields can be accessed directly.
     */
    public class SubSector {

        /** The x coordinate origin of this <code>SubSector</code>. */
        public final int x;
        /** The y coordinate origin of this <code>SubSector</code>. */
        public final int y;
        /** The length of this <code>SubSector</code>. */
        public final int size;
        /** The designation of this <code>SubSector</code>. */
        public final int number;

        private SubSector(int x, int y, int size, int number) {

            this.x = x;
            this.y = y;
            this.size = size;
            this.number = number;
        }
    }
}