Ten Apples Puzzle
<< Trivia Game | Applications | How To Convert Your Applet To An Application >>
Node.java
import java.awt.Color; import java.awt.Graphics; import java.util.ArrayList; /** * A Node in the Blocking Game is a circular disc * that can be linked to other Nodes * * The Instance fields are: * 1. Its color (of type Color) * 2. The x,y coords of the Top Left corner * 3. The radius * 4. If it is selected (of type boolean) * 5. An ArrayList of type Node that has the nodes it can be linked to * * The constructor should have three fields: the x,y Coords of the the * top left corner, and the radius, sets the Color to Color.WHITE and * selected to false. * * * * @author Chris Thiel * @version 19 May 2016 */ public class Node { private int x; private int y; private int radius; private Color color; private boolean selected, occupied; public Node(int x, int y, int radius) { this(x,y,radius, Color.WHITE); } public Node(int x, int y, int radius, Color c) { this.x=x; this.y=y; this.radius=radius; color=c; selected = false; setOccupied(false); } /** * Draws itself in the correct color as well as * indicating it is selected. * @param g the Graphics object to draw itself upon */ public void draw(Graphics g){ g.setColor(Color.BLACK); if (selected) g.setColor(Color.RED); g.fillOval(x-3, y-3, 2*radius+6, 2*radius+6); g.setColor(color); g.fillOval(x, y, 2*radius, 2*radius); if (occupied){ g.setColor(Color.RED); int r=20; g.fillOval(centerX()-r, centerY()-r, 2*r, 2*r); } } /** * Using the pythagorean theorem, detects if a coordinate * is within the node's circular area * @param h the horizontal location of the point to test * @param k the vertical location of the point to test * @return true if (h,k) is inside the node */ public boolean contains(int h, int k) { return (h-centerX())*(h-centerX())+(centerY()-k)*(centerY()-k) < radius*radius; } public ArrayList<Node> legalMoves( ArrayList<Link> links){ ArrayList<Node> result = new ArrayList<Node>(); for (Link link:links){ if (link.hasEnd(this)) if (link.isLegal(this, link.otherEnd(this))){ result.add(link.otherEnd(this)); } } return result; } /** * Other Accessor methods: */ public void toggle() { selected=!selected;} public void deselect(){selected=false; } public void select() {selected=true;} public void setColor(Color color){this.color=color;} public int centerX(){return x+radius;} public int centerY(){return y+radius;} public boolean isSelected(){return selected;} public Color color(){return color;} public boolean isOccupied() { return occupied; } public void setOccupied(boolean occupied) { this.occupied = occupied; } }
Link.java
import java.awt.Color; import java.util.ArrayList; /** * * @author Chris Thiel, ofmcap * version 18 May 2016 * * Links are for describing possible connections * between nodes that require one to * jump over an occupied node as in checkers * or droughts */ public class Link { private Node[] ends; private Node middle; public Link(Node end0, Node middle, Node end1){ ends = new Node[2]; ends[0]=end0; ends[1]=end1; this.middle=middle; } public boolean hasEnd(Node n) { return n==ends[0] || n==ends[1]; } public Node otherEnd(Node n){ if (n==ends[0]) return ends[1]; return ends[0]; } public boolean isLegal(Node from, Node to){ return from.isOccupied() && !to.isOccupied() && middle.isOccupied(); } }
TenApplesPuzzle.java
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JPanel; /** * * @author Chris Thiel * @version 19 March 2016 * */ public class TenApplesPuzzle extends JPanel implements MouseListener { public static int WIDTH=800,HEIGHT=600, TOP=100, LEFT=55, GAP=80, SIZE=40; private Font titleFont, regularFont, giantFont; private Node[] nodes; private ArrayList<Link> links; private String message, message2, message3; private Color bgColor; private Color currentPlayer; private Node selectedNode; /** * The class constructor will initialize the ArrayList<Balloon> * and other object fields (variables), including a Timer * object from the javax.swing.* library. The timer will * generate an Action Event, so that something happens * in regular intervals without the user typing anything. */ public TenApplesPuzzle() { //initialize variables here... this.currentPlayer=null; this.selectedNode=null; titleFont = new Font("SansSerif", Font.BOLD, 24); giantFont = new Font("SansSerif", Font.BOLD, 72); regularFont = new Font("Serif", Font.PLAIN, 18); message="message"; message2="message2"; message3="message3"; bgColor = Color.GREEN; nodes=new Node[16]; links=new ArrayList<Link>(); for(int r=0; r<4; r++){ for(int c=0; c<4;c++){ int x=LEFT+c*(GAP+SIZE); int y=TOP+r*(GAP+SIZE); nodes[r*4+c]=new Node(x,y,SIZE); } } for (int r=0; r< 16; r+=4 ){ links.add(new Link(nodes[r], nodes[r+1], nodes[r+2])); links.add(new Link(nodes[r+1], nodes[r+2], nodes[r+3])); } for (int c=0; c< 4; c++ ){ links.add(new Link(nodes[c], nodes[c+4], nodes[c+8])); links.add(new Link(nodes[c+4], nodes[c+8], nodes[c+12])); } reset(); repaint(); } public void reset(){ for (Node n:nodes){ n.deselect(); n.setColor(Color.WHITE); n.setOccupied(false); } nodes[0].setOccupied(true); nodes[1].setOccupied(true); nodes[2].setOccupied(true); nodes[3].setOccupied(true); nodes[4].setOccupied(true); nodes[7].setOccupied(true); nodes[8].setOccupied(true); nodes[11].setOccupied(true); nodes[12].setOccupied(true); nodes[13].setOccupied(true); nodes[10].setOccupied(true); nodes[15].setOccupied(true); } /** * the main method makes an instance of our application and puts it in a JFrame * that will end the application when it is closed. * */ public static void main(String[] args) { TenApplesPuzzle app= new TenApplesPuzzle(); JFrame window = new JFrame("Blocking Game"); window.setSize(WIDTH, HEIGHT); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(app); window.getContentPane().addMouseListener(app); window.setVisible(true); } /** * This is the method to change what is drawn to the screen: */ public void paintComponent(Graphics g){ //super.paintComponent(g); if (this.currentPlayer!=null) bgColor=new Color(200, 255, 200); g.setColor(bgColor); g.fillRect(0, 0, getWidth(),getHeight()); g.setColor(Color.BLUE); g.setFont(titleFont); g.drawString("Ten Apples Puzzle ver. 1.0", 20, 30); g.setColor(Color.RED); g.setFont(giantFont); //g.drawString("LEVEL ", WIDTH-300, TOP+100); g.setColor(Color.BLACK); g.setFont(regularFont); g.drawString(message, 20, 60); g.drawString(message2, WIDTH-400, TOP-80); g.drawString(message3, WIDTH-400, TOP-50); for (Node n: nodes) n.draw(g); } /** * getLegalMoves will return the Nodes that are white * that are connected to the current player's nodes. * If there is no current player it returns the * non-white nodes. If the size of the result is * zero, there are no legal moves left. * @return */ /** * New Turn will switch the current player * then check to see if the game is over * that is, the new current player has no move to make */ public void newTurn() { String winner=""; if (currentPlayer.equals(Color.CYAN)){ currentPlayer=Color.RED; winner="Blue"; }else{ currentPlayer=Color.CYAN; winner="Red"; } } /** * These 5 methods need to be declared to implement the MouseListener Interface */ @Override public void mouseClicked(MouseEvent e) {} @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) { int x=e.getX(); int y=e.getY(); if (this.selectedNode==null) checkForNodeSelection(x,y); else checkForDestination(x,y); repaint(); } public void checkForDestination(int x, int y) { ArrayList<Node> legal = selectedNode.legalMoves(links); if (legal.size()<1){ message="Select an apple to move"; message2="No moves possible"; selectedNode=null; return; } Node to = null; Node from = selectedNode; for(int i=0; i< legal.size(); i++) { Node n=nodes[i]; if(n.contains(x, y)){ to = n; selectedNode=null; from.deselect(); from.setOccupied(false); to.setOccupied(true); message2= selectedNode.legalMoves(links).size() +" legal moves "; //diag message3="node "+i; //diag message="Select an apple to move"; } } if (to==null){ message2="Not a legal move"; } } public void checkForNodeSelection(int x, int y) { for(int i=0; i< nodes.length; i++) { Node n=nodes[i]; if(n.contains(x, y)){ message2= n.legalMoves(links).size() +" legal moves "; //diag message3="node "+i; //diag if(n.legalMoves(links).size()>0){ selectedNode=n; message="Select destination"; selectedNode.select(); }else{ message="No moves possable from there-select another"; } } } } @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} }