Ok so basically, for some reason, the first array value of "a0" keeps on being chosen in the for loop math.random section. Why is it doing this and how can I fix it? (P.S., you don't have to read every single String array value)
public class Battleship extends JPanel
{
public static void main(String[] args)
{
String[][] pos = new String[10][10];
...
//we initialize pos here
...
int horcol = 0;
boolean[][] tof = new boolean[10][10];
boolean taken = false;
int vertcol = 0;
for(int k=0; k<=9;k++)
{
for(int l=0;l<=9;l++)
{
if(taken == false)
{
int random = (int)Math.random()*15;
if(random == 1 || random == 2)
tof[k][l] = true;
taken = true;
vertcol = k;
horcol = l;
}
else
{
tof[k][l] = false;
}
}
}
}
The problem here is remarkably simple.
The issue is with your parenthasis!
Currently you have this:
int x = (int)Math.random()*15;
So the computer will first do Math.random(), which will return a float between 0 and 1 (something ike 0.648294), then make that into an int, which will always be 0 because that truncates the number, then multiply by 15, which is still 0.
You need to add parenthesis around the Math.random()*15 part, like this:
int x = (int)(Math.random()*15);
That will first multiply the random value by 15, and THEN convert it to an int (and truncate in the process).
Related
I am not sure if it's rly possible to check but I have an issue rn where I have an array
let's say: int[] unmarkedSum = new int[100];
Now I put something in this array when a certain condition is true so not in every single iteration. But I know for a fact that at some point the whole array will be filled with any positive values that are not 0 because of how my algorithm works.
My question here is: Is there a way of checking WHEN it's fully filled?
Like I started like this:
for(int i = 0; i < unmarkedSum.length; i++) {
if(unmarkedSum[i] == 0 {
break;
}
else {
// idk tbh
}
}
In Java by default an array of ints is filled with zeros. You can use this to check if the array is fully filled. For example you can create a method which checks for 0 and returns true if there are no 0:
public static bool isArrayFilled(int[] array) {
for(int i = array.length; i >= 0; i--){
if(array[i] == 0) {
return false;
}
}
return true;
}
If array is big enough and filled out of order, you can use advanced algorithms to find at least one 0 value in the array.
I would simply maintain a variable size that keep tracks of how many values have been written to the array.
Example:
int size = 0;
int[] array = new int[100];
Random r = new Random();
while(size < array.length){
int index = r.nextInt(100);
int val = r.nextInt(1000)+500;
if (array[index] == 0){
array[index] = val;
size++;
}
}
System.out.println(Arrays.toString(array));
Per my previous comment, you can share this array with another thread so that one thread can fill the values and another can check the array at the same time. When the second thread finds that there are no default values (or 0s) then it can notify the first thread (or the main thread). Here is how you can do that
import java.util.Arrays;
import java.util.Random;
public class CheckArray {
public static void main(String[] args) throws InterruptedException {
var arr = new int[50];
Thread arrayChecker = new Thread(() -> {
var isZeroPresent = false;
while (true) {
for (int index = 0; index < arr.length; index++) {
isZeroPresent = false;
if (arr[index] == 0) {
isZeroPresent = true;
break;
}
}
if (isZeroPresent == false) {
// if the for loop completed then control will come here
System.out.println("Array has been filled");
System.out.println(Arrays.toString(arr));
System.exit(0);
}
}
});
arrayChecker.start();
// fill random values in the array
// while another thread has been started
Random random = new Random();
while(true) {
Thread.sleep(500);
int index = random.nextInt(arr.length);
arr[index] = random.nextInt(100);
System.out.println(Arrays.toString(arr));
}
}
}
So at the moment i am writing some code for my last comp sci paper, it requires you to red in some input on system.in, process it, first line is always a set of numbers upto 25 numbers. This is followed by a single N or L, and another int which is the aim. Using this input you have to find the the right set of operations (+ and *) that uses the int values to create the aim.
I am using a Boolean array to keep track of what operands i am using in very check however I'm unsure how to "brute force" the solution by trying every different set of operands, i have the code to check each set however Im not sure if there is an simple and easy way to change the array by such as [0,0,0,0] (0 is false) to [0,0,0,1], [0,0,1,0], [0,0,1,1] etc?
Im sure there is a really simple way i have overlooked but for the life of me i am unsure of what it is atm.
static boolean evlN(int[] input, boolean[]ops, int aim){
boolean run = true, found = false;
int[] used = new int[input.length];
int runs = 0 ,ans = 0;
while(!found && runs < (1 << ops.length)){
//finding all multiplys and doing them first
search:
for(int x = 0; x < ops.length; x++){
if(!ops[x]){
used[x] = input[x] * input[x+1];
//need to stop working out and change the ops
if(used[x] > aim){
run = false;
break;
}
}
}
//once multiplys have been done need to do all the adds
if(run){
for(int x = 0; x < ops.length; x++){
if(ops[x]){
if(used[x] != 0) ans += used[x] + input[x+1];
else if(used[x+1] != 0) ans += input[x] + used[x];
}
if(ans > aim) break;
}
}
if(ans == aim) found = true;
used = new int[input.length];
ans= 0;
runs++;
run = !run;
}
if(found) return true;
else return false;
}
this is what im using to work out each set of operands and numbers i just trying to change the boolean array to brute force the answer
Your set of input combinations looks like a binary integer (call it N). You can progress through the different combinations by incrementing N.
There is a fairly generic mechanism that can be used to increment through a set of combination, just as you would do for digits in an integer. I'll demonstrate it using an interface so you can see how it can be applied in general.
public interface UnitValue {
boolean isLast();
UnitValue next();
}
public class <T extends UnitValue> MultiUnitValue {
private final int size;
private final T first;
private final T[] units;
private boolean complete = false;
public MultiUnitValue(int size, T first) {
this.size = size;
this.first = first;
this.units = new T[size];
for (int i = 0; i < size; i++)
units[i] = first;
}
public void next() {
if (!complete) {
int i = 0;
while (units[i].isLast())
units[i++] = first;
units[i].next();
complete = i == size - 1 && units[i].isLast();
}
}
}
I've left out getters for clarity but they should be obvious.
For a non-generic solution for booleans it'd look like:
boolean[] values = new boolean[size];
int i = 0;
while (values[i])
values[i++] = false;
values[i] = true;
A very similar solution works for characters, digits, enums and anything else that fits the same pattern.
I am using an ArrayList of ArrayLists for a data structure to play a game of towers of hanoi. The game is constructed and initialized as follows:
private ArrayList<ArrayList> lists = new ArrayList<ArrayList>();
private ArrayList<Integer> peg1 = new ArrayList<Integer>();
private ArrayList<Integer> peg2 = new ArrayList<Integer>();
private ArrayList<Integer> peg3 = new ArrayList<Integer>();
//Constructor
public TowersOfHanoi() {
lists.add(null);
lists.add(peg1);
lists.add(peg2);
lists.add(peg3);
}
public ArrayList initializeGame(int n) {
for (int i = 0; i < n; i++) {
peg1.add(i+1);
}
return peg1;
}
}
I am trying to use a Boolean method to do a check and make sure the user doesn't try to move a larger disc on top of a smaller disc, however, I don't understand how I would grab the the integer value stored in the arrayList. The integer values should serve as a way to gauge the diameter of the discs. I.E. 1 is smaller than two is smaller than 3 etc. This is the code I have come up with... I believe I am just getting the indexes and not the actual values of the integers stored there. How can I get the actual values?
public boolean isMoveLegal(int moveFrom, int moveTo){
ArrayList<Integer> fromPeg = lists.get(moveFrom);
int x = (fromPeg.remove(0)).intValue();
ArrayList<Integer> toPeg = lists.get(moveTo);
int y = (toPeg.get(0)).compareTo(x);
if(x<y){
System.out.println("illegal move");
}
return false;
}
The problem with your code is that isMoveLegal does not have a path where it would return true: the only return statement returns false. You should change the return statement as follows:
return x >= y;
This line is wrong too:
int y = (toPeg.get(0)).compareTo(x);
rather than getting the actual value into y, you are storing the result of comparison of y to x, which is not something you should compare to x again.
Additionally, your check is invasive: it removes the disks at the top of your pegs (it is apparent from your code that the top of the tower corresponds to position zero; this is unorthodox, but you can certainly make it work).
Rather than using remove(0), you should use get(0) after checking that the peg's content is not empty.
If the "from" peg is empty, the move is invalid. If the "to" peg is empty, the move is valid. Otherwise, the regular comparison rules apply (i.e. a bigger disk cannot go on top of a smaller disk).
public boolean isMoveLegal(int moveFrom, int moveTo){
ArrayList<Integer> toPeg = lists.get(moveTo);
if (toPeg.isEmpty()) return true; // You can move anything on an empty peg
int y = toPeg.get(0).intValue();
ArrayList<Integer> fromPeg = lists.get(moveFrom);
if (fromPeg.isEmpty()) return false; // No disks on the "from" peg
int x = fromPeg.get(0).intValue();
if(x>y){
System.out.println("illegal move");
return false;
}
return true;
}
This,
int y = (toPeg.get(0)).compareTo(x);
should be something like
int y = (toPeg.size() > 0) ? toPeg.get(0).intValue() : -1;
Then you can use
if (x > y) { // <-- the reverse of like you were, because the to peg is y.
public boolean isMoveLegal(int moveFrom, int moveTo){
ArrayList<Integer> fromPeg = lists.get(moveFrom);
if(fromPeg != null && fromPeg.size() > 0) {
int x = fromPeg.get(0).intValue();
ArrayList<Integer> toPeg = lists.get(moveTo);
if(toPeg != null) {
if(toPeg.size() == 0) {
return true;
} else {
int y = toPeg.get(0).intValue();
if(x<y){
return true;
}
}
}
}
System.out.println("illegal move");
return false;
}
This question already has answers here:
Java generating non-repeating random numbers
(12 answers)
Closed 9 years ago.
I am trying to write a guessing game program where a 4 digit number is randomly generated. The numbers need to be unique (as in they do not repeat at any time) I am fairly new to Java and I am having trouble displaying the numbers in an array. Also I can't figure out a way to check a number against the others more than once. EX: If random number A is the same as random number B it will make a new random number A. But I dont know how to check if the NEW random A is the same as number B without writing the same code over and over and over. (clearly some kind of loop but I have no idea which kind)
import java.util.Random;
public class Game {
public static void main(String[] args) {
// TODO Auto-generated method stub
int rand1 = 0;
int rand2 = 0;
int rand3 = 0;
int rand4 = 0;
int[] randArray = new int[]{rand1, rand2, rand3, rand4};
Random randy = new Random();
int a = randy.nextInt(9);
int b = randy.nextInt(9);
int c = randy.nextInt(9);
int d = randy.nextInt(9);
//how to check the variable more than one time?
a = rand1;
if (b == a) {
b = randy.nextInt(9);
}
else rand2 = b;
if (c == a || c == b) {
c = randy.nextInt(9);
}
else rand3 = c;
if (d == a || d == b || d == c) {
d = randy.nextInt(9);
}
else rand4 = d;
System.out.print(randArray); //prints gibberish
//prints the numbers fine
//System.out.print(rand1);
//System.out.print(rand2);
//System.out.print(rand3);
//System.out.print(rand4);
}
}
You might first add the random numbers to a java.util.HashSet and then convert it to an array. This way you get rid of all duplicates.
How about using an ArrayList instead?
The syntax is different, but then you can do your program in a looping fashion.
For example:
ArrayList<Integer> randNums = new ArrayList();
while(randNums.size() != 4) {
int a = randy.nextInt(9);
if(false == randNums.contains(a))
randNums.add(a);
}
Edit to add a side note: ArrayList has the prettier printing you are looking for as well.
If you want to change your current array type to Integer instead of an int then i suggest you to take one of the other answers. My first instinct was to show you how clean, readable and simple it will be if you used ArrayList<Integer> and its power and then convert it to Integer[] again no int[].
At the end i decided to wrote you an answer, that may not be the most elegant and defentily not the shortest one, but it will teach you how to think right before you could use tools that will take those element off (ArrayList and its powers as we said).
The algorithm is quite simple.
You create int-array at the n size you needed.
You iterate over it from 0 to n and with every iteration you:
A. Creating a do-while loop that will generate a random number from 0-9.
B. Generate a random temp number from 0-9.
C. Iterating over your current readArray to look-up if the generated number is inside, and if so it will flag it and stop the look-up process (because we found that we already have it).
D. Will check if the flag isExists set as true, if so, then will go into step B again otherwise will go to step 3.
If we reached to the end of look-up(for) without changing flag to true, than the temp(generated number) is not at our current array, and it will be safe to add it.
Will check if we reach to the end of the array or there are more array cell to fill. i < readArray.length.
Code:
Random randy = new Random();
int[] readArray = new int[4];
for (int i = 0; i < readArray.length; i++) {
int temp;
boolean isExists;
do {
isExists = false;
temp = randy.nextInt(10);
for (int j = 0; j < i; j++)
{
if (readArray[j] == temp)
{
isExists = true;
break;
}
}
} while (isExists);
readArray[i] = temp;
}
System.out.println(Arrays.toString(readArray));
If you're OK with storing in memory an 'int' array of 10000 entries:
public class YourClass
{
private static int final SIZE = 10000;
private int[] array = new int[SIZE];
private int currIteration = 0;
private Random random = new Random();
public YourClass()
{
for (int i=0; i<SIZE; i++)
array[i] = i;
}
public int getRandVal()
{
int index = random.nextInt(SIZE-currIteration);
int val = array[index];
array[index] = array[SIZE-currIteration-1];
array[SIZE-currIteration-1] = val;
if (++currIteration == SIZE)
currIteration = 0;
return val;
}
}
For generating random unique integers
Use a Set to create a collection of unique values. Otherwise, for each random number generated, iterate over the array to ensure it's unique before adding it.
Integer[] createGuesses(int numGuesses, int low, int high)
{
Set<Integer> guesses = new HashSet<>();
Random rand = new Random();
while(guesses.size() < numGuesses)
guesses.add(low + rand.nextInt(high - low));
return guesses.toArray(new Integer[numGuesses]);
}
I am fairly new to java so this will probably seem like a basic question. I am trying to use the random java.util and nextInt to create a random number in a range specified by user input and then cast it as a character, to then be stored in an array;
gridCells[x][y] = (char)(r.nextInt(numberOfRegions) + 'a');
However, because I want nextInt to use user Input, and although im controlling the range of values, im guessing the error is caused because nextInt thinks numberOfRegions could be 0?
// Map Class
import java.util.Random;
public class map
{
// number of grid regions
private int numberOfRegions;
private boolean correctRegions = false
// grid constants
private int xCord = 13; // 13 so the -1 makes 12 for a 12x12 grid
private int yCord = 13;
// initiate grid
private int[][] gridCells = new int[xCord][yCord];
Random r = new Random();
map() { }
// ask for number of regions
public void regions()
{
keyboard qwerty = new keyboard(); // keyboard class
while(correctRegions = false)
{
System.out.print("Please enter the number of regions: ");
numberOfRegions = qwerty.readInt();
if(numberOfRegions < 2) // nothing less then 2 accepted
{
correctRegions = false;
}
else if(numberOfRegions > 4) // nothing greater then 4 accepted
{
correctRegions = false;
}
else
{
correctRegions = true;
}
}
}
// fills the grid with regions
public void populateGrid()
{
for(int x =0; x<gridCells[x].length-1; x++) // -1 to avoid outofboundsexception error
{
for(int y =0; y<gridCells[y].length-1; y++)
{
gridCells[x][y] = (char)(r.nextInt(numberOfRegions) + 'a');
}
}
}
public void showGrid()
{
for(int x=0;x<gridCells[x].length-1; x++)
{
for(int y=0; y<gridCells[x].length-1; y++)
{
System.out.print(gridCells[x][y] + " ");
}
System.out.println();
}
}
}
public void populateGrid()
{
for(int x =0; x<gridCells[x].length-1; x++) // -1 to avoid outofboundsexception error
{
for(int y =0; y<gridCells[y].length-1; y++)
{
gridCells[x][y] = (char)(r.nextInt(numberOfRegions) + 'a');
}
}
}
This is bogus, either you do index < array.length or index <= array.length-1.
index < array.length-1 is most likely not what you intended.
Also, if you get compilation errors, it is maybe because you did not initialize numberOfRegions. Normally, thats not an error but a warning, but maybe your compiler is set to issue an error in this case. Try
private int numberOfRegions = 0;
you have to know how the java.util.random works.
Random r = new Random();
int number = r.nextInt(numberOfRegions);
this will produce an integer from zero (0) to ur numberRegions.
to exclude zero from ur possible range of random number generated, do something like this
int number = 1 + r.nextInt(numberOfRegions);
with this, the minimum number that can be generated is 1
int number = 2 + r.nextInt(numberOfRegions);
with this, the minimum number that can be generated is 2
...and so on
Well I have found something:
Your while condition is an assignment:
while(correctRegions = false)
You should write:
while(correctRegions == false) // == is a boolean operator, = is an assignment