Array of random numbers as Object in java - java

I am new at java and want to ask you one question. So first what I have to do: My goal is to create different points in one area. I decided to create a class Koord for saving the coordinates of the points. I have used an array of 2 elements for this - for the x and y value. After that I added a random generator for x and y (they have to be random).
Here is my class:
import java.util.Random;
public class Koord {
private int number;
private static int numberOfNodes = 0;
public static int[] koord;
public Koord(int x, int y){
koord = new int[2];
koord[0] = x;
koord[1] = y;
number = ++numberOfNodes;
}
public int getNumber() {
return number;
}
public static int getNumberOfNodes() {
return numberOfNodes;
}
private static int randomFill(){
Random rand = new Random();
int randomNum = rand.nextInt(99);
return randomNum;
}
public int getX(){
return koord[0] = randomFill();
}
public int getY(){
return koord[1] = randomFill();
}
}
So, until now everything is OK. But now at my main class, I want to create some points and add them to a list. This is also not a problem. The problem starts when I want to print the coordinates of the points. As I am calling the methods getX() when I am printing the coordinates of the points in the list, I am getting different coordinates every time.
import java.util.LinkedList;
import java.util.ListIterator;
public class Display {
public static void main(String args[]) {
LinkedList<Koord> ownArea = new LinkedList<Koord>();
Koord point1 = new Koord(0, 0);
Koord point2 = new Koord(0, 0);
Koord point3 = new Koord(0, 0);
Koord point4 = new Koord(0, 0);
Koord point5 = new Koord(0, 0);
Koord point6 = new Koord(0, 0);
Koord point7 = new Koord(0, 0);
ownArea.add(point1);
ownArea.add(point2);
ownArea.add(point3);
ownArea.add(point4);
ownArea.add(point5);
ownArea.add(point6);
ownArea.add(point7);
System.out.println("ListIterator Approach: ");
ListIterator<Koord> listIterator = ownArea.listIterator();
while (listIterator.hasNext()) {
System.out.println(listIterator.next().getX());
}
System.out.println("ListIterator Approach: ");
ListIterator<Koord> listIterator2 = ownArea.listIterator();
while (listIterator2.hasNext()) {
System.out.println(listIterator2.next().getX());
}
}
}
So I know where the problem is, I know that this is wrong, but I don't know how to assign static coordinates to every point and how to print them. And I need this, because I want to operate with the coordinates (comparing them, printing them and so on). I know I have to learn a lot, but for now it will be very helpful, if you can give me some advice.

Since you are calling randomFill() every time you try to getX() or getY() It will be better to initialize every Koord object with the X and Y value already randomized.
Example:
Random rand = new Random();
LinkedList<Koord> ownArea = new LinkedList<Koord>();
Koord point1 = new Koord(rand.nextInt(99), rand.nextInt(99));
Koord point2 = new Koord(rand.nextInt(99), rand.nextInt(99));
ownArea.add(point1);
ownArea.add(point2);
for(Koord c : ownArea) {
System.out.println("x: " + c.getX() + " y: " + c.getY());
}
Also in your Koord class
The variable int[] koord should not be static and change
getX() and getY() to simply return the value.
In fact this would be a better approach
public class Koord {
private int number;
private static int numberOfNodes = 0;
private int x;
private int y;
public Koord(int x, int y) {
this.x = x;
this.y = y;
this.number = ++numberOfNodes;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getNumber() {
return number;
}
}

I think this is the problem
public int getX(){
return koord[0] = randomFill();
}
This makes the x random every time you call it!
Move all assignemts to the constructor, and make getX() work like an actual getter, ie. return x
I avoid posting code. You should figure it out yourself :)

You need to look at your getX() function. I have no idea why you're using randomFill() there, since it will continously return a random x value. If you want a random set of coordinates per point, but you only want them to be set once, I suggest calling randomFill() in the constructor.
public Koord() { // you don't need the x - y parameters if you're calling the random function anyways.
koord = new int[2];
koord[0] = randomFill();
koord[1] = randomFill();
number = ++numberOfNodes;
}
// you can now create points like so
Koord point1 = new Koord();
Koord point2 = new Koord();
Koord point3 = new Koord();
You'll also need to update your getX() (and getY()) :
public int getX() {
return koord[0];
}

Related

I'm trying to create random object using arrays and class with random locations?

