0% found this document useful (0 votes)
31 views14 pages

Added Autocorrect

The document describes changes made to an Engine class for a solitaire game. A new boolean variable called autoStart is added to control an auto-start feature, which is enabled by default. Methods are also added to get and set the autoStart value.

Uploaded by

dandamudi.ramya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views14 pages

Added Autocorrect

The document describes changes made to an Engine class for a solitaire game. A new boolean variable called autoStart is added to control an auto-start feature, which is enabled by default. Methods are also added to get and set the autoStart value.

Uploaded by

dandamudi.ramya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 14

In the Engine class, a new boolean variable autoStart is added to control the auto-

start feature. This variable is set to true by default.

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;

// New variable to control auto-start feature


private boolean autoStart = true;

/**
* 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();

drawPile = new Pile(120);


drawPile.setOffset(0);

getPile = new Pile(180);


getPile.setOffset(0);

finalPiles = new ArrayList<Pile>();


piles = new ArrayList<Pile>();

allPiles = new ArrayList<Pile>();


allPiles.add(drawPile);
allPiles.add(getPile);
}

/**
* Setup the initial game state
*/
public void setupGame() {
// Generate piles
drawPile.type = PileType.Draw;
getPile.type = PileType.Get;

for(int i = 1; i <= pileNumber; ++i) {


Pile p = new Pile(120);

// Add i cards to the current pile


for(int j = 1; j <= i; ++j) {
Card card = deck.drawCard();
p.addCard(card);

if(j!=i)
card.hide();
else
card.show();
}

piles.add(p);
allPiles.add(p);
}

for(Suit suit : Suit.values()) {


Pile p = new Pile(100);
p.setOffset(0);
p.type = PileType.Final;
finalPiles.add(p);
allPiles.add(p);
}
while(deck.size() > 0) {
Card card = deck.drawCard();
card.hide();
drawPile.addCard(card);
}
}

/**
* 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() {

String saveString = "";

try {
DocumentBuilder docBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();

Document doc = docBuilder.newDocument();

String newLine = System.getProperty( "line.separator" );

Element game = doc.createElement("game");


doc.appendChild(game);

// This is from previous implementation, save each pile in a new


line
for(Pile p : piles)
saveString += p.toString() + newLine;
for(Pile p: finalPiles)
saveString += p.toString() + newLine;
saveString += drawPile.toString() + newLine;
saveString += getPile.toString() + newLine;

String[] lines = saveString.split(newLine);

for(String pile : lines) {


Element p = doc.createElement("pile");

String cardStrings[] = pile.split("-");


for(String c: cardStrings) {
String parts[] = c.split(" of ");

Element cardE = doc.createElement("card");


cardE.setAttribute("value", parts[0]);
cardE.setAttribute("suit", parts[1]);
cardE.setAttribute("isReversed", parts[2]);

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")) {

NodeList cardList = el.getChildNodes();


Pile tempPile = new Pile(100);

if (cardList != null) {
// Iterate through all cards
for (int j = 0; j < cardList.getLength();
j++) {
if
(cardList.item(j).getNodeType() != Node.ELEMENT_NODE)
continue;

Element cardNode = (Element)


cardList.item(j);

String suitName =
cardNode.getAttribute("suit");
boolean isReversed =
cardNode.getAttribute("isReversed").equals("true");
int value =
Card.valueInt(cardNode.getAttribute("value"));

// Skip the base card


if (value == 100)
continue;

// Search for the card in all piles


Card card = null;
Pile foundPile = null;

for (Pile p : allPiles) {


if ((card =
p.searchCard(value, suitName)) != null) {
foundPile = p;
break;
}
}
tempPile.addCard(card);
foundPile.removeCard(card);

// Face-up or face-down card


if (isReversed) {
card.hide();
} else {
card.show();
}
}

// Add the cards to the correct pile


if (currentPileCount < pileNumber) {

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());

for(Card card: cards)


p.addCard(card);
}

} 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;

public class GUI extends JFrame implements ActionListener, MouseListener,


MouseMotionListener {

private JMenuBar menuBar;

private JCheckBox autoStartCheckBox; // New checkbox to control auto-


start

// Map all the GUI text


Map<String, String> displayText;
JPanel gameArea;
JPanel columns;
JPanel topColumns;
JLayeredPane lp;
Engine game;

// Auxiliary elements to use while dragging


Pile tempPile;
Point mouseOffset;

/**
* 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 = new JPanel();


gameArea.setOpaque(false);
gameArea.setLayout(new BoxLayout(gameArea, BoxLayout.PAGE_AXIS));

// Center the window


setLocationRelativeTo(null);

// Window close event


setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

// Add GUI elements


createTopMenu();

// Flow layout to display multiple columns on the same row


FlowLayout flow = new FlowLayout(FlowLayout.CENTER);
flow.setAlignOnBaseline(true);

// Add the columns panel


columns = new JPanel();
columns.setOpaque(false);
columns.setLayout(flow);
columns.setMinimumSize(new Dimension(200, 900));

// Add the top columns panel


FlowLayout topFlow = new FlowLayout(FlowLayout.LEFT);
topFlow.setAlignOnBaseline(true);

topColumns = new JPanel();


topColumns.setOpaque(false);
topColumns.setLayout(topFlow);

gameArea.add(topColumns);
gameArea.add(columns);

//layers.add(dragLayer, JLayeredPane.DRAG_LAYER);
add(gameArea);

// Display the window


lp = getLayeredPane();
setVisible(true);

// Auxiliarry elements
mouseOffset = new Point(0, 0);

initialize();
}

/**
* Add cards from the game to the GUI
*/
private void initialize() {
topColumns.removeAll();
columns.removeAll();

// Add a listener for each card


for(Card c: game.deck.cards) {
c.addMouseListener(this);
c.addMouseMotionListener(this);
}

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();

JMenu FileMenu = new JMenu("File");


FileMenu.setMnemonic(KeyEvent.VK_F);
menuBar.add(FileMenu);

menuOption[] fileOptions = new menuOption[] {


new menuOption(displayText.get("New"), KeyEvent.VK_N),
new menuOption(displayText.get("Save"), KeyEvent.VK_S),
new menuOption(displayText.get("Load"), KeyEvent.VK_L),
new menuOption(displayText.get("Exit"), KeyEvent.VK_X)
};

for(menuOption option: fileOptions) {


JMenuItem opt = new JMenuItem(option.name);
if(option.shorcut != 0) opt.setMnemonic(option.shorcut);

opt.addActionListener(this);
FileMenu.add(opt);
}

setJMenuBar(menuBar);

//Code added by Ramya Dandamudi


autoStartCheckBox = new JCheckBox("Auto-Start",
game.isAutoStart());
autoStartCheckBox.addActionListener(this);
FileMenu.add(autoStartCheckBox);
///////////////////////

/**
* 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;

public menuOption(String name, Integer shorcut) {


this.name = name;
this.shorcut = shorcut;
}
}

/**
* 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();

// Do nothing if card is reversed


if(c.isReversed)
return;

Pile p = (Pile)c.getParent();

if(p.cards.isEmpty() || p.type == PileType.Final) return;

tempPile = p.split(c);

lp.add(tempPile, JLayeredPane.DRAG_LAYER);

Point pos = getLocationOnScreen();


mouseOffset = e.getPoint();
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 mouseReleased(MouseEvent e) {
if(tempPile != null) {

Point mousePos = e.getLocationOnScreen();


boolean match = false;

// Check if pile can merge with the pile it is dropped on


ArrayList<Pile> droppable = new
ArrayList<Pile>(game.piles);
droppable.addAll(game.finalPiles);

for(Pile p: droppable) {
Point pilePos = p.getLocationOnScreen();
Rectangle r = p.getBounds();
r.x = pilePos.x;
r.y = pilePos.y;

if(r.contains(mousePos) && p.acceptsPile(tempPile)) {


p.merge(tempPile);
match = true;
break;
}
}

// Snap back if no merge is found


if(!match) tempPile.parent.merge(tempPile);

lp.remove(tempPile);
tempPile = null;

repaint();

if(game.checkWin()) {
JOptionPane.showMessageDialog(this, "You won!
Congrats!");
reset();
}
}
}

public void mouseEntered(MouseEvent arg0) {}


public void mouseExited(MouseEvent arg0) {}

public class JPanelWithBackground extends JPanel {


private Image backgroundImage;

// Some code to initialize the background image.


// Here, we use the constructor to load the image. This
// can vary depending on the use case of the panel.
public JPanelWithBackground(String fileName) throws IOException
{
URL urlToImage = this.getClass().getResource(fileName);
backgroundImage = ImageIO.read(urlToImage);
}

public void paintComponent(Graphics g) {


super.paintComponent(g);

// Draw the background image.


g.drawImage(backgroundImage, 0, 0, this);
}
}
}

You might also like