Introduction
A Kids Game for improving problem solving skills and Memory, the number game is being converted into image game, in a device powered with touch screen the game can recognize touch gestures and the kid can play shuffling the tiles to reach the goal state ( Original Image ).
Background
Using the Code
import java.util.Vector;
import java.util.Arrays;
import java.util.Random;
import java.lang.Math;
import java.util.Date;
class Puzzle
{
private int[] pieces = new int[9];
private boolean manhattan = true; private int depth; private int parentID=-1; public Puzzle(int move) {generate(move);}
public Puzzle(int[] squares, boolean isManhattan)
{
for (int i=0; i<9; i++)
{
pieces[i] = squares[i];
setHeuristic(isManhattan);
}
}
public Puzzle(int[] squares, boolean isManhattan, int depth)
{
this.depth = depth;
for (int i=0; i<9; i++)
{
pieces[i] = squares[i];
setHeuristic(isManhattan);
}
}
public Puzzle(int[] squares, boolean isManhattan, int depth, int parentID)
{
this.depth = depth;
this.parentID = parentID;
for (int i=0; i<9; i++)
{
pieces[i] = squares[i];
setHeuristic(isManhattan);
}
}
public Puzzle(Puzzle puzzle)
{
pieces = puzzle.copyArray();
manhattan = puzzle.isManhattan();
depth = puzzle.getDepth();
parentID = puzzle.getParentID();
}
public void generate(int move)
{
for (int i=0; i<9; i++)
pieces[i] = i;
for (int j=0; j<move; j++)
{
Random rand = new Random();
int choice = rand.nextInt(4)+1;
switch (choice)
{
case 1:
pieces = up(pieces);
break;
case 2:
pieces = down(pieces);
break;
case 3:
pieces = left(pieces);
break;
case 4:
pieces = right(pieces);
break;
}
}
}
private int[] up(int[] puzzleArray)
{
int i;
int[] temp = new int[puzzleArray.length];
int holder;
for (i=0; i<puzzleArray.length; i++)
temp[i] = puzzleArray[i];
int square= 0;
for (i=0; i<temp.length; i++)
{
if (temp[i] == 0)
square = i;
}
if (square < 3)
return temp;
holder = temp[square];
temp[square] = temp[square-3];
temp[square-3] = holder;
return temp;
}
private int[] down(int[] puzzleArray)
{
int holder;
int[] temp = new int[puzzleArray.length];
for (int i=0; i<puzzleArray.length; i++)
temp[i] = puzzleArray[i];
int square= 0;
for (int i=0; i<temp.length; i++)
{
if (temp[i] ==0 )
square = i;
}
if (square > 5)
return temp;
holder = temp[square];
temp[square] = temp[square+3];
temp[square+3] = holder;
return temp;
}
private int[] left(int[] puzzleArray)
{
int holder;
int[] temp = new int[puzzleArray.length];
for (int i=0; i<puzzleArray.length; i++)
temp[i] = puzzleArray[i];
int square= 0;
for (int i=0; i<temp.length; i++)
{
if (temp[i] ==0 )
square = i;
}
if (square%3 == 0)
return temp;
holder = temp[square];
temp[square] = temp[square-1];
temp[square-1] = holder;
return temp;
}
private int[] right(int[] puzzleArray)
{
int holder;
int[] temp = new int[puzzleArray.length];
for (int i=0; i<puzzleArray.length; i++)
temp[i] = puzzleArray[i];
int square= 0;
for (int i=0; i<temp.length; i++)
{
if (temp[i] ==0 )
square = i;
}
if (square%3 == 2)
return temp;
holder = temp[square];
temp[square] = temp[square+1];
temp[square+1] = holder;
return temp;
}
public String toString()
{
String out = new String("===============\n");
for (int i=1; i<=9; i++) {
if ((i%3) == 1)
out += " | ";
if (pieces[i-1] == 0)
out += " | ";
else
out += pieces[i-1]+" | ";
if ((i%3) == 0)
out += "\n===============\n";
}
return out;
}
public boolean equals(Puzzle p)
{
return (p.toString().equals(toString()));
}
public boolean isManhattan() {return manhattan;}
public int getDepth() {return depth;}
public int getParentID() {return parentID;}
public void setDepth(int depth) {this.depth = depth;}
public void setHeuristic(boolean isManhattan)
{
manhattan = isManhattan;
}
public int getH()
{
if (manhattan)
return getmanhattanH();
else
return getOtherH();
}
private int getOtherH()
{
int wrong = 0;
for (int i=0; i<9; i++)
if (pieces[i] != i)
wrong++;
return wrong;
}
private int getmanhattanH()
{
int h = 0;
int xs, xg, ys, yg;
for (int i=0; i<9; i++)
{
xg = i%3;
yg = i/3;
xs = pieces[i]%3;
ys = pieces[i]/3;
h += Math.abs(xs-xg) + Math.abs(ys-yg);
}
return h;
}
public void addMove() { depth++;}
public int[] copyArray()
{
int[] temp = new int[9];
for (int i=0; i<9; i++)
temp[i] = pieces[i];
return temp;
}
public int[] up() { return up(pieces);}
public int[] down() { return down(pieces);}
public int[] left() { return left(pieces);}
public int[] right() {return right(pieces);}
} class Solver
{
private int cost = 0;
private Vector usedList;
private Vector fringeList;
private Puzzle p;
public Solver(int depth)
{
usedList = new Vector();
fringeList = new Vector();
p = new Puzzle(depth);
fringeList.add(p);
}
public Solver(Puzzle puzzle)
{
usedList = new Vector();
fringeList = new Vector();
p = new Puzzle(puzzle);
fringeList.add(p);
}
public void solve() {while (expandNodes(p)) {p=findBestNode();}}
public int getCost() {return (usedList.size() + fringeList.size());}
private Puzzle findBestNode()
{
Puzzle best;
Puzzle test;
if (fringeList.size()==0)
best = (Puzzle)usedList.elementAt(0);
else
best = (Puzzle)fringeList.elementAt(0);
for (int i=1; i<fringeList.size();i++)
{
test = (Puzzle)fringeList.get(i);
int bestH = best.getDepth() + best.getH();
int testH = test.getDepth() + test.getH();
if (testH < bestH)
best = test;
}
return best;
}
private boolean expandNodes(Puzzle p)
{
int[] test;
Puzzle temp;
fringeList.remove(p);
int parentID = usedList.size();
usedList.add(p);
if (p.getH() == 0)
return false;
test = p.up();
temp = new Puzzle(test, p.isManhattan(), p.getDepth(), parentID);
addToFringe(temp);
test = p.down();
temp = new Puzzle(test, p.isManhattan(), p.getDepth(), parentID);
addToFringe(temp);
test = p.left();
temp = new Puzzle(test, p.isManhattan(), p.getDepth(), parentID);
addToFringe(temp);
test = p.right();
temp = new Puzzle(test, p.isManhattan(), p.getDepth(), parentID);
addToFringe(temp);
return true;
}
private void addToFringe(Puzzle p)
{
if (!nodeRepeated(p))
{
p.addMove();
fringeList.add(p);
}
}
private boolean nodeRepeated (Puzzle node)
{
for (int i=0; i<usedList.size(); i++)
{
if (node.equals((Puzzle)usedList.get(i)))
return true;
}
return false;
}
public void print()
{
Vector list = new Vector();
Puzzle node = getPuzzleSolution();
list.add(node);
int parentID = node.getParentID();
while (parentID != -1)
{
node = (Puzzle)usedList.elementAt(parentID);
list.add(node);
parentID = node.getParentID();
} for (int i = 1; i <= list.size(); i++)
{
if (i ==1)
{
System.out.println("Original:");
System.out.println((Puzzle)list.elementAt(list.size()-i));
}
else
{
System.out.println("Step " + ( i -1)+ ":");
System.out.println((Puzzle)list.elementAt(list.size()-i));
}
}
System.out.println("\nSolution with "+getPuzzleSolution().getDepth()+" step(s).");
}
public Puzzle getPuzzleSolution()
{
return (Puzzle)usedList.lastElement();
}
} class Project01
{
public static void main(String[] args)
{
Solver puzzle = new Solver(25);
puzzle.solve();
puzzle.print();
}
} class Computation
{
private int[] counter; private int[] timer;
private int[] cost;
private int max; private int min = 0; private int num = 10; private int size = 75; public Computation(int max)
{
this.max = max;
counter = new int[max];
timer = new int[max];
cost = new int[max];
}
public Computation(int min, int max)
{
this.max = max;
this.min = min;
counter = new int[max];
timer = new int[max];
cost = new int[max];
}
public void run()
{
int i;
do
{
Solver p = new Solver(size);
Timer t = new Timer();
t.start();
p.solve();
long time = t.end();
Puzzle solution = p.getPuzzleSolution();
if (solution.getDepth() <= max && (solution.getDepth()-min) > 0)
{
if (counter[(solution.getDepth()-1)-min] < num)
{
counter[(solution.getDepth()-1)-min]++;
timer[(solution.getDepth()-1)-min] += time;
cost[(solution.getDepth()-1)-min] += p.getCost();
}
}
} while (!checkCounter());
System.out.println("Depth\tCost\tTime to Execute");
for (i=0; i<(max-min); i++)
System.out.println((i+1)+min+"\t"+(cost[i]/num)+"\t"+timer[i]/num);
}
public boolean checkCounter()
{
int count = 0;
for (int i=0; i<(max-min); i++)
{
count += counter[i];
}
return (count == ((max-min)*num));
}
} class Timer
{
Date now;
long start;
public Timer() {}
public void start()
{
now = new Date();
start = now.getTime();
}
public long end()
{
now = new Date();
long end = now.getTime();
return ((end-start));
}
}
Points of Interest
We can set the number of tiles to move towards advanced category, i terms of (x2-1) square of a number minus one ex: 8,15,24,35 .....
History
As the App is already touch enabled , Using gyro meter sensor to implement tilt function to move the tiles in four directions (left , right , up, down )