Sequence of random numbers without repeats - java

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.

Related

Java Bubble Sort method for Object's fields

I want to sort Token objects first based on their usedNumber bigger to smaller.
Then for the tokens have same usedNumber i want to sort them smaller to bigger based their priority number for example:
name priority usedNumber
a 1 3
b 2 4
c 3 0
d 4 3
e 5 3
f 6 4
Sorted version should be first bigger usedNumbers then smaller priorty:
b 2 4
f 6 4
a 1 3
d 4 3
e 5 3
c 3 0
Code below doesnt sort them correctly
public class Token {
int usedNumber;
int priority;
String name;
public Queue<Token> reversebubbleSort(Queue<Token> queue)
{
int n = queue.size();
int i;
int j;
Token temp;
boolean swapped;
for (i = 0; i < n - 1; i++)
{
swapped = false;
for (j = 0; j < n - i - 1; j++)
{
int namenumber1 = Integer.parseInt(queue.get(j).priority);
int namenumber2 = Integer.parseInt(queue.get(j+1).priority);
int number1 = queue.get(j).getUsedNumber();
int number2 = queue.get(j+1).getUsedNumber();
if (((number1^5)-namenumber1) < ((number2^5)-namenumber2))
{
// swap arr[j] and arr[j+1]
temp = queue.get(j);
queue.set(j, queue.get(j+1));
queue.set(j+1, temp);
swapped = true;
}
}
// IF no two elements were
// swapped by inner loop, then break
if (swapped == false)
break;
}
return queue;
}
Queue class in here is not from java.util. This is a class designed by me due the restrictions in my assigment. Queue class uses Arraylists to perform.
public class Queue<Token> {
private ArrayList<Token> queue;
public Queue() {
queue = new ArrayList<>();
}
public void add(Token addItem){
//In queues, adding in the back, first in first out.
queue.add(addItem);
}
public void removeFromFront(){
queue.remove(0);
}
public int size(){
return queue.size();
}
public Token get(int location){
return queue.get(location);
}
public void remove(int index){
queue.remove(index);
}
public void set(int location, Token setItem) {
queue.set(location, setItem);
}
}
}
Rather than wrapping ArrayList in your Queue, extend it: makes for simpler code
Don't use "Token" as a generic class name: it's confusing. Rather use the standard T
Which gives you code for Queue.java:
import java.util.ArrayList;
/*
* If it's only ever used for Token, it could also be
* public class Queue extends ArrayList<Token>
* and then you could override the sort method of ArrayList
* with the implementation shown in Token.sortSpecial below
*/
public class Queue<T> extends ArrayList<T> {
private static final long serialVersionUID = 1L;
public void removeFromFront() {
super.remove(0);
}
}
Method for sorting queues in class Token should be static: it's not linked to the state of an instance. I've renamed it sortSpecial. It also doesn't have to return, as the sorting is done in place on the Queue
Use List.sort with a custom Comparator to do the sorting
Fields should be private with getters and setters (which are not shown here)
Which gives you Token.java:
public class Token {
private String name;
private int priority;
private int usedNumber;
public Token(String name, int priority, int usedNumber) {
super();
this.usedNumber = usedNumber;
this.priority = priority;
this.name = name;
}
/* Getters and Setters go here */
/** Sort by usedNumber DESC / priority ASC */
public static void sortSpecial(Queue<Token> queue) {
queue.sort((x, y) -> {
int comp = -Integer.compare(x.usedNumber, y.usedNumber);
if (comp == 0)
comp = Integer.compare(x.priority, y.priority);
return comp;
});
}
#Override
public String toString() {
return getClass().getSimpleName() + "[" + name + " (p=" + priority + ", un=" + usedNumber + ")]";
}
}
Or if you want to play smart-ass, you could write the comparator as a one-liner (after defining your getters):
Comparator.comparingInt(Token::getUsedNumber).reversed().thenComparingInt(Token::getPriority)
Entry point for your program (Main.java):
public class Main {
public static void main(String[] args) {
Queue<Token> toks = new Queue<>();
toks.add(new Token("a", 1, 3));
toks.add(new Token("b", 2, 4));
toks.add(new Token("c", 3, 0));
toks.add(new Token("d", 4, 3));
toks.add(new Token("e", 5, 3));
toks.add(new Token("f", 6, 4));
System.out.println("Input:");
toks.stream().forEach(t -> System.out.println('\t' + t.toString()));
System.out.println();
Token.sortSpecial(toks);
System.out.println("Output:");
toks.stream().forEach(t -> System.out.println('\t' + t.toString()));
}
}
Console output:
Input:
Token[a (p=1, un=3)]
Token[b (p=2, un=4)]
Token[c (p=3, un=0)]
Token[d (p=4, un=3)]
Token[e (p=5, un=3)]
Token[f (p=6, un=4)]
Output:
Token[b (p=2, un=4)]
Token[f (p=6, un=4)]
Token[a (p=1, un=3)]
Token[d (p=4, un=3)]
Token[e (p=5, un=3)]
Token[c (p=3, un=0)]

