/* Simple Solitare Card Game in Java Written by Tim Budd, Oregon State University, 1996 */ import java.awt.*; import java.util.Random; import java.awt.event.*; import java.util.Enumeration; class SuitPile extends CardPile { SuitPile (int x, int y) { super(x, y); } public boolean canTake (Card aCard) { if (isEmpty()) return aCard.rank() == 0; Card topCard = top(); return (aCard.suit() == topCard.suit()) && (aCard.rank() == 1 + topCard.rank()); } } class DeckPile extends CardPile { DeckPile (int x, int y) { // first initialize parent super(x, y); // then create the new deck // first put them into a local pile for (int i = 0; i < 4; i++) for (int j = 0; j <= 12; j++) addCard(new Card(i, j)); // then shuffle the cards Random generator = new Random(); for (int i = 0; i < 52; i++) { int j = Math.abs(generator.nextInt() % 52); // swap the two card values Object temp = thePile.elementAt(i); thePile.setElementAt(thePile.elementAt(j), i); thePile.setElementAt(temp, j); } } public void select(int tx, int ty) { if (isEmpty()) return; Solitare.discardPile.addCard(pop()); } } class DiscardPile extends CardPile { DiscardPile (int x, int y) { super (x, y); } public void addCard (Card aCard) { if (! aCard.faceUp()) aCard.flip(); super.addCard(aCard); } public void select (int tx, int ty) { if (isEmpty()) return; Card topCard = pop(); for (int i = 0; i < 4; i++) if (Solitare.suitPile[i].canTake(topCard)) { Solitare.suitPile[i].addCard(topCard); return; } for (int i = 0; i < 7; i++) if (Solitare.tableau[i].canTake(topCard)) { Solitare.tableau[i].addCard(topCard); return; } // nobody can use it, put it back on our list addCard(topCard); } } class TablePile extends CardPile { TablePile (int x, int y, int c) { // initialize the parent class super(x, y); // then initialize our pile of cards for (int i = 0; i < c; i++) { addCard(Solitare.deckPile.pop()); } // flip topmost card face up top().flip(); } public boolean canTake (Card aCard) { if (isEmpty()) return aCard.rank() == 12; Card topCard = top(); return (aCard.color() != topCard.color()) && (aCard.rank() == topCard.rank() - 1); } public boolean includes (int tx, int ty) { // don't test bottom of card return x <= tx && tx <= x + Card.width && y <= ty; } public void select (int tx, int ty) { if (isEmpty()) return; // if face down, then flip Card topCard = top(); if (! topCard.faceUp()) { topCard.flip(); return; } // else see if any suit pile can take card topCard = pop(); for (int i = 0; i < 4; i++) if (Solitare.suitPile[i].canTake(topCard)) { Solitare.suitPile[i].addCard(topCard); return; } // else see if any other table pile can take card for (int i = 0; i < 7; i++) if (Solitare.tableau[i].canTake(topCard)) { Solitare.tableau[i].addCard(topCard); return; } // else put it back on our pile addCard(topCard); } public void display (Graphics g) { int localy = y; for (Enumeration e = thePile.elements(); e.hasMoreElements(); ) { Card aCard = (Card) e.nextElement(); aCard.draw (g, x, localy); localy += 35; } } } public class Solitare { static public DeckPile deckPile; static public DiscardPile discardPile; static public TablePile tableau [ ]; static public SuitPile suitPile [ ]; static public CardPile allPiles [ ]; private Frame window; static public void main (String [ ] args) { Solitare world = new Solitare(); } public Solitare () { window = new SolitareFrame(); init(); window.show(); } public void init () { // first allocate the arrays allPiles = new CardPile[13]; suitPile = new SuitPile[4]; tableau = new TablePile[7]; // then fill them in allPiles[0] = deckPile = new DeckPile(335, 30); allPiles[1] = discardPile = new DiscardPile(268, 30); for (int i = 0; i < 4; i++) allPiles[2+i] = suitPile[i] = new SuitPile(15 + (Card.width+10) * i, 30); for (int i = 0; i < 7; i++) allPiles[6+i] = tableau[i] = new TablePile(15 + (Card.width+5) * i, Card.height + 35, i+1); } private class SolitareFrame extends Frame { private class RestartButtonListener implements ActionListener { public void actionPerformed (ActionEvent e) { init(); window.repaint(); } } private class MouseKeeper extends MouseAdapter { public void mousePressed (MouseEvent e) { int x = e.getX(); int y = e.getY(); for (int i = 0; i < 13; i++) if (allPiles[i].includes(x, y)) { allPiles[i].select(x, y); repaint(); } } } public SolitareFrame() { setSize(600, 500); setTitle("Solitaire Game"); addMouseListener (new MouseKeeper()); Button restartButton = new Button("New Game"); restartButton.addActionListener(new RestartButtonListener()); add("South", restartButton); } public void paint(Graphics g) { for (int i = 0; i < 13; i++) allPiles[i].display(g); } } }