Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package giftest;
- import java.awt.Color;
- import java.awt.Dimension;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.Toolkit;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyEvent;
- import java.awt.event.KeyListener;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import javax.swing.ImageIcon;
- import javax.swing.JMenuBar;
- import javax.swing.JPanel;
- import javax.swing.Timer;
- public class Board extends JPanel implements ActionListener {
- private Dimension d;
- private Image ii;
- private CardListener cL;
- private CardGame theGame;
- private Deck deck;
- private ArrayList<Stack> piles;
- private ArrayList<SortedStack> sortedPiles;
- private Shallow shallow;
- private MoveMemory mm;
- private JMenuBar menuBar_1;
- // was going to implement this but not enough time.
- public Timer timer;
- //public boolean isStarted = false;
- //public boolean isPaused = false;
- // called if no seed is presented
- public Board() {
- // create seed based off time...
- long seed = System.currentTimeMillis()%32767;
- // load in the games data and set the board up...
- loadData(seed);
- // load the drawing assests and other nonesense...
- init(seed, null);
- timer = new Timer(400, this);
- timer.start();
- // last minute changes before drawing....
- setBackground(Color.DARK_GRAY);
- // refresh twice as often...
- setDoubleBuffered(true);
- // obvious...
- setFocusable(true);
- }
- public Board(long seed, String saveFile){
- // load game data and recreate board state from save...
- loadData(seed);
- // load assests and over nonesense...
- init(seed, saveFile);
- timer = new Timer(400, this);
- timer.start();
- // last minute changes before drawing....
- setBackground(Color.DARK_GRAY);
- // refresh twice as often...
- setDoubleBuffered(true);
- // obvious...
- setFocusable(true);
- }
- // add a specific card movement to move history, boolean t says if we carry.
- public void addMove(Card c, CardContainer prev_cc, CardContainer cur_cc, boolean t) {
- this.mm.addMove(new Move(c.getSerialized(), prev_cc, cur_cc, t));
- }
- // add specific cards to move history, carry assumed false.
- public void addMove(ArrayList<Card> c, CardContainer prev_cc, CardContainer cur_cc) {
- ArrayList<String> cl = new ArrayList<>();
- for (Card cidx : c) {
- cl.add(cidx.getSerialized());
- }
- this.mm.addMove(new Move(cl, prev_cc, cur_cc));
- }
- // add specific cards to move history, boolean t says if we carry.
- public void addMove(ArrayList<Card> c, CardContainer prev_cc, CardContainer cur_cc, boolean t) {
- ArrayList<String> cl = new ArrayList<>();
- for (Card cidx : c) {
- cl.add(cidx.getSerialized());
- }
- this.mm.addMove(new Move(cl, prev_cc, cur_cc, t));
- }
- private void init(long seed, String saveFile) {
- d = new Dimension(400, 400);
- Card.back = new ImageIcon(this.getClass().getResource("assets/back01.gif")).getImage();
- //record or set the boards initial state...
- theGame = new Solitaire(this);
- if(saveFile != null){
- mm = new MoveMemory(this, seed, saveFile);
- } else {
- mm = new MoveMemory(this, seed);
- }
- theGame.processMove();
- menuBar_1 = new JMenuBar();
- //menuBar_1.setBounds(0, 0, 441, 21);
- this.add(menuBar_1);
- cL = new CardListener(this, theGame);
- this.addMouseMotionListener(cL);
- this.addMouseListener(cL);
- // messy keylistener; didnt deserve its own class...
- this.addKeyListener(new KeyListener() {
- @Override
- public void keyTyped(KeyEvent ke) {}
- @Override
- public void keyReleased(KeyEvent ke) {}
- @Override
- public void keyPressed(KeyEvent ke) {
- if(ke.isControlDown()){
- if(ke.getKeyCode() == KeyEvent.VK_Z){
- mm.Undo();
- theGame.processMove();
- }
- if(ke.getKeyCode() == KeyEvent.VK_S){
- try {
- mm.saveGame();
- } catch (IOException ex) {
- Logger.getLogger(Board.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
- }
- });
- }
- public CardContainer getContainerByID(String id){
- for (Stack s : piles) {
- if(s.getID() == null ? id == null : s.getID().equals(id)){
- return s;
- }
- }
- if(deck.getID() == null ? id == null : deck.getID().equals(id)){
- return deck;
- }
- if(shallow.getID() == null ? id == null : shallow.getID().equals(id)){
- return shallow;
- }
- for (SortedStack ssl : sortedPiles) {
- if(ssl.getID() == null ? id == null : ssl.getID().equals(id)){
- return ssl;
- }
- }
- return null;
- }
- private void loadData(long seed){
- //loads new data...
- // add deck..
- deck = new Deck(seed, "deck");
- deck.shuffle();
- deck.shuffle();
- // make some stacks from the deck..
- piles = new ArrayList<>();
- for (int n = 0; n < 7; n++) {
- piles.add(new Stack(n * 32, 60, "stack"+n));
- for (int a = 0; a < n + 1; a++) {
- deck.dealCard(piles.get(n));
- }
- piles.get(n).getTopCard().setRevealed(true);
- }
- // specifiy a shallow...
- shallow = new Shallow(40, 0, "shallow");
- // add sorted piles...
- sortedPiles = new ArrayList<>();
- for (int idx = 0; idx < 4; idx++) {
- sortedPiles.add(new SortedStack(32 * (3 + idx), 0, "sortedstack"+idx));
- }
- }
- // draws all the cards in all of the containers...
- private void drawCards(Graphics g) {
- for (Stack s : piles) {
- s.drawCards(g, this);
- }
- for (Card c : deck.getDeck()) {
- c.draw(g, this);
- }
- for (Card c : getShallow().getStack()) {
- c.draw(g, this);
- }
- for (SortedStack ssl : sortedPiles) {
- for (Card c : ssl.getStack()) {
- c.draw(g, this);
- }
- }
- if (cL.isDragging()) {
- for (Card c : cL.getManipulatedCards()) {
- c.draw(g, this);
- }
- }
- }
- // finds the manipulated card and removes it from its container.
- public boolean reportManipulatedCard(Card c) {
- for (Stack s : piles) {
- for (Card c_idx : s.getStack()) {
- if (c_idx == c) {
- return s.removeCard(c);
- }
- }
- }
- return deck.removeCard(c);
- }
- // gets all cards and returns it as a list.
- public ArrayList<Card> getCards() {
- ArrayList<Card> cards = new ArrayList<>();
- for (Stack s : piles) {
- cards.addAll(s.getStack());
- }
- cards.addAll(deck.getStack());
- cards.addAll(shallow.getStack());
- for (CardContainer s : sortedPiles) {
- if (!s.cards.isEmpty()) {
- cards.addAll(s.getStack());
- }
- }
- return cards;
- }
- public ArrayList<Stack> getStacks() {
- return piles;
- }
- public ArrayList<SortedStack> getSortedStacks() {
- return sortedPiles;
- }
- public Deck getDeck() {
- return deck;
- }
- public Shallow getShallow() {
- return shallow;
- }
- public MoveMemory getMoveMemory() {
- return mm;
- }
- // gets the stack containing a specific card.
- public Stack getStackContaining(Card c) {
- for (Stack s : piles) {
- for (Card c_idx : s.getStack()) {
- if (c == c_idx) {
- return s;
- }
- }
- }
- return null;
- }
- // gets the real container of the card; not a instanced reference of it...
- // wish I could use pointers...
- public CardContainer getContainer(CardContainer cc_ref){
- for(CardContainer cc : this.getStacks()){
- if(cc == cc_ref){
- return cc;
- }
- }
- for(CardContainer cc : this.getSortedStacks()){
- if(cc == cc_ref){
- return cc;
- }
- }
- if(cc_ref == this.getShallow()){
- return this.getShallow();
- }
- //should never reach this.
- return null;
- }
- @Override
- public void paintComponent(Graphics g) {
- super.paintComponent(g);
- drawCards(g);
- g.drawImage(ii, 0, 0, this);
- Toolkit.getDefaultToolkit().sync();
- g.dispose();
- System.out.println("paint");
- }
- @Override
- public void actionPerformed(ActionEvent e) {
- repaint();
- }
- public void forceRepaint() {
- repaint();
- }
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.awt.Dimension;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.Point;
- import java.awt.Rectangle;
- import java.awt.image.ImageObserver;
- // card is very forward; doesnt require too much commenting because the names
- // of the methods and variables are pretty obvious.
- public class Card {
- private final int SUIT;
- private final int VALUE;
- // point in space.
- private Point p;
- // dimensions of the cards
- private int width;
- private int height;
- private boolean revealed;
- // hight with 0 being the bottom and n being the top. 0 <= n < highest int
- private int stackHeight;
- private CardContainer container;
- // card face to draw.
- public Image i;
- // card back; static because call cards share one instance of the image.
- public static Image back;
- // DONT USE THIS!!
- Card(int suit, int value){
- this.SUIT = suit;
- this.VALUE = value;
- }
- Card(Image i, int suit, int value){
- this.i = i;
- this.SUIT = suit;
- this.VALUE = value;
- this.revealed = true;
- this.stackHeight = 0;
- this.container = null;
- p = new Point(0,0);
- width = 32;
- height = 48;
- }
- Card(Image i, int suit, int value, CardContainer container){
- this.i = i;
- this.SUIT = suit;
- this.VALUE = value;
- this.revealed = false;
- this.stackHeight = 0;
- this.container = container;
- p = new Point(0,0);
- width = 32;
- height = 48;
- }
- Image getImage(){
- return revealed ? i : back;
- }
- void setPos(int x, int y){
- p = new Point(x, y);
- }
- void setPos(Point pos){
- p = pos;
- }
- void setContainer(CardContainer cc){
- this.container = cc;
- }
- Point getPos(){
- return p;
- }
- CardContainer getContainer(){
- return container;
- }
- Point getCenterPoint(){
- return new Point(p.x+(width/2), p.y+(height/2));
- }
- int getValue(){
- return VALUE;
- }
- int getSuit(){
- return SUIT;
- }
- // returns the card in a form that can be saved and loaded from file.
- String getSerialized(){
- String derp = "";
- derp += this.VALUE > 9 ? this.VALUE : "0"+this.VALUE;
- derp += "0"+this.SUIT;
- return derp;
- }
- void setRevealed(boolean b){
- revealed = b;
- }
- void setStackHeight(int d){
- stackHeight = d;
- }
- int getStackHeight(){
- return stackHeight;
- }
- int x(){
- return p.x;
- }
- int y(){
- return p.y;
- }
- boolean isRevealed(){
- return revealed;
- }
- // draws the front or back of the card based on revealed
- void draw(Graphics g, ImageObserver io){
- g.drawImage((revealed ? i : back), p.x, p.y, io);
- }
- // returns true if the point is inside the bounds of the card.
- boolean containsPoint(Point p){
- Rectangle r = new Rectangle(this.p, new Dimension(width, height));
- return r.contains(p);
- }
- // takes a serialized card and turns it into a card instance with no image.
- static Card deSerialize(String id){
- String derp = id+"";
- int val = Integer.parseInt(derp.substring(2, 4));
- int suit = Integer.parseInt(derp.substring(0, 2));
- return new Card(val, suit);
- }
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.awt.Dimension;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.awt.Rectangle;
- import java.awt.image.ImageObserver;
- import java.util.ArrayList;
- /**
- *
- * @author Ryland
- */
- // does this really need any comments? its all very readable...
- public abstract class CardContainer {
- protected ArrayList<Card> cards;
- protected Point pos;
- protected int width;
- protected int height;
- protected String id;
- CardContainer(){
- cards = new ArrayList<>();
- pos = new Point(0,0);
- width = 32;
- height = 48;
- }
- CardContainer(int x, int y){
- cards = new ArrayList<>();
- pos = new Point(x,y);
- width = 32;
- height = 48;
- }
- public void setStack(ArrayList<Card> s){
- cards = s;
- }
- public void addCard(Card c){
- cards.add(c);
- processCard(c);
- }
- public boolean addCards(ArrayList<Card> cL){
- for(Card c : cL){
- if(cards.contains(c)){
- return false;
- } else {
- cards.add(c);
- processCard(c);
- }
- }
- return true;
- }
- public ArrayList<Card> getStack(){
- return cards;
- }
- public boolean removeCard(Card c){
- for(Card c_idx : cards){
- if(c_idx == c){
- cards.remove(c);
- processCard(null);
- return true;
- }
- }
- return false;
- }
- public boolean removeCards(ArrayList<Card> cL){
- for(Card c : cL){
- if(!cards.remove(c)){return false;}
- }
- return true;
- }
- public Card getTopCard(){
- if(cards.isEmpty()){return null;}
- return cards.get(cards.size()-1);
- }
- String getID(){
- return id;
- }
- // check to see if the coordinate is inside the cards bounds...
- boolean containsPoint(Point p){
- Rectangle r = new Rectangle(this.pos, new Dimension(width, height));
- return r.contains(p);
- }
- // made for any specific behaviour the cardcontainers might want to do...
- abstract void processCard(Card c);
- // handles any funny ways to draw the card if they want to do anyting...
- abstract void drawCards(Graphics g, ImageObserver io);
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.util.ArrayList;
- /**
- *
- * @author Ryland
- */
- public interface CardGame {
- // can a card move to this container?
- public boolean canMoveCardTo(CardContainer cc, Card c);
- // can a stack of cards be changed?
- public boolean canManipulateStack(ArrayList<Card> c);
- // do logic after a move is done...
- public void processMove();
- // do something when a card container is clicked?
- public void interact(CardContainer cL);
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.awt.Point;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.util.ArrayList;
- class CardListener extends MouseAdapter {
- private final Board b;
- private ArrayList<Card> manipulatedCards;
- private boolean dragging;
- private Point absHandle;
- private CardContainer lastCardContainer;
- private final CardGame theGame;
- CardListener(Board b, CardGame theGame) {
- // get reference of the board
- this.b = b;
- // get reference of the game being played...
- this.theGame = theGame;
- // initialize other things...
- manipulatedCards = new ArrayList<>();
- dragging = false;
- }
- ArrayList<Card> getManipulatedCards() {
- return manipulatedCards;
- }
- boolean isDragging() {
- return dragging;
- }
- @Override
- public void mouseDragged(MouseEvent me) {
- // if were holding a card....
- if (dragging) {
- // for each card were moving...
- for (int idx = 0; idx < manipulatedCards.size(); idx++) {
- // move them to our new mouse location with an offset
- // based on where we click the card...
- Point p = new Point(
- me.getPoint().x - absHandle.x,
- me.getPoint().y - absHandle.y + +20 * idx
- );
- // set its position to our current cursor pos + the offset
- // given by where we held the card.
- manipulatedCards.get(idx).setPos(p);
- }
- // repaint because we dont want to look like were running at 2 fps..
- b.forceRepaint();
- }
- }
- @Override
- public void mouseMoved(MouseEvent me) {
- }
- @Override
- public void mousePressed(MouseEvent me) {
- manipulatedCards = new ArrayList<>();
- // get the container we clicked on if we clicked on a container...
- CardContainer cc = getContainer(me.getPoint());
- // we didnt click on the container, do nothing...
- if (cc == null) {
- return;
- }
- // we clicked on the deck so dont allow a drag but interact instead.
- if (cc.getClass() == Deck.class) {
- theGame.interact(cc);
- return;
- }
- // if the container we clicked on is not empty...
- if (!cc.getStack().isEmpty()) {
- // get the card we clicked on.
- Card c = getCard(me.getPoint());
- // if its the shallow only allow the top card as our selected card.
- if (cc.getClass() == Shallow.class) {
- if (c != cc.getTopCard()) {
- return;
- }
- }
- //get all cards under the selected card.
- for (int idx = c.getStackHeight(); idx < cc.getStack().size(); idx++) {
- manipulatedCards.add(cc.getStack().get(idx));
- }
- // see if we can move these cards based on the games logic...
- if (theGame.canManipulateStack(manipulatedCards)) {
- // if so start dragging...
- dragging = true;
- // record the last container it was in...
- lastCardContainer = manipulatedCards.get(0).getContainer();
- // and create a relative offset based on click...
- absHandle = new Point(
- me.getPoint().x - manipulatedCards.get(0).getPos().x,
- me.getPoint().y - manipulatedCards.get(0).getPos().y
- );
- // remove the cards from their' container.
- manipulatedCards.get(0).getContainer().removeCards(manipulatedCards);
- }
- }
- }
- @Override
- public void mouseReleased(MouseEvent me) {
- // if were dragging some cards...
- if (dragging && manipulatedCards != null) {
- // see if we dropped them into another container...
- CardContainer cc = approximateDrop(me);
- // if we did then see if were allowed to move the cards to that
- // container based on the games logic...
- if (theGame.canMoveCardTo(cc, manipulatedCards.get(0))) {
- // if we did then record the cards movement for the movement list.
- CardContainer prev_cc = manipulatedCards.get(0).getContainer();
- // move the card to the new container...
- cc.addCards(manipulatedCards);
- b.addMove(manipulatedCards, prev_cc, manipulatedCards.get(0).getContainer());
- // let the game do logic to determine if it needs to do anything.
- theGame.processMove();
- } else {
- // move the card to the last container it was in...
- lastCardContainer.addCards(manipulatedCards);
- }
- // clear the card list for later...
- manipulatedCards = new ArrayList<>();
- // clear the container for later..
- lastCardContainer = null;
- // tell the game were no longer holding cards...
- dragging = false;
- }
- }
- private CardContainer approximateDrop(MouseEvent me) {
- Point cCenter = manipulatedCards.get(0).getCenterPoint();
- //try to see if our mouse is hovering over a top card or an empty container...
- CardContainer best_match = getContainer(me.getPoint());
- if (best_match != null) {
- return best_match;
- }
- // try to see if the center of our card is hovering over the top of a
- // card or an empty container...
- best_match = getContainer(cCenter);
- if (best_match != null) {
- return best_match;
- }
- // return whatever container the cards were already in as a last effort
- // to find a container.
- return manipulatedCards.get(0).getContainer();
- }
- // looks for the container that contains the point p and returns the
- // container; returns null if no container was found.
- private CardContainer getContainer(Point p) {
- for (Stack s : b.getStacks()) {
- if ((s.containsPoint(p) && s.getStack().isEmpty()) || s.containsPoint(p)) {
- return (CardContainer) s;
- }
- }
- if ((b.getShallow().getTopCard() != null) && b.getShallow().containsPoint(p)) {
- return b.getShallow();
- }
- for (Card c_idx : b.getCards()) {
- if (c_idx.containsPoint(p)) {
- return c_idx.getContainer();
- }
- }
- return null;
- }
- // finds the card that intersects with point p that is the closest to the
- // top
- private Card getCard(Point p) {
- int height = -1;
- Card c = null;
- for (Card c_idx : b.getCards()) {
- if (c_idx.containsPoint(p) && (c_idx.getStackHeight() > height)) {
- c = c_idx;
- }
- }
- return c;
- }
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.awt.Graphics;
- import java.awt.image.ImageObserver;
- import java.net.URL;
- import java.util.ArrayList;
- import javax.swing.ImageIcon;
- public class Deck extends CardContainer {
- // clubs, diamonds, hearts, spades.
- private final String suits = "cdhs";
- private final long seed;
- public Deck(long seed, String id){
- super();
- this.id = "deck";
- this.seed = seed;
- String str = "";
- // load a deck of cards!
- // values...
- for (int n = 1; n <= 13; n++) {
- // suits...
- for (int s = 0; s < 4; s++) {
- // basic parsing for assets...
- if (n <= 9) {
- str = "assets/0" + n + suits.charAt(s) + ".gif";
- } else {
- str = "assets/" + n + suits.charAt(s) + ".gif";
- }
- // get the image...
- URL loc = this.getClass().getResource(str);
- // load the image...
- ImageIcon iia = new ImageIcon(loc);
- // hold a reference of the image in the card.
- Card c = new Card(iia.getImage(), s, n, this);
- // add the card to the deck.
- cards.add(c);
- }
- }
- }
- public void shuffle(){
- // super mario 64 rng code!
- // I seriously cannot step through this code but I can assure you it is
- // sufficently random; unfortunately java doesnt support unsigned
- // variables so Ive had to improvise...
- for(short idx = 0; idx < cards.size(); idx++){
- short in = (short)(idx+seed);
- short s0 = (short) (in << 8);
- s0 = (short) (s0 ^ in);
- in = (short) (((s0 & 0xFF) << 8) | ((s0 & 0xFF00) >> 8));
- s0 = (short) ((s0 << 1) ^ in);
- short s1 = (short) ((s0 >> 1) ^ 0xFF80);
- if((s0 & 1) == 0){
- in = (short) (s1 ^ 0x1FF4);
- } else {
- in = (short) (s1 ^ 0x8180);
- }
- // java doesnt support unsigned... :(
- Card temp = cards.get(Math.abs(in%cards.size()));
- cards.set(Math.abs(in%cards.size()), cards.get(idx));
- cards.set(idx, temp);
- }
- }
- public Card drawCard(){
- Card c = this.getTopCard();
- cards.remove(c);
- processCard(null);
- return c;
- }
- public void addToBottom(Card c){
- cards.add(0, c);
- processCard(c);
- }
- public void dealCard(Stack p){
- p.addCard(cards.get(cards.size()-1));
- cards.remove(cards.size()-1);
- processCard(null);
- }
- public ArrayList<Card> getDeck(){
- return cards;
- }
- @Override
- public void drawCards(Graphics g, ImageObserver io) {
- for(Card c : cards){
- c.draw(g, io);
- }
- }
- @Override
- public void processCard(Card c) {
- if(c != null){
- c.setPos(this.pos);
- c.setRevealed(false);
- c.setContainer(this);
- }
- getTopCard().setRevealed(false);
- }
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.awt.EventQueue;
- import java.io.BufferedReader;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import javax.swing.JFileChooser;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- public class Main extends JFrame {
- JLabel statusbar;
- private MainMenuPanel mmp;
- public Main() {
- // create the main menu panel and add it to the frame
- mmp = new MainMenuPanel(this);
- this.add(mmp);
- // set some basic stuff fo the panel
- setTitle("Pacman");
- setDefaultCloseOperation(EXIT_ON_CLOSE);
- setSize(32*8, 48*6);
- setVisible(true);
- }
- // removes anything in the panel and creates the game from scratch.
- public void makeGame(){
- this.remove(mmp);
- this.add(new Board());
- setVisible(true);
- }
- // removes everything from panel and loads the game from a saved state
- public void loadGame() throws FileNotFoundException, IOException{
- // open a file chooser to go get the file.
- final JFileChooser fc = new JFileChooser();
- fc.showOpenDialog(this);
- // get the name of the file
- String saveFile = fc.getSelectedFile().toString();
- // does it end with .txt?
- if(!saveFile.endsWith(".txt")){
- // nope; cry about it.
- System.out.println("bad save!");
- } else {
- // remove the main menu panel and read the random seed of the game.
- this.remove(mmp);
- BufferedReader r = new BufferedReader(new FileReader(saveFile));
- String seed = r.readLine();
- // create a new instance of solitaire with the seed.
- this.add(new Board(Long.parseLong(seed), saveFile));
- setVisible(true);
- }
- }
- public JLabel getStatusBar() {
- return statusbar;
- }
- public static void main(String[] args) {
- EventQueue.invokeLater(new Runnable() {
- // run on a new thread....
- @Override
- public void run() {
- Main ex = new Main();
- ex.setVisible(true);
- }
- });
- }
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.io.IOException;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- /**
- *
- * @author Ryland
- */
- public class MainMenuPanel extends java.awt.Panel {
- Main m;
- public MainMenuPanel(Main m) {
- initComponents();
- this.m = m;
- }
- /**
- * This method is called from within the constructor to initialize the form.
- * WARNING: Do NOT modify this code. The content of this method is always
- * regenerated by the Form Editor.
- */
- // <editor-fold defaultstate="collapsed" desc="Generated Code">
- private void initComponents() {
- jButton1 = new javax.swing.JButton();
- jPanel1 = new javax.swing.JPanel();
- jLabel1 = new javax.swing.JLabel();
- filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 32767));
- jButton2 = new javax.swing.JButton();
- jButton3 = new javax.swing.JButton();
- jButton4 = new javax.swing.JButton();
- jButton1.setText("jButton1");
- setLayout(new java.awt.BorderLayout());
- jPanel1.setAutoscrolls(true);
- jPanel1.setPreferredSize(new java.awt.Dimension(256, 288));
- jLabel1.setFont(new java.awt.Font("Comic Sans MS", 0, 48)); // NOI18N
- jLabel1.setText("Solitaire");
- jButton2.setAction(jButton1.getAction());
- jButton2.setText("New game");
- jButton2.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- jButton2ActionPerformed(evt);
- }
- });
- jButton3.setText("Load game");
- jButton3.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- jButton3ActionPerformed(evt);
- }
- });
- jButton4.setText("Quit");
- jButton4.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- jButton4ActionPerformed(evt);
- }
- });
- javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
- jPanel1.setLayout(jPanel1Layout);
- jPanel1Layout.setHorizontalGroup(
- jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addGap(31, 31, 31)
- .addComponent(jLabel1))
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addGap(62, 62, 62)
- .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(jButton3, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
- .addComponent(jButton4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
- .addGap(324, 324, 324))
- );
- jPanel1Layout.setVerticalGroup(
- jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel1Layout.createSequentialGroup()
- .addGap(26, 26, 26)
- .addComponent(jLabel1)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(jButton2)
- .addGap(18, 18, 18)
- .addComponent(jButton3)
- .addGap(18, 18, 18)
- .addComponent(jButton4)
- .addContainerGap())
- );
- add(jPanel1, java.awt.BorderLayout.CENTER);
- }// </editor-fold>
- private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
- m.makeGame();
- }
- private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
- try {
- m.loadGame();
- } catch (IOException ex) {
- Logger.getLogger(MainMenuPanel.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
- System.exit(0);
- }
- // Variables declaration - do not modify
- private javax.swing.Box.Filler filler1;
- private javax.swing.JButton jButton1;
- private javax.swing.JButton jButton2;
- private javax.swing.JButton jButton3;
- private javax.swing.JButton jButton4;
- private javax.swing.JLabel jLabel1;
- private javax.swing.JPanel jPanel1;
- // End of variables declaration
- }
- package giftest;
- import java.util.ArrayList;
- public class Move {
- private ArrayList<String> Cards;
- private CardContainer prev_cc;
- private CardContainer cur_cc;
- private boolean carry;
- // bad constructor...
- public Move(){
- Cards = new ArrayList<>();
- prev_cc = null;
- cur_cc = null;
- this.carry = false;
- }
- // single card with no carry.
- public Move(String c, CardContainer prev_cc, CardContainer cur_cc){
- Cards = new ArrayList<>();
- Cards.add(c);
- this.prev_cc = prev_cc;
- this.cur_cc = cur_cc;
- this.carry = false;
- }
- // many cards with no carry.
- public Move(ArrayList<String> c, CardContainer prev_cc, CardContainer cur_cc){
- Cards = c;
- this.prev_cc = prev_cc;
- this.cur_cc = cur_cc;
- this.carry = false;
- }
- // many cards with carry.
- public Move(ArrayList<String> c, CardContainer prev_cc, CardContainer cur_cc, boolean carry){
- Cards = c;
- this.prev_cc = prev_cc;
- this.cur_cc = cur_cc;
- this.carry = carry;
- }
- // single card with carry.
- public Move(String c, CardContainer prev_cc, CardContainer cur_cc, boolean carry){
- Cards = new ArrayList<>();
- Cards.add(c);
- this.prev_cc = prev_cc;
- this.cur_cc = cur_cc;
- this.carry = carry;
- }
- public void setCarry(boolean t){
- this.carry = t;
- }
- public boolean getCarry(){
- return this.carry;
- }
- public ArrayList<String> getSeralizedCards(){
- return Cards;
- }
- public CardContainer getPreviousCardContainer(){
- return prev_cc;
- }
- public CardContainer getCurrentCardContainer(){
- return cur_cc;
- }
- //creats a seralized version of the move...
- @Override
- public String toString(){
- String derp = "*";
- for(int idx = 0; idx < Cards.size(); idx++){
- // get the cards serialized value...
- derp += Cards.get(idx)+"";
- if(idx != Cards.size()-1){
- derp+=",";
- }
- }
- // get the seralized moves...
- derp += "*"+prev_cc.getID()+","+cur_cc.getID()+"*";
- return derp;
- }
- }
- package giftest;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- public class MoveMemory {
- // reference to the board...
- private Board b;
- // an array of moves to keep track of the moves made...
- private ArrayList<Move> moveHistory;
- // the seed of the current game.
- private final long seed;
- // creates fresh move history.
- public MoveMemory(Board b, long seed) {
- moveHistory = new ArrayList<>();
- this.b = b;
- this.seed = seed;
- }
- // loads move history from a file and continues from there...
- public MoveMemory(Board b, long seed, String saveFile) {
- moveHistory = new ArrayList<>();
- this.b = b;
- this.seed = seed;
- try {
- // try to load the file!
- loadSave(saveFile);
- } catch (IOException ex) {
- // woops something went wrong 50ms after initial check...
- Logger.getLogger(MoveMemory.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- public void addMove(Move m) {
- moveHistory.add(m);
- }
- public void Undo() {
- // continue until the move is not a carry move...
- while (true) {
- // is there a move to undo?
- if (moveHistory.isEmpty()) {
- // no; were done here.
- break;
- }
- // yes; lets get the most recent move...
- Move m = moveHistory.get(moveHistory.size() - 1);
- // is the move a compound move?
- boolean carryNext = m.getCarry();
- // if we somehow got a null move.... end here; honestly cant
- // remember why this is here but Im pretty certain its here for a
- // reason...
- if (m == null) {
- break;
- }
- // get a shallow reference of the card that was last moved...
- Card c_ref = Card.deSerialize(m.getSeralizedCards().get(0));
- // for each card on the board...
- for (Card c : b.getCards()) {
- // if the shallow card matches the real cards values; use the
- // matching card.
- if (c.getValue() == c_ref.getValue() && c.getSuit() == c_ref.getSuit()) {
- ArrayList<Card> cl = new ArrayList<>();
- ArrayList<Card> cs = c.getContainer().getStack();
- // chances are if the card is up the stack, then they were
- // all moved together; so take all of the cards under the
- // the given card.
- for (int idx = cs.indexOf(c); idx < cs.size(); idx++) {
- cl.add(cs.get(idx));
- }
- // if the container we're moving the cards back to is not
- // empty then set the card's face to not be revealed.
- if (!b.getContainer(m.getPreviousCardContainer()).getStack().isEmpty()) {
- b.getContainer(m.getPreviousCardContainer()).getTopCard().setRevealed(false);
- }
- // move cards back to their original container...
- b.getContainer(m.getPreviousCardContainer()).addCards(cl);
- // and remove them from their current container...
- b.getContainer(m.getCurrentCardContainer()).removeCards(cl);
- // undo history! remove the history that the move ever happened.
- moveHistory.remove(m);
- }
- }
- // did it mention to carry to the next move?
- if (!carryNext) {
- // no; return.
- break;
- }
- }
- }
- // sets a previous move to be a compound move just in case we need it...
- public void setLastCarry(boolean t) {
- if (moveHistory.size() > 0) {
- moveHistory.get(0).setCarry(t);
- }
- }
- public int getSize() {
- return moveHistory.size();
- }
- public void saveGame() throws IOException {
- // create a file with the seed of this game...
- File file = new File("solitaire" + seed + ".txt");
- file.createNewFile();
- // write the seed of the game, followed by all the moves serialized...
- FileWriter writer = new FileWriter(file);
- writer.write(seed + "\n");
- for (Move m : moveHistory) {
- writer.write(m.toString() + "\n");
- }
- // clean up...
- writer.flush();
- writer.close();
- }
- private void loadSave(String saveFile) throws FileNotFoundException, IOException {
- // try to open the file
- BufferedReader r = new BufferedReader(new FileReader(saveFile));
- // skip the seed of the game, we already have it.
- r.readLine();
- // loop until we have no more lines from the file.
- while (true) {
- String s = r.readLine();
- // if there are no more lines then stop loading.
- if (s == null) {
- break;
- }
- // cut off some meta characters from the data..
- s = s.substring(1, s.length() - 1);
- // split the cards from the containers...
- String ss[] = s.split("\\*");
- // get a list of the shallow references of cards.
- String[] string_list = ss[0].split(",");
- ArrayList<Card> card_list = new ArrayList<>();
- // only one card?
- if(string_list == null) {
- // hold the shallow references to help find real cards soon.
- card_list.add(Card.deSerialize(ss[0]));
- } else {
- // many cards; iterate through them...
- for(int idx = 0; idx < string_list.length; idx++){
- // hold the shallow references to help find real cards soon.
- card_list.add(Card.deSerialize(string_list[idx]));
- }
- }
- // go through our cards...
- for (Card c_ref : card_list) {
- // go through the real cards...
- for (Card c : b.getCards()) {
- // find the matching real cards to our fake cards...
- if (c.getValue() == c_ref.getValue() && c.getSuit() == c_ref.getSuit()) {
- // and move the real cards to the corrisponding containers
- // that the move specified....
- c.getContainer().removeCard(c);
- // work around for moving cards to the deck instead of
- // the shallow...
- String c_name = (ss[1].split(","))[1].equals("shallow") ? "deck" : (ss[1].split(","))[1];
- // move cards to the container.
- b.getContainerByID(c_name).addCard(c);
- // card has been moved; its probably revealed...
- c.setRevealed(true);
- }
- }
- }
- // re-serialize our cards and recreate the move history for the game.
- ArrayList<String> card_serial = new ArrayList<>();
- for(Card c : card_list){
- card_serial.add(c.getSerialized());
- }
- CardContainer prev = b.getContainerByID((ss[1].split(","))[0]);
- CardContainer cur = b.getContainerByID((ss[1].split(","))[1]);
- moveHistory.add(new Move(card_serial, prev, cur));
- }
- }
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.awt.image.ImageObserver;
- public class Shallow extends CardContainer {
- // how much to offset each card from eachother.
- private final static int X_OFFSET = 10;
- Shallow(){
- super();
- }
- Shallow(int x, int y, String id){
- super(x,y);
- this.id = id;
- }
- // moves the cards by the offset...
- @Override
- void processCard(Card c) {
- Point p = pos;
- for(int idx = 0; idx < cards.size(); idx++){
- cards.get(idx).setRevealed(true);
- cards.get(idx).setPos(p.x+(idx*X_OFFSET), p.y);
- cards.get(idx).setStackHeight(idx);
- }
- if(c != null){
- c.setContainer(this);
- }
- }
- @Override
- void drawCards(Graphics g, ImageObserver io) {
- for(Card c : cards){
- c.draw(g, io);
- }
- }
- }
- package giftest;
- import java.util.ArrayList;
- /**
- *
- * @author Ryland
- */
- public class Solitaire implements CardGame {
- private final Board b;
- public Solitaire(Board b){
- // hold a reference of the board...
- this.b = b;
- // set all of the tops of the stacks as revealed...
- for(CardContainer p : this.b.getStacks()){
- if(p.getClass() == Stack.class){
- p.getTopCard().setRevealed(true);
- }
- }
- }
- @Override
- public boolean canMoveCardTo(CardContainer cc, Card c){
- // get the top card of the container the card is moving to...
- Card c_top = cc.getTopCard();
- // if the stack is a sorted stack; dont let the player move it there;
- // the computer should do that.
- if(cc.getClass() == SortedStack.class){return false;}
- // if the container were moving to is empty, return false...
- if(c_top == null){return true;}
- // is our card 1 value lower than the top card of the pile?
- boolean decending_value = c.getValue() == c_top.getValue()-1;
- int cts = c_top.getSuit();
- int cs = c.getSuit();
- // is our suit a different color than the other
- boolean different_suit = (cs == 0 || cs == 3) ? (cts == 1 || cts == 2) : (cts == 0 || cts == 3);
- return decending_value && different_suit;
- }
- @Override
- public boolean canManipulateStack(ArrayList<Card> cL) {
- // get the top cards we want to move...
- Card c = cL.get(0);
- // if the top card is in the deck
- if(c.getContainer().getClass() == Deck.class){
- return false;
- }
- // otherwise if our card is revealed and the cards are in the right order...
- if(c.isRevealed()){
- for(int idx = 0; idx < cL.size()-1; idx++){
- if(cL.get(idx).getValue() <= cL.get(idx+1).getValue()){
- return false;
- }
- }
- // the card was not revealed...
- } else {
- return false;
- }
- // the card is revealed and all the cards are in the right order.
- return true;
- }
- @Override
- public void processMove() {
- ArrayList<SortedStack> ssl = b.getSortedStacks();
- while(true){
- // toggle to see if we should cycle through again.
- boolean toggle = true;
- // look througth all of the stacks on the board.
- for(Stack s : b.getStacks()){
- // get the top card
- Card c = s.getTopCard();
- // if there is a top card...
- if(c != null){
- int suitID = c.getSuit();
- // look at the cards corrisponding sorted pile and see if
- // that pile is not empty
- if(!ssl.get(suitID).getStack().isEmpty()){
- // if so is our card the next to go on the list
- if(ssl.get(suitID).getTopCard().getValue()+1 == c.getValue()){
- // then hold the previous container...
- CardContainer prev_cc = c.getContainer();
- // add the card to the sorted pile..
- ssl.get(suitID).addCard(c);
- // remove the card from its original pile
- s.removeCard(c);
- // then add the move to the move list.
- b.addMove(c, prev_cc , c.getContainer(), true);
- // tell the program to cycle through again to see
- // if anything has changed...
- toggle = false;
- }
- }
- // if there is no top card then is our card an ace?
- else if(c.getValue() == 1) {
- // make the last move we did combine with this move
- // because this move is reflexive.
- b.getMoveMemory().setLastCarry(true);
- // hold the container...
- CardContainer prev_cc = c.getContainer();
- // add the card to the sorted pile
- ssl.get(suitID).addCard(c);
- // remove the card from the current container...
- s.removeCard(c);
- // add the move to the move list
- b.addMove(c, prev_cc , c.getContainer(), true);
- // cycle through the list again for changes...
- toggle = false;
- }
- }
- }
- // true = dont cycle, false = cycle again.
- if(toggle){
- break;
- }
- }
- //check to see if any cards need to be revealed...
- for(Stack s: b.getStacks()){
- Card c = s.getTopCard();
- if(c != null){
- if(!c.isRevealed()){
- c.setRevealed(true);
- }
- }
- }
- }
- @Override
- public void interact(CardContainer cL) {
- // check to see if the container is the deck...
- if(cL.getClass() == Deck.class){
- // if so cycle the shallow...
- Deck deck = (Deck)cL;
- Shallow sh = b.getShallow();
- // move the shallow to the bottom of the deck...
- while(!sh.getStack().isEmpty()){
- deck.addToBottom(sh.getStack().get(0));
- sh.removeCard(sh.getStack().get(0));
- }
- int upper = cL.getStack().size();
- int lower = upper-3;
- // and move the top 3 cards of the deck to the shallow.
- for(; lower < upper; lower++){
- sh.addCard(deck.drawCard());
- }
- }
- }
- }
- package giftest;
- import java.awt.Graphics;
- import java.awt.image.ImageObserver;
- public class SortedStack extends CardContainer {
- public SortedStack(){
- super();
- }
- public SortedStack(int x, int y, String id){
- super(x,y);
- this.id = id;
- }
- @Override
- void processCard(Card c) {
- if(c != null){
- // set all cards to be in the container and revealed.
- for(int idx = 0; idx < cards.size(); idx++){
- cards.get(idx).setPos(this.pos);
- cards.get(idx).setContainer(this);
- cards.get(idx).setStackHeight(idx);
- cards.get(idx).setRevealed(true);
- }
- }
- }
- @Override
- void drawCards(Graphics g, ImageObserver io) {
- getTopCard().draw(g, io);
- }
- }
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package giftest;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.awt.image.ImageObserver;
- /**
- *
- * @author Ryland
- */
- public class Stack extends CardContainer {
- // how far should each card be offset from eachother?
- private final static int Y_OFFSET = 20;
- Stack(){
- super();
- }
- Stack(int x, int y, String id){
- super(x,y);
- this.id = id;
- }
- @Override
- void processCard(Card c){
- Point p = pos;
- // sets the cards in the right spots...
- for(int idx = 0; idx < cards.size(); idx++){
- if(c == cards.get(idx)){
- cards.get(idx).setPos(p.x, p.y + (idx*Y_OFFSET));
- cards.get(idx).setContainer(this);
- cards.get(idx).setStackHeight(idx);
- }
- }
- }
- // draws the cards based off of cards' draw method.
- @Override
- void drawCards(Graphics g, ImageObserver io) {
- for(Card c : cards){
- c.draw(g, io);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement