Added Autocorrect
Added Autocorrect
package solitaire;
import java.io.File;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import solitaire.Card.Suit;
import solitaire.Pile.PileType;
/**
* Core class of the application.
* Contains all objects and states of the game
*/
public class Engine {
ArrayList<Pile> piles;
ArrayList<Pile> finalPiles;
Pile drawPile, getPile;
ArrayList<Pile> allPiles;
public final int pileNumber = 7;
public Deck deck;
/**
* Set the auto-start feature.
* @param autoStart Whether to enable auto-start.
*/
public void setAutoStart(boolean autoStart) {
this.autoStart = autoStart;
}
/**
* Get the current status of the auto-start feature.
* @return true if auto-start is enabled, false otherwise.
*/
public boolean isAutoStart() {
return autoStart;
}
/**
* Class constructor
*/
public Engine() {
resetCards();
}
/**
* Reset all game piles and the deck
*/
public void resetCards() {
deck = new Deck();
deck.shuffle();
/**
* Setup the initial game state
*/
public void setupGame() {
// Generate piles
drawPile.type = PileType.Draw;
getPile.type = PileType.Get;
if(j!=i)
card.hide();
else
card.show();
}
piles.add(p);
allPiles.add(p);
}
/**
* Draw a card from the draw pile and place it into the get pile
*/
public void drawCard() {
if(!drawPile.cards.isEmpty()) {
Card drew = drawPile.drawCard();
drew.isReversed = false;
getPile.addCard(drew);
}
}
/**
* When a normal pile is clicked, if the top card is reversed show it
* @param {Pile} p
*/
public void clickPile(Pile p) {
if(!p.cards.isEmpty()) {
Card c = p.cards.get(p.cards.size() - 1);
if(c.isReversed) {
c.isReversed = false;
}
}
}
/**
* Reverse the Get pile and place it again for Draw
*/
public void turnGetPile() {
if(!drawPile.cards.isEmpty()) return;
while(!getPile.cards.isEmpty()) {
Card c = getPile.drawCard();
c.isReversed = true;
drawPile.addCard(c);
}
}
/**
* Tests wheter all the cards have been placed in the correct pile
* @return {Boolean}
*/
public boolean checkWin() {
for(Pile p : finalPiles) {
if(p.cards.size() != 13)
return false;
}
return true;
}
/**
* Save the game state to save.xml file
*/
public void save() {
try {
DocumentBuilder docBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
p.appendChild(cardE);
}
game.appendChild(p);
}
Transformer transformer =
TransformerFactory.newInstance().newTransformer();
DOMSource src = new DOMSource(doc);
StreamResult res = new StreamResult(new File("save.xml"));
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
"2");
transformer.transform(src, res);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Load the game state from save.xml file
*/
public void load() {
try {
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse("save.xml");
Element docEle = dom.getDocumentElement();
NodeList nl = docEle.getChildNodes();
int currentPileCount = 0;
if (nl != null) {
// Iterate through all piles
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i).getNodeType() != Node.ELEMENT_NODE)
continue;
Element el = (Element) nl.item(i);
if (el.getNodeName().contains("pile")) {
if (cardList != null) {
// Iterate through all cards
for (int j = 0; j < cardList.getLength();
j++) {
if
(cardList.item(j).getNodeType() != Node.ELEMENT_NODE)
continue;
String suitName =
cardNode.getAttribute("suit");
boolean isReversed =
cardNode.getAttribute("isReversed").equals("true");
int value =
Card.valueInt(cardNode.getAttribute("value"));
piles.get(currentPileCount).merge(tempPile);
} else if (currentPileCount < pileNumber
+ 4) {
finalPiles.get(currentPileCount -
pileNumber)
.merge(tempPile);
if (!tempPile.isEmpty()) {
// Set the pile filter for
final piles
Card c =
tempPile.peekTopCard();
finalPiles.get(currentPileCount
-
pileNumber).suitFilter = c.suit;
}
} else if (currentPileCount == pileNumber
+ 4) {
drawPile.merge(tempPile);
} else {
getPile.merge(tempPile);
}
}
currentPileCount++;
}
}
}
// Draw and add the cards again so the offsets are re-calculated
for(Pile p: allPiles) {
ArrayList<Card> cards = new ArrayList<Card>();
while(!p.isEmpty()) cards.add(p.drawCard());
} catch(Exception e ) {
e.printStackTrace();
}
}
}
In the GUI class, a new checkbox is added to the top menu bar to toggle the auto-
start feature. The checkbox state is linked to the Engine class, and the auto-start
behavior is adjusted according
package solitaire;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import solitaire.Pile.PileType;
/**
* GUI class constructor
*/
public GUI (Engine game) {
this.game = game;
// Initialize stuff
createTextMap();
// Window settings
setTitle("Solitaire");
setSize(900, 700);
try {
setContentPane((new
JPanelWithBackground("../images/background.jpg")));
} catch (IOException e) {
e.printStackTrace();
}
setLayout(new BorderLayout());
gameArea.add(topColumns);
gameArea.add(columns);
//layers.add(dragLayer, JLayeredPane.DRAG_LAYER);
add(gameArea);
// Auxiliarry elements
mouseOffset = new Point(0, 0);
initialize();
}
/**
* Add cards from the game to the GUI
*/
private void initialize() {
topColumns.removeAll();
columns.removeAll();
game.setupGame();
for(Pile p : game.piles) {
columns.add(p);
}
topColumns.add(game.drawPile);
topColumns.add(game.getPile);
for(Pile p : game.finalPiles) {
topColumns.add(p);
}
validate();
}
/**
* Resets the whole game
*/
public void reset() {
game.resetCards();
initialize();
repaint();
}
/**
* Creates the displayText map
* Change this if you want to translate the game into another language
*/
private void createTextMap() {
displayText = new HashMap<String, String>();
displayText.put("File", "File");
displayText.put("New", "New");
displayText.put("Save", "Save");
displayText.put("Load", "Load");
displayText.put("Exit", "Exit");
}
/**
* Create the top menu bar
*/
private void createTopMenu() {
menuBar = new JMenuBar();
opt.addActionListener(this);
FileMenu.add(opt);
}
setJMenuBar(menuBar);
/**
* Auxiliary class which stores information about a single menu option
* @member {String} name The name of the
* @member {Integer} shortcut The mnemonic for this button
*/
class menuOption {
public String name;
public Integer shorcut = 0;
/**
* Handles the activation of any of the menu bar buttons
* @param {ActionEvent} e
*/
private void handleMenuInteraction(ActionEvent e) {
JMenuItem item = (JMenuItem)e.getSource();
if(item.getText().equals(displayText.get("Exit"))) {
this.dispose();
return;
}
if(item.getText().equals(displayText.get("New"))) {
reset();
return;
}
if(item.getText().equals(displayText.get("Save"))) {
game.save();
JOptionPane.showMessageDialog(this, "Game saved!");
return;
}
if(item.getText().equals(displayText.get("Load"))) {
game.load();
validate();
return;
}
}
/**
* code by Ramya Dandamudi
* Function to handle most of the events performed on the GUI
*/
@Override
public void actionPerformed(ActionEvent e) {
// Handle checkbox action event
if (e.getSource() == autoStartCheckBox) {
game.setAutoStart(autoStartCheckBox.isSelected());
}
// Handle all other menu interactions
else if (e.getSource() instanceof JMenuItem) {
handleMenuInteraction(e);
}
}
///////////////////////////////////////////////////////
@Override
public void mouseDragged(MouseEvent e) {
if(tempPile != null) {
Point pos = getLocationOnScreen();
pos.x = e.getLocationOnScreen().x - pos.x - mouseOffset.x;
pos.y = e.getLocationOnScreen().y - pos.y - mouseOffset.y;
tempPile.setLocation(pos);
}
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
@Override
public void mouseClicked(MouseEvent e) {
if(e.getComponent() instanceof Card) {
Card c = (Card)e.getComponent();
Pile p = (Pile)c.getParent();
switch(p.type) {
case Draw:
game.drawCard();
break;
case Normal:
game.clickPile(p);
break;
case Get:
game.turnGetPile();
break;
}
repaint();
}
}
@Override
public void mousePressed(MouseEvent e) {
if(e.getComponent() instanceof Card) {
Card c = (Card)e.getComponent();
Pile p = (Pile)c.getParent();
tempPile = p.split(c);
lp.add(tempPile, JLayeredPane.DRAG_LAYER);
repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
if(tempPile != null) {
for(Pile p: droppable) {
Point pilePos = p.getLocationOnScreen();
Rectangle r = p.getBounds();
r.x = pilePos.x;
r.y = pilePos.y;
lp.remove(tempPile);
tempPile = null;
repaint();
if(game.checkWin()) {
JOptionPane.showMessageDialog(this, "You won!
Congrats!");
reset();
}
}
}