How to compare images? - java

For a project I am making a memory game, but I am trying to make to objects disappear when the are equal. This is my code:
public void opencard(){
int duiker = 0;
int duiker2 = 0;
if (duiker == duiker2){
if(Greenfoot.mouseClicked(Duiker.class)){
setImage("duiker_tcm46-175501.jpg");
if(Greenfoot.mouseClicked(duiker2)){
duiker2 = 1;
}
duiker = 1;{
getWorld().removeObject(this);
}
}
else if(Greenfoot.mouseClicked(this)){
setImage("duiker_tcm46-175501.jpg");
Greenfoot.delay(150);
setImage("150px_RGB_WEBSAFE_D_B_G_26-29652.gif");
}
}
}
But they disappear even when I don't click on them.

Related

How to create a simple user interface to declare variables?

I am working on my first java project, one that simulates the behaviour of a neutrophil catching a bacterium (So random/semirandom particle behaviour). At the beginning of this program I have several variables (such as the radii of the organisms, etc) and right now they are fixed to the value I hardcoded in there. I want to create a user interface so that before the program starts, a screen pops up in which you can type in the values you want to use, and it uses those to run to program. Now I have used a swing script to create such a window and that looks a bit like this:
Now I'm wondering how I could implement it such that I can take the values used in those text boxes and assign them to my variables in my program.
This is the program I am referring to:
package nanocourse;
import java.awt.Color;
import nano.*;
import java.util.Random;
import prescreen.PreScreen;
public class Exercise3_final {
public Exercise3_final() {
int xSize = 1000;
int ySize = 800;
Canvas myScreen = new Canvas(xSize, ySize);
Pen myPen = new Pen(myScreen);
Random random = new Random();
int frame=0; //how many frames have passed since start program
//properties bacterium
int xPosBacterium=random.nextInt(xSize); //random starting position of bacterium
int yPosBacterium=random.nextInt(ySize);
int K=1000; //how many points used to draw bacterium
double [] xValueBacterium = new double[K]; //
double [] yValueBacterium = new double[K];
double bacteriumRadiusInput=20;
double bacteriumRadius=bacteriumRadiusInput; //radius of bacterium
boolean bacteriumAlive=true;
//properties biomolecules
int amountBio=30000;
boolean [] bioExist = new boolean[amountBio];
int [] xPosBio = new int [amountBio];
int [] yPosBio = new int [amountBio];
int [] dXBio = new int [amountBio];
int [] dYBio = new int [amountBio];
int [] lifetimeBio = new int [amountBio];
double chanceDegrade=0.1; //chance that a biomolecule gets degraded per frame
double chanceSynthesize=100; //chance that a biomolecule gets synthesized per frame
for(int i=0;i<amountBio;i++)
{
bioExist[i]=false; //setting existing state to false
}
//properties Neutrophil
int xPosNeutrophil=random.nextInt(xSize);
int yPosNeutrophil=random.nextInt(ySize);
int L=1000;
double [] xValueNeutrophil= new double[L];
double [] yValueNeutrophil= new double[L];
double neutrophilRadius=40;
double xVector, yVector, xNormVector,yNormVector,magnitude,xSumVector,ySumVector;
double aggressiveness=1;
while(bacteriumAlive==true) //while program is running
{
frame++;
//1. Simulating a moving Bacterium
int dXBacterium=random.nextInt(11)-5; //random motion
int dYBacterium=random.nextInt(11)-5;
xPosBacterium=xPosBacterium+dXBacterium;
yPosBacterium=yPosBacterium+dYBacterium;
if(xPosBacterium<(bacteriumRadius/2+2*myPen.getSize())) //boundaries bacterium,accounting for size bacterium
{
xPosBacterium=(int)bacteriumRadius/2+2*myPen.getSize();
}
else if(xPosBacterium>xSize - (bacteriumRadius/2+2*myPen.getSize()))
{
xPosBacterium=xSize - ((int)bacteriumRadius/2+2*myPen.getSize());
}
else if(yPosBacterium<(bacteriumRadius/2+2*myPen.getSize()))
{
yPosBacterium=((int)bacteriumRadius/2+2*myPen.getSize());
}
else if(yPosBacterium>ySize - (bacteriumRadius/2+2*myPen.getSize()))
{
yPosBacterium=ySize - ((int)bacteriumRadius/2+2*myPen.getSize());
}
//2. Simulating synthesis and secretion of biomolecules by the bacterium.
for(int i=0;i<amountBio;i++)
{
double synthesizeNumber=Math.random()*100;
if(synthesizeNumber<chanceSynthesize && i==frame)
{
bioExist[frame]=true; //make the biomolecules exist
}
if(bioExist[i]==true && frame!=1) //if biomolecule exist apply motion
{
dXBio[i]=random.nextInt(41)-20;
dYBio[i]=random.nextInt(41)-20;
xPosBio[i]=xPosBio[i]+dXBio[i];
yPosBio[i]=yPosBio[i]+dYBio[i];
}
else //if biomolecule doesn't exist, make position equal bacterium position
{
xPosBio[i]=xPosBacterium;
yPosBio[i]=yPosBacterium;
}
if(xPosBio[i]>xSize) //boundaries biomolecules
{
xPosBio[i]=xSize;
}
if(xPosBio[i]<0)
{
xPosBio[i]=0;
}
if(yPosBio[i]>ySize)
{
yPosBio[i]=ySize;
}
if(yPosBio[i]<0)
{
yPosBio[i]=0;
}
if(bioExist[i]==true)
{
lifetimeBio[i]++;
double degradationNumber=Math.random()*100;
if(degradationNumber<chanceDegrade)
{
bioExist[i]=false;
}
}
if(bioExist[i]==true && lifetimeBio[i]<=100) //if biomolecule lives shorter than 100 frames==>green
{
myPen.setColor(Color.GREEN); //drawing biomolecules
myPen.setShape(Shape.CIRCLE);
myPen.setSize(5);
}
if(bioExist[i]==true && (lifetimeBio[i]>100 && lifetimeBio[i]<=500)) //if biomolecule lives 101-500 frames==>green
{
myPen.setColor(Color.yellow); //drawing biomolecules
myPen.setShape(Shape.CIRCLE);
myPen.setSize(5);
}
if(bioExist[i]==true && (lifetimeBio[i]>500 && lifetimeBio[i]<=1000)) //if biomolecule lives 501-1000 frames==>orange
{
myPen.setColor(Color.ORANGE); //drawing biomolecules
myPen.setShape(Shape.CIRCLE);
myPen.setSize(5);
}
if(bioExist[i]==true && (lifetimeBio[i]>1000 && lifetimeBio[i]<=1500)) //if biomolecule lives 1001-1500 frames==>red
{
myPen.setColor(Color.RED); //drawing biomolecules
myPen.setShape(Shape.CIRCLE);
myPen.setSize(5);
}
if(bioExist[i]==true && lifetimeBio[i]>1500) //if biomolecule lives 2001+ frames==>magenta
{
myPen.setColor(Color.magenta); //drawing biomolecules
myPen.setShape(Shape.CIRCLE);
myPen.setSize(5);
}
if(bioExist[i]==true)
{
myPen.draw(xPosBio[i],yPosBio[i]);
}
if(Math.sqrt(Math.pow(Math.abs(xPosBio[i]-xPosNeutrophil),2)+Math.pow(Math.abs(yPosBio[i]-yPosNeutrophil), 2))<neutrophilRadius)
{
bioExist[i]=false; //degrade if inside neutrophil
}
}
if(bacteriumAlive==true)
{
for(int i = 0; i <K ; i++) //defining circle, drawing points, placed here because it needs to be on top
{
xValueBacterium[i] = bacteriumRadius*Math.cos(2*Math.PI*i/K);
yValueBacterium[i] = bacteriumRadius*Math.sin(2*Math.PI*i/K);
myPen.setColor(Color.red);
myPen.setShape(Shape.CIRCLE);
myPen.setSize(5);
myPen.draw((int)xValueBacterium[i]+xPosBacterium,(int)yValueBacterium[i]+yPosBacterium);
}
}
//5. Simulating the neutrophil eating the bacteriun
xSumVector=0;
ySumVector=0;
for(int i=0;i<amountBio;i++)
{
if(Math.abs(xPosBio[i]-xPosNeutrophil)<(30+neutrophilRadius) && Math.abs(yPosBio[i]-yPosNeutrophil)<(30+neutrophilRadius) && bioExist[i]==true)
{
xVector=xPosBio[i]-xPosNeutrophil;
yVector=yPosBio[i]-yPosNeutrophil;
magnitude=Math.sqrt(Math.pow(xVector, 2)+Math.pow(yVector, 2));
xNormVector=xVector/magnitude;
yNormVector=yVector/magnitude;
xSumVector=xSumVector+xNormVector;
ySumVector=ySumVector+yNormVector;
}
}
//3. Simulating a moving neutrophil
int dXNeutrophil=random.nextInt(11)-5+(int)aggressiveness*(int)xSumVector; //random motion
int dYNeutrophil=random.nextInt(11)-5+(int)aggressiveness*(int)ySumVector;
xPosNeutrophil=xPosNeutrophil+dXNeutrophil;
yPosNeutrophil=yPosNeutrophil+dYNeutrophil;
myPen.setSize(8);
if(xPosNeutrophil<(neutrophilRadius/2+2*myPen.getSize())) //boundaries neutrophil
{
xPosNeutrophil=(int)neutrophilRadius/2+2*myPen.getSize();
}
else if(xPosNeutrophil>xSize - (neutrophilRadius/2+2*myPen.getSize()))
{
xPosNeutrophil=xSize - ((int)neutrophilRadius/2+2*myPen.getSize());
}
else if(yPosNeutrophil<(neutrophilRadius/2+2*myPen.getSize()))
{
yPosNeutrophil=((int)neutrophilRadius/2+2*myPen.getSize());
}
else if(yPosNeutrophil>ySize - (neutrophilRadius/2+2*myPen.getSize()))
{
yPosNeutrophil=ySize - ((int)neutrophilRadius/2+2*myPen.getSize());
}
for(int i = 0; i <L ; i++) //defining circle, drawing points, placed here because it needs to be on top
{
xValueNeutrophil[i] = neutrophilRadius*Math.cos(2*Math.PI*i/L);
yValueNeutrophil[i] = neutrophilRadius*Math.sin(2*Math.PI*i/L);
myPen.setColor(Color.blue);
myPen.setShape(Shape.CIRCLE);
myPen.draw((int)xValueNeutrophil[i]+xPosNeutrophil,(int)yValueNeutrophil[i]+yPosNeutrophil);
}
if(Math.abs(xPosNeutrophil-xPosBacterium)<2*bacteriumRadiusInput && Math.abs(yPosNeutrophil-yPosBacterium)<2*bacteriumRadiusInput && bacteriumRadius >=0)
{
bacteriumRadius=bacteriumRadius-1;
if(bacteriumRadius==0)
{
bacteriumAlive=false;
}
}
if(bacteriumAlive==false)
{
bacteriumAlive=true;
xPosBacterium=random.nextInt(xSize); //random starting position of bacterium
yPosBacterium=random.nextInt(ySize);
bacteriumRadius=bacteriumRadiusInput;
}
myScreen.update(); //updating/refreshing screen
myScreen.pause(10);
myScreen.clear();
}
}
public static void main(String[] args) {
Exercise3_final e = new Exercise3_final();
}
}
Any help would be appreciated!
Sounds like you need an action listener on the "Run!" button from your dialog:
_run.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// set the variables here by getting the text from the inputs
field1Var = Integer.parseInt(field1Input.getText());
field2Var = Integer.parseInt(field2Input.getText());
...
}
});
I would suggest creating a singleton class to save all the values that are captured from the first screen (options menu screen).
You can get the instance of this class anywhere in the application later on and use it.
Advantages would be:
- You will not have to carry forward the values everywhere in the application.
- The values captured will the persisted till the application is shut down.
Note: Make sure to add validations while fetching values from the options menu so that incorrect values are not set.

