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