implementing another class to create the first 100 prime numbers

ok I'm a little mind blown from an assignment i have to do. We have to implement a sequence class from wiley.com/go/javaexamples (the chapter 10 example) to make a new class called PrimeSequence and it has to right align the first 100 prime sequence numbers. I don't understand the point of implementing the other class and i did it but i know im not following the assignment rules because i dont understand what im supposed to implement from the other class and i also use nothing from the other class. I'm not sure on what i have to do
Sequence Class
public interface Sequence
{
int next();
}
PrimeSequence Class
public class PrimeSequence implements Sequence
{
public PrimeSequence()
{
}
public boolean isPrime(int x)
{
for (int start = 2; start <= Math.sqrt(x); start++)
{
if (x % start == 0)
{
return false;
}
}
return true;
}
public int next()
{
}
}
PrimeSequenceTester
public class PrimeSequenceTester {
public static void main(String[] args)
{
PrimeSequence prime = new PrimeSequence();
int currentNumber = 2;
int primesFound = 0;
while (primesFound < 100) {
if (prime.isPrime(currentNumber))
{
primesFound++;
System.out.printf("%4s",currentNumber + " ");
if (primesFound % 10 == 0)
{
System.out.println();
}
}
currentNumber++;
}
}
Here is a sample implementation using a Sieve of Eratosthenes (sieving only the odd numbers) and optimised to only sieve numbers once across multiple instances of the sequence. You need to do something a LOT simpler and just keep a track of what the current prime is and override the next() function so that when it is called you keep incrementing the value of the current prime until your isPrime() function returns true and then return that value.
import java.util.BitSet;
public class PrimeSequence implements Sequence {
private static final BitSet OddPrimeSieve = new BitSet( 8000 );
private static int MaxSievedPrime = 2;
static {
OddPrimeSieve.set(0, OddPrimeSieve.size() - 1, true );
}
private static int PrimeToIndex( final int prime ){
return (prime - 3) / 2;
}
private static int IndexToPrime( final int index ){
return 2*index + 3;
}
private static synchronized void setMaxSievedPrime( final int max ){
MaxSievedPrime = max;
for ( int index = PrimeToIndex( MaxSievedPrime ) + MaxSievedPrime;
index < OddPrimeSieve.length();
index += MaxSievedPrime )
OddPrimeSieve.set( index, false );
}
int currentPrime = 2;
#Override
public synchronized int next() {
final int current = currentPrime;
if ( current == 2 )
{
currentPrime++;
}
else
{
if ( currentPrime > MaxSievedPrime )
setMaxSievedPrime( currentPrime );
currentPrime = IndexToPrime( OddPrimeSieve.nextSetBit( PrimeToIndex( currentPrime ) + 1 ) );
}
return current;
}
public static void main( final String[] args ){
PrimeSequence p = new PrimeSequence();
for ( int i = 0; i < 100; i++ )
System.out.println( p.next() );
}
}

How to sort an array when it is filled with numbers from a get method

Arrays.sort() gives and error of:
FiveDice.java:19: error: no suitable method found for sort(int)
Arrays.sort(compNums);
If I take anything out of the for loop, it thinks thee is only 1 number or gives an error. What other sorting options would be usable?
import java.util.*;
public class FiveDice {
public static void main(String[] args) {
int x;
int compNums = 0;
int playerNums;
Die[] comp = new Die[5];
Die[] player = new Die[5];
System.out.print("The highest combination wins! \n5 of a kind, 4 of a kind, 3 of a kind, or a pair\n");
//computer
System.out.print("Computer rolled: ");
for(x = 0; x < comp.length; ++x) {
comp[x] = new Die();
compNums = comp[x].getRoll();
//Arrays.sort(compNums); <--does not work
System.out.print(compNums + " ");
}
//player
System.out.print("\nYou rolled: \t ");
for(x = 0; x < player.length; ++x) {
player[x] = new Die();
playerNums = player[x].getRoll();
System.out.print(playerNums + " ");
}
}
}
die class
public class Die {
int roll;
final int HIGHEST_DIE_VALUE = 6;
final int LOWEST_DIE_VALUE = 1;
public Die()
{ }
public int getRoll() {
roll = ((int)(Math.random() * 100) % HIGHEST_DIE_VALUE + LOWEST_DIE_VALUE);
return roll; }
public void setRoll()
{ this.roll = roll; }
}
Easiest way is to implement Comparable to Die class , set value of roll in constructor of Die not in the getter method and your problem is solved.
public class Die implements Comparable<Die> {
private int roll;
final int HIGHEST_DIE_VALUE = 6;
final int LOWEST_DIE_VALUE = 1;
public Die() {
roll = ((int)(Math.random() * 100) % HIGHEST_DIE_VALUE + LOWEST_DIE_VALUE);
}
public int getRoll() {
return roll;
}
public void setRoll(int roll) {
this.roll = roll;
}
public int compareTo(Die d) {
return new Integer(d.getRoll()).compareTo(new Integer(this.getRoll()));
}
}
now Arrays.sort(Die[]) will sort the array of Die.
You don't have to use 2 arrays for the sorting. If you implement the Comparable<T> interface, your classes can be sorted by Java Collections API. In your case, Die class can implement Comparable<T> and provide a way for the Java framework to compare dice values.
Take a look at the Java API:
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
In your case:
public class Die implements Comparable<Die>{
int roll;
final int HIGHEST_DIE_VALUE = 6;
final int LOWEST_DIE_VALUE = 1;
public Die() { }
public int computeRoll() {
roll = ((int)(Math.random() * 100) % HIGHEST_DIE_VALUE + LOWEST_DIE_VALUE);
return roll;
}
// I also changed this to store the value
public int getRoll() {
return roll;
}
public void setRoll() { this.roll = roll; }
// This is the method you have to implement
public int compareTo(Die d) {
if(getRoll() < d.getRoll()) return -1;
if(getRoll() > d.getRoll()) return +1;
if(getRoll() == d.getRoll()) return 0;
}
}
Whenever you have a Collection of Dies, like an ArrayList or LinkedList, you simply sort the collection itself. Below is a sample code.
ArrayList<Die> myCollection = new ArrayList<Die>();
myCollection.add(die1);
// more array population code
// ...
Collections.sort(myCollection);
You can't perform sort() on compNums because it is a single value. You declare it as an int value, rather than as an array of integers.
Instead, you should make compNums an array, populate it with the Die roll values, and then perform a sort operation on the resultant array. I believe the following will achieve what you are after.
int[] compNums = new int[5];
...
for(x = 0; x < comp.length; ++x) {
comp[x] = new Die();
compNums[x] = comp[x].getRoll();
}
Arrays.sort(compNums);
// print results
you must pass an array to the Array.Sort(arr) not parameter you must do something like this Array.Sort(int[]compNums);
and if you are using a anonymous type like comp[]compNums you must do it like this
java.util.Arrays.sort(comp[]compNums, new java.util.Comparator<Object[]>() {
public int compare(Object a[], Object b[]) {
if(something)
return 1;
return 0;
}
});

implementing a loop using final variables

Is there a way to implement a loop using final variables?
I mean a loop that would run for a specified number of iterations when you are not allowed to change anything after initialization!
Is recursion allowed, or do you literally need a loop construct like for or while? If you can use recursion, then:
void loop(final int n) {
if (n == 0) {
return;
} else {
System.out.println("Count: " + n);
loop(n-1);
}
}
One way is to create an Iterable<Integer> class representing an arbitrary range (without actually having to store all of the values in a list):
public static class FixedIntRange implements Iterable<Integer> {
private final int min;
private final int max;
public FixedIntRange(final int min, final int max) {
this.min = min;
this.max = max;
}
#Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private Integer next = FixedIntRange.this.min;
#Override
public boolean hasNext() {
return next != null;
}
#Override
public Integer next() {
final Integer ret = next;
next = ret == max ? null : next + 1;
return ret;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
and then iterate over it normally:
for (final int i : new FixedIntRange(-10, 20)) {
// this will be run for each i in the range [-10, 20]
}
Create an array whose size is the required number of iterations, then use it in a for-each loop:
public class Test {
public static void main(String[] args) {
final int N = 20;
final int[] control = new int[N];
for(final int i : control){
System.out.println(i);
}
}
}
The trick here is that the iteration indexing is generated by the compiler as part of the enhanced for statement, and does not use any user-declared variable.
Something like this -
final int max = 5;
for(int i=0; i<max; i++) {}
Or another interesting one-
final boolean flag = true;
while(flag) {
// keep doing your stuff and break after certain point
}
One more-
List<String> list = ......
for(final Iterator iterator = list.iterator(); iterator.hasNext(); ) {
}

Random math questions generator for Android

Any help or advice would be greatly appreciated. I'm trying to create a simple game which generates ten different, random questions. The questions can contain 2, 3 or 4 integers. So something like this: 55 2 − 4 − 101, 102/3/3, 589 − 281, 123 + 5 6 + 2.
The question will be displayed in a textview and then the user can take a guess, entering values into an edittext and then upon clicking a key on a custom keypad I have created it will check the answer, and then display the next question in the sequence of 10.
I know how to create random numbers, just struggling to work out how to create a whole question with random operators (+, -, /, *).
Big thank you to anyone who has the time to construct a reply.
A little of spare time produced a complete example for your case. Create new RandomMathQuestionGenerator.java file and it is cooked for compilation.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public class RandomMathQuestionGenerator {
private static final int NUMBER_OF_QUESTIONS = 10;
private static final int MIN_QUESTION_ELEMENTS = 2;
private static final int MAX_QUESTION_ELEMENTS = 4;
private static final int MIN_QUESTION_ELEMENT_VALUE = 1;
private static final int MAX_QUESTION_ELEMENT_VALUE = 100;
private final Random randomGenerator = new Random();
public static void main(String[] args) {
RandomMathQuestionGenerator questionGenerator = new RandomMathQuestionGenerator();
List<Question> randomQuestions = questionGenerator.getGeneratedRandomQuestions();
for (Question question : randomQuestions) {
System.out.println(question);
}
}
public List<Question> getGeneratedRandomQuestions() {
List<Question> randomQuestions = new ArrayList<Question>(NUMBER_OF_QUESTIONS);
for (int i = 0; i < NUMBER_OF_QUESTIONS; i++) {
int randomQuestionElementsCapacity = getRandomQuestionElementsCapacity();
Question question = new Question(randomQuestionElementsCapacity);
for (int j = 0; j < randomQuestionElementsCapacity; j++) {
boolean isLastIteration = j + 1 == randomQuestionElementsCapacity;
QuestionElement questionElement = new QuestionElement();
questionElement.setValue(getRandomQuestionElementValue());
questionElement.setOperator(isLastIteration ? null
: Operator.values()[randomGenerator.nextInt(Operator.values().length)]);
question.addElement(questionElement);
}
randomQuestions.add(question);
}
return randomQuestions;
}
private int getRandomQuestionElementsCapacity() {
return getRandomIntegerFromRange(MIN_QUESTION_ELEMENTS, MAX_QUESTION_ELEMENTS);
}
private int getRandomQuestionElementValue() {
return getRandomIntegerFromRange(MIN_QUESTION_ELEMENT_VALUE, MAX_QUESTION_ELEMENT_VALUE);
}
private int getRandomIntegerFromRange(int min, int max) {
return randomGenerator.nextInt(max - min + 1) + min;
}
}
class Question {
private List<QuestionElement> questionElements;
public Question(int sizeOfQuestionElemets) {
questionElements = new ArrayList<QuestionElement>(sizeOfQuestionElemets);
}
public void addElement(QuestionElement questionElement) {
questionElements.add(questionElement);
}
public List<QuestionElement> getElements() {
return questionElements;
}
public int size() {
return questionElements.size();
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (QuestionElement questionElement : questionElements) {
sb.append(questionElement);
}
return sb.toString().trim();
}
}
class QuestionElement {
private int value;
private Operator operator;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Operator getOperator() {
return operator;
}
public void setOperator(Operator operator) {
this.operator = operator;
}
#Override
public String toString() {
return value + (operator == null ? "" : " " + operator.getDisplayValue()) + " ";
}
}
enum Operator {
PLUS("+"), MINUS("-"), MULTIPLIER("*"), DIVIDER("/");
private String displayValue;
private Operator(String displayValue) {
this.displayValue = displayValue;
}
public String getDisplayValue() {
return displayValue;
}
}
Run and preview. Hope this helps.
Thanks to:
Generating random number in
range
Retrieving random
element from array
Create an array char[] ops = { '+', '-', '/', '*' } and create a random int i in range [0,3], and chose ops[i]
You will need to take care that you do not generate a divide by zero question.
You can make it even more generic by creating an interface MathOp and creating 4 classes that implement it: Divide, Sum , ... and create an array: MathOp[] ops instead of the char[]
Using this, it will also give you much easier time to check the result later on...
Put your operators in an array (4 elements), generate a random integer from 0 to 3, and pick the operator that is at this index in the array.
Do that each time you need to have a random operator, i.e. after every number of your question except the last one.
Make an array that has one entry for each of the operators. Then generate a random number between 0 and the length of the array minus 1.
So since each operation is binary you can just worry about figuring out the base case and then building up your expressions from there.
An easy way would just to select a random number an correlate that which operation will be used.
int displayAnswer(int leftSide, int rightSide, int operation {
int answer;
string operation;
switch(operation) {
case 1:
operation = "+";
answer = leftSide + rightSide;
break;
case 2:
operation = "-";
answer = leftSide - rightSide;
break;
case 3:
operation = "*";
answer = leftSide * rightSide;
break;
case 4:
operation = "/";
answer = leftSide / rightSide:
break;
}
textView.setText(leftSide + operation + rightSide);
return answer;
}

Categories