How to use the Comparable Interface compareTo when comparing an object that is dependent on array position?

I am trying to implement the Game Pac-Man and I am having a bug that I know is wrong, but I do not know how to fix. I am using a generic Pellet class that has two subtypes, smallPellet and energizerPellet. I have a intersects method that will tell if Pac-Man's location is the same. I have stored the instances of pellet on my map in a set so there are no repeats, but I am think my implementation of the compareTo override method is wrong. Each pellet has a pos_x and pos_y that are different for each pellet and I am trying to differentiate each pellet using those two factors, but when I implement it, sometimes they are not removed from the set when I go over them. Any help would be appreciated!
#Override
public int compareTo(Pellet pellet) {
// TODO Auto-generated method stub
if (pellet == null) {
throw new NullPointerException();
}
if (this.pos_x == pellet.pos_x && this.pos_y == pellet.pos_y) {
return 0;
} else if ((this.pos_x^2 + this.pos_y^2) < (pellet.pos_x^2 + pellet.pos_y^2)) {
return -1;
} else {
return 1;
}
}
And my Background Class (JPanel) methods that are related:
public static Set<SmallPellet> smallPellet() {
Set<SmallPellet> pellets = new TreeSet<>();
for (int i = 1; i < width; i++) {
for (int j = 1; j < height; j++) {
if (map[j][i] == 0) {
pellets.add(new SmallPellet(10*i, 10*j));
}
}
}
System.out.println(pellets.size());
return pellets;
}
Set<SmallPellet> smallPellets = new TreeSet<>(smallPellet());
Removing them when intersecting:
Set<SmallPellet> smPellets = new TreeSet<>(smallPellets);
for (SmallPellet pellet : smallPellets) {
if (pellet.intersects(pacman)) {
smPellets.remove(pellet);
score += 10;
scoreLabel.setText("Score: " + score);
}
}
smallPellets = smPellets;
I think my problem in comparing is that when comparing 5,7 and 7,5 obviously they are not equal, but which one is greater and which one is less than than the other? When I put them in a set, Set.remove(a) is confused where to find it and remove it when it is close to a similar number.

