.wait() and .notifyAll() not working as intended - java

I'm working on a program which should instantiate n amount of threads. Their job is to draw from a deck existing of 52 distinct cards, wait until the round have been evaluated(who had the highest card) and the user has the highest card shown and then repeat until the deck is empty.
The first round runs flawless, not accounting for the wrong evaluation of the cards, but then the program just locks. Never drawing new cards.
I can't quite figure out what the problem is, but my guess is that I'm calling notifyAll() before the threads wake, causing a deadlock. Even though I'm counting the number of waiting threads and only notifying if the number of waiting threads corresponds to the number of players.
EDIT: I found out that if I debug, the code runs smoothly and as intended. But as soon as I run it, it runs as earlier described.
public class Deck {
Stack<Card> stack = new Stack<>();
public Deck()
{
makeAndShuffleDeck();
}
public synchronized Card drawOneCard()
{
Card card = stack.pop();
System.out.println(Thread.currentThread() + " is drawing " + card);
return card;
}
public void setCardValues(int x)
{
if(x == 0)
{
Rank.ACE.setValue(14);
}
else
{
Rank.ACE.setValue(1);
}
}
public void makeAndShuffleDeck()
{
for(Suit suit : Suit.values())
{
for(Rank value : Rank.values())
{
stack.add(new Card(suit,value));
}
}
Collections.shuffle(stack);
}
public Stack<Card> getDeck()
{
return stack;
}
}
public class Round {
ArrayList<Thread> playersInTheRound = new ArrayList<>();
ArrayList<Card> cardsDrawnInTheRound = new ArrayList<>();
Deck deck;
int numberOfRounds;
public Round(int nrOfPlayers, Deck deck)
{
this.deck = deck;
fillListWithPlayers(nrOfPlayers);
calcNumberOfRounds();
for(Thread p: playersInTheRound)
{
p.start();
}
}
public void fillListWithPlayers(int nrOfPlayers)
{
for (int i = 0; i < nrOfPlayers; i++)
{
playersInTheRound.add(new Thread(new Player(deck, this)));
}
}
public void addPlayerCards(Card card)
{
cardsDrawnInTheRound.add(card);
}
public void calcNumberOfRounds()
{
numberOfRounds = deck.getDeck().size()/playersInTheRound.size();
}
public void playRound()
{
while(numberOfRounds > 0)
{
findWinnerOfRound();
cardsDrawnInTheRound.clear();
while(Player.waiting == playersInTheRound.size())
{
synchronized (this)
{
this.notifyAll();
}
Player.waiting = 0;
}
numberOfRounds--;
}
}
public void findWinnerOfRound()
{
Card highestCard = null;
Comparator<Card> comp = (Card c1, Card c2) ->
{
if (c1.rank.getValue() == c2.rank.getValue())
{
if (c1.suit.getRank() > c2.suit.getRank())
{
return 1;
}
return -1;
}
if (c1.rank.getValue() > c2.rank.getValue())
{
return 1;
}
return -1;
};
for (int i = 0; i < cardsDrawnInTheRound.size()-1; i++)
{
for (int j = i+1; j < cardsDrawnInTheRound.size(); j++)
{
if(comp.compare(cardsDrawnInTheRound.get(i), cardsDrawnInTheRound.get(j)) == -1)
{
highestCard = cardsDrawnInTheRound.get(j);
}
highestCard = cardsDrawnInTheRound.get(i);
}
}
System.out.println(cardsDrawnInTheRound);
System.out.println("Winner: " + highestCard);
}
}
public class Player implements Runnable {
Deck deck;
Round round;
public static int waiting = 0;
public Player(Deck deck, Round round)
{
this.deck = deck;
this.round = round;
}
#Override
public void run()
{
Card card = deck.drawOneCard();
synchronized (round)
{
try
{
round.addPlayerCards(card);
waiting++;
round.wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}

Related

How do i generate a deck of cards in Java?

I have tried again and again but the loop is stuck at the king of clubs.
currently I am trying to generate a deck of cards and print it out to check if the deck is actual
import java.util.*;
import java.math.*;
public class Deck extends Card{
private static Card[][]cardDeck=new Card[4][13];
int counter;
public Deck (String suit, String cardType, int value)
{
super(suit,cardType,value);
}
public void removeCard()
{
if(counter>=40)
generateDeck();
int Randr=(int)(Math.random()*26);
int Randc=(int)(Math.random()*2);
if(cardDeck[Randr][Randc]==null)
{
removeCard();
}
else
{
cardDeck[Randr][Randc]=null;
counter++;
}
}
public void print2DArray()
{
for(int i=0;i<cardDeck.length;i++)
{
for(int j=0;j<cardDeck[0].length;j++)
{
System.out.print(super.draw(cardDeck[i][j])+" "+j);
}
System.out.println();
}
}
public static void generateDeck()
{
for(int i=0; i<cardDeck.length;i++) {
for(int j=0;j<cardDeck[0].length;j++) {
if(i==0)
{
if(j==0)
{
cardDeck[0][0]=new Card("Clubs","Ace",1);
continue;
}
else if(j>0&&j<10)
{
cardDeck[i][j]=new Card("Clubs",""+(j+1),j+1);
continue;
}
else if(j==10)
{
cardDeck[i][j]=new Card("Clubs","Jack",10);
continue;
}
else if(j==11)
{
cardDeck[i][j]=new Card("Clubs","Queen",10);
continue;
}
else if(j==12)
{
cardDeck[i][j]=new Card("Clubs","King",10);
continue;
}
else if(i==1)
{
if(j==0)
{
cardDeck[1][0]=new Card("Hearts","Ace",1);
continue;
}
else if(j>0&&j<10)
{
cardDeck[i][j]=new Card("Hearts",""+(j+1),j+1);
continue;
}
else if(j==10)
{
cardDeck[i][j]=new Card("Hearts","Jack",10);
continue;
}
else if(j==11)
{
cardDeck[i][j]=new Card("Hearts","Queen",10);
continue;
}
else if(j==12)
{
cardDeck[i][j]=new Card("Hearts","King",10);
continue;
}
}
else if(i==2)
{
if(j==0)
{
cardDeck[2][0]=new Card("Spades","Ace",1);
continue;
}
else if(j>0&&j<10)
{
cardDeck[i][j]=new Card("Spades",""+(j+1),j+1);
continue;
}
else if(j==10)
{
cardDeck[i][j]=new Card("Spades","Jack",10);
continue;
}
else if(j==11)
{
cardDeck[i][j]=new Card("Spades","Queen",10);
continue;
}
else if(j==12)
{
cardDeck[i][j]=new Card("Spades","King",10);
continue;
}
}
else if(i==3)
{
if(j==0)
{
cardDeck[3][0]=new Card("Diamonds","Ace",1);
continue;
}
else if(j>0&&j<10)
{
cardDeck[i][j]=new Card("Diamonds",""+(j+1),j+1);
continue;
}
else if(j==10)
{
cardDeck[i][j]=new Card("Diamonds","Jack",10);
continue;
}
else if(j==11)
{
cardDeck[i][j]=new Card("Diamonds","Queen",10);
continue;
}
else if(j==12)
{
cardDeck[i][j]=new Card("Diamonds","King",10);
continue;
}
}
}
}
}
}
}
my card class is just a basic class with a few get methods
public class Card {
private static String suit;
private static int numVal;
private static String cardType;
public Card(String s,String cT, int val) {
suit=s;
numVal=val;
cardType=cT;
}
public String draw(Card card) {
return "Your card is "+card.getSuit()+" "+card.getCardType()+" its value is "+card.getValue();
}
public static String getSuit()
{
return suit;
}
public static String getCardType()
{
return cardType;
}
public static int getValue()
{
return numVal;
}
}
my main method is just to check if it will print
public class TestEnvironment {
public static void main(String[] args) {
Deck x= new Deck("","",0);
x.generateDeck();
x.print2DArray();
}
}
heres my updated code for the if else statements aforementioned
import java.util.*;
import java.math.*;
public class Deck extends Card{
private static Card[][]cardDeck=new Card[4][13];
int counter;
public Deck (String suit, String cardType, int value)
{
super(suit,cardType,value);
}
public void removeCard()
{
if(counter>=40)
generateDeck();
int Randr=(int)(Math.random()*26);
int Randc=(int)(Math.random()*2);
if(cardDeck[Randr][Randc]==null)
{
removeCard();
}
else
{
cardDeck[Randr][Randc]=null;
counter++;
}
}
public void print2DArray()
{
for(int i=0;i<4;i++)
{
for(int j=0;j<cardDeck[0].length;j++)
{
System.out.print(i);
//System.out.println(super.draw(cardDeck[i][j])+" "+i+","+j);
}
System.out.println();
}
}
public static void generateDeck()
{ int value=0;
String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
String[] ranks = {"Ace","2","3","4","5","6","7","8","9","10","Jack","Queen","King"};
for (int i=0;i<suits.length;i++)
for (int j=0;j<ranks.length;j++)
{
cardDeck[i][j] = new Card(suits[i],ranks[j],value);
if(j>9)
value =10;
else
value=j+1;
cardDeck[i][j] = new Card(suits[i],ranks[j],value);
}
Don't use a 2D Array. Instead use an ArrayList to hold the cards.
Then you create two loops to add the cards to the ArrayList. The outer loop will iterate through the 4 suits and the inner loop will add the 13 cards for each suit.
Then you can use Collections.shuffle() to shuffle the Cards in the ArrayList.
To play a card you just remove card 0 from the ArrayList.
Edit:
but the loop is stuck at the king of clubs.
Well your generateCards() method uses too many if/else statements to generate the cards. It is hard to notice which if/else statement might be causing the problem.
You can simplify the code by using arrays and loops.
Something like:
String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
String[] ranks = {"Ace", "2", "3", ... , "Jack", "Queen", "King"};
for (each suit) // assume i is the index
for (each rank) // assume j is the index
{
int value = (j < 10) ? 10 : j;
cardDeck[i][j] = new Card(...);
}
}
Edit 2:
it is stuck at the spades of kings
I'm guessing the following is your problem:
private static String suit;
private static int numVal;
private static String cardType;
Don't use static variables. The Static keyword means that all instances of the Card class will share the same value.

Print Floyd triangle using multithreading in java

I want to use two threads to print Floyd triangle(say one thread prints the number and the other prints the number in the line) as below.
and so forth until the max number which is 15 in this case.
I tried following but it keeps on printing numbers one on each line
public class MyThread extends Thread{
static volatile int lineNumber = 1;
public static void main(String... args) {
PrintFloyd print = new PrintFloyd();
Thread t1 = new Thread(new TaskHandler(print, 10), "T1");
Thread t2 = new Thread(new TaskHandler(print, 10), "T2");
t1.start();
t2.start();
}
}
class TaskHandler implements Runnable {
static volatile int i = 1;
static volatile int lineCount = 1;
static volatile int lineNumber = 1;
private int max;
private PrintFloyd print;
TaskHandler(PrintFloyd print2, int max) {
this.print = print2;
this.max = max;
}
#Override
public void run() {
System.out.println(">>>>" + Thread.currentThread().getName());
while(i < max){
if (Thread.currentThread().getName().equals("T1")){
print.printNumber(i);
} else {
print.breakLine();
}
}
}
}
class PrintFloyd {
boolean isBreakPoint = false;
public void printNumber(int i) {
synchronized(this){
while (isBreakPoint == false) {
try {
wait();
} catch (InterruptedException ex) {
}
System.out.print(i++ + " ");
isBreakPoint = false;
notifyAll();
}
}
}
public void breakLine(){
synchronized(this){
while (isBreakPoint == true) {
try {
wait();
} catch (InterruptedException ex) {
}
}
System.out.println();
isBreakPoint = true;
notifyAll();
}
}
}
The following code would help:
public class PrintPatternWith2Threads {
final static int MAX = 15;
final static String itemWriterName = "itemWriter";
final static String newLineWriterName = "newLineWriter";
public static void main(String[] args) {
Printer print = new Printer(MAX);
Thread itemWriter = new Thread(new ItemWriter(print), itemWriterName);
itemWriter.start();
Thread newLineWriter = new Thread(new NewLineWriter(print), newLineWriterName);
newLineWriter.start();
}
}
class ItemWriter implements Runnable {
private Printer print;
ItemWriter(Printer print) {
this.print = print;
}
public void run() {
while (print.current <= print.MAX) {
print.printNumber();
}
}
}
class NewLineWriter implements Runnable {
private Printer print;
NewLineWriter(Printer print) {
this.print = print;
}
public void run() {
while (print.current <= print.MAX) {
print.printNewLine();
}
}
}
class Printer {
public final int MAX;
public int current = 1;
public int itemsInALine = 1;
Printer(int max) {
this.MAX = max;
}
public void printNumber() {
synchronized(this) {
for(int i = current; i < current + itemsInALine && i <= MAX; i++) {
System.out.print(i + " ");
}
this.current = current + itemsInALine;
itemsInALine++;
notifyAll();
try {
if(this.current < MAX) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void printNewLine() {
synchronized(this) {
System.out.println();
notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Sorting Card objects inside of the Hand object

I have almost everything ready for my poker game. What I want to do next is to sort cards in players hand by rank value. You know "two" is byte 2, "three" is byte 3 etc...
This is my enum CardRank class
public enum CardRank {
TWO((byte)2, "Two"),
THREE((byte)3, "Three"),
FOUR((byte)4, "Four"),
FIVE((byte)5, "Five"),
SIX((byte)6, "Six"),
SEVEN((byte)7, "Seven"),
EIGHT((byte)8, "Eight"),
NINE((byte)9, "Nine"),
TEN((byte)10, "Ten"),
JACK((byte)11, "Jack"),
QUEEN((byte)12, "Queen"),
KING((byte)13, "King"),
ACE((byte)14, "Ace");
private final byte rankValue;
private final String rankValueName;
//Constructor
private CardRank(byte rankValue, String rankValueName){
this.rankValue=rankValue;
this.rankValueName = rankValueName;
}
//reusable methods
protected byte getRankValue(){
return rankValue;
}
protected String getRankValueName(){
return rankValueName;
}
}
I need to find a way to sort them using enum values but to be honest I don't really know how.
This method returns enum values of player hand cards:
protected void sortHand(){
for (Hand playerHand: players){
i = 0;
while(i<5){
System.out.println(playerHand.cards.get(i).getRankValue());
i++;
}
}
}
I can't use Collections from a very obvious reason:
The method sort(List) in the type Collections is not applicable for the arguments (Hand)
And this is my Hand class
import java.util.ArrayList;
public class Hand {
protected ArrayList<Card> cards;
private String handCards;
// Constructor
protected Hand() {
cards = new ArrayList<Card>(5);
}
// reusable methods
protected void add(Card card) {
cards.add(card);
}
protected void emptyHand() {
cards.clear();
}
protected void flipHandCards() {
for (Card card : cards) {
card.flipCard();
}
}
protected String displayHand() {
handCards = "";
for (Card i : cards) {
handCards += i.toString() + "\n";
}
return handCards;
}
protected boolean giveCard(Card card, Hand differentHand) {
if (!cards.contains(card)) {
return false;
} else {
cards.remove(card);
differentHand.add(card);
return true;
}
}
}
And this is my Card class
public class Card {
private CardSuit suit;
private CardRank rank;
private String cardName;
private boolean visibility;
//Constructor
protected Card(CardRank rank, CardSuit suit){
this.rank = rank;
this.suit = suit;
}
//reusable methods
protected String getCardSuit(){
return suit.getCardSuit();
}
protected byte getRankValue(){
return rank.getRankValue();
}
protected void flipCard(){
visibility = !visibility;
}
public String toString(){
if (visibility){
cardName="";
cardName+=rank.getRankValueName() + " of " + suit.getCardSuit();
}
else{
cardName = "You cannot see your opponents card";
}
return cardName;
}
}
Help. I appreciate for any help that will direct me into the right direction.
Saying you can't use Guava (Google Collections) for this seems incorrect at face value. Just give hand a sort method that lets it interact with cards (which is an ArrayList).
protected void sortHand(){
for (Hand playerHand: players){
List<Card> sortedHand = playerHand.getSortedCards();
// Do whatever
}
}
Hand.java
public class Hand {
...
public List<Card> getSortedCards() {
Collections.sort(cards);
return cards; // Consider deep copying.
}
}
From there, making Card implement Comparable will let you sort the list.
Card.java
public class Card implements Comparable<Card>
{
...
#Override
public int compareTo(Card o) {
if (this.rank.getRankValue() < o.rank.getRankValue()) {
return -1;
}
else if (o.rank.getRankValue() < this.rank.getRankValue()) {
return 1;
}
return 0;
}
}
protected void sortHand(){
for (Hand playerHand: players){
i = 0;
int []arr = new int[5];
while(i<5){
System.out.println(playerHand.cards.get(i).getRankValue());
arr[i] = playerHand.cards.get(i).getRankValue();
i++;
}
Arrays.sort(arr);
}
}
you can try adding it to an array and call Array.sort(). where i assume that getRankvalue will return an int . try this
ArrayLists can be easily sorted using a Comparator.
You would then get something like this:
cards.sort(new Comparator<Card>() {
#Override
public int compare(Card card1, Card card2) {
// return -1 if card1 should come before card2
// return 0 if card1 and card2 have equal values
// return 1 if card1 should come after card2
}
});
I suggest you use a static array to store cards in hand:
public class Hand {
private static final int MAX_CARD = 5;//modify with your value
protected Card[] cards;
private int currentCardNumber;
private String handCards;
// Constructor
protected Hand() {
cards = new Card[MAX_CARD];
currentCardNumber = 0;
}
// reusable methods
protected void add(Card card) {
if (currentCardNumber == MAX_CARD - 1) { return; }
cards[currentCardNumber] = card;
currentCardNumber++;
}
protected void emptyHand() {
for (int i = 0; i < MAX_CARD; i++) {
cards[i] = null;
}
currentCardNumber = 0;
}
protected void flipHandCards() {
for (int i = 0; i < currentCardNumber; i++) {
cards[i].flipCard();
}
}
protected String displayHand() {
handCards = "";
for (int i = 0; i < currentCardNumber; i++) {
handCards += cards[i].toString() + "\n";
}
return handCards;
}
protected boolean giveCard(Card card, Hand differentHand) {
int index = getCardIndex(card);
if (index == -1) {
return false;
} else {
differentHand.add(remove(index));
return true;
}
}
protected void sortHand() {
for(int i = 0; i < currentCardNumber; i++) {
for(int j = i + 1; j < currentCardNumber; j++) {
if(cards[j].getRankValue() < cards[i].getRankValue()) {
Card tmp = cards[j];
cards[j] = cards[i];
cards[i] = tmp;
}
}
}
}
private int getCardIndex(Card card) {
for (int i = 0; i < currentCardNumber; i++) {
if(card.equals(cards[i]) {
return i;
}
}
return -1;
}
private Card remove(int cardIndex) {
if (currentCardNumber == 0) { return null; }
Card tmp = cards[cardIndex];
for (int i = cardIndex + 1; i < currentCardNumber; i++) {
cards[i - 1] = cards[i];
}
cards[currentCardNumber - 1] = null;
currentCardNumber--;
return tmp;
}
}
Or you can create your own List and apply a your own sort method.

StackOverFlowError when looping through options

I'm working on an exercise and I'm running into something. The following code gives me a stackoverflow error, but I have no idea why because my code should stop.
class Options {
private int amount;
private ArrayList<Integer> pieces;
public void execute() {
pieces = new ArrayList<Integer>();
pieces.add(5);
pieces.add(2);
pieces.add(3);
amount = pieces.size();
combinations(new StringBuilder());
}
public void combinations(StringBuilder current) {
if(current.length() == pieces.size()) {
System.out.println(current.toString());
return;
}
for(int i = 0; i < amount; i++) {
current.append(pieces.get(i));
combinations(current);
}
}
}
It only prints the first output (555).
Thanks.
Add a return to end your recursion
public void combinations(StringBuilder current) {
if(current.length() == pieces.size()) {
System.out.println(current.toString());
return; // <-- like so.
}
for(int i = 0; i < amount; i++) {
current.append(pieces.get(i));
combinations(current);
}
}
or put the loop in an else like
public void combinations(StringBuilder current) {
if(current.length() == pieces.size()) {
System.out.println(current.toString());
} else {
for(int i = 0; i < amount; i++) {
current.append(pieces.get(i));
combinations(current);
}
}
}
Edit
static class Options {
private List<Integer> pieces;
public void execute() {
pieces = new ArrayList<>();
pieces.add(5);
pieces.add(2);
pieces.add(3);
combinations(new StringBuilder());
}
public void combinations(StringBuilder current) {
if (current.length() == pieces.size()) {
System.out.println(current.toString());
} else {
for (int i = current.length(); i < pieces.size(); i++) {
current.append(pieces.get(i));
combinations(current);
}
}
}
}
public static void main(String[] args) {
Options o = new Options();
o.execute();
System.out.println(o.pieces);
}
Output is
523
[5, 2, 3]

Java's Thread.sleep causes my previously called method to cancel

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.
Card.java
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();
}
}
Grid.java
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();
}
}
Client.java
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.

Categories