quote: Original post by edotorpedo
Bangz,
Why did you code this with an octree? The way I see it you only have 4(!) choices with the puzzle. As you said you sometimes calculate some options twice, so you don''t recurse with this node. When you only calculate using say left-turnes, you don''t have his problem, making the tree a lot simpler with the same (or less?) number of calculations.
Know what I mean?
Edo
I think i''m getting you, but say u needed only one right turn to solve the solution, the program would return a result of 3 left turns. Maybe an alogrithm could be written to then tidy up the solution?! But seems like too much hard work! ;-)
bangz.
Here''s my solution...
#include <iostream.h>struct SNode{ unsigned int grid[4][4]; int level; unsigned int parent;};class CTree{public: SNode node[12000]; int nodePointer; void addNode(SNode node, int parent, int level); // Adds node to tree int solve(SNode start, SNode finish); // Solves puzzel bool rotateL(int read, int store, int type, int checkExist); // Rotate puzzel left bool rotateR(int read, int store, int type); // Rotate puzzel right void output(int out); // Output node[out] void cpy(SNode read, int store); // Copy a node from node[read] to node[store] bool cmp(int a, SNode b); // Compare node[a] with b bool isExist(int i); // Check to see if node exists elsewhere on the tree};// Check to see if node exists elsewhere on the tree//// node to check with other entries in the tree<br></font><br><font color="blue">bool</font> CTree::isExist(<font color="blue">int</font> i)<br>{<br> <font color="blue">for</font>(<font color="blue">int</font> j=1; j<nodePointer; j++)<br> {<br> <font color="blue">if</font>(cmp(nodePointer, node[<font color="purple">j</font>]))<br> {<br> <font color="blue">return</font> true;<br> }<br> }<br><br> <font color="blue">return</font> false;<br>}<br><br><font color="gray">// Output node[out]<br></font><br><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray">//<br></font></font></font></font></font></font><br><font color="gray">// basically outputs node[out].grid[][]<br></font><br><font color="blue">void</font> CTree::output(<font color="blue">int</font> out)<br>{<br> cout << node[<font color="purple">out</font>].grid[<font color="purple">1</font>][<font color="purple">1</font>] << <font color="darkred">" "</font> << node[<font color="purple">out</font>].grid[<font color="purple">2</font>][<font color="purple">1</font>] << <font color="darkred">" "</font> << node[<font color="purple">out</font>].grid[<font color="purple">3</font>][<font color="purple">1</font>] << endl;<br> cout << node[<font color="purple">out</font>].grid[<font color="purple">1</font>][<font color="purple">2</font>] << <font color="darkred">" "</font> << node[<font color="purple">out</font>].grid[<font color="purple">2</font>][<font color="purple">2</font>] << <font color="darkred">" "</font> << node[<font color="purple">out</font>].grid[<font color="purple">3</font>][<font color="purple">2</font>] << endl;<br> cout << node[<font color="purple">out</font>].grid[<font color="purple">1</font>][<font color="purple">3</font>] << <font color="darkred">" "</font> << node[<font color="purple">out</font>].grid[<font color="purple">2</font>][<font color="purple">3</font>] << <font color="darkred">" "</font> << node[<font color="purple">out</font>].grid[<font color="purple">3</font>][<font color="purple">3</font>] << endl;<br> cout << endl;<br>}<br><br><font color="gray">// Compares two node grids<br></font><br><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray">//<br></font></font></font></font></font></font><br><font color="gray">// if both grids are the same, will return true<br></font><br><font color="blue">bool</font> CTree::cmp(<font color="blue">int</font> a, SNode b)<br>{<br> <font color="blue">for</font> (<font color="blue">int</font> i=1; i<4; i++)<br> {<br> <font color="blue">for</font>(<font color="blue">int</font> j=1; j<4; j++)<br> {<br> <font color="blue">if</font> (node[<font color="purple">a</font>].grid[<font color="purple">i</font>][<font color="purple">j</font>]!=b.grid[<font color="purple">i</font>][<font color="purple">j</font>])<br> <font color="blue">return</font> false;<br> }<br> }<br> <font color="blue">return</font> true;<br>}<br><br><font color="gray">// Copy grid to another location<br></font><br><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray">//<br></font></font></font></font></font></font><br><font color="gray">// copy read to node[store]<br></font><br><font color="blue">void</font> CTree::cpy(SNode read, <font color="blue">int</font> store)<br>{<br> <font color="blue">for</font> (<font color="blue">int</font> i=1; i<4; i++)<br> {<br> <font color="blue">for</font>(<font color="blue">int</font> j=1; j<4; j++)<br> {<br> node[<font color="purple">store</font>].grid[<font color="purple">i</font>][<font color="purple">j</font>]=read.grid[<font color="purple">i</font>][<font color="purple">j</font>];<br> }<br> }<br>}<br><br><font color="gray">// Rotate 2x2 Left<br></font><br><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray">//<br></font></font></font></font></font></font><br><font color="gray">// copies read to node[store] then rotates depending on the passed type<br></font><br><font color="gray">// checkExist = 1 used when on final right rotation and all left rotations<br></font><br><font color="blue">bool</font> CTree::rotateL(<font color="blue">int</font> read, <font color="blue">int</font> store, <font color="blue">int</font> type, <font color="blue">int</font> checkExist)<br>{<br> cpy(node[<font color="purple">read</font>], nodePointer);<br> <font color="blue">int</font> startx=0;<br> <font color="blue">int</font> starty=0;<br> <font color="blue">switch</font>(type)<br> {<br> <font color="blue">case</font> 1: <font color="gray">//top left<br></font><br> break;<br> <font color="blue">case</font> 2: <font color="gray">//top right<br></font><br> startx=1;<br> break;<br> <font color="blue">case</font> 3: <font color="gray">//bottom right<br></font><br> starty=1;<br> startx=1;<br> break;<br> <font color="blue">case</font> 4: <font color="gray">//bottom left<br></font><br> starty=1;<br> break;<br> }<br><br> node[<font color="purple">nodePointer</font>].grid[<font color="purple">1+startx</font>][<font color="purple">1+starty</font>]=node[<font color="purple">read</font>].grid[<font color="purple">2+startx</font>][<font color="purple">1+starty</font>];<br> node[<font color="purple">nodePointer</font>].grid[<font color="purple">1+startx</font>][<font color="purple">2+starty</font>]=node[<font color="purple">read</font>].grid[<font color="purple">1+startx</font>][<font color="purple">1+starty</font>];<br> node[<font color="purple">nodePointer</font>].grid[<font color="purple">2+startx</font>][<font color="purple">2+starty</font>]=node[<font color="purple">read</font>].grid[<font color="purple">1+startx</font>][<font color="purple">2+starty</font>];<br> node[<font color="purple">nodePointer</font>].grid[<font color="purple">2+startx</font>][<font color="purple">1+starty</font>]=node[<font color="purple">read</font>].grid[<font color="purple">2+startx</font>][<font color="purple">2+starty</font>];<br> node[<font color="purple">nodePointer</font>].level=node[<font color="purple">read</font>].level+1;<br> node[<font color="purple">nodePointer</font>].parent=read;<br><br> <font color="blue">if</font>(checkExist==1)<br> {<br> <font color="blue">if</font>(isExist(nodePointer))<br> <font color="blue">return</font> false;<br> nodePointer++;<br> }<br> <font color="blue">return</font> true;<br>}<br><br><font color="gray">// Warning… >12pm humor within…<br></font><br><font color="blue">bool</font> CTree::rotateR(<font color="blue">int</font> read, <font color="blue">int</font> store, <font color="blue">int</font> type)<br>{<br> <font color="gray">//2 wrongs mite not make a right, but 3 lefts do!!! :-D<br></font><br> rotateL(read, store, type, 0);<br> rotateL(read, store, type, 0);<br> rotateL(read, store, type, 1);<br><br> <font color="blue">return</font> true;<br>}<br><br><font color="gray">// The brain of the puzzel solver :-)<br></font><br><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray"><font color="gray">//<br></font></font></font></font></font></font><br><font color="gray">// pass the start and end nodes for the solution - so it knows wot 2 work<br></font><br><font color="gray">// from and what 2 wrk 2!<br></font><br><font color="blue">int</font> CTree::solve(SNode start, SNode finish)<br>{<br> <font color="blue">int</font> level=1; <font color="gray">//level in tree… top level = 1<br></font><br> <font color="blue">int</font> parent=0; <font color="gray">//parent = daddy node<br></font><br> <br> node[<font color="purple">1</font>].level=1; <font color="gray">//setup root node<br></font><br> node[<font color="purple">1</font>].parent=0;<br> cpy(start, 1);<br><br> nodePointer=2; <font color="gray">//setup nodePointer - points 2 next availble node in node[]<br></font><br><br> <font color="blue">int</font> i=0;<br> <font color="blue">int</font> iLimit=0;<br><br> <font color="gray">//Here we loop round all the bottom level nodes, calculate and store<br></font><br> <font color="gray">//the answers in the tree - until we get our result<br></font><br> <font color="blue">do</font><br> {<br> i=0;<br> iLimit=nodePointer; <font color="gray">//used 2 break loop @ appropiate time<br></font><br> <font color="blue">do</font><br> {<br> i++;<br> <font color="blue">if</font>(node[<font color="purple">i</font>].level==level)<br> {<br> parent=i;<br> <br> <font color="gray">//8 possible outcomes for each node<br></font><br> <font color="blue">for</font> (<font color="blue">int</font> a=1; a<5; a++)<br> {<br> rotateR(i, i+a, a);<br> <font color="blue">if</font> (cmp(nodePointer-1, finish)==true)<br> <font color="blue">return</font> (nodePointer-1);<br> }<br> <br> <font color="blue">for</font> (a=5; a<9; a++)<br> {<br> rotateL(i, i+a, (a-4), 1);<br> <font color="blue">if</font> (cmp(nodePointer-1, finish)==true)<br> <font color="blue">return</font> (nodePointer-1);<br> }<br> }<br> } <font color="blue">while</font> (i<iLimit);<br> level++;<br> } <font color="blue">while</font>(1==1);<br><br> <font color="blue">return</font> 0;<br>}<br><br><font color="gray">// Main program<br></font><br><font color="blue">void</font> main()<br>{<br> CTree AI;<br><br> SNode start;<br> SNode finish;<br><font color="gray">/*<br>tested nodes:<br>421<br>756<br>983<br><br>253<br>146<br>789<br><br>413<br>825<br>796<br>*/</font><br> <font color="gray">//setup arrays<br></font><br> start.grid[<font color="purple">1</font>][<font color="purple">1</font>]=4;<br> start.grid[<font color="purple">2</font>][<font color="purple">1</font>]=1;<br> start.grid[<font color="purple">3</font>][<font color="purple">1</font>]=3;<br><br> start.grid[<font color="purple">1</font>][<font color="purple">2</font>]=8;<br> start.grid[<font color="purple">2</font>][<font color="purple">2</font>]=2;<br> start.grid[<font color="purple">3</font>][<font color="purple">2</font>]=5;<br><br> start.grid[<font color="purple">1</font>][<font color="purple">3</font>]=7;<br> start.grid[<font color="purple">2</font>][<font color="purple">3</font>]=9;<br> start.grid[<font color="purple">3</font>][<font color="purple">3</font>]=6;<br><br><br> finish.grid[<font color="purple">1</font>][<font color="purple">1</font>]=1;<br> finish.grid[<font color="purple">2</font>][<font color="purple">1</font>]=2;<br> finish.grid[<font color="purple">3</font>][<font color="purple">1</font>]=3;<br><br> finish.grid[<font color="purple">1</font>][<font color="purple">2</font>]=4;<br> finish.grid[<font color="purple">2</font>][<font color="purple">2</font>]=5;<br> finish.grid[<font color="purple">3</font>][<font color="purple">2</font>]=6;<br><br> finish.grid[<font color="purple">1</font>][<font color="purple">3</font>]=7;<br> finish.grid[<font color="purple">2</font>][<font color="purple">3</font>]=8;<br> finish.grid[<font color="purple">3</font>][<font color="purple">3</font>]=9;<br><br> <font color="blue">int</font> nextNode=AI.solve(start, finish);<br><br> <font color="gray">//output solution from tree<br></font><br> cout << <font color="darkred">"Solution:"</font> << endl;<br> <font color="blue">do</font><br> {<br> AI.output(nextNode);<br> nextNode=AI.node[<font color="purple">nextNode</font>].parent;<br> } <font color="blue">while</font> (nextNode!=0);<br><br> cout << <font color="darkred">"Number of Nodes: "</font> << AI.nodePointer-1 << endl;<br><br>}<br> </pre></DIV><!–ENDSCRIPT–>