//*********************** Copy right information ************************* // FAQ's // Q. Is this program copy right protected? // Ans. No. Even if it was you will copy it anyway so what is the point //************************************************************************ // Program: Can You Recall card game // Programmer: H K Gupta Date: 30 May 1998 //************************************************************************ import java.awt.*; import java.awt.image.*; import java.applet.Applet; public class CanYouRecall extends Applet implements Runnable{ Panel pTop; Button bNewGame; Label lTitle; Panel pTopRight; Label results; Button bHelp; CanYouRecallArea playArea; HridayeshCardDeck deck; // card deck for playing the game Thread runThread = null; boolean firstTime = true; boolean pauseInEffect = false; public void init() { } public void start() { if (firstTime) { deck = new HridayeshCardDeck(); // get a new card deck setUpDisplay() ; results.setText("*****"); firstTime = false; } if (runThread == null) { if(!pauseInEffect) { runThread = new Thread(this, "CanYouRecall"); runThread.start(); } } } public void run() { while (Thread.currentThread() == runThread) { playArea.move(); try { Thread.sleep(40); } catch (InterruptedException e){} } } public void stop() { runThread = null; } void setUpDisplay() { setLayout(new BorderLayout()); pTop = new Panel(); pTop.setLayout(new BorderLayout()); add("North", pTop); bNewGame = new Button("New Game"); pTop.add("West", bNewGame); lTitle = new Label("CAN YOU RECALL by HRIDAYESH", Label.CENTER); pTop.add("Center", lTitle); pTopRight = new Panel(); pTopRight.setLayout(new GridLayout(0, 2)); pTop.add("East", pTopRight); bHelp = new Button("Help Me!"); pTopRight.add(bHelp); results = new Label("Tries: ****", Label.CENTER); pTopRight.add(results); playArea = new CanYouRecallArea(this); add("Center", playArea); validate(); } public boolean action(Event e, Object arg) { Object target = e.target; if(target == bNewGame) {playArea.dealHand(); return true;} if(target == bHelp) {processHelp(); return true;} return false; } private void processHelp() { HridayeshHelp window = null; try { window = new HridayeshHelp(); } catch (Exception e) { bHelp.setLabel("Error"); bHelp.disable(); return; } window.setTitle("CanYouRecallHelp"); window.setText( "\n Want to understand what is going on ???????" + "\n\n The objective of the game is to match two cards by uncovering" + "\n them togather. If you open two cards and they are not same, both" + "\n cards will close. However if they happen to be same, both the cards" + "\n will magically disappear. Your objective is to clear the screen" + "\n with minimum effort. A counter at the top right corner keeps track" + "\n of no. of attempts." + "\n\n Attempts > 40 you are not paying attention" + "\n 40 < > 30 Reasonable" + "\n 30 < > 25 Good" + "\n 25 < > 20 Excellent" + "\n 20 < > 14 Your name is GARY KASPAROV" + "\n Less than 14 You are lying" + "\n\n How to cheat: use pencil and paper"); window.pack(); window.show(); } } class CanYouRecallArea extends Canvas { private CanYouRecall controller; private HridayeshLoadCards deckImages; int rowCount = 4; int columnCount = 8; int[][] cards; int[][] cardStatus; int cardW; int cardH; int xOff; int yOff; public CanYouRecallArea(CanYouRecall controller) { super(); this.controller = controller; deckImages = new HridayeshLoadCards((Applet)controller); cardW = deckImages.getCardW(); cardH = deckImages.getCardH(); cards = new int[rowCount][columnCount]; cardStatus = new int[rowCount][columnCount]; } private int openCardsCount; private int openCardOne; private int openCardTwo; private int tries = 0; public void dealHand() { controller.deck.reset(); for(int i = 0; i < rowCount; i++) { // Empty the display grid for(int j = 0; j < columnCount; j++) { cards[i][j] = -1; cardStatus[i][j] = 0; // Card close } } for(int k = 0; k < rowCount * columnCount / 2; k++) { int newCard = controller.deck.newCard(); addRandom(newCard); addRandom(newCard); } openCardsCount = 0; tries = 0; controller.results.setText("Tries : " + tries); gameInProgress = true; repaint(); } private void addRandom(int newCard) { int freeCount = 0; for(int i = 0; i < rowCount; i++) { for(int j = 0; j < columnCount; j++) { if (cards[i][j] == -1) freeCount++; } } int randomOffset = (int)(Math.random() * freeCount) + 1; int offset = 0; for(int i = 0; i < rowCount; i++) { for(int j = 0; j < columnCount; j++) { if (cards[i][j] == -1) offset++; if(offset == randomOffset) { cards[i][j] = newCard; return; } } } } private boolean flagSetOffsets = true; Image offImage; Graphics o; private int radius = 0; public void update(Graphics g) { Dimension d = size(); if(flagSetOffsets) { offImage = createImage(d.width, d.height); o = offImage.getGraphics(); xOff = (d.width - cardW * columnCount) / 2; yOff = (d.height - cardH * rowCount) /2; flagSetOffsets = false; } o.setColor(Color.green); o.fillRect(0, 0, d.width, d.height); if (gameInProgress) { for(int i = 0; i < rowCount; i++) { // draw all cards for(int j = 0; j < columnCount; j++) { paintCard(o, i, j); } } } else { showFace(o); } g.drawImage(offImage, 0, 0, this); } private int incr = 5; private void showFace(Graphics o) { Dimension d = size(); int x = d.width / 2; int y = d.height / 2; if (radius > d.height / 2) incr = -5; if (radius < 20) incr = 5; radius = radius + incr; o.setColor(Color.red); int r = radius; o.drawOval(x - r, y - r, r * 2, r * 2); o.drawOval(x - 2 * r / 4, y - 2 * r / 4, r / 4, r / 4); o.drawOval(x + r / 4, y - 2 * r / 4, r / 4, r / 4); o.drawOval(x - r / 10, y - r / 5, r / 5, 3 * r / 5); o.drawOval(x - 2 * r / 5, y + 3 * r / 5, 4 * r / 5, r / 5); } void paintCard(Graphics g, int row, int column) { int x = xOff + column * cardW; int y = yOff + row * cardH; if(cards[row][column] != -1) { int drawCardNumber = cards[row][column]; if(cardStatus[row][column] == 0) drawCardNumber = -1; g.drawImage(deckImages.getCardImage(drawCardNumber), x, y, this); } else { g.setColor(Color.green); g.fillRect(x, y, cardW, cardH); } } boolean autoInProgress = false; boolean moveInProgress = false; boolean gameInProgress = false; public boolean mouseDown(Event event, int x, int y) { if(!gameInProgress) return false; if(autoInProgress || moveInProgress) return false; for(int i = 0; i < rowCount; i++) { for(int j = 0; j < columnCount; j++) { if((x > (xOff + j * cardW)) && (x < xOff + (j + 1) * cardW) && (y > (yOff + i * cardH)) && (y < yOff + (i + 1) * cardH)) { if(cards[i][j] == -1) return false; if(cardStatus[i][j] != 0) return false; processMove(i, j); return true; } } } return false; } private void processMove(int row, int column) { switch (openCardsCount) { case 0: cardStatus[row][column] = 1; openCardsCount = 1; openCardOne = cards[row][column]; repaint(); break; case 1: cardStatus[row][column] = 1; openCardsCount = 2; openCardTwo = cards[row][column]; waitCount = 10; tries++; controller.results.setText("Tries : " + tries); repaint(); break; default: } } private int waitCount = 0; void move() { if(gameInProgress) { processGameMove(); checkGameOver(); } else { repaint(); } } private void processGameMove() { if(openCardsCount < 2) return; waitCount--; if(waitCount > 0) return; for(int i = 0; i < rowCount; i++) { for(int j = 0; j < columnCount; j++) { cardStatus[i][j] = 0; if(openCardOne == openCardTwo) { if(cards[i][j] == openCardOne) { cards[i][j] = -1; // remove matched cards } } } } openCardsCount = 0; repaint(); } private void checkGameOver() { for(int i = 0; i < rowCount; i++) { for(int j = 0; j < columnCount; j++) { if(cards[i][j] != -1) return; } } gameInProgress = false; } public void paint(Graphics g) { update(g); } }