There are two functions with the same structure, but different details. How to get rid of duplication?

So, here is my functions:
private void sendLeft() {
leftSendersIndexes = newLeftSendersIndexes;
Agent rightRecepient;
int rightRecepientIdx = 0;
Agent leftSender;
for (int i = 0; i < leftSendersIndexes.size(); i++) {
rightRecepientIdx = leftSendersIndexes.get(i) + 1;
rightRecepient = list.get(rightRecepientIdx);
leftSender = list.get(rightRecepientIdx - 1);
rightRecepient.setNewLeftMsg(leftSender.getLeftMsg());
rightRecepient.setLeftMsg(0); // reset left messages
}
}
private void sendRight() {
rightSendersIndexes = newRightSendersIndexes;
Agent leftRecepient;
int leftRecepientIdx = 0;
Agent rightSender;
for (int i = 0; i < rightSendersIndexes.size(); i++) {
leftRecepientIdx = rightSendersIndexes.get(i) - 1;
leftRecepient = list.get(leftRecepientIdx);
rightSender = list.get(leftRecepientIdx + 1);
leftRecepient.setNewRightMsg(rightSender.getRightMsg());
}
}
They are very similar. The problem is that in first function I have leftRecepientIdx+1 and after that leftRecepientIdx-1 and I have leftRecepientIdx-1 and leftRecepientIdx+1 in second function. I may to combine two functions in one and add a boolean parameter. But is there a better way to get rid of duplication?
One way to do that is with this refactoring:
private void sendLeft() {
leftSendersIndexes = newLeftSendersIndexes;
send(leftSendersIndexes, -1);
}
private void sendRight() {
rightSendersIndexes = newRightSendersIndexes;
send(rightSendersIndexes, +1);
}
private void send(List<Integer> indexes, int direction) {
for (int i = 0; i < indexes.size(); i++) {
int recipientIdx = indexes.get(i) - direction;
Agent recipient = list.get(recipientIdx);
Agent sender = list.get(recipientIdx + direction);
if (direction == -1) {
recipient.setNewLeftMsg(sender.getLeftMsg());
recipient.setLeftMsg(0); // reset left messages
}
else {
recipient.setNewRightMsg(sender.getRightMsg());
}
}
}
The send method encapsulates the logic based on the direction parameter: +1 for right, -1 for left.
The order in which those appears is important, I would suggest merging, but, I have no idea what that would do. Keep them separate, if this was borrowed, this was made on purpose.
Both functions are some send functions where sender and receiver are different and reset may happen. So I would try to make one function with arguments sender, receiver and boolean reset.

