tile disappearing from rubiks cube with rotation - java

I'm working on a 2x2 rubik cube, and was having trouble getting one side rotate with my program. The cube is a 2d array of squares. I'm just triying to do a 90 degree counter clockwise turn.
This is what happens
https://imgur.com/a/tlskNKY
I changed the colour so I could see the specific squares and how they changed. I tried changing the order, moving specific pieces at a time to see if the problem was just overlapping pieces (no such luck).
//square class
public class square implements Comparable {
int c;
private Rectangle r;
int xpos, ypos, width, height;
public square(int a, int x, int y) {
c = a;
xpos = x;
ypos = y;
r = new Rectangle(xpos, ypos, 50, 50);
}
//some unused methods
}
//inside the cube class
public class cube{
square[] temp = new square[4]
square[][] sq= new square[6][4]
//two for loops make squares and fills the sq 2d array
//the result is in the imgur link
public void turnVc(){
temp= sq[2];
sq[2][0]=temp[1];
sq[2][1]=temp[3];
sq[2][2]=temp[2];
sq[2][3]=temp[0];
}
}
I expect the output to be the original image turned counter clockwise.

tmp is a pointer that points to the same object that sq[2] pointers. That's why when you change sq[2] content, you change tmp's as well.
i think instead of assign "temp= sq[2];" you should do the following:
temp = new square[4];
for (int i = 0; i < 4; i++) {
temp[i] = sq[2][i];
}
Edit:
i think a little improvement you could do is that you don;t need to save all the sq[2] array, you could only save the fist item. i would do like this (tmp is now a square, not an array):
tmp = sq[2][0];
sq[2][0] = sq[2][1];
sq[2][1] = sq[2][3];
sq[2][3] = sq[2][2];
sq[2][2] = tmp;

If your square class implements Cloneable, you should use clone() method possible, it is also similar to answer of #Nguyen Tan Bao, but shorter
I guess you 're C++ dev, reference in Java is like pointer in C++, you can research more Have fun !

Related

How can I get the different results as I put the number?

I wanna get the different results as the inputted number.
For example, when I put 4 I get the results of the rectangle and when I put 3 I get the triangle.
import java.util.Scanner;
public class Source9_1 {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x, y; // 클래스 Parameter(내부 변수)
Point[] v = new Point[n]
for(int i=0; i <= v.length; i++) {
v[i] = new Point();
v[i].
}
}
class Point {
int x, y; // 클래스 Parameter (내부 변수)
public void setPoint(int x, int y) { // Point 세팅
this.x = x;
this.y = y;
}
public void printPoint() { // Point 출력
System.out.println("x = " + x + ", y = " + y);
}
}
class Rectangle extends Point {
Point[] p = new Point[4];
Rectangle(Point[] p) {
this.p = p;
}
}
class Triangle extends Point {
Point[] p = new Point[3]; // 3개의 Point인스턴스를 담을 배열 생성
Triangle(Point[] p) {
this.p = p;
}
}
class Shape extends Point { // Point 배열 및 상속을 받아 세팅 후 출력가능한 클래스
Point coord[10];
static int s = 0; // 불릴 때마다 값 증가 ???
public void printShapePoint() { // 배열에 담은 Point 출력
}
public void setShapePoint() { // 배열에 담기 위해 Point 증가
}
}
So far, I coded like this but I don't know what to do now.
How can I get the different result as I put the number?
This is the result what I want
First of all, about your Rectangle and Triangle classes. I feel like you have missed your point there (pun not intended), because you've put both extending the Point class. That doesn't make much sense, since you have the Shape class, which would do a much better job as the superclass for them.
So:
class Rectangle extends Shape {
...
}
class Triangle extends Shape {
...
}
With that out of the way, what you have so far:
You are capturing the number of points from the input;
You are creating an array of that size;
You are instantiating and setting an Point object for each of the array positions.
What you need to do next:
Capture the points coordinates from the input
Set said coordinates to the Point objects
Instantiate an Triangle or Rectangle object, depending on how many points you have.
So, inside your for statement you will want to do:
for (int i=0; i <= v.length; i++) {
v[i] = new Point();
x = sc.nextInt(); // Save 'x' value into the variable
y = sc.nextInt(); // Save 'y' value into the variable
v[i].setPoint(x, y); // Set both values using the method from Point
}
Then, since both Rectangle and Triangle have Shape as a common superclass, you are allowed to put objects of either one of these class in a Shape variable. So right after the for statement you will want to do:
Shape s; // Create the empty variable here, so it will exist outside the if-else scope
if (n == 3)
s = new Triangle(v);
else
s = new Rectangle(v);
Finally, just print your points:
for (int i = 0; i < v.length; i++)
v[i].printPoint();
And that's pretty much it.
The answer from Pedro is great. I have an additional suggestion to make. Using a switch or conditional to create the different types of shapes is a bit of a code smell. I suggest using an abstract factory for this. I put up a little example of how you could do this here.
Deducing the shape from the number of points might be insufficient. For instance, a rectangle is defined by two points (not four) and so would a line, even though you are not currently modeling lines.
I think it would be more clear to select the shape by name and use a factory to instantiate it from the entered points.
Note that he shapes object hierarchy is used a lot to explain object orientation. There are several pitfalls with designing class structures like this. See for example this article. Keep in mind also the Liskov Substitution principle which is easily violated, see this article.

