没有重复的随机数序列

时间:2016-05-01 17:23:23

标签: java

我正在尝试在我的游戏服务器中执行pvp事件,该服务器使用3个区域随机执行。我使用以下代码但总是返回值1和2并重复。我需要一些这样的序列,例如:3-2-1-2-1-3或者从不重复相同数字的东西。

int random = Rnd.get(1, 3);

if (random == 1)
{
    setstartedpvpzone1(true);
}

if (random == 2)
{
    setstartedpvpzone2(true);
}

if (random == 3)
{
    setstartedpvpzone3(true);
}

这是我在rnd中得到的:

public final class Rnd
{
    /**
     * This class extends {@link java.util.Random} but do not compare and store atomically.<br>
     * Instead it`s using a simple volatile flag to ensure reading and storing the whole 64bit seed chunk.<br>
     * This implementation is much faster on parallel access, but may generate the same seed for 2 threads.
     * @author Forsaiken
     * @see java.util.Random
     */
    public static final class NonAtomicRandom extends Random
    {
        private static final long serialVersionUID = 1L;
        private volatile long _seed;

        public NonAtomicRandom()
        {
            this(++SEED_UNIQUIFIER + System.nanoTime());
        }

        public NonAtomicRandom(final long seed)
        {
            setSeed(seed);
        }

        @Override
        public final int next(final int bits)
        {
            return (int) ((_seed = ((_seed * MULTIPLIER) + ADDEND) & MASK) >>> (48 - bits));
        }

        @Override
        public final void setSeed(final long seed)
        {
            _seed = (seed ^ MULTIPLIER) & MASK;
        }
    }

和rnd.get:

/**
 * Gets a random integer number from min(inclusive) to max(inclusive)
 * @param min The minimum value
 * @param max The maximum value
 * @return A random integer number from min to max
 */
public static final int get(final int min, final int max)
{
    return rnd.get(min, max);
}

5 个答案:

答案 0 :(得分:1)

如果您要查找的是一个不等于前一个返回的随机数,那么解决方案就更简单了:

private Random random = new Random();
private int previousZone = 0;

public int nextZone() {
    int zone;
    do {
        zone = random.nextInt(3) + 1;
    } while (zone == previousZone);

    previousZone = zone; //store last "generated" zone

    return zone;
}

答案 1 :(得分:0)

此代码从不重复任何数字,例如,如果您有1,2,3,则可以获得4个数字的随机序列,例如2,1,3。

创建一个包含您需要的所有数字的数组...

   int[] a = {1, 2, 3};

然后选择随机项

   for (int i=0; i<a.length; i++){
       int random = Rnd.get(0, a.length);
       //remove the selected item from the array
       ArrayUtils.removeElement(a, random);

       if (random == 1) {
            setstartedpvpzone1(true);
       } else if (random == 2) {
            setstartedpvpzone2(true);
       } else if (random == 3) {
            setstartedpvpzone3(true);
       }
    }

答案 2 :(得分:0)

[未经测试]由于我不是Java程序员,因此可能包含一些语法错误。

    int a=0,b=0;
    while(true)
   {
        int random = Rnd.get(1, 3);
        if(!(a==random or b==random))
        {
            a=b;
            b=random;
            break;
        }
   }

if (random == 1)
{
    setstartedpvpzone1(true);
}

if (random == 2)
{
    setstartedpvpzone2(true);
}

if (random == 3)
{
    setstartedpvpzone3(true);
}

答案 3 :(得分:0)

您的问题归结为graph遍历,在每个当前区域中,您只有2个可能的下一个区域,这些选择永远不会改变。以下是我将如何实现它:

public static class EventLocator{
    private int currentZone;
    private Random random;
    private Map<Integer, int[]> locations;
    private static EventLocator instance;

    private EventLocator() {
    }

    public static EventLocator getInstance(){
        if (instance == null) {
            instance = new EventLocator();
        }
        return instance;

    }

    public int getNextZone(){
        if (this.currentZone == 0) {//first time called
            this.random = new Random();
            this.locations = new HashMap<>(3);//graph <currentZone, posibleZones>
            this.locations.put(1, new int[] { 2, 3 });
            this.locations.put(2, new int[] { 1, 3 });
            this.locations.put(3, new int[] { 1, 2 });

            this.currentZone = this.random.nextInt(3) + 1;// to 1-based Zones
            return currentZone;
        }
        int[] possibleZones = this.locations.get(this.currentZone);
        int randomIndex = this.random.nextInt(2);//0 or 1 index
        this.currentZone = possibleZones[randomIndex];
        return this.currentZone;
    }
}

您可以这样称呼:

EventLocator eventLocator = MyProgram.EventLocator.getInstance();
System.out.println(eventLocator.getNextZone());
System.out.println(eventLocator.getNextZone());

答案 4 :(得分:0)

	private boolean _lastevent1 = false;
	
	public boolean lastevent1()
	{
		
		return _lastevent1;
	}
	
	public void setlastevent1(boolean val)
	{
		_lastevent1 = val;
	}
	
	private boolean _lastevent2 = false;
	
	public boolean lastevent2()
	{
		
		return _lastevent2;
	}
	
	public void setlastevent2(boolean val)
	{
		_lastevent2 = val;
	}
	
	private boolean _lastevent3 = false;
	
	public boolean lastevent3()
	{
		
		return _lastevent3;
	}
	
	public void setlastevent3(boolean val)
	{
		_lastevent3 = val;
	}

				if (!lastevent1())
				{
					setlastevent3(false);
					setstartedpvpzone3(false);
					
					setstartedpvpzone1(true);
					setlastevent1(true);
				}
				
				else if (!lastevent2())
				{
					setstartedpvpzone1(false);
					setstartedpvpzone2(true);
					setlastevent2(true);
				}
				
				else if (!lastevent3())
				{
					setlastevent1(false);
					setlastevent2(false);
					
					setstartedpvpzone2(false);
					setstartedpvpzone3(true);
					setlastevent3(true);
				}

你好我最后用固定器固定了,我得到了这个安全,1-2-3-1-2-3-1-2-3-1-2-3,我用它打破了我的想法,因为这很混乱代码,但它现在作为一个魅力,感谢所有人试图帮助我,我非常感谢它,伟大的社区。