Memory game does not call compare function correctly

I have coded a simple memory game. Card values are added to two arrays and after that, a compare function is called. But there is a problem with the logic of the compare function.
The specific problem seems related to the fact that the compare function is called on the third button click. So on first click it adds first value to first array , on second click second value to second array. But I must click for yet a third time to call the compare function to compare the match of two arrays.
The main problem is that after all cards are inverted (10 matches in 5x4 memory game), it does not show the result.
I have uploaded full code here : http://uloz.to/xcsJkYUK/memory-game-rar .
public class PEXESO5x4 extends JFrame implements ActionListener {
private JButton[] aHracieTlactika = new JButton[20];
private ArrayList<Integer> aHodnoty = new ArrayList<Integer>();
private int aPocitadlo = 1;
private int[] aTlacitkoIden = new int[2];
private int[] aHodnotaTlac = new int[2];
private JButton aTlacitkoExit;
private JButton aTlacitkoReplay;
private JButton[] aHracieTlacitko = new JButton[20];
private int aPocetTahov = 0;
public void vkladanieHodnot() {
for (int i = 0; i < 2; i++) {
for (int j = 1; j < (this.aHracieTlactika.length / 2) + 1; j++) {
this.aHodnoty.add(j);
}
}
Collections.shuffle(this.aHodnoty);
}
public boolean zhoda() {
if (this.aHodnotaTlac[0] == this.aHodnotaTlac[1]) {
return true;
}
return false;
}
public void zapisCislaDoSuboru() {
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Semestralka.txt", true)))) {
out.println("haha");
//more code
out.println("hahahahha");
//more code
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
}
public void actionPerformed(ActionEvent e) {
int match = 0;
if (this.aTlacitkoExit == e.getSource()) {
System.exit(0);
}
if (this.aTlacitkoReplay == e.getSource()) {
}
for (int i = 0; i < this.aHracieTlactika.length; i++) {
if (this.aHracieTlactika[i] == e.getSource()) {
this.aHracieTlactika[i].setText("" + this.aHodnoty.get(i));
this.aHracieTlactika[i].setEnabled(false);
this.aPocitadlo++;
this.aPocetTahov += 1;
if (this.aPocitadlo == 3) {
if (this.zhoda()) {
match+=1;
if (match==10)
{
System.out.println("You win");
}
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(false);
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(false);
} else {
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[0]].setText("");
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[1]].setText("");
}
this.aPocitadlo = 1;
}
if (this.aPocitadlo == 1) {
this.aTlacitkoIden[0] = i;
this.aHodnotaTlac[0] = this.aHodnoty.get(i);
}
if (this.aPocitadlo == 2) {
this.aTlacitkoIden[1] = i;
this.aHodnotaTlac[1] = this.aHodnoty.get(i);
}
}
}
}
}