Objects dissappearing from array in java

I'm making a game similar to agar.io where a blob goes around and eats dots. I'm making it on my phone and you control the blob with your finger to collect the dots. I noticed that when I collect a single dot some random other dots dissappearing as well. I debugged some and found out that unless you collected the dots in the order that they were added to the array, any dot with a lower array order would be destroyed. Example: if you collected the dot added to the array 7th then dots 0-6 would dissappear, bit if you collected 1 then 2 and so on then no other dots would dissappear randomly. I created another simpler example to explore this problem. Now it's a simple screen with 5 circles. You can pick up and drag and drop any circle. I noticed the same problem where you drag a circle and other circles randomly dissappear even though there is no code to make them dissappear. My code is as follows:
// Drag n' Drop //
Objects[] box;
int objCount = 5;
void setup() {
box = new Objects[objCount];
for (int i = 0; i < objCount; i++){
box[i] = new Objects(random(displayWidth),random(displayHeight),200);
}
}
void draw() {
background(170);
for (Objects boxes : box) {
boxes.display();
boxes.dragging();
}
}
class Objects {
float x, y;
float s;
Objects(float tempX, float tempY, int tempS) {
x = tempX;
y = tempY;
s = tempS;
}
void display() {
ellipse(x, y, s, s);
}
void dragging() {
if (dist(x, y, mouseX, mouseY) < 500) {
x = mouseX;
y = mouseY;
s = 300;
}
}
}
I believe my problem may lie in the loop I use to call the display function of the box object, but I cannot find out any other way to make it work. Any help us very much appreciated. Thank you for your time. PS Im using processing to run this code.
Kelton
Firstly, I'd like to thank you for I have never played with Processing before and you inspired me to download it!
There are quite a few things wrong that I'd like to point out and maybe steer you in the right direction. The main issue lies within your dragging() method you are not actually removing the objects you are just moving them to your mouse position, giving you the illusion they are being removed!
Anyway, as you said you were creating the game Agar.io, I would assume that you yourself should have your own Blob. For the sake of my Java brain I have switched what you called Objects to Blobs.
First off, the setup.
import java.util.*;
public static final int BLOB_COUNT = 10;
List<Blob> blobs = new ArrayList<Blob>();
// this is our blob, the one that displays in the middle of the screen
Blob myBlob = new Blob(mouseX, mouseY, 50);
void setup() {
size(1000, 500);
for (int i = 0; i < BLOB_COUNT; i++){
blobs.add(new Blob(random(displayWidth/2),random(displayHeight/2),50));
}
}
Notice how I am using ArrayLists rather than an array, this will make it easier for you to add and remove from the List.
Next, the draw() so this happens each frame.
void draw() {
background(170);
// refreshes the players blob wherever the cursor is!
myBlob.setX(mouseX);
myBlob.setY(mouseY);
myBlob.display();
// display the other blobs on the screen
for (Blob boxes : blobs) {
boxes.display();
boxes.dragging();
}
}
Notice, we want to update our blob to the current position of the mouse!
Lastly, the Blob class!
class Blob {
float x, y;
float size;
Blob(float tempX, float tempY, int size) {
this.x = tempX;
this.y = tempY;
this.size = size;
}
void display() {
ellipse(x, y, size, size);
}
void dragging() {
if (dist(x, y, mouseX, mouseY) < myBlob.getSize()/2) {
myBlob.setBlobSize(25);
this.x = random(displayWidth/2);
this.y = random(displayHeight/2);
}
}
void setX(float x){
this.x = x;
}
void setY(float y) {
this.y = y;
}
void setBlobSize(float size) {
this.size += size;
}
float getSize() {
return this.size;
}
}
So now, we check in the dragging() method whether the blob is close to our blob, and if it is we want to consume that blob (which increases our mass) and then we want that blob to re-spawn to another location, well that's how most Agar.io games work, but of course this is entirely up to you. There is also much more accurate ways to calculate the area of the blob and determine whether two blobs are within touching distance, but I'll leave the maths to you.

Draw and get OpenSimplexNoise result

