The title could be incorrect but I couldn't think of anything else to name this question.
My issue comes with some Java code I've been writing that is driving me insane. Basically I'm trying to make a "card memory" game where I have a 4X4 grid of cards laid out; when you click one it flips, then you click the second, it flips, and if they're the same card it disappears and if they're different cards it flips them back over.
This works fine except one little detail. When you click the first card it flips, then when you click the second card it flips it and checks the value of it so fast that you can't tell if the 2nd card flips at all before they're gone or the first one is flipped back over. So I added
try{Thread.sleep(2000);}catch(InterruptedException ex) {}
after I flipped the second card. Well now it's becoming clear that the second card doesn't flip at all. I click the first card, it flips, I click the second card, it waits 2 seconds (thread sleep) and then it determines the equality and either hides or flips the first card back. All without ever showing what the 2nd card was.
I am going to add all the code I have below. I'm sorry that it's a lot but I don't know which part is relevant.
import objectdraw.*;
import java.awt.Image;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
public class Card {
private int value;
private VisibleImage imageFront, imageBack;
public Card(int val, Location p, double w, double h, DrawingCanvas c) {
value = val;
String urlStr = "images/" + val + ".png";
BufferedImage img = null, imgb = null;
try {
img = ImageIO.read(new File(urlStr));
imgb = ImageIO.read(new File("images/card-back.png"));
} catch(IOException ex) {}
imageFront = new VisibleImage(img,p,w,h,c);
imageFront.hide();
imageBack = new VisibleImage(imgb,p,w,h,c);
}
public void flip() {
if(imageFront.isHidden()) {
imageFront.show();
imageBack.hide();
} else {
imageBack.show();
imageFront.hide();
}
}
public Boolean contains(Location p) {
if(imageFront.isHidden()) {
return imageBack.contains(p);
} else {
return imageFront.contains(p);
}
}
public void moveTo(double x, double y) {
imageFront.moveTo(x,y);
imageBack.moveTo(x,y);
}
public int getValue() {
return value;
}
public void hide() {
imageFront.hide();
imageBack.hide();
}
}
import objectdraw.*;
public class Grid {
private static final int ROWS = 4;
private static final int COLS = 4;
private Card[] cards = new Card[COLS * ROWS];
public Grid(double cardW, double cardH, DrawingCanvas c) {
int cnt = 0;
Location p1 = new Location(0,0);
Location p2 = new Location(0,(ROWS/2)*cardH);
for(int i = 0; i < ROWS; i++) {
for(int j = 0; j < COLS; j++) {
// Set up 2 of the same card, one at cnt and one at cnt + cards.length/2
if(cnt < cards.length/2) {
cards[cnt] = new Card(cnt+1,p1,cardW,cardH,c);
p1.translate(cardW,0);
cards[cnt + cards.length/2] = new Card(cnt+1,p2,cardW,cardH,c);
p2.translate(cardW,0);
cnt++;
}
}
p1.translate(-(cardW * COLS),cardH);
p2.translate(-(cardW * COLS),cardH);
}
}
private static int sel = -1;
public void select(Location p) {
for(int i = 0; i < cards.length; i++) {
// Find the correct card
if(cards[i].contains(p)) {
if(sel == -1) {
// This is the first card selected
System.out.printf("\nThis is the first card selected");
cards[i].flip();
sel = i;
break;
} else {
System.out.printf("\nThis is the second card");
// They selected the same card
if(i == sel) {
break;
} else {
// This is the second card selected and it's unique
// Flip it and check if they match. If they do, then hide both,
// if they don't then flip both back
cards[i].flip();
if(cards[i].getValue() == cards[sel].getValue()) {
try {
remove(cards[i], cards[sel]);
} catch(InterruptedException ex) {}
sel = -1;
break;
} else {
cards[i].flip();
cards[sel].flip();
sel = -1;
break;
}
}
}
}
} // for loop
}
public void remove(final Card card1, final Card card2) throws InterruptedException {
new Thread() {
public void run() {
sleep(2000);
card1.hide();
card2.hide();
}
}.start();
}
}
import objectdraw.*;
public class Client extends WindowController {
public static void main(String[]args) {
new Client().startController(310,460);
}
Grid board;
public void begin() {
board = new Grid(75,102,canvas);
}
public void onMouseClick(Location p) {
board.select(p);
}
}
For reference all of this comes from the objectdraw library
I would separate the select()
and remove()
logic. Exactly here:
if(cards[i].getValue() == cards[sel].getValue()) {
remove(cards[i], cards[sel]); //call the remove
And remove()
would start a Thread and remove the wanted values:
public void remove(final Card card1, final Card card2) {
new Thread() {
@Override
public void run() {
try {
sleep(2000);
} catch (InterruptedException e) {
}
card1.hide();
card2.hide();
}
}.start();
}
So this way you don't block the UI thread (the user can see the flip) and the new thread will hide the cards after the two seconds.