Java Sorting "queue" list based on DateTime and Z Position (part of school project)

For a school project i have a list of 50k containers that arrive on a boat.
These containers need to be sorted in a list in such a way that the earliest departure DateTimes are at the top and the containers above those above them.
This list then gets used for a crane that picks them up in order.
I started out with 2 Collection.sort() methods:
1st one to get them in the right X>Y>Z order
Collections.sort(containers, new Comparator<ContainerData>()
{
#Override
public int compare(ContainerData contData1, ContainerData contData2)
{
return positionSort(contData1.getLocation(),contData2.getLocation());
}
});
Then another one to reorder the dates while keeping the position in mind:
Collections.sort(containers, new Comparator<ContainerData>()
{
#Override
public int compare(ContainerData contData1, ContainerData contData2)
{
int c = contData1.getLeaveDateTimeFrom().compareTo(contData2.getLeaveDateTimeFrom());
int p = positionSort2(contData1.getLocation(), contData2.getLocation());
if(p != 0)
c = p;
return c;
}
});
But i never got this method to work..
What i got working now is rather quick and dirty and takes a long time to process (50seconds for all 50k):
First a sort on DateTime:
Collections.sort(containers, new Comparator<ContainerData>()
{
#Override
public int compare(ContainerData contData1, ContainerData contData2)
{
return contData1.getLeaveDateTimeFrom().compareTo(contData2.getLeaveDateTimeFrom());
}
});
Then a correction function that bumps top containers up:
containers = stackCorrection(containers);
private static List<ContainerData> stackCorrection(List<ContainerData> sortedContainerList)
{
for(int i = 0; i < sortedContainerList.size(); i++)
{
ContainerData current = sortedContainerList.get(i);
// 5 = Max Stack (0 index)
if(current.getLocation().getZ() < 5)
{ //Loop through possible containers above current
for(int j = 5; j > current.getLocation().getZ(); --j)
{ //Search for container above
for(int k = i + 1; k < sortedContainerList.size(); ++k)
if(sortedContainerList.get(k).getLocation().getX() == current.getLocation().getX())
{
if(sortedContainerList.get(k).getLocation().getY() == current.getLocation().getY())
{
if(sortedContainerList.get(k).getLocation().getZ() == j)
{ //Found -> move container above current
sortedContainerList.add(i, sortedContainerList.remove(k));
k = sortedContainerList.size();
i++;
}
}
}
}
}
}
return sortedContainerList;
}
I would like to implement this in a better/faster way. So any hints are appreciated. :)
I think you probably want to sort with a single Comparator that compares on all of the criteria. E.g.:
compareTo(other)
positionComparison = this.position.compareTo(other.position)
if positionComparison != 0
return positionComparison
return this.departureTime.compareTo(other.departureTime)

Categories