I want to generate a random terrain with OpenSimplexNoise. To start I just want to get a result and draw it to a window.
My question is now: How can I get the correct output of OpenSimplexNoise (cause there are many methods and I just don't know which is the correct one) and how to draw this result.
It should look like this:
public double[][] generateMap(long seed, int width, int height) {
double[][] map = new double[width][height];
// start generating things here, just how?
OpenSimplexNoise simplex = new OpenSimplexNoise(seed);
return map;
}
public void drawMap(double[][] map, Graphics g) {
for(int x = 0; x < map.length; x++) {
for(int y = 0; y < map[0].length; y++) {
Color color = new Color(); // how to get the color here?
}
}
}
This is the current code I've got.
Here is the link to OpenSimplexNoise for anyone who needs it:
https://gist.github.com/KdotJPG/b1270127455a94ac5d19
There's actually only 3 public methods - one for each for 2D, 3D & 4D noise.
Since you're filling a 2D array for your map , use the 2D noise eval method,
something like this:
for(int x=0; x<width; x++){
for(int y=0<y<height; y++){
map[x][y] = simplex.eval(x, y);
}
}
Later on, you can generate a color from the map values as follows:
Color color = Color.color(map[x][y], ma[x][y], map[x][y]);
The author also provides example usage code in OpenSimplexNoiseTest; he's using the 3D eval method, but always holding the z coord at zero. My guess is the example code was written before he added the 2D & 4D implementations. At any rate, it still works, but it might be a little slower than directly using 2D.

I need a row of rectangles, how can I name their variables automatically?

Maybe it's a bit vague questions, but I'm just learning java and programming(using Stanford videos) and I need to make a row of rectangles to build pyramid. But as I'm doing this in loop, all rectangles get the same variable name and they just "change" places and I only get one rectangle. So how can I name the rectangles differently in loop and add them, because it'd take so long to make them manually.
My code:
private void BuildingRow() {
int Q = BRICK_QUANTITY;
double length; // length from row beginning spot
length = RowStartSpot(Q);
for (int i = 0; i < Q; i++)
{
GRect brick = new GRect(length, height - BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT);
add(brick);
}
Create an array of rectangles and populate it using your for loop. The name of your rectangle will be its place in the array. For example if your rectangle array is called myRectangles, your first rectangle is myRectangles[0] etc.
You need to add them on some sort of list, so you can access them in the future:
List<GRect> listOfBricks = new ArrayList<GRect>();
for (int i = 0; i < Q; i++){
GRect brick = new GRect(length, height - BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT);
listOfBricks.add(brick);
}
And then, to access each brick:
listOfBricks.get(index);

How to flip an image horizontally with an ImageJ-Plugin?

I want to develop a Java-Plugin for ImageJ that flips an image horizontally.
But my code flips only half of the picture. Maybe, there is something wrong with the construction or the output of the image copy?
public class flipHorizontal implements PlugInFilter {
public int setup (String arg, ImagePlus imp)
{
return DOES_ALL;
}
public void run (ImageProcessor ip)
{
int height=ip.getHeight();
int width=ip.getWidth();
ImageProcessor copy = ip;
for (int x=0; x<width; x++) {
for (int y=0; y<height; y++) {
int p=ip.getPixel(width-x-1,y);
copy.putPixel(x,y,p);
}
}
}
}
Your logic is wrong. What you get is normal: you're not processing half of your image but flipping horizontally once half of your image and twice the other half (if I'm not mistaken).
Anyway, if you want to flip horizontally by manipulating pixels yourself directly, as in your code sample, then instead of going to width, you need to go to half the width (width/2).
You then need to actually invert the two pixels from "left" and "right"
Here's an horizontal flip that works:
for (int x = 0; x < w / 2; x++) {
for (int y = 0; y < h; y++) {
final int l = tmp.getRGB( w - (x + 1), y);
final int r = tmp.getRGB( x, y);
tmp.setRGB( x, y, l );
tmp.setRGB( w - (x + 1), y, r );
}
}
There may be "off-by-one" errors in the code above but you should get the idea.
TacticalCoder is correct that you should only be iterating to half way across the image, and you need to save the value from the other side before overwriting it.
There are two additional points that might be worth making, however - one is the the ImageProcessor class already has a method called flipHorizontal, so you can simplify your code to:
public class flipHorizontal implements PlugInFilter {
public int setup (String arg, ImagePlus imp) {
return DOES_ALL;
}
public void run (ImageProcessor ip) {
ip.flipHorizontal();
}
}
The other point that would be worth making is that it seems that you misunderstand what this line means:
ImageProcessor copy = ip;
That's just creating another reference to the same object as ip, so:
copy.putPixel(x,y,p);
... and:
ip.putPixel(x,y,p);
... have exactly the same effect. If you want to create a new ImageProcessor representing the same pixel data, you could do:
ImageProcessor copy = ip.duplicate();
However, that's not necessary in this case.

Categories