001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package net.tridentsdk.world.gen; 018 019import net.tridentsdk.util.FastRandom; 020 021import javax.annotation.concurrent.ThreadSafe; 022 023/** 024 * Used to generate random values for world generators 025 * 026 * @author The TridentSDK Team 027 */ 028@ThreadSafe 029public class GeneratorRandom { 030 private final long seed; 031 private volatile long next; 032 033 /** 034 * Creates a new generator random using a random seed 035 */ 036 public GeneratorRandom() { 037 this(FastRandom.random()); 038 } 039 040 /** 041 * Creates a new seeded generator random 042 * 043 * @param seed the seed 044 */ 045 public GeneratorRandom(long seed) { 046 this.seed = seed; 047 this.next = seed; 048 } 049 050 // non-atomic bit ops, nice. 051 private long next() { 052 next ^= (next << 21); 053 next ^= (next >>> 35); 054 next ^= (next << 4); 055 return next; 056 } 057 058 /** 059 * Forks the random using a new random seed generated from this random 060 * 061 * @return the new generator random 062 */ 063 public GeneratorRandom fork() { 064 return new GeneratorRandom(next()); 065 } 066 067 /** 068 * Forks the random using the provided sed 069 * 070 * @param seed the seed to use 071 * @return the new generator random 072 */ 073 public GeneratorRandom fork(long seed) { 074 return new GeneratorRandom(seed); 075 } 076 077 /** 078 * Obtains the next long between 0 and the upper limit (inclusive) 079 * 080 * @param end the upper bound 081 * @return a random long 082 */ 083 public long under(long end) { 084 long random = next(); 085 return Math.abs(random % end); 086 } 087 088 /** 089 * Scales the next random long between the given min and max values 090 * 091 * <p>Helps smooth the random distribution curve</p> 092 * 093 * @param end the upper random bound 094 * @param min the minimum 095 * @param max the maximum 096 * @return the scaled random 097 */ 098 public long scaleUnder(long end, long min, long max) { 099 return (long) (((double) (max - min)) * ((under(end) + 1) / 2)) + min; 100 } 101 102 /** 103 * Obtains the seed used to generate the random longs 104 * 105 * @return the seed 106 */ 107 public long seed() { 108 return this.seed; 109 } 110}