I have an enum that I would like to randomly select a value from, but not truly random. I would like some of the values to be less likely of being selected so far. Here is what I have so far...
private enum Type{
TYPE_A, TYPE_B, TYPE_C, TYPE_D, TYPE_E;
private static final List<Type> VALUES =
Collections.unmodifiableList(Arrays.asList(values()));
private static final int SIZE = VALUES.size();
private static final Random RANDOM = new Random();
public static Type randomType() {
return VALUES.get(RANDOM.nextInt(SIZE));
}
}
Is there an efficient way of assigning probabilities to each of these values?
Code found from here
several ways to do it, one of them, similar to your approach
private enum Type{
TYPE_A(10 /*10 - weight of this type*/),
TYPE_B(1),
TYPE_C(5),
TYPE_D(20),
TYPE_E(7);
private int weight;
private Type(int weight) {
this.weight = weight;
}
private int getWeight() {
return weight;
}
private static final List<Type> VALUES =
Collections.unmodifiableList(Arrays.asList(values()));
private int summWeigts() {
int summ = 0;
for(Type value: VALUES)
summ += value.getWeight();
return summ;
}
private static final int SIZE = summWeigts();
private static final Random RANDOM = new Random();
public static Type randomType() {
int randomNum = RANDOM.nextInt(SIZE);
int currentWeightSumm = 0;
for(Type currentValue: VALUES) {
if (randomNum > currentWeightSumm &&
randomNum <= (currentWeightSumm + currentValue.getWeight()) {
break;
}
currentWeightSumm += currentValue.getWeight();
}
return currentValue.get();
}
}
Here's a generic approach to choosing an enum value at random. You can adjust the probabilities as suggested here.
Assuming you have a finite number of values you could have a separate array (float[] weights;) of weights for each value. These values would be between 0 and 1. When you select a random value also generate another random number between and only select the value if the second generated number is below the weight for that value.
You can create an enum with associated data bby provding a custom constructor, and use the constructor to assign weightings for the probabilities and then
public enum WeightedEnum {
ONE(1), TWO(2), THREE(3);
private WeightedEnum(int weight) {
this.weight = weight;
}
public int getWeight() {
return this.weight;
}
private final int weight;
public static WeightedEnum randomType() {
// select one based on random value and relative weight
}
}
import java.util.*;
enum R {
a(.1),b(.2),c(.3),d(.4);
R(final double p) {
this.p=p;
}
private static void init() {
sums=new double[values().length+1];
sums[0]=0;
for(int i=0;i<values().length;i++)
sums[i+1]=values()[i].p+sums[i];
once=true;
}
static R random() {
if (!once) init();
final double x=Math.random();
for(int i=0;i<values().length;i++)
if (sums[i]<=x&&x<sums[i+1]) return values()[i];
throw new RuntimeException("should not happen!");
}
static boolean check() {
double sum=0;
for(R r:R.values())
sum+=r.p;
return(Math.abs(sum-1)<epsilon);
}
final double p;
static final double epsilon=.000001;
static double[] sums;
static boolean once=false;
}
public class Main{
public static void main(String[] args) {
if (!R.check()) throw new RuntimeException("values should sum to one!");
final Map<R,Integer> bins=new EnumMap<R,Integer>(R.class);
for(R r:R.values())
bins.put(r,0);
final int n=1000000;
for(int i=0;i<n;i++) {
final R r=R.random();
bins.put(r,bins.get(r)+1);
}
for(R r:R.values())
System.out.println(r+" "+r.p+" "+bins.get(r)/(double)n);
}
}
Here is another alternative which allows the distribution to be specified at runtime.
Includes suggestion from Alexey Sviridov. Also method random() could incorporate suggestion from Ted Dunning when there are many options.
private enum Option {
OPTION_1, OPTION_2, OPTION_3, OPTION_4;
static private final Integer OPTION_COUNT = EnumSet.allOf(Option.class).size();
static private final EnumMap<Option, Integer> buckets = new EnumMap<Option, Integer>(Option.class);
static private final Random random = new Random();
static private Integer total = 0;
static void setDistribution(Short[] distribution) {
if (distribution.length < OPTION_COUNT) {
throw new ArrayIndexOutOfBoundsException("distribution too short");
}
total = 0;
Short dist;
for (Option option : EnumSet.allOf(Option.class)) {
dist = distribution[option.ordinal()];
total += (dist < 0) ? 0 : dist;
buckets.put(option, total);
}
}
static Option random() {
Integer rnd = random.nextInt(total);
for (Option option : EnumSet.allOf(Option.class)) {
if (buckets.get(option) > rnd) {
return option;
}
}
throw new IndexOutOfBoundsException();
}
}
You can use EnumeratedDistribution from the Apache Commons Math library.
EnumeratedDistribution<Type> distribution = new EnumeratedDistribution<>(
RandomGeneratorFactory.createRandomGenerator(new Random()),
List.of(
new Pair<>(Type.TYPE_A, 0.2), // get TYPE_A with probability 0.2
new Pair<>(Type.TYPE_B, 0.5), // get TYPE_B with probability 0.5
new Pair<>(Type.TYPE_C, 0.3) // get TYPE_C with probability 0.3
)
);
Type mySample = distribution.sample();
Related
I want to produce unique values of Movie Object via Random. I wrote a code snippet but I'm not sure all values cannot be unique by using Random().
How can I do this process to produce all of these unique values?
Here is my code snippets shown below.
private static ArrayList<Movie> addMovies(ArrayList<Movie> movieList) {
for(int i=0;i<20;i++) {
Movie movie = new Movie();
movie.setId(defineMovieId());
movie.setTitle(defineMovieName(15));
movieList.add(movie);
}
return movieList;
}
public static String defineMovieName(int n) {
// chose a Character random from this String
String AlphaNumericString = "ABCÇDEFGHIİJKLMNOÖPQRSŞTUÜVWXYZ"
+ "abcçdefghıijklmnoöpqrsştuüvxyz";
StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; i++) {
int index
= (int)(AlphaNumericString.length()
* Math.random());
sb.append(AlphaNumericString
.charAt(index));
}
return sb.toString();
}
public static long defineMovieId() {
int max = 1000;
int min = 1;
int range = max - min + 1;
int res = (int) ( Math.random()*range) + min;
return res;
}
The methods which you have defined do not guarantee random IDs or random names. For guaranteed unique values, you can do the following:
For unique ID: create a static variable of AtomicLong type and use getAndIncrement()
For unique names: use UUID.randomUUID()
Demo:
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
public class Main {
static final long INITIAL_VALUE = 1000000;
static AtomicLong atomicLong = new AtomicLong(INITIAL_VALUE);
public static void main(String[] args) {
// Tests
System.out.println("10 random IDs:");
for (int i = 1; i <= 10; i++) {
System.out.print(defineMovieId() + " ");
}
System.out.println();
System.out.println("10 random movie names:");
for (int i = 1; i <= 10; i++) {
System.out.print(defineMovieName() + " ");
}
}
public static long defineMovieId() {
return atomicLong.getAndIncrement();
}
public static String defineMovieName() {
return UUID.randomUUID().toString().replace("-", "");
}
}
Output:
10 random IDs:
1000000 1000001 1000002 1000003 1000004 1000005 1000006 1000007 1000008 1000009
10 random movie names:
0c77d209fb624415af7100c3184b35a6 1262e50b680f4a738a607ff757f2b510 7b93c73d93b34db88fc99d1096c1ce84 cbb9c6c90fb8489dbd9c52d4ebdc2ca3 9ba1d409b32b4c55a7562d714aadc220 ec40b647f33a4fc6becc8c5741eb8bf7 c1fbb7bb77d1417c86c2064039f62dec 82b52fdae1d24602b5ee9becd73ba3ce 2d82d481282b4684b55c168e9d216f36 27b02bf63b054d32a0e43992a5fcb124
Random is not generate a series of unique numbers, just if get lucky.
Better use a static int field for id and increase it each time you need a new id.
//classes names are obvious fake since there are not any random involved, just an example
public class TestRandom {
static int id=0;
public static void main(String[] args)
{
TestRandom tr = new TestRandom();
RandomIdObj ro1 = tr.new RandomIdObj(tr.getNextId(),"obj_1");
RandomIdObj ro2 = tr.new RandomIdObj(tr.getNextId(),"obj_2");
System.out.println(ro1);
System.out.println(ro2);
}
public int getNextId()
{
return ++id;
}
class RandomIdObj
{
int id;
String name;
RandomIdObj(int id,String name)
{
this.id =id;
this.name = name;
}
public String toString()
{
return this.id+":"+this.name;
}
}
}
Output:
[unique_id,obj_name]
1:obj_1
2:obj_2
Final(?) edit:
Leonardo Pina's solution looks like what I needed. Thank you all for your input! My code is now:
public final class Roll {
private static final Random r1 = new Random();
private final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
And the implementation in the other class:
public class Damage {
Roll r;
Damage(Roll r) {
this.r = r;
}
public int damageOut() {
int a = r.getR(); //roll value
return a * 2; //test math on r
}
}
Edit:
Thank you for the responses. However, it seems my use of this method was not clear. Apologies! This is what I need:
Call Roll class, get e.g. "12"
OtherClass1 receives "12" from Roll via getter
OtherClass2 also receives "12" from Roll via getter
Call Roll class again, get a new random number, e.g. "48"
OtherClass1 receives "48" from Roll via getter
OtherClass2 also receives "48" from Roll via getter
Using the solutions provided, Roll creates a single random number and never creates a new one again. I need Roll to create random numbers on demand, and then share that random number with other classes. I do not want it to only generate one number and then stop. I hope this makes sense. Thank you for the responses so far!
I have searched for and read the other threads of a similar topic (including this one, which is how I tried to solve my problem), but the methods I have tried have failed. I need to create a single random value and then use that same value across multiple classes.
My random class:
public final class Roll {
private static final Random r1 = new Random();
private final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
And a class where I call for the static value from the random class:
public class OtherClass{
Roll roll = new Roll();
int r = roll.getR();
public int getR() {
return r;
}
}
When I call the getter from OtherClass, the value is different than the getter from Roll. I would expect them to be the same value.
I call the values for testing like so:
Roll roll = new Roll();
int r = roll.getR();
OtherClass other = new OtherClass();
int o = other.getR();
Any guidance would be greatly appreciated. Have a good day.
When you create a new instance of OtherClass you also create a new instance of Roll, therefore, the rolls are different.
You need to make sure you are getting the value R from the same object Roll.
This could be achieved by using a singleton pattern for the Roll class, or you could specify the Roll object you want to use to get values, this way you could have several rolls for different purposes. i.e.
Edit:
Answering your edit: to get a new number, you should update the value of r in the Roll class whenever you generate a new value, for example, instead of returning a value, the level() method could update the r variable:
public final class Roll {
private static final Random r1 = new Random();
// We now attribute a value to r uppon construction
private final int r;
public Roll() {
level();
}
// Whenever level() is called the value of r is updated
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
this.r = r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
class Game {
public static void main(String[] args) {
// Create the Roll obj
Roll myRoll = new Roll();
// Initialize the other objs with myRoll
Board board = new Board(myRoll);
Player player = new Player(myRoll);
// Do your comparison
int b = board.getRoll();
int p = player.getRoll();
// EDIT: get a new value
myRoll.level();
// Do your comparison once more
b = board.getRoll();
p = player.getRoll();
}
class Board {
Roll r;
Board(Roll roll) {
this.r = roll;
}
public int getRoll() {
return r.getR();
}
}
class Player {
Roll r;
Player(Roll roll) {
this.r = roll;
}
public int getRoll() {
return r.getR();
}
}
}
Probably the simplest way to make it work would be to field r in class Roll as static, so that the Roll class looks like this:
ublic final class Roll {
private static final Random r1 = new Random();
private static final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
Or second approach would be to make Roll class a singleton.
Edit:
Since you have changed the intent of the question, and from what I understand you should look into Observer design pattern. It may be helpful for your case.
As someone said in the comments, you should follow the singleton design pattern, meaning that your variable r should be unique across all Roll class instances. To do this, your code will have to look something like this:
public class RandomTest {
public static void main(String[] args) {
Roll roll = new Roll();
int r = roll.getR();
OtherClass other = new OtherClass();
int o = other.getR();
}
}
class Roll {
private static Random r1 = new Random();
private static int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
class OtherClass{
Roll roll = new Roll();
int r = roll.getR();
public int getR() {
return r;
}
}
How about sharing the Roll instance?
Roll roll = new Roll();
// roll.roll(); // Unclear how you "refresh" the data
int r = roll.getR();
OtherClass other = new OtherClass(roll);
int o = other.getR();
assert(o == r);
class OtherClass {
private final Roll roll;
public OtherClass(Roll roll) {
this.roll = roll;
}
public int getR() {
return roll.getR();
}
}
Tip: I think a Dice class with a roll() method makes more sense.
I'm trying to figure out how to randomize the object selected as a parameter in a method. So I created two Pokemon classes below (rattata and pidgey)
class WildPokemon {
private static int randomHealth(int min, int max) {
int range = (max - min) + 1;
return (int)(Math.random() * range) + min;
}
private static int randomAttack(int min, int max) {
int range = (max - min) + 1;
return (int)(Math.random() * range) + min;
}
private static int randomSpeed(int min, int max) {
int range = (max - min) + 1;
return (int)(Math.random() * range) + min;
}
static Pokemon rattata = new Pokemon("Rattata",randomHealth(15,20),randomAttack(2,5),randomSpeed(2,6));
static Pokemon pidgey = new Pokemon("Pidgey",randomHealth(10,17),randomAttack(3,4),randomSpeed(3,5));
}
Below I am able to call rattata in the method Pokemon.battle() and it functions as expected. Is there a way I could randomize my second parameter to where it could be either rattata or pidgey selected at random?
public class PokemonTester{
public static void main(String[] args){
Pokemon.battle(starter, WildPokemon.rattata);
}
}
Important remark : using static methods and static fields for model is generally not advised.
Instead you should create an instance of WildPokemon and call method on it.
Do it in the same way you have already done to calculate random values.
You should use a List of pokemon rather than doing the compute with two hard coded values.
Try this :
public class WildPokemon{
...
private Random rand = new Random();
private List<Pokemon> pokemonList;
...
public WildPokemon(){
pokemonList = new ArrayList();
Pokemon rattata = new Pokemon("Rattata",randomHealth(15,20),randomAttack(2,5),randomSpeed(2,6));
pokemonList.add(rattata);
Pokemon pidgey = new Pokemon("Pidgey",randomHealth(10,17),randomAttack(3,4),randomSpeed(3,5));
pokemonList.add(pidgey);
...
}
private Pokemon getRandomPokemon() {
int n = rand.nextInt(pokemonList.size());
return pokemonList.get(n);
}
...
}
And call it :
WildPokemon wildPokemon = new WildPokemon();
Pokemon.battle(starter, wildPokemon.getRandomPokemon());
Use an array (or list) of objects and randomly generate an index value.
public class PokemonTester{
public static void main(String[] args){
WildPokemon[] pokemons = { rattata, pidgey };
Pokemon.battle(starter, pokemons[ (int)(Math.random()*pokemons.length) ] );
}
}
So i am trying to build a genetic algorithm on java i stuck on getting
fitness of my population here 3 classes from my project:
Class Individu
public class Individu {
int Popsize=4;
int Health[]= new int[Popsize];
int Attack[]= new int[Popsize];
int Atspeed[]= new int[Popsize];
int Move[]= new int[Popsize];
int health,attack,lifetime,dmgdone,attspeed,range,move;
double fitness;
double Pitness[]= new double[20];
Random random = new Random();
public int setHealth(){
health = random.nextInt(150 - 75) + 75;
return health;
}
public int setAttack(){
attack = random.nextInt(10 - 5) + 10;
return attack;
}
public int setAttspeed(){
attspeed = random.nextInt(3 - 1) + 3;
return attspeed;
}
public int setMoveSpeed(){
move = random.nextInt(8 - 4) + 1;
return move;
}
public int getGeneHealth(int index) {
return Health[index];
}
public int getGeneAttack(int index) {
return Attack[index];
}
public int getGeneAtspedd(int index) {
return Atspeed[index];
}
public int getGeneMove(int index) {
return Move[index];
}
public void setGene(int index, int value) {
Health[index]=value;
Attack[index]=value;
Atspeed[index]=value;
Move[index]=value;
fitness = 0;
}
public int size() {
return Popsize;
}
public double[] GenerateIndividual(){
for (int i = 0; i <Popsize; i++) {
Health[i]=setHealth();
Attack[i]=setAttack();
Atspeed[i]=setAttspeed();
Move[i]=setMoveSpeed();
}
return Pitness;
}
Class Fitness
public class Fitness {
Individu individu= new Individu();
double fitness;
double Pitness[]= new double[20];
public double getFitness(){
individu.GenerateIndividual();
for (int i = 0; i <=3; i++) {
fitness=
individu.getGeneHealth(i)+individu.getGeneAtspedd(i)+
individu.getGeneAttack(i)+
individu.getGeneMove(i));
fitness=fitness/171;
Pitness[i]=fitness;
System.out.println("Health from class
fitness"+individu.Health[i]);
}
return fitness;
}
}
Main Class
public class main {
public static void main(String[] args) {
Individu aaa=new Individu();
Fitness bbb= new Fitness();
bbb.getFitness();
aaa.GenerateIndividual();
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(3);
for (int i=0; i<=3; i++){
//System.out.println("Fitness ");
System.out.println("Generasi ke :"+i+1);
System.out.println("Health "+aaa.getGeneHealth(i));
System.out.println("Attackspeed "+aaa.getGeneAtspedd(i));
System.out.println("Attack "+aaa.getGeneAttack(i));
System.out.println("movementSpeed "+aaa.getGeneMove(i));
}
}
}
What i struggle is when i run this script i got 2 double value from 1 variable first value is from Fitness class as i printed here
System.out.println("Health from class fitness"+individu.Health[i]);
and second variable i printed here from Main Class
System.out.println("Health "+aaa.getGeneHealth(i));
that 2 variable is always have different value causing my fitness and my generation is not correlated each other.
My question is how to make this 2 variable print same value?
Well, aside from the many problems I can detect about the essentials of Genetic Algorithms, I see 'individu' and 'aaa' are two different Java objects.
Individu aaa=new Individu();
aaa.GenerateIndividual();
and
Individu individu= new Individu();
individu.GenerateIndividual();
Since your Health and Fitness are randomly generated on GenerateIndividual(), both 'aaa' and 'individu' will get different Health values.
I strongly recommend you to review GA essentials, since I can see many conception errors in your system.
I am trying to do a pvp event in my game server which uses 3 zones to do it randomly. I use the following code but always is returning me the values 1 and 2 and repeated as well. I need some sequence like this for example: 3-2-1-2-1-3 or something that never repeats the same number.
int random = Rnd.get(1, 3);
if (random == 1)
{
setstartedpvpzone1(true);
}
if (random == 2)
{
setstartedpvpzone2(true);
}
if (random == 3)
{
setstartedpvpzone3(true);
}
this is what i get in 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;
}
}
and 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);
}
If all you are looking for is a random number that doesn't equal the previous one returned then the solution is much simpler:
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;
}
[not tested] It is possible that it may contain some syntax errors as I am not a Java programmer.
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);
}
Your problem boils down to a graph traversal in which from each current zone, you only have 2 possible next zones and those choices never change. So here is how I would implement it:
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;
}
}
You would call it like:
EventLocator eventLocator = MyProgram.EventLocator.getInstance();
System.out.println(eventLocator.getNextZone());
System.out.println(eventLocator.getNextZone());
This code never repeats any numbers, for example if you have 1,2,3 you can get a random sequence of 4 numbers, example 2,1,3.
Create an array with all numbers you need...
int[] a = {1, 2, 3};
Then select random items
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);
}
}
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);
}
hello finally i fixed using booleans and i get this secuence, 1-2-3-1-2-3-1-2-3-1-2-3 , i breaked my mind with it because is very confuse this code but it work now as a charm , thanks for all to try to help me i very appreciate it, great community.