I'm trying to create a game using classes, in which objects move to random locations and use arrays in order to add up in a random amount. Can someone help me to code this better as it isn't working? I'm using the software "Processing" by the way.
My Code
My Class
*final color ALIEN_COLOR = color(30, 100, 0);
PImage background;
int x=0; //global variable background location
Superhero hero1;
Alien [] invader1 = new Alien[8];
void setup(){
size(800,400);
background = loadImage("spaceB.jpg");
background.resize(width,height);
hero1 = new Superhero(10, height/2);
for(int i = 0; i < invader1.length; i++){
invader1[i] = new Alien();
invader1 = new Alien(width,300);
}
} // setup ends
void draw ()
{
drawBackground();
hero1.render();
invader1.render();
if(invader1.move() == false){
invader1 = new Alien(width, 500);
}
} // draw ends*
and object as:
***class Alien{
int x;
int y;
Alien(int x, int y){
this.x = x;
this.y = y;
}
void render(){
fill(ALIEN_COLOR);
rect(x, y, 50, 50);
}
boolean move(){
x = x - 1;
return (x >= 0);
}
}***
The error messages that I received are:
the constructor Alien() doesn't exist.
mismatch, Defenders.Alien doesn't match Defenders.Alien[]
You are calling invader1[i] = new Alien(); but you do not have no-arg constructor in Alien class. Declare a no-arg constructor in Alien class as follows to get rid of the issue:
Alien() {
// Put here some initialization code if needed else leave it as it is
}

pass array to a class as an argument

