carfield.com.hk AbstractGraphSearch.java 2002-01-20T16:00:00Z 2002-01-20T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import java.util.Vector; abstract public class AbstractGraphSearch { public void addNode(String name, int x, int y) { System.out.println(&quot;Adding node: &quot; + name + &quot;, &quot; + x + &quot;, &quot; + y); nodeNames[numNodes] = name; node_x[numNodes] = x; node_y[numNodes] = y; numNodes++; } public int getNumNodes() { return numNodes; } public int getNumLinks() { return numLinks; } public String getNodeName(int index) { try { return nodeNames[index]; } catch (Exception e) { System.out.println(&quot;Error in getNodeName: &quot; + e); } return &quot;no name&quot;; // error condition } public int getNodeX(int index) { try { return node_x[index]; } catch (Exception e) { System.out.println(&quot;Error in getNodePosition: &quot; + e); } return 0; // error condition } public int getNodeY(int index) { try { return node_y[index]; } catch (Exception e) { System.out.println(&quot;Error in getNodePosition: &quot; + e); } return 0; // error condition } public int getLink1(int index) { return link_1[index]; } public int getLink2(int index) { return link_2[index]; } public void addLink(int node1, int node2) { link_1[numLinks] = node1; link_2[numLinks] = node2; int dist_squared = (node_x[node1] - node_x[node2]) * (node_x[node1] - node_x[node2]) + (node_y[node1] - node_y[node2]) * (node_y[node1] - node_y[node2]); lengths[numLinks] = (int)Math.sqrt(dist_squared); numLinks++; } public void addLink(String name1, String name2) { int index1 = -1, index2 = -1; for (int i=0; i&lt;numNodes; i++) { if (name1.equals(nodeNames[i])) index1 = i; if (name2.equals(nodeNames[i])) index2 = i; } if (index1 != -1 &amp;&amp; index2 != -1) addLink(index1, index2); } /** findPath - abstract method that is defined in subclasses */ abstract public int [] findPath(int start_node, int goal_node); // return an array of node indices protected int getNodeIndex(String name) { for (int i=0; i&lt;numNodes; i++) { if (name.equals(nodeNames[i])) return i; } return -1; // error condition } final public static int MAX = 50; // max number of nodes and max number of links protected int [] path = new int[AbstractGraphSearch.MAX]; protected int num_path = 0; // for nodes: protected String [] nodeNames = new String[MAX]; protected int [] node_x = new int[MAX]; protected int [] node_y = new int[MAX]; // for links between nodes: protected int [] link_1 = new int[MAX]; protected int [] link_2 = new int[MAX]; protected int [] lengths = new int[MAX]; protected int numNodes = 0; protected int numLinks = 0; protected int goalNodeIndex = -1, startNodeIndex = -1; } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-20T16:00:00Z BreadthFirstSearch.java 2002-01-20T16:00:00Z 2002-01-20T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">public class BreadthFirstSearch extends AbstractGraphSearch { /** findPath - abstract method in super class */ public int [] findPath(int start_node, int goal_node) { // return an array of node indices System.out.println(&quot;Entered BreadthFirstSearch.findPath(&quot; + start_node + &quot;, &quot; + goal_node + &quot;)&quot;); // data structures for depth first search: boolean [] alreadyVisitedFlag = new boolean[numNodes]; int [] predecessor = new int[numNodes]; IntQueue queue = new IntQueue(numNodes + 2); for (int i=0; i&lt;numNodes; i++) { alreadyVisitedFlag[i] = false; predecessor[i] = -1; } alreadyVisitedFlag[start_node] = true; queue.addToBackOfQueue(start_node); outer: while (queue.isEmpty() == false) { int head = queue.peekAtFrontOfQueue(); int [] connected = connected_nodes(head); if (connected != null) { for (int i=0; i&lt;connected.length; i++) { if (alreadyVisitedFlag[connected[i]] == false) { predecessor[connected[i]] = head; queue.addToBackOfQueue(connected[i]); if (connected[i] == goal_node) break outer; // we are done } } alreadyVisitedFlag[head] = true; queue.removeFromQueue(); // ignore return value } } // now calculate the shortest path from the predecessor array: int [] ret = new int[numNodes + 1]; int count = 0; ret[count++] = goal_node; for (int i=0; i&lt;numNodes; i++) { ret[count] = predecessor[ret[count - 1]]; count++; if (ret[count - 1] == start_node) break; // back to starting node } int [] ret2 = new int[count]; for (int i=0; i&lt;count; i++) { ret2[i] = ret[count - 1 - i]; } return ret2; } protected class IntQueue { public IntQueue(int num) { queue = new int[num]; head = tail = 0; len = num; } public IntQueue() { this(400); } private int [] queue; int tail, head, len; public void addToBackOfQueue(int n) { queue[tail] = n; if (tail &gt;= (len - 1)) { tail = 0; } else { tail++; } } public int removeFromQueue() { int ret = queue[head]; if (head &gt;= (len - 1)) { head = 0; } else { head++; } return ret; } public boolean isEmpty() { return head == (tail + 1); } public int peekAtFrontOfQueue() { return queue[head]; } } protected int [] connected_nodes(int node) { int [] ret = new int[AbstractGraphSearch.MAX]; int num = 0; for (int n=0; n&lt;numNodes; n++) { boolean connected = false; // See if there is a link between node 'node' and 'n': for (int i=0; i&lt;numLinks; i++) { if (link_1[i] == node) { if (link_2[i] == n) { connected = true; break; } } if (link_2[i] == node) { if (link_1[i] == n) { connected = true; break; } } } if (connected) { ret[num++] = n; } } if (num == 0) return null; int [] ret2 = new int[num]; for (int i=0; i&lt;num; i++) { ret2[i] = ret[i]; } return ret2; } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-20T16:00:00Z DepthFirstSearch.java 2002-01-20T16:00:00Z 2002-01-20T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">public class DepthFirstSearch extends AbstractGraphSearch { /** findPath - abstract method in super class */ public int [] findPath(int start_node, int goal_node) { // return an array of node indices System.out.println(&quot;Entered DepthFirstSearch.findPath(&quot; + start_node + &quot;, &quot; + goal_node + &quot;)&quot;); path[0] = start_node; return findPathHelper(path, 1, goal_node); } public int [] findPathHelper(int [] path, int num_path, int goal_node) { System.out.println(&quot;Entered DepthFirstSearch.findPathHelper(...,&quot; + num_path + &quot;, &quot; + goal_node + &quot;)&quot;); if (goal_node == path[num_path - 1]) { int [] ret = new int[num_path]; for (int i=0; i&lt;num_path; i++) ret[i] = path[i]; return ret; // we are done! } int [] new_nodes = connected_nodes(path, num_path); if (new_nodes != null) { for (int j=0; j&lt;new_nodes.length; j++) { path[num_path] = new_nodes[j]; int [] test = findPathHelper(path, num_path + 1, goal_node); if (test != null) { if (test[test.length - 1] == goal_node) { return test; } } } } return null; } protected int [] connected_nodes(int [] path, int num_path) { // find all nodes connected to the last node on 'path' // that are not already on 'path' int [] ret = new int[AbstractGraphSearch.MAX]; int num = 0; int last_node = path[num_path - 1]; for (int n=0; n&lt;numNodes; n++) { // see if node 'n' is already on 'path': boolean keep = true; for (int i=0; i&lt;num_path; i++) { if (n == path[i]) { keep = false; break; } } boolean connected = false; if (keep) { // now see if there is a link between node 'last_node' and 'n': for (int i=0; i&lt;numLinks; i++) { if (link_1[i] == last_node) { if (link_2[i] == n) { connected = true; break; } } if (link_2[i] == last_node) { if (link_1[i] == n) { connected = true; break; } } } if (connected) { ret[num++] = n; } } } if (num == 0) return null; int [] ret2 = new int[num]; for (int i=0; i&lt;num; i++) { ret2[i] = ret[i]; } return ret2; } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-20T16:00:00Z GraphBreadthFirstSearch.java 2002-01-20T16:00:00Z 2002-01-20T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import javax.swing.*; import java.awt.*; public class GraphBreadthFirstSearch extends JFrame { JPanel jPanel1 = new JPanel(); public GraphBreadthFirstSearch() { BreadthFirstSearch engine = new BreadthFirstSearch(); // Define a test network before calling the super class 'init': engine.addNode(&quot;0&quot;, 20, 40); engine.addNode(&quot;1&quot;, 60, 60); engine.addNode(&quot;2&quot;, 100, 40); engine.addNode(&quot;3&quot;, 50, 110); engine.addNode(&quot;4&quot;, 140, 80); engine.addNode(&quot;5&quot;, 160, 150); engine.addNode(&quot;6&quot;, 200, 80); engine.addNode(&quot;7&quot;, 160, 40); engine.addNode(&quot;8&quot;, 240, 120); engine.addNode(&quot;9&quot;, 260, 90); engine.addLink(0,1); engine.addLink(1,2); engine.addLink(2,3); engine.addLink(2,4); engine.addLink(4,5); engine.addLink(4,6); engine.addLink(6,8); engine.addLink(8,9); engine.addLink(2,7); engine.addLink(7,9); System.out.println(&quot;Before calculating path&quot;); path = engine.findPath(0, 9); System.out.println(&quot;After calculating path:&quot;); for (int i=0; i&lt;path.length; i++) { System.out.println(&quot; node # &quot; + path[i]); } this.engine = engine; try { jbInit(); } catch(Exception e) { e.printStackTrace(); } } private int [] path = null; private BreadthFirstSearch engine = null; public static void main(String[] args) { GraphBreadthFirstSearch graphBreadthFirstSearch1 = new GraphBreadthFirstSearch(); } private void jbInit() throws Exception { this.setDefaultCloseOperation(3); jPanel1.setBackground(Color.white); this.getContentPane().add(jPanel1, BorderLayout.CENTER); this.setSize(290, 180); this.setVisible(true); } protected void paintNode(Graphics g, String name, int x, int y) { int len = name.length() * 10 + 6; int x1 = x - (len / 2); int x2 = x + (len / 2); int y1 = y - 10; int y2 = y + 10; g.setColor(Color.cyan); g.fill3DRect(x1, y1, len, 20, true); g.setColor(Color.black); g.drawString(name, x1 + 4, y2 - 6); } public void paint(Graphics g) { super.paint(g); if (engine != null &amp;&amp; path != null) { int numNodes = engine.getNumNodes(); int numLinks = engine.getNumLinks(); for (int i=0; i&lt;numLinks; i++) { int l1 = engine.getLink1(i); int l2 = engine.getLink2(i); int x1 = engine.getNodeX(l1); int y1 = engine.getNodeY(l1); int x2 = engine.getNodeX(l2); int y2 = engine.getNodeY(l2); g.setColor(Color.lightGray); g.drawLine(x1, y1, x2, y2); } for (int i=1; i&lt;path.length; i++) { int x1 = engine.getNodeX(path[i-1]); int y1 = engine.getNodeY(path[i-1]); int x2 = engine.getNodeX(path[i]); int y2 = engine.getNodeY(path[i]); g.setColor(Color.black); g.drawLine(x1, y1, x2, y2); } for (int i=0; i&lt;numNodes; i++) { int x1 = engine.getNodeX(i); int y1 = engine.getNodeY(i); paintNode(g, engine.getNodeName(i), x1, y1); } } } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-20T16:00:00Z GraphDepthFirstSearch.java 2002-01-20T16:00:00Z 2002-01-20T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import javax.swing.*; import java.awt.*; public class GraphDepthFirstSearch extends JFrame { JPanel jPanel1 = new JPanel(); public GraphDepthFirstSearch() { DepthFirstSearch engine = new DepthFirstSearch(); // Define a test network before calling the super class 'init': engine.addNode(&quot;0&quot;, 20, 40); engine.addNode(&quot;1&quot;, 60, 60); engine.addNode(&quot;2&quot;, 100, 40); engine.addNode(&quot;3&quot;, 50, 110); engine.addNode(&quot;4&quot;, 140, 80); engine.addNode(&quot;5&quot;, 160, 150); engine.addNode(&quot;6&quot;, 200, 80); engine.addNode(&quot;7&quot;, 160, 40); engine.addNode(&quot;8&quot;, 240, 120); engine.addNode(&quot;9&quot;, 260, 90); engine.addLink(0,1); engine.addLink(1,2); engine.addLink(2,3); engine.addLink(2,4); engine.addLink(4,5); engine.addLink(4,6); engine.addLink(6,8); engine.addLink(8,9); engine.addLink(2,7); engine.addLink(7,9); System.out.println(&quot;Before calculating path&quot;); path = engine.findPath(0, 9); System.out.println(&quot;After calculating path:&quot;); for (int i=0; i&lt;path.length; i++) { System.out.println(&quot; node # &quot; + path[i]); } this.engine = engine; try { jbInit(); } catch(Exception e) { e.printStackTrace(); } } private int [] path = null; private DepthFirstSearch engine = null; public static void main(String[] args) { GraphDepthFirstSearch graphDepthFirstSearch1 = new GraphDepthFirstSearch(); } private void jbInit() throws Exception { this.setDefaultCloseOperation(3); jPanel1.setBackground(Color.white); this.getContentPane().add(jPanel1, BorderLayout.CENTER); this.setSize(290, 180); this.setVisible(true); } protected void paintNode(Graphics g, String name, int x, int y) { int len = name.length() * 10 + 6; int x1 = x - (len / 2); int x2 = x + (len / 2); int y1 = y - 10; int y2 = y + 10; g.setColor(Color.cyan); g.fill3DRect(x1, y1, len, 20, true); g.setColor(Color.black); g.drawString(name, x1 + 4, y2 - 6); } public void paint(Graphics g) { super.paint(g); if (engine != null &amp;&amp; path != null) { int numNodes = engine.getNumNodes(); int numLinks = engine.getNumLinks(); for (int i=0; i&lt;numLinks; i++) { int l1 = engine.getLink1(i); int l2 = engine.getLink2(i); int x1 = engine.getNodeX(l1); int y1 = engine.getNodeY(l1); int x2 = engine.getNodeX(l2); int y2 = engine.getNodeY(l2); g.setColor(Color.lightGray); g.drawLine(x1, y1, x2, y2); } for (int i=1; i&lt;path.length; i++) { int x1 = engine.getNodeX(path[i-1]); int y1 = engine.getNodeY(path[i-1]); int x2 = engine.getNodeX(path[i]); int y2 = engine.getNodeY(path[i]); g.setColor(Color.black); g.drawLine(x1, y1, x2, y2); } for (int i=0; i&lt;numNodes; i++) { int x1 = engine.getNodeX(i); int y1 = engine.getNodeY(i); paintNode(g, engine.getNodeName(i), x1, y1); } } } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-20T16:00:00Z Maze.java 2002-01-19T16:00:00Z 2002-01-19T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import java.awt.Dimension; /** * Class Maze - private class for representing search space as a two-dimensional maze */ public class Maze { public static short OBSTICLE = -1; public static short START_LOC_VALUE = -2; public static short GOAL_LOC_VALUE = -3; private int width = 0; private int height = 0; public Dimension startLoc = new Dimension(); public Dimension goalLoc = new Dimension(); /** * The maze (or search space) data is stored as a short integer rather than * as a boolean so that bread-first style searches can use the array to store * search depth. A value of -1 indicates a barrier in the maze. */ private short [][]maze; public Maze(int width, int height) { System.out.println(&quot;New maze of size &quot; + width + &quot; by &quot; + height); this.width = width; this.height = height; maze = new short[width+2][height+2]; for (int i=0; i&lt;width+2; i++) { for (int j=0; j&lt;height+2; j++) { maze[i][j] = 0; } } for (int i=0; i&lt;height+2; i++) { maze[0][i] = maze[width+1][i] = OBSTICLE; } for (int i=0; i&lt;width+2; i++) { maze[i][0] = maze[i][height+1] = OBSTICLE; } /** * Randomize the maze by putting up arbitray obsticals */ int max_obsticles = (width * height) / 3; for (int i=0; i&lt;max_obsticles; i++) { int x = (int)(Math.random()*width); int y = (int)(Math.random()*height); setValue(x, y, OBSTICLE); } /** * Specify the starting location */ startLoc.width = 0; startLoc.height = 0; setValue(0, 0, (short)0); /** * Specify the goal location */ goalLoc.width = width - 1; goalLoc.height = height - 1; setValue(width - 1, height - 1, GOAL_LOC_VALUE); } synchronized public short getValue(int x, int y) { return maze[x+1][y+1]; } synchronized public void setValue(int x, int y, short value) { maze[x+1][y+1] = value; } public int getWidth() { return width; } public int getHeight() { return height; } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-19T16:00:00Z MazeBreadthFirstSearch.java 2002-01-19T16:00:00Z 2002-01-19T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import javax.swing.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; /** * Title: MazeBreadthFirstSearch&lt;p&gt; * Description: Demo program for Java AI Programming&lt;p&gt; * Copyright: Copyright (c) Mark Watson, Released under Open Source Artistic License&lt;p&gt; * Company: Mark Watson Associates&lt;p&gt; * @author Mark Watson * @version 1.0 */ public class MazeBreadthFirstSearch extends javax.swing.JFrame { JPanel jPanel1 = new JPanel(); BreadthFirstSearchEngine currentSearchEngine = null; public MazeBreadthFirstSearch() { try { jbInit(); } catch (Exception e) { System.out.println(&quot;GUI initilization error: &quot; + e); } currentSearchEngine = new BreadthFirstSearchEngine(10, 10); repaint(); } public void paint(Graphics g_unused) { if (currentSearchEngine == null) return; Maze maze = currentSearchEngine.getMaze(); int width = maze.getWidth(); int height = maze.getHeight(); System.out.println(&quot;Size of current maze: &quot; + width + &quot; by &quot; + height); Graphics g = jPanel1.getGraphics(); BufferedImage image = new BufferedImage(320, 320, BufferedImage.TYPE_INT_RGB); Graphics g2 = image.getGraphics(); g2.setColor(Color.white); g2.fillRect(0, 0, 320, 320); g2.setColor(Color.black); for (int x=0; x&lt;width; x++) { for (int y=0; y&lt;height; y++) { short val = maze.getValue(x,y); if ( val == Maze.OBSTICLE) { g2.setColor(Color.lightGray); g2.fillRect(6 + x * 28, 3 + y * 29, 29, 30); } else if (val == Maze.START_LOC_VALUE || (x==0 &amp;&amp; y==0)) { g2.setColor(Color.blue); g2.drawString(&quot;S&quot;, 16 + x * 28, 19 + y * 29); } else if (val == Maze.GOAL_LOC_VALUE) { g2.setColor(Color.red); g2.drawString(&quot;G&quot;, 16 + x * 28, 19 + y * 29); } } } // redraw the path in black: g2.setColor(Color.black); Dimension [] path = currentSearchEngine.getPath(); for (int i=1; i&lt; (path.length-1); i++) { int x = path[i].width; int y = path[i].height; short val = maze.getValue(x,y); g2.drawString(&quot;&quot; + (path.length - i), 16 + x * 28, 19 + y * 29); } g.drawImage(image, 30, 40, 320, 320, null); } public static void main(String[] args) { MazeBreadthFirstSearch mazeSearch1 = new MazeBreadthFirstSearch(); } private void jbInit() throws Exception { this.setContentPane(jPanel1); this.setCursor(null); this.setDefaultCloseOperation(3); this.setTitle(&quot;MazeBreadthFirstSearch&quot;); this.getContentPane().setLayout(null); jPanel1.setBackground(Color.white); jPanel1.setDebugGraphicsOptions(DebugGraphics.NONE_OPTION); jPanel1.setDoubleBuffered(false); jPanel1.setRequestFocusEnabled(false); jPanel1.setLayout(null); this.setSize(370, 420); this.setVisible(true); } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-19T16:00:00Z MazeDepthFirstSearch.java 2002-01-19T16:00:00Z 2002-01-19T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import javax.swing.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; /** * Title: MazeDepthFirstSearch&lt;p&gt; * Description: Demo program for Java AI Programming&lt;p&gt; * Copyright: Copyright (c) Mark Watson, Released under Open Source Artistic License&lt;p&gt; * Company: Mark Watson Associates&lt;p&gt; * @author Mark Watson * @version 1.0 */ public class MazeDepthFirstSearch extends javax.swing.JFrame { JPanel jPanel1 = new JPanel(); DepthFirstSearchEngine currentSearchEngine = null; public MazeDepthFirstSearch() { try { jbInit(); } catch (Exception e) { System.out.println(&quot;GUI initilization error: &quot; + e); } currentSearchEngine = new DepthFirstSearchEngine(10, 10); repaint(); } public void paint(Graphics g_unused) { if (currentSearchEngine == null) return; Maze maze = currentSearchEngine.getMaze(); int width = maze.getWidth(); int height = maze.getHeight(); System.out.println(&quot;Size of current maze: &quot; + width + &quot; by &quot; + height); Graphics g = jPanel1.getGraphics(); BufferedImage image = new BufferedImage(320, 320, BufferedImage.TYPE_INT_RGB); Graphics g2 = image.getGraphics(); g2.setColor(Color.white); g2.fillRect(0, 0, 320, 320); g2.setColor(Color.black); for (int x=0; x&lt;width; x++) { for (int y=0; y&lt;height; y++) { short val = maze.getValue(x,y); if ( val == Maze.OBSTICLE) { g2.setColor(Color.lightGray); g2.fillRect(6 + x * 28, 3 + y * 29, 29, 30); } else if (val == Maze.START_LOC_VALUE || val == 1) { g2.setColor(Color.blue); g2.drawString(&quot;S&quot;, 16 + x * 28, 19 + y * 29); } else if (val == Maze.GOAL_LOC_VALUE) { g2.setColor(Color.red); g2.drawString(&quot;G&quot;, 16 + x * 28, 19 + y * 29); } else if (val &gt; 0) { //g2.setColor(Color.green); //g2.drawString(&quot;&quot; + val, 16 + x * 28, 19 + y * 29); } } } // redraw the path in black: g2.setColor(Color.black); Dimension [] path = currentSearchEngine.getPath(); for (int i=1; i&lt; path.length; i++) { int x = path[i].width; int y = path[i].height; short val = maze.getValue(x,y); g2.drawString(&quot;&quot; + val, 16 + x * 28, 19 + y * 29); } g.drawImage(image, 30, 40, 320, 320, null); } public static void main(String[] args) { MazeDepthFirstSearch mazeSearch1 = new MazeDepthFirstSearch(); } private void jbInit() throws Exception { this.setContentPane(jPanel1); this.setCursor(null); this.setDefaultCloseOperation(3); this.setTitle(&quot;MazeDepthFirstSearch&quot;); this.getContentPane().setLayout(null); jPanel1.setBackground(Color.white); jPanel1.setDebugGraphicsOptions(DebugGraphics.NONE_OPTION); jPanel1.setDoubleBuffered(false); jPanel1.setRequestFocusEnabled(false); jPanel1.setLayout(null); this.setSize(370, 420); this.setVisible(true); } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2002-01-19T16:00:00Z Chess$aMove.class 2000-06-01T16:00:00Z 2000-06-01T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-01T16:00:00Z Chess.class 2000-06-01T16:00:00Z 2000-06-01T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-01T16:00:00Z Chess.java 2000-06-01T16:00:00Z 2000-06-01T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import java.util.*; import java.io.*; public class Chess extends GameSearch { /** * Notes: PROGRAM false -1, HUMAN true 1 */ /** * PUBLIC API (mostly fromGameSearch) */ public boolean drawnPosition(Position p) { /** * We want to keep searching: */ return false; } public boolean wonPosition(Position p, boolean player) { // evetually, we should check for checkmates here... return false; } public float positionEvaluation(Position p, boolean player) { ChessPosition pos = (ChessPosition)p; int [] b = pos.board; float ret = 0.0f; // adjust for material: for (int i=22; i&lt;100; i++) { if (b[i] != 0 &amp;&amp; b[i] != 7) ret += b[i]; } // adjust for positional advantages: setControlData(pos); int control = 0; for (int i=22; i&lt;100; i++) { control += humanControl[i]; control -= computerControl[i]; } // Count center squares extra: control += humanControl[55] - computerControl[55]; control += humanControl[56] - computerControl[56]; control += humanControl[65] - computerControl[65]; control += humanControl[66] - computerControl[66]; control /= 10.0f; ret += control; // credit for attacked pieces: for (int i=22; i&lt;100; i++) { if (b[i] == 0 || b[i] == 7) continue; if (b[i] &lt; 0) { if (humanControl[i] &gt; computerControl[i]) { ret += 0.9f * value[-b[i]]; } } if (b[i] &gt; 0) { if (humanControl[i] &lt; computerControl[i]) { ret -= 0.9f * value[b[i]]; } } } // adjust if computer side to move: if (!player) ret = -ret; return ret; } public void printPosition(Position p) { System.out.println(&quot;Board position:&quot;); ChessPosition pos = (ChessPosition)p; int [] b = pos.board; for (int col=92; col&gt;=22; col-=10) { System.out.println(); for (int ii=0; ii&lt;8; ii++) { int i = ii + col; if (b[i] != 0) { System.out.print(pp(b[i], i)); } else { boolean white_sq = true; for (int k=0; k&lt;blackSquares.length; k++) { if (i == blackSquares[k]) { white_sq = false; break; } } if (white_sq) System.out.print(&quot; &quot;); else System.out.print(&quot; . &quot;); } } } System.out.println(); } private String pp(int piece, int square_index) { if (piece == 0) return &quot; &quot;; String color; if (piece &lt; 0) color = &quot;B&quot;; else color = &quot;W&quot;; int p = piece; if (p &lt; 0) p = -p; switch (p) { case 1: return &quot; &quot; + color + &quot;P&quot;; case 2: return &quot; &quot; + color + &quot;N&quot;; case 3: return &quot; &quot; + color + &quot;B&quot;; case 4: return &quot; &quot; + color + &quot;R&quot;; case 5: return &quot; &quot; + color + &quot;Q&quot;; case 9: return &quot; &quot; + color + &quot;K&quot;; } return &quot;error&quot;; } public Position [] possibleMoves(Position p, boolean player) { if (GameSearch.DEBUG) System.out.println(&quot;posibleMoves(&quot;+p+&quot;,&quot;+player+&quot;)&quot;); ChessPosition pos = (ChessPosition)p; //System.out.println(&quot;Chess.possibleMoves(): pos=&quot; + pos); //for (int i=22; i&lt;40; i++) System.out.println(pos.board[i]); int num = calcPossibleMoves(pos, player); if (num == 0) { System.out.println(&quot;Stalemate&quot;); System.exit(0); } ChessPosition [] chessPos = new ChessPosition[num]; for (int i=0; i&lt;num; i++) { chessPos[i] = new ChessPosition(); for (int j=22; j&lt;100; j++) chessPos[i].board[j] = pos.board[j]; chessPos[i].board[possibleMoveList[i].to] = chessPos[i].board[possibleMoveList[i].from]; chessPos[i].board[possibleMoveList[i].from] = 0; } return chessPos; } public Position makeMove(Position p, boolean player, Move move) { if (GameSearch.DEBUG) System.out.println(&quot;Entered Chess.makeMove&quot;); ChessMove m = (ChessMove)move; ChessPosition pos = (ChessPosition)p; ChessPosition pos2 = new ChessPosition(); for (int i=0; i&lt;120; i++) pos2.board[i] = pos.board[i]; int pp; if (player) pp = 1; else pp = -1; if (GameSearch.DEBUG) System.out.println(&quot;makeMove: m.from = &quot; + m.from + &quot;, m.to = &quot; + m.to); pos2.board[m.to] = pos2.board[m.from]; pos2.board[m.from] = 0; return pos2; } public boolean reachedMaxDepth(Position p, int depth) { if (depth &lt; 5) return false; return true; } private BufferedReader in = null; public Move getMove() { if (GameSearch.DEBUG) System.out.println(&quot;Enter blank square index [0,8]:&quot;); ChessMove mm = new ChessMove(); System.out.println(&quot;enter a move like 'd2d4' or 'oo'&quot;); try { if (in == null) { in = new BufferedReader(new InputStreamReader(System.in)); } String s = in.readLine().toLowerCase(); System.out.println(&quot;s=&quot;+s); char c0 = (char)(s.charAt(0) - 'a' + 2); char r0 = (char)(s.charAt(1) - '1' + 2); char c1 = (char)(s.charAt(2) - 'a' + 2); char r1 = (char)(s.charAt(3) - '1' + 2); mm.from = r0*10+c0; mm.to = r1*10+c1; System.out.println(&quot;From &quot; + mm.from + &quot;, to &quot; + mm.to); } catch (Exception e) { System.out.println(e); } return mm; } static public void main(String [] args) { ChessPosition p = new ChessPosition(); for (int i=0; i&lt;120; i++) p.board[i] = initialBoard[i]; Chess ttt = new Chess(); /* DEBUG*/ // ttt.setControlData(p); ttt.playGame(p, true); } /** * PRIVATE API, mostly chess move and evaluation utilities */ // static data that can be re-used (assume single threading!) static private float [] computerControl = new float[120]; static private float [] humanControl = new float[120]; private void setControlData(ChessPosition pos) { for (int i=0; i&lt;120; i++) { computerControl[i] = 0; humanControl[i] = 0; } int [] b = pos.board; float [] control; // set to computerControl or humanControl, as appropriate for (int square_index=22; square_index&lt;100; square_index++) { int piece = b[square_index]; if (piece == 7 || piece == 0) continue; int piece_type = piece; if (piece_type &lt; 0) { piece_type = -piece_type; control = computerControl; } else { control = humanControl; } int count = 0, side_index, move_offset, temp, next_square; int piece_index = index[piece_type]; int move_index = pieceMovementTable[piece_index]; if (piece &lt; 0) side_index = -1; else side_index = 1; switch (piece_type) { case ChessPosition.PAWN: { // first check for possible pawn captures: for (int delta=-1; delta&lt;= 1; delta += 2) { move_offset = square_index + side_index * 10 + delta; int target = b[move_offset]; if ((target &lt;= -1 &amp;&amp; target != 7 &amp;&amp; piece &gt; 0) || (target &gt;= 1 &amp;&amp; target != 7 &amp;&amp; piece &lt; 0)) { // kluge: count pawn control more: control[square_index + side_index * delta] += 1.25f; } } } // Note: no break here: we want pawns to use move table also: case ChessPosition.KNIGHT: case ChessPosition.BISHOP: case ChessPosition.ROOK: case ChessPosition.KING: case ChessPosition.QUEEN: { move_index = piece; if (move_index &lt; 0) move_index = -move_index; move_index = index[move_index]; //System.out.println(&quot;move_index=&quot;+move_index); next_square = square_index + pieceMovementTable[move_index]; outer: while (true) { inner: while (true) { if (next_square &gt; 99) break inner; if (next_square &lt; 22) break inner; if (b[next_square] == 7) break inner; control[next_square] += 1; // the next statement should be augmented for x-ray analysis: if (side_index &lt; 0 &amp;&amp; b[next_square] &lt; 0) break inner; if (side_index &gt; 0 &amp;&amp; b[next_square] &gt; 0 &amp;&amp; b[next_square] != 7) break inner; // NOTE: prevents calculating guarding: //if (b[next_square] != 0) break inner; if (piece_type == ChessPosition.PAWN &amp;&amp; (square_index / 10 == 3)) break inner; if (piece_type == ChessPosition.KNIGHT) break inner; if (piece_type == ChessPosition.KING) break inner; next_square += pieceMovementTable[move_index]; } move_index += 1; if (pieceMovementTable[move_index] == 0) break outer; next_square = square_index + pieceMovementTable[move_index]; } } } } // System.out.println(&quot;Human control:&quot;); // for (int i=99; i&gt;=22; i--) { // if (b[i] == 7 &amp;&amp; b[i+1]==7) System.out.println(); // if (b[i] != 7) System.out.print(humanControl[i]); // } // System.out.println(); // System.out.println(&quot;Computer control:&quot;); // for (int i=99; i&gt;=22; i--) { // if (b[i] == 7 &amp;&amp; b[i+1]==7) System.out.println(); // if (b[i] != 7) System.out.print(computerControl[i]); // } // System.out.println(); // System.exit(1); } static class aMove { int from; int to; } private static aMove [] possibleMoveList = new aMove[255]; static { for (int i=0; i&lt;255; i++) possibleMoveList[i] = new aMove(); } private int calcPossibleMoves(ChessPosition pos, boolean player) { //System.out.println(&quot;calcPossibleMoves()&quot;); int [] b = pos.board; int count = 0; for (int i=22; i&lt;100; i++) { int board_val = b[i]; //System.out.println(board_val); if (board_val == 7) continue; // computer pieces will be negative: if ((board_val &lt; 0 &amp;&amp; !player) || (board_val &gt; 0 &amp;&amp; player)) { int num = calcPieceMoves(pos, i); for (int j=0; j&lt;num; j++) { if (b[piece_moves[j]] != 7) { //System.out.println(&quot;count=&quot;+count+&quot;, i=&quot;+i); possibleMoveList[count].from = i; possibleMoveList[count].to = piece_moves[j]; // System.out.println(&quot;possible move: player=&quot;+player+ // &quot;, from=&quot;+i+&quot;, to=&quot;+piece_moves[j]); count++; } } // TBD: castle logic, etc. (page 159) } } return count; } private int calcPieceMoves(ChessPosition pos, int square_index) { int [] b = pos.board; int piece = b[square_index]; int piece_type = piece; if (piece_type &lt; 0) piece_type = -piece_type; int count = 0, side_index, move_offset, temp, next_square; int piece_index = index[piece_type]; int move_index = pieceMovementTable[piece_index]; if (piece &lt; 0) side_index = -1; else side_index = 1; switch (piece_type) { case ChessPosition.PAWN: { // first check for possible pawn captures: for (int delta=-1; delta&lt;= 1; delta += 2) { move_offset = square_index + side_index * 10 + delta; int target = b[move_offset]; if ((target &lt;= -1 &amp;&amp; target != 7 &amp;&amp; piece &gt; 0) || (target &gt;= 1 &amp;&amp; target != 7 &amp;&amp; piece &lt; 0)) { piece_moves[count++] = square_index + side_index * delta; } } // check for initial pawn move of 2 squares forward: move_offset = square_index + side_index * 20; if (piece &gt; 0) temp = 3; else temp = 8; if (b[move_offset] == 0 &amp;&amp; (square_index / 10) == temp &amp;&amp; ((piece &lt; 0 &amp;&amp; b[square_index - 10]==0) || (piece &gt; 0 &amp;&amp; b[square_index + 10]==0))) { piece_moves[count++] = square_index + side_index * 20; } // try to move forward 1 square: move_offset = square_index + side_index * 10; if (b[move_offset] == 0) { piece_moves[count++] = move_offset; } } break; case ChessPosition.KNIGHT: case ChessPosition.BISHOP: case ChessPosition.ROOK: case ChessPosition.KING: case ChessPosition.QUEEN: { move_index = piece; if (move_index &lt; 0) move_index = -move_index; move_index = index[move_index]; //System.out.println(&quot;move_index=&quot;+move_index); next_square = square_index + pieceMovementTable[move_index]; outer: while (true) { inner: while (true) { if (next_square &gt; 99) break inner; if (next_square &lt; 22) break inner; if (b[next_square] == 7) break inner; // check for piece on the same side: if (side_index &lt; 0 &amp;&amp; b[next_square] &lt; 0) break inner; if (side_index &gt;0 &amp;&amp; b[next_square] &gt; 0) break inner; piece_moves[count++] = next_square; if (b[next_square] != 0) break inner; if (piece_type == ChessPosition.KNIGHT) break inner; if (piece_type == ChessPosition.KING) break inner; next_square += pieceMovementTable[move_index]; } move_index += 1; if (pieceMovementTable[move_index] == 0) break outer; next_square = square_index + pieceMovementTable[move_index]; } } } return count; } private static int [] piece_moves = new int[255]; private static int [] initialBoard = { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 2, 3, 5, 9, 3, 2, 4, 7, 7, // white pieces 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, // white pawns 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, // 8 blank squares, 2 off board 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, // 8 blank squares, 2 off board 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, // 8 blank squares, 2 off board 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, // 8 blank squares, 2 off board -1,-1,-1,-1,-1,-1,-1,-1, 7, 7, // black pawns -4,-2,-3,-5,-9,-3,-2,-4, 7, 7, // black pieces 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }; private static int [] index = { 0, 12, 15, 10, 1, 6, 0, 0, 0, 6 }; private static int [] pieceMovementTable = { 0, -1, 1, 10, -10, 0, -1, 1, 10, -10, -9, -11, 9, 11, 0, 8, -8, 12, -12, 19, -19, 21, -21, 0, 10, 20, 0, 0, 0, 0, 0, 0, 0, 0 }; private static int [] value = { 0, 1, 3, 3, 5, 9, 0, 0, 0, 12 }; private static int [] blackSquares = { 22, 24, 26, 28, 33, 35, 37, 39, 42, 44, 46, 48, 53, 55, 57, 59, 62, 64, 66, 68, 73, 75, 77, 79, 82, 84, 86, 88, 93, 95, 97, 99 }; } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-01T16:00:00Z jprobe.jpl 2000-06-01T16:00:00Z 2000-06-01T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-01T16:00:00Z out.txt 2000-06-01T16:00:00Z 2000-06-01T16:00:00Z <br/>Board position:<br/><br/> BR BN BB BQ BK BB BN BR<br/> BP BP BP BP BP BP BP BP<br/> . . . . <br/> . . . . <br/> . . . . <br/> . . . . <br/> WP WP WP WP WP WP WP WP<br/> WR WN WB WQ WK WB WN WR<br/>Your move:<br/>enter a move like 'd2d4' or 'oo'<br/>s=d2d4<br/>From 35, to 55<br/>Board position:<br/><br/> BR BN BB BQ BK BB BN BR<br/> BP BP BP BP BP BP BP BP<br/> . . . . <br/> . . . . <br/> . WP . . <br/> . . . . <br/> WP WP WP . WP WP WP WP<br/> WR WN WB WQ WK WB WN WR<br/> next element: 5.4<br/> next element: [4,2,3,5,9,3,2,4,7,7,1,1,1,0,1,1,1,1,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,0,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,-5,-9,-3,-2,-4,]<br/> next element: [4,2,3,0,9,3,2,4,7,7,1,1,1,5,1,1,1,1,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,0,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,-5,-9,-3,-2,-4,]<br/> next element: [4,2,3,0,9,3,2,4,7,7,1,1,1,5,1,1,1,1,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,-5,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,-3,-2,-4,]<br/> next element: [4,2,3,0,9,3,0,4,7,7,1,1,1,5,1,1,1,1,7,7,0,0,0,0,0,2,0,0,7,7,0,0,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,-5,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,-3,-2,-4,]<br/> next element: [4,2,3,0,9,3,0,4,7,7,1,1,1,5,1,1,1,1,7,7,0,0,0,0,0,2,0,0,7,7,0,0,0,1,0,0,0,0,7,7,-1,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,-5,0,0,7,7,0,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,-3,-2,-4,]<br/>Board position:<br/><br/> BR BN BB BQ BK BB BN BR<br/> BP BP BP BP . BP BP BP<br/> . . BP . . <br/> . . . . <br/> . WP . . <br/> . . . . <br/> WP WP WP . WP WP WP WP<br/> WR WN WB WQ WK WB WN WR<br/>Your move:<br/>enter a move like 'd2d4' or 'oo'<br/>s=g1f3<br/>From 28, to 47<br/>Board position:<br/><br/> BR BN BB BQ BK BB BN BR<br/> BP BP BP BP . BP BP BP<br/> . . BP . . <br/> . . . . <br/> . WP . . <br/> . . . WN . <br/> WP WP WP . WP WP WP WP<br/> WR WN WB WQ WK WB . WR<br/> next element: 6.1999993<br/> next element: [4,2,3,5,9,3,0,4,7,7,1,1,1,0,1,1,1,1,7,7,0,0,0,0,0,2,0,0,7,7,0,0,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,-5,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,-3,-2,-4,]<br/> next element: [4,2,3,0,9,3,0,4,7,7,1,1,1,0,1,1,1,1,7,7,0,0,0,5,0,2,0,0,7,7,0,0,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,-5,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,-3,-2,-4,]<br/> next element: [4,2,3,0,9,3,0,4,7,7,1,1,1,0,1,1,1,1,7,7,0,0,0,5,0,2,0,0,7,7,0,-3,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,-5,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,0,-2,-4,]<br/> next element: [4,2,3,0,9,3,0,4,7,7,1,1,0,0,1,1,1,1,7,7,0,0,1,5,0,2,0,0,7,7,0,-3,0,1,0,0,0,0,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,-5,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,0,-2,-4,]<br/> next element: [4,2,3,0,9,3,0,4,7,7,1,1,0,0,1,1,1,1,7,7,0,0,1,5,0,2,0,0,7,7,0,-3,0,1,0,0,0,-5,7,7,0,0,0,0,0,0,0,0,7,7,0,0,0,0,-1,0,0,0,7,7,-1,-1,-1,-1,0,-1,-1,-1,7,7,-4,-2,-3,0,-9,0,-2,-4,]<br/>Board position:<br/><br/> BR BN BB . BK BB BN BR<br/> BP BP BP BP . BP BP BP<br/> . . BP BQ . <br/> . . . . <br/> . WP . . <br/> . . . WN . <br/> WP WP WP . WP WP WP WP<br/> WR WN WB WQ WK WB . WR<br/>Your move:<br/>enter a move like 'd2d4' or 'oo'<br/>java.lang.NullPointerException<br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-06-01T16:00:00Z ChessPosition.java 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">public class ChessPosition extends Position { final static public int BLANK = 0; final static public int HUMAN = 1; final static public int PROGRAM = -1; final static public int PAWN = 1; final static public int KNIGHT = 2; final static public int BISHOP = 3; final static public int ROOK = 4; final static public int QUEEN = 5; final static public int KING = 6; int [] board = new int[120]; public String toString() { StringBuffer sb = new StringBuffer(&quot;[&quot;); for (int i=22; i&lt;100; i++) { sb.append(&quot;&quot;+board[i]+&quot;,&quot;); } sb.append(&quot;]&quot;); return sb.toString(); } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z GameSearch.class 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z GameSearch.java 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import java.util.*; public abstract class GameSearch { public static final boolean DEBUG = false; /* * Note: the abstract Position also needs to be * subclassed to write a new game program. */ /* * Note: the abstract class Move also needs to be subclassed. * */ public static boolean PROGRAM = false; public static boolean HUMAN = true; /** * Notes: PROGRAM false -1, HUMAN true 1 */ /* * Abstract methods: */ public abstract boolean drawnPosition(Position p); public abstract boolean wonPosition(Position p, boolean player); public abstract float positionEvaluation(Position p, boolean player); public abstract void printPosition(Position p); public abstract Position [] possibleMoves(Position p, boolean player); public abstract Position makeMove(Position p, boolean player, Move move); public abstract boolean reachedMaxDepth(Position p, int depth); public abstract Move getMove(); /* * Search utility methods: */ protected Vector alphaBeta(int depth, Position p, boolean player) { Vector v = alphaBetaHelper(depth, p, player, 1000000.0f, -1000000.0f); //System.out.println(&quot;^^ v(0): &quot; + v.elementAt(0) + &quot;, v(1): &quot; + v.elementAt(1)); return v; } protected Vector alphaBetaHelper(int depth, Position p, boolean player, float alpha, float beta) { if (GameSearch.DEBUG) System.out.println(&quot;alphaBetaHelper(&quot;+depth+&quot;,&quot;+p+&quot;,&quot;+alpha+&quot;,&quot;+beta+&quot;)&quot;); if (reachedMaxDepth(p, depth)) { Vector v = new Vector(2); float value = positionEvaluation(p, player); v.addElement(new Float(value)); v.addElement(null); if(GameSearch.DEBUG) { System.out.println(&quot; alphaBetaHelper: mx depth at &quot; + depth+ &quot;, value=&quot;+value); } return v; } Vector best = new Vector(); Position [] moves = possibleMoves(p, player); for (int i=0; i&lt;moves.length; i++) { Vector v2 = alphaBetaHelper(depth + 1, moves[i], !player, -beta, -alpha); // if (v2 == null || v2.size() &lt; 1) continue; float value = -((Float)v2.elementAt(0)).floatValue(); if (value &gt; beta) { if(GameSearch.DEBUG) System.out.println(&quot; ! ! ! value=&quot;+value+&quot;, beta=&quot;+beta); beta = value; best = new Vector(); best.addElement(moves[i]); Enumeration enum = v2.elements(); enum.nextElement(); // skip previous value while (enum.hasMoreElements()) { Object o = enum.nextElement(); if (o != null) best.addElement(o); } } /** * Use the alpha-beta cutoff test to abort search if we * found a move that proves that the previous move in the * move chain was dubious */ if (beta &gt;= alpha) { break; } } Vector v3 = new Vector(); v3.addElement(new Float(beta)); Enumeration enum = best.elements(); while (enum.hasMoreElements()) { v3.addElement(enum.nextElement()); } return v3; } public void playGame(Position startingPosition, boolean humanPlayFirst) { if (humanPlayFirst == false) { Vector v = alphaBeta(0, startingPosition, PROGRAM); startingPosition = (Position)v.elementAt(1); } while (true) { printPosition(startingPosition); if (wonPosition(startingPosition, PROGRAM)) { System.out.println(&quot;Program won&quot;); break; } if (wonPosition(startingPosition, HUMAN)) { System.out.println(&quot;Human won&quot;); break; } if (drawnPosition(startingPosition)) { System.out.println(&quot;Drawn game&quot;); break; } System.out.println(&quot;Your move:&quot;); Move move = getMove(); startingPosition = makeMove(startingPosition, HUMAN, move); printPosition(startingPosition); Vector v = alphaBeta(0, startingPosition, PROGRAM); Enumeration enum = v.elements(); while (enum.hasMoreElements()) { System.out.println(&quot; next element: &quot; + enum.nextElement()); } startingPosition = (Position)v.elementAt(1); } } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z Move.class 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z Move.java 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">abstract public class Move { } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z Position.class 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z Position.java 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">abstract public class Position { }</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z TicTacToe.class 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z TicTacToe.java 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">import java.util.*; public class TicTacToe extends GameSearch { public boolean drawnPosition(Position p) { if (GameSearch.DEBUG) System.out.println(&quot;drawnPosition(&quot;+p+&quot;)&quot;); boolean ret = true; TicTacToePosition pos = (TicTacToePosition)p; for (int i=0; i&lt;9; i++) { if (pos.board[i] == TicTacToePosition.BLANK){ ret = false; break; } } if (GameSearch.DEBUG) System.out.println(&quot; ret=&quot;+ret); return ret; } public boolean wonPosition(Position p, boolean player) { if (GameSearch.DEBUG) System.out.println(&quot;wonPosition(&quot;+p+&quot;,&quot;+player+&quot;)&quot;); boolean ret = false; TicTacToePosition pos = (TicTacToePosition)p; if (winCheck(0,1,2, player, pos)) ret = true; else if (winCheck(3,4,5, player, pos)) ret = true; else if (winCheck(6,7,8, player, pos)) ret = true; else if (winCheck(2,5,8, player, pos)) ret = true; else if (winCheck(0,4,8, player, pos)) ret = true; else if (winCheck(2,4,6, player, pos)) ret = true; else if (winCheck(0,3,6, player, pos)) ret = true; else if (winCheck(1,4,7, player, pos)) ret = true; if (GameSearch.DEBUG) System.out.println(&quot; ret=&quot;+ret); return ret; } private boolean winCheck(int i1, int i2, int i3, boolean player, TicTacToePosition pos) { int b = 0; if (player) b = TicTacToePosition.HUMAN; else b = TicTacToePosition.PROGRAM; if (pos.board[i1] == b &amp;&amp; pos.board[i2] == b &amp;&amp; pos.board[i3] == b) return true; return false; } public float positionEvaluation(Position p, boolean player) { int count = 0; TicTacToePosition pos = (TicTacToePosition)p; for (int i=0; i&lt;9; i++) { if (pos.board[i] == 0) count++; } count = 10 - count; // prefer the center square: float base = 1.0f; if (pos.board[4] == TicTacToePosition.HUMAN &amp;&amp; player) { base += 0.4f; } if (pos.board[4] == TicTacToePosition.PROGRAM &amp;&amp; !player) { base -= 0.4f; } float ret = (base - 1.0f); if (wonPosition(p, player)) { return base + (1.0f / count); } if (wonPosition(p, !player)) { return -(base + (1.0f / count)); } return ret; } public void printPosition(Position p) { System.out.println(&quot;Board position:&quot;); TicTacToePosition pos = (TicTacToePosition)p; int count = 0; for (int row=0; row&lt;3; row++) { System.out.println(); for (int col=0; col&lt;3; col++) { if (pos.board[count] == TicTacToePosition.HUMAN) { System.out.print(&quot;H&quot;); } else if (pos.board[count] == TicTacToePosition.PROGRAM) { System.out.print(&quot;P&quot;); } else { System.out.print(&quot; &quot;); } count++; } } System.out.println(); } public Position [] possibleMoves(Position p, boolean player) { if (GameSearch.DEBUG) System.out.println(&quot;posibleMoves(&quot;+p+&quot;,&quot;+player+&quot;)&quot;); TicTacToePosition pos = (TicTacToePosition)p; int count = 0; for (int i=0; i&lt;9; i++) if (pos.board[i] == 0) count++; if (count == 0) return null; Position [] ret = new Position[count]; count = 0; for (int i=0; i&lt;9; i++) { if (pos.board[i] == 0) { TicTacToePosition pos2 = new TicTacToePosition(); for (int j=0; j&lt;9; j++) pos2.board[j] = pos.board[j]; if (player) pos2.board[i] = 1; else pos2.board[i] = -1; ret[count++] = pos2; if (GameSearch.DEBUG) System.out.println(&quot; &quot;+pos2); } } return ret; } public Position makeMove(Position p, boolean player, Move move) { if (GameSearch.DEBUG) System.out.println(&quot;Entered TicTacToe.makeMove&quot;); TicTacToeMove m = (TicTacToeMove)move; TicTacToePosition pos = (TicTacToePosition)p; TicTacToePosition pos2 = new TicTacToePosition(); for (int i=0; i&lt;9; i++) pos2.board[i] = pos.board[i]; int pp; if (player) pp = 1; else pp = -1; if (GameSearch.DEBUG) System.out.println(&quot;makeMove: m.moveIndex = &quot; + m.moveIndex); pos2.board[m.moveIndex] = pp; return pos2; } public boolean reachedMaxDepth(Position p, int depth) { boolean ret = false; if (wonPosition(p, false)) ret = true; else if (wonPosition(p, true)) ret = true; else if (drawnPosition(p)) ret = true; if (GameSearch.DEBUG) { System.out.println(&quot;reachedMaxDepth: pos=&quot; + p.toString() + &quot;, depth=&quot;+depth +&quot;, ret=&quot; + ret); } return ret; } public Move getMove() { if (GameSearch.DEBUG) System.out.println(&quot;Enter blank square index [0,8]:&quot;); int i = 0; try { int ch = System.in.read(); i = ch - 48; System.in.read(); System.in.read(); System.out.println(&quot;ch=&quot;+ch+&quot;, i=&quot; + i); } catch (Exception e) { } TicTacToeMove mm = new TicTacToeMove(); mm.moveIndex = i; return mm; } static public void main(String [] args) { TicTacToePosition p = new TicTacToePosition(); TicTacToe ttt = new TicTacToe(); ttt.playGame(p, false); } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z TicTacToeMove.class 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z TicTacToePosition.class 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z TicTacToePosition.java 2000-05-30T16:00:00Z 2000-05-30T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">public class TicTacToePosition extends Position { final static public int BLANK = 0; final static public int HUMAN = 1; final static public int PROGRAM = -1; int [] board = new int[9]; public String toString() { StringBuffer sb = new StringBuffer(&quot;[&quot;); for (int i=0; i&lt;9; i++) { sb.append(&quot;&quot;+board[i]+&quot;,&quot;); } sb.append(&quot;]&quot;); return sb.toString(); } } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2000-05-30T16:00:00Z