I am trying to pass an array to another class as an argument but keep getting the error
"error: incompatible types: Point cannot be converted to int[]"
the first portion of my code is:
public Circle(int n, int x, int y)
{
radius = n;
counter++;
center[0] = x;
center[1] = y;
Point center = new Point(center);
}
Point is the class that needs to have the array passed to it.
the second portion of code:
public class Point
{
private int xCord;
private int yCord;
public Point (int [] center)
{
xCord = center[0];
yCord = center[1];
This is unclear to me, however it should clearly cause an error in the circle class constructor.
center[0] = x; // center is an int array
center[1] = y;
Point center = new Point(center); // ?????
// ^^^ ^^^^ Duplicate variable names
Fix this by changing the name of the new Point variable.
Point center = new Point(center);
Duplicate variable
Change to
Point point = new Point(center);
You have to consider Object here. The variable name here is duplicate. As the center objects hold the array reference you cannot keep the same variable to hold the point object.
You can modify your code accordingly. Attached you sample code
public class Test {
public static void main(String[] args) {
Circle(1,2,3);
}
static void Circle(int n, int x, int y)
{ int center[] = new int[2];
//Do your operation and initialize the array
center[0] = 25;
center[1] = 26;
Point pointObject = new Point(center);
}
}
class Point
{
private int xCord;
private int yCord;
public Point (int [] center)
{
xCord = center[0];
yCord = center[1];
}
}

Call method on multidimensional array

Let's say I have a method like so:
public class ColoredPoint {
private final Color color;
private final int x;
private final int y;
public ColoredPoint(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public ColoredPoint(int x, int y, int color) {
this(x,y, new Color(color));
}
public int getX() {
return x;
}
}
Then I populate a single dimension array with some data like so for example:
public class DemoInput {
final static ColoredPoint[] test2 = new ColoredPoint[]
{ new ColoredPoint( 208, 324, -1 )
, new ColoredPoint( 154, 313, -1 )
, new ColoredPoint( 288, 316, -1 )
, new ColoredPoint( 312, 296, -1 )
}
How can I figure out the biggest x in the array? I have a method to get x from the ColoredPoint so this should be easy, right?
I know I can use a for-loop for this. I just don't now to to get the x from the ColoredPoint inside the array.
I want the x value of a ColoredPoint in the array called test2 in the class DemoInput so I thought:
DemoInput.test2.ColoredPoint.getX[i]
would do the trick but that doesn't work.
Can anyone help me out? Also, how would it work for a multidimensional array, like such:
allTests = new ColoredPoint[][]
{ test1
, test2
};
You need to first get a ColoredPoint element from the array (using the [] operator), and then call the getX() method on it:
x = DemoInput.test2[i].getX()
// Here -----------^
The same logic applies for a 2D array - using the [] operator will return a 1D array, on which you'll need to use the [] operator in order to get a ColoredPoint element:
x = DemoInput.allTests[i][j].getX()
// Here --------------^
Java streams are pretty useful for finding things like largest and smallest:
Arrays.stream(test2).mapToInt(ColoredPoint::getX).max();
Multi-dimensional is slightly less elegant:
Arrays.stream(allTests).map(Arrays::stream)
.flatMapToInt(test -> test.mapToInt(ColoredPoint::getX)).max();
This is a possible implementation
public class ColoredPoint implements Comparable<ColoredPoint> {
private final Color color;
private final int x;
private final int y;
public ColoredPoint(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public ColoredPoint(int x, int y, int color) {
this(x, y, new Color(color));
}
public int getX() {
return x;
}
#Override
public int compareTo(ColoredPoint o) {
return Integer.compare(this.x, o.x);
}
public static void main(String[] args) {
ColoredPoint[] test2 = new ColoredPoint[]{new ColoredPoint(208, 324, -1)
, new ColoredPoint(154, 313, -1)
, new ColoredPoint(288, 316, -1)
, new ColoredPoint(312, 296, -1)
};
Optional<ColoredPoint> maxColor = Arrays.stream(test2).max(ColoredPoint::compareTo);
maxColor.ifPresent(coloredPoint -> System.out.println("Max X = " + coloredPoint.getX()));
}
}
This is a Java 8 compatible solution.
Hope this helps!

New Instances of Objects Set to Identical Values

public class TriVal {
private static int x;
private static int y;
private static int z;
TriVal(int x, int y, int z) {
TriVal.x = x;
TriVal.y = y;
TriVal.z = z;
}
public int sum(TriVal p2) {
int a = Math.abs(TriVal.x + p2.x);
int b = Math.abs(TriVal.y + p2.y);
int c = Math.abs(TriVal.z + p3.z);
int sum = a + b + c;
return sum;
}
}
This is a piece of a constructor for an object that contains a set of 3 values.
However, I am writing a function that creates a new TriVal made by summing the x, y, and z, of two instances of this object.
So say we have
TriVal p1 = new TriVal(10, 10, 10);
TriVal p2 = new TriVal(20, 20, 20);
calling the function
p1.sum(p2)
(Which is included elsewhere in the class) should return 90.
However, it returns 120.
I am learning that upon creating a new instance of the TriVal Object, the previously defined p1 instance is somehow being set to the same values as p2, which explains the sum being 120.
I believe this error is located somewhere in my constructor, perhaps in the way I am updating values or declaring variables at the top of the class?
Any helpful tips would be appreciated, thank you!
private static int x;
private static int y;
private static int z;
You declared your instance member as static which will be same for all the instances. They store last assigned values. remove static and you'll be fine.
As #Orin pointed, you'll need to change the code a bit where you should bind your parameters to instance members.

Why is Color.colorToHSV and HSVToColor inaccurate?

I am writing an Android game. In the game, different colored blocks will fall to the ground. When two blocks with the same color are on top of each other, they will merge into one block that is in a darker color. However, I observed that the blocks with the same color do not merge sometimes. After some debugging, I found that they are actually in slightly different colors: -16757700 and -16757444. I used Color.colorToHSV and Color.HSVToColor to make the color darker as you can see in my code below (The checkLanded method). So I think there must be something wrong with those two hsv methods. Here is my code (Actually I don't think there is anything else wrong with the code, you can just look at the checkLanded method. But I pasted the other code because the problem might not be where I think it is. Just almost scroll to the bottom and you will see the checkLanded method):
package com.shades;
import android.graphics.Color;
import android.support.annotation.IntDef;
import com.shades.util.BlockView;
import com.shades.util.Timer;
import java.util.HashMap;
import java.util.Random;
public class Block {
private static Random r = new Random ();
private static HashMap<Integer, Float> colorValuesMap;
#IntDef ({LEFT, RIGHT})
public #interface Direction {}
public static final int LEFT = -1;
public static final int RIGHT = 1;
static {
colorValuesMap = new HashMap<> ();
colorValuesMap.put (4, 0.1F);
colorValuesMap.put (3, 0.3F);
colorValuesMap.put (2, 0.5F);
colorValuesMap.put (1, 0.7F);
colorValuesMap.put (0, 0.9F);
}
private int x;
private int y;
private int color;
protected Timer timer;
public int getX() {
return x;
}
public int getY() {
return y;
}
private void setY(int y) {
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
matrix[this.x][this.y] = null;
this.y = y;
matrix[this.x][this.y] = this;
BlockView.updateViews ();
}
private void setX(int x) {
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
matrix[this.x][this.y] = null;
this.x = x;
matrix[this.x][this.y] = this;
BlockView.updateViews ();
}
private void setXY (int x, int y) {
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
matrix[this.x][this.y] = null;
this.y = y;
this.x = x;
matrix[x][y] = this;
BlockView.updateViews ();
}
public int getColor () {
return color;
}
public Block(int x, int y) {
setXY (x, y);
this.y = y;
float[] hsv = new float[3];
hsv[0] = Game.getInstance ().getHueNumber ();
hsv[1] = 1F;
hsv[2] = colorValuesMap.get (r.nextInt (4));
color = Color.HSVToColor (hsv);
BlockView.updateViews ();
timer = new Timer (new Runnable () {
#Override
public void run() {
moveDown ();
}
}, 1000, true);
}
private void moveDown () {
//if reached bottom
if (getY () == Game.MATRIX_HEIGHT - 1) {
timer.stopTimer ();
Game.getInstance ().nextBlock (r);
return;
}
color = Game.getInstance ().getBlockViewMatrix ()[x][y].getColor ();
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
if (checkLanded (matrix[x][y + 1])) {
Game.getInstance ().nextBlock(r);
return;
}
setY (getY () + 1);
}
private boolean checkLanded(Block blockBelow) {
//if it can merge into another block
float[] currentHSV = new float[3];
Color.colorToHSV (color, currentHSV);//here is the possible inaccurate method
if (blockBelow != null &&
blockBelow.getColor () == color &&
currentHSV[2] != colorValuesMap.get (4)) {
Color.colorToHSV (blockBelow.getColor (), currentHSV);
currentHSV[2] -= 0.2F;
blockBelow.color = Color.HSVToColor (currentHSV); //here is the possible inaccurate method
selfDestroy ();
timer.stopTimer ();
//if the block below is not the block at the bottom
if (blockBelow.getY () != Game.MATRIX_HEIGHT - 1) {
blockBelow.checkLanded (Game.getInstance ().
getBlockMatrix ()[blockBelow.getX ()][blockBelow.getY () + 1]);
}
return true;
}
//if a block is touched
if (blockBelow != null &&
blockBelow.getColor () != color) {
timer.stopTimer ();
return true;
}
return false;
}
private void selfDestroy () {
Game.getInstance ().getBlockMatrix ()[x][y] = null;
BlockView.updateViews ();
}
private boolean checkPositionValid (int x, int y) {
return !(x < 0 || x >= Game.MATRIX_WIDTH ||
y < 0 || y >= Game.MATRIX_HEIGHT)
&& Game.getInstance ().getBlockMatrix ()[x][y] == null;
}
public void moveHorizontally (#Direction int direction) {
if (checkPositionValid (x + direction, y)) {
setX (x + direction);
}
}
}
Can anyone tell me whether Color.colorToHSV and Color.HSVToColor are inaccurate or where else did I do wrong?
Just to let you know, Game.getInstance().getHueNumber() returns 167 if that helps
I would probably create a custom color class for this, where I would keep the accurate color information and only converted to another format if needed for the output. The conversion woudn't matter in this case because the converted values wouldn't be used for comparisons.
Something similar to this should solve your problem:
class CustomColor {
private static final Random RANDOM = new Random();
private static final int DARKNESS_LEVEL_COUNT = 5;
private static final float[] DARKNESS_LEVELS = new float[] {0.9f, 0.7f, 0.5f, 0.3f, 0.1f};
private static final float SATURATION = 1f;
private float hue;
private int darknessLevel;
public CustomColor(float hue) {
this.hue = hue;
darknessLevel = RANDOM.nextInt(DARKNESS_LEVEL_COUNT - 1); // I'm guessing you don't create the darkest blocks
}
public int getColor() {
float[] hsv = new float[] {hue, SATURATION, DARKNESS_LEVELS[darknessLevel]};
return Color.HSVToColor(hsv);
}
public boolean equals(CustomColor other) {
return (hue == other.hue) && (darknessLevel == other.darknessLevel);
}
public boolean darken() {
darknessLevel++;
return darknessLevel == DARKNESS_LEVEL_COUNT - 1; // are we at max darkness?
}
}
I don't know how you pick hues, but you could probably use a similar array approach as with darkness here.
After some time, I found a solution for this. From #Cinnam 's comments, I know that HSV colors use floats and they are inaccurate. RGB is is not a good idea for me because I cannot easily know the hue.
According to Code Complete 2nd Edition by Steve McConnell, Section 12.3:
... One Effective approach is to determine whether the values are close enough. Typically, you'd write a equals() function that returns true if the values are close enough and false otherwise.
And I think that the two slightly different colors are "approximately equal" so I wrote a method like this:
private boolean intColorEquals(int color1, int color2) {
final int MAXIMUM_ERROR = 1000;
return Math.abs (color1 - color2) < MAXIMUM_ERROR;
}
private boolean floatEquals (float a, float b) {
final float MAXIMUM_ERROR = 0.05F;
return Math.abs (a - b) < MAXIMUM_ERROR;
}
And I replaced all the comparisons between colors and that between floats.
I really don't know whether an answer to my own question should be in a style like this. So if I did anything wrong, please tell me.

Categories

Resources