Advertisement
LegendSujay2019

Making FourByFour game using Java

Aug 27th, 2019
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 136.07 KB | None | 0 0
  1. import java.applet.Applet;
  2. import java.awt.AWTEvent;
  3. import java.awt.Button;
  4. import java.awt.Canvas;
  5. import java.awt.Checkbox;
  6. import java.awt.CheckboxGroup;
  7. import java.awt.Color;
  8. import java.awt.Graphics;
  9. import java.awt.Image;
  10. import java.awt.Label;
  11. import java.awt.Panel;
  12. import java.awt.TextArea;
  13. import java.awt.TextField;
  14. import java.awt.event.ActionEvent;
  15. import java.awt.event.ActionListener;
  16. import java.awt.event.MouseEvent;
  17. import java.awt.event.MouseListener;
  18. import java.awt.event.WindowAdapter;
  19. import java.awt.event.WindowEvent;
  20. import java.io.BufferedInputStream;
  21. import java.io.BufferedReader;
  22. import java.io.FileInputStream;
  23. import java.io.FileOutputStream;
  24. import java.io.IOException;
  25. import java.io.InputStream;
  26. import java.io.InputStreamReader;
  27. import java.io.OutputStream;
  28. import java.io.OutputStreamWriter;
  29. import java.io.Reader;
  30. import java.io.StreamTokenizer;
  31. import java.net.URL;
  32. import java.util.BitSet;
  33. import java.util.Enumeration;
  34.  
  35. import javax.media.j3d.AmbientLight;
  36. import javax.media.j3d.Appearance;
  37. import javax.media.j3d.Background;
  38. import javax.media.j3d.Behavior;
  39. import javax.media.j3d.BoundingLeaf;
  40. import javax.media.j3d.BoundingSphere;
  41. import javax.media.j3d.BranchGroup;
  42. import javax.media.j3d.Canvas3D;
  43. import javax.media.j3d.CapabilityNotSetException;
  44. import javax.media.j3d.DirectionalLight;
  45. import javax.media.j3d.Group;
  46. import javax.media.j3d.Material;
  47. import javax.media.j3d.Node;
  48. import javax.media.j3d.PickRay;
  49. import javax.media.j3d.QuadArray;
  50. import javax.media.j3d.SceneGraphPath;
  51. import javax.media.j3d.Shape3D;
  52. import javax.media.j3d.Switch;
  53. import javax.media.j3d.Transform3D;
  54. import javax.media.j3d.TransformGroup;
  55. import javax.media.j3d.View;
  56. import javax.media.j3d.WakeupCriterion;
  57. import javax.media.j3d.WakeupOnAWTEvent;
  58. import javax.media.j3d.WakeupOr;
  59. import javax.vecmath.Color3f;
  60. import javax.vecmath.Point3d;
  61. import javax.vecmath.Vector3d;
  62. import javax.vecmath.Vector3f;
  63.  
  64. import com.sun.j3d.utils.applet.MainFrame;
  65. import com.sun.j3d.utils.geometry.Sphere;
  66. import com.sun.j3d.utils.universe.SimpleUniverse;
  67.  
  68. /**
  69.  * Class FourByFour
  70.  *
  71.  * Description: High level class for the game FourByFour
  72.  *
  73.  * Version: 1.2
  74.  *  
  75.  */
  76.  
  77. public class FourByFour extends Applet implements ActionListener {
  78.  
  79.   String host; // Host from which this applet came from
  80.  
  81.   int port; // Port number for writing high scores
  82.  
  83.   Image backbuffer2D; // Backbuffer image used for 2D double buffering
  84.  
  85.   int width, height; // Size of the graphics window in pixels
  86.  
  87.   int score; // Final game score
  88.  
  89.   int level_weight; // Weighting factor for skill level
  90.  
  91.   int move_weight; // Weighting factor for number of moves to win
  92.  
  93.   int time_weight; // Weighting factor for amount of time it took to win
  94.  
  95.   int skill_level; // Skill level, 0 - 4
  96.  
  97.   Canvas2D canvas2D; // 2D rendering canvas
  98.  
  99.   Canvas3D canvas3D; // 3D rendering canvas
  100.  
  101.   Board board; // Game board object
  102.  
  103.   Panel b_container; // Container to hold the buttons
  104.  
  105.   Panel c_container; // Container to hold the canvas
  106.  
  107.   Panel l_container; // Container to hold the labels
  108.  
  109.   Panel skill_panel; // Panel to hold skill levels
  110.  
  111.   Panel instruct_panel; // Panel to hold instructions
  112.  
  113.   Panel winner_panel; // Panel to hold winner announcement
  114.  
  115.   Panel high_panel; // Panel to hold high scores
  116.  
  117.   Button instruct_button; // Instructions button
  118.  
  119.   Button new_button; // New Game button
  120.  
  121.   Button skill_button; // Skill Level button
  122.  
  123.   Button high_button; // High Scores button
  124.  
  125.   Button undo_button; // Undo Move button
  126.  
  127.   Label skill_label; // Label on skill panel
  128.  
  129.   Label winner_label; // Label on winner panel
  130.  
  131.   Label winner_score_label; // Score label on winner panel
  132.  
  133.   Label winner_name_label; // Name label on winner panel
  134.  
  135.   Label winner_top_label; // Top 20 label on winner panel
  136.  
  137.   Label high_label; // High score label
  138.  
  139.   Label high_places[]; // Labels to hold places
  140.  
  141.   Label high_names[]; // Labels to hold names
  142.  
  143.   Label high_scores[]; // Labels to hold scores
  144.  
  145.   TextArea instruct_text; // TextArea object that holds instructions
  146.  
  147.   TextArea high_text; // TextArea object that holds top 20 scores
  148.  
  149.   TextField winner_name; // TextField object that holds winner's name
  150.  
  151.   Button instruct_return_button; // Return button for instruction panel
  152.  
  153.   Button skill_return_button; // Return button for skill level panel
  154.  
  155.   Button winner_return_button; // Return button for winner panel
  156.  
  157.   Button high_return_button; // Return button for high scores panel
  158.  
  159.   CheckboxGroup group; // CheckboxGroup object for skill level panel
  160.  
  161.   InputStream inStream; // Input stream for reading instructions and high
  162.  
  163.   // scores
  164.  
  165.   OutputStream outStream; // Output stream for writing high scores
  166.  
  167.   static boolean appletFlag = true; // Applet flag
  168.  
  169.   boolean winner_flag = false; // Winner flag
  170.  
  171.   byte text[]; // Temporary storage area for reading instructions file
  172.  
  173.   byte outText[]; // Temporary storage area for writing high scores file
  174.  
  175.   String textString; // Storage area for instructions
  176.  
  177.   String scoresString; // String used for writing high scores file
  178.  
  179.   int places[]; // Storage area for high score places
  180.  
  181.   int scores[]; // Storage area for high score scores
  182.  
  183.   String names[]; // Storage area for high score names
  184.  
  185.   Positions positions; // Positions object, used to render player positions
  186.  
  187.   private SimpleUniverse universe = null;
  188.  
  189.   /**
  190.    * Initialization
  191.    */
  192.   public void init() {
  193.  
  194.     // Set the port number.
  195.     port = 4111;
  196.  
  197.     // Set the graphics window size.
  198.     width = 350;
  199.     height = 350;
  200.  
  201.     // Set the weighting factors used for scoring.
  202.     level_weight = 1311;
  203.     move_weight = 111;
  204.     time_weight = 1000;
  205.  
  206.     // Create the "base" color for the AWT components.
  207.     setBackground(new Color(200, 200, 200));
  208.  
  209.     // Read the instructions file.
  210.     if (appletFlag) {
  211.  
  212.       // Get the host from which this applet came.
  213.       host = getCodeBase().getHost();
  214.  
  215.       try {
  216.         inStream = new BufferedInputStream(new URL(getCodeBase(),
  217.             "instructions.txt").openStream(), 8192);
  218.         text = new byte[5000];
  219.         int character = inStream.read();
  220.         int count = 0;
  221.         while (character != -1) {
  222.           text[count++] = (byte) character;
  223.           character = inStream.read();
  224.         }
  225.         textString = new String(text);
  226.         inStream.close();
  227.       } catch (Exception e) {
  228.         System.out.println("Error: " + e.toString());
  229.       }
  230.     } else {
  231.  
  232.       try {
  233.         inStream = new BufferedInputStream(new FileInputStream(
  234.             "instructions.txt"));
  235.         text = new byte[5000];
  236.         int character = inStream.read();
  237.         int count = 0;
  238.         while (character != -1) {
  239.           text[count++] = (byte) character;
  240.           character = inStream.read();
  241.         }
  242.         textString = new String(text);
  243.         inStream.close();
  244.       } catch (Exception e) {
  245.         System.out.println("Error: " + e.toString());
  246.       }
  247.     }
  248.  
  249.     // Read the high-scores file.
  250.     places = new int[20];
  251.     scores = new int[20];
  252.     names = new String[20];
  253.     if (appletFlag) {
  254.       try {
  255.         inStream = new BufferedInputStream(new URL(getCodeBase(),
  256.             "scores.txt").openStream(), 8192);
  257.         Reader read = new BufferedReader(
  258.             new InputStreamReader(inStream));
  259.         StreamTokenizer st = new StreamTokenizer(read);
  260.         st.whitespaceChars(32, 44);
  261.         st.eolIsSignificant(false);
  262.  
  263.         int count = 0;
  264.         int token = st.nextToken();
  265.         boolean scoreFlag = true;
  266.         String string;
  267.         while (count < 20) {
  268.           places[count] = (int) st.nval;
  269.           string = new String("");
  270.           token = st.nextToken();
  271.           while (token == StreamTokenizer.TT_WORD) {
  272.             string += st.sval;
  273.             string += " ";
  274.             token = st.nextToken();
  275.           }
  276.           names[count] = string;
  277.           scores[count] = (int) st.nval;
  278.           token = st.nextToken();
  279.           count++;
  280.         }
  281.         inStream.close();
  282.       } catch (Exception e) {
  283.         System.out.println("Error: " + e.toString());
  284.       }
  285.     } else {
  286.       try {
  287.         inStream = new BufferedInputStream(new FileInputStream(
  288.             "scores.txt"));
  289.         Reader read = new BufferedReader(
  290.             new InputStreamReader(inStream));
  291.         StreamTokenizer st = new StreamTokenizer(read);
  292.         st.whitespaceChars(32, 44);
  293.         st.eolIsSignificant(false);
  294.  
  295.         int count = 0;
  296.         int token = st.nextToken();
  297.         boolean scoreFlag = true;
  298.         String string;
  299.         while (count < 20) {
  300.           places[count] = (int) st.nval;
  301.           string = new String("");
  302.           token = st.nextToken();
  303.           while (token == StreamTokenizer.TT_WORD) {
  304.             string += st.sval;
  305.             string += " ";
  306.             token = st.nextToken();
  307.           }
  308.           names[count] = string;
  309.           scores[count] = (int) st.nval;
  310.           token = st.nextToken();
  311.           count++;
  312.         }
  313.         inStream.close();
  314.       } catch (Exception e) {
  315.         System.out.println("Error: " + e.toString());
  316.       }
  317.     }
  318.  
  319.     // The positions object sets up the switch nodes which
  320.     // control the rendering of the player's positions.
  321.     positions = new Positions();
  322.  
  323.     // Create the game board object which is responsible
  324.     // for keeping track of the moves on the game board
  325.     // and determining what move the computer should make.
  326.     board = new Board(this, positions, width, height);
  327.     positions.setBoard(board);
  328.  
  329.     // Create a 2D graphics canvas.
  330.     canvas2D = new Canvas2D(board);
  331.     canvas2D.setSize(width, height);
  332.     canvas2D.setLocation(width + 10, 5);
  333.     canvas2D.addMouseListener(canvas2D);
  334.     board.setCanvas(canvas2D);
  335.  
  336.     // Create the 2D backbuffer
  337.     backbuffer2D = createImage(width, height);
  338.     canvas2D.setBuffer(backbuffer2D);
  339.  
  340.     // Create a 3D graphics canvas.
  341.     canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
  342.     canvas3D.setSize(width, height);
  343.     canvas3D.setLocation(5, 5);
  344.  
  345.     // Create the scene branchgroup.
  346.     BranchGroup scene3D = createScene3D();
  347.  
  348.     // Create a universe with the Java3D universe utility.
  349.     universe = new SimpleUniverse(canvas3D);
  350.     universe.addBranchGraph(scene3D);
  351.  
  352.     // Use parallel projection.
  353.     View view = universe.getViewer().getView();
  354.     view.setProjectionPolicy(View.PARALLEL_PROJECTION);
  355.  
  356.     // Set the universe Transform3D object.
  357.     TransformGroup tg = universe.getViewingPlatform()
  358.         .getViewPlatformTransform();
  359.     Transform3D transform = new Transform3D();
  360.     transform.set(65.f, new Vector3f(0.0f, 0.0f, 400.0f));
  361.     tg.setTransform(transform);
  362.  
  363.     // Create the canvas container.
  364.     c_container = new Panel();
  365.     c_container.setSize(720, 360);
  366.     c_container.setLocation(0, 0);
  367.     c_container.setVisible(true);
  368.     c_container.setLayout(null);
  369.     add(c_container);
  370.  
  371.     // Add the 2D and 3D canvases to the container.
  372.     c_container.add(canvas2D);
  373.     c_container.add(canvas3D);
  374.  
  375.     // Turn off the layout manager, widgets will be sized
  376.     // and positioned explicitly.
  377.     setLayout(null);
  378.  
  379.     // Create the button container.
  380.     b_container = new Panel();
  381.     b_container.setSize(720, 70);
  382.     b_container.setLocation(0, 360);
  383.     b_container.setVisible(true);
  384.     b_container.setLayout(null);
  385.  
  386.     // Create the buttons.
  387.     instruct_button = new Button("Instructions");
  388.     instruct_button.setSize(135, 25);
  389.     instruct_button.setLocation(10, 10);
  390.     instruct_button.setVisible(true);
  391.     instruct_button.addActionListener(this);
  392.  
  393.     new_button = new Button("New Game");
  394.     new_button.setSize(135, 25);
  395.     new_button.setLocation(150, 10);
  396.     new_button.setVisible(true);
  397.     new_button.addActionListener(this);
  398.  
  399.     undo_button = new Button("Undo Move");
  400.     undo_button.setSize(135, 25);
  401.     undo_button.setLocation(290, 10);
  402.     undo_button.setVisible(true);
  403.     undo_button.addActionListener(this);
  404.  
  405.     skill_button = new Button("Skill Level");
  406.     skill_button.setSize(135, 25);
  407.     skill_button.setLocation(430, 10);
  408.     skill_button.setVisible(true);
  409.     skill_button.addActionListener(this);
  410.  
  411.     high_button = new Button("High Scores");
  412.     high_button.setSize(135, 25);
  413.     high_button.setLocation(570, 10);
  414.     high_button.setVisible(true);
  415.     high_button.addActionListener(this);
  416.  
  417.     b_container.add(new_button);
  418.     b_container.add(undo_button);
  419.     b_container.add(skill_button);
  420.     b_container.add(high_button);
  421.     b_container.add(instruct_button);
  422.  
  423.     // Add the button container to the applet.
  424.     add(b_container);
  425.  
  426.     // Create the "Skill Level" dialog box.
  427.     skill_panel = new Panel();
  428.     skill_panel.setSize(400, 300);
  429.     skill_panel.setLocation(200, 20);
  430.     skill_panel.setLayout(null);
  431.  
  432.     skill_label = new Label("Pick your skill level:");
  433.     skill_label.setSize(200, 25);
  434.     skill_label.setLocation(25, 20);
  435.     skill_label.setVisible(true);
  436.     skill_panel.add(skill_label);
  437.  
  438.     group = new CheckboxGroup();
  439.     Checkbox skill_1 = new Checkbox("Babe in the Woods        ", group,
  440.         false);
  441.     Checkbox skill_2 = new Checkbox("Walk and Chew Gum        ", group,
  442.         false);
  443.     Checkbox skill_3 = new Checkbox("Jeopardy Contestant      ", group,
  444.         false);
  445.     Checkbox skill_4 = new Checkbox("Rocket Scientist         ", group,
  446.         false);
  447.     Checkbox skill_5 = new Checkbox("Be afraid, be very afraid", group,
  448.         true);
  449.     skill_1.setSize(170, 25);
  450.     skill_1.setLocation(80, 60);
  451.     skill_1.setVisible(true);
  452.     skill_2.setSize(170, 25);
  453.     skill_2.setLocation(80, 100);
  454.     skill_2.setVisible(true);
  455.     skill_3.setSize(170, 25);
  456.     skill_3.setLocation(80, 140);
  457.     skill_3.setVisible(true);
  458.     skill_4.setSize(170, 25);
  459.     skill_4.setLocation(80, 180);
  460.     skill_4.setVisible(true);
  461.     skill_5.setSize(170, 25);
  462.     skill_5.setLocation(80, 220);
  463.     skill_5.setVisible(true);
  464.     skill_return_button = new Button("Return");
  465.     skill_return_button.setSize(120, 25);
  466.     skill_return_button.setLocation(300, 370);
  467.     skill_return_button.setVisible(false);
  468.     skill_return_button.addActionListener(this);
  469.     skill_panel.add(skill_1);
  470.     skill_panel.add(skill_2);
  471.     skill_panel.add(skill_3);
  472.     skill_panel.add(skill_4);
  473.     skill_panel.add(skill_5);
  474.     skill_panel.setVisible(false);
  475.     add(skill_return_button);
  476.     add(skill_panel);
  477.  
  478.     // Create the "Instructions" panel.
  479.     instruct_return_button = new Button("Return");
  480.     instruct_return_button.setLocation(300, 370);
  481.     instruct_return_button.setSize(120, 25);
  482.     instruct_return_button.setVisible(false);
  483.     instruct_return_button.addActionListener(this);
  484.     instruct_text = new TextArea(textString, 100, 200,
  485.         TextArea.SCROLLBARS_VERTICAL_ONLY);
  486.     instruct_text.setSize(715, 350);
  487.     instruct_text.setLocation(0, 0);
  488.     instruct_text.setVisible(false);
  489.     add(instruct_text);
  490.  
  491.     add(instruct_return_button);
  492.  
  493.     high_panel = new Panel();
  494.     high_panel.setSize(715, 350);
  495.     high_panel.setLocation(0, 0);
  496.     high_panel.setVisible(false);
  497.     high_panel.setLayout(null);
  498.  
  499.     high_label = new Label("High Scores");
  500.     high_label.setLocation(330, 5);
  501.     high_label.setSize(200, 30);
  502.     high_label.setVisible(true);
  503.     high_panel.add(high_label);
  504.  
  505.     high_places = new Label[20];
  506.     high_names = new Label[20];
  507.     high_scores = new Label[20];
  508.     for (int i = 0; i < 20; i++) {
  509.       high_places[i] = new Label(Integer.toString(i + 1));
  510.       high_places[i].setSize(20, 30);
  511.       high_places[i].setVisible(true);
  512.       high_names[i] = new Label(names[i]);
  513.       high_names[i].setSize(150, 30);
  514.       high_names[i].setVisible(true);
  515.       high_scores[i] = new Label(Integer.toString(scores[i]));
  516.       high_scores[i].setSize(150, 30);
  517.       high_scores[i].setVisible(true);
  518.       if (i < 10) {
  519.         high_places[i].setLocation(70, i * 30 + 40);
  520.         high_names[i].setLocation(100, i * 30 + 40);
  521.         high_scores[i].setLocation(260, i * 30 + 40);
  522.       } else {
  523.         high_places[i].setLocation(425, (i - 10) * 30 + 40);
  524.         high_names[i].setLocation(455, (i - 10) * 30 + 40);
  525.         high_scores[i].setLocation(615, (i - 10) * 30 + 40);
  526.       }
  527.       high_panel.add(high_places[i]);
  528.       high_panel.add(high_names[i]);
  529.       high_panel.add(high_scores[i]);
  530.     }
  531.     high_return_button = new Button("Return");
  532.     high_return_button.setSize(120, 25);
  533.     high_return_button.setLocation(300, 370);
  534.     high_return_button.setVisible(false);
  535.     high_return_button.addActionListener(this);
  536.     add(high_return_button);
  537.     add(high_panel);
  538.  
  539.     // Create the "Winner" dialog box
  540.     winner_panel = new Panel();
  541.     winner_panel.setLayout(null);
  542.     winner_panel.setSize(600, 500);
  543.     winner_panel.setLocation(0, 0);
  544.     winner_return_button = new Button("Return");
  545.     winner_return_button.setSize(120, 25);
  546.     winner_return_button.setLocation(300, 360);
  547.     winner_return_button.addActionListener(this);
  548.     winner_panel.add(winner_return_button);
  549.     winner_label = new Label("");
  550.     winner_label.setSize(200, 30);
  551.     winner_label.setLocation(270, 110);
  552.     winner_score_label = new Label("");
  553.     winner_score_label.setSize(200, 30);
  554.     winner_top_label = new Label("You have a score in the top 20.");
  555.     winner_top_label.setSize(200, 25);
  556.     winner_top_label.setLocation(260, 185);
  557.     winner_top_label.setVisible(false);
  558.     winner_name_label = new Label("Enter your name here:");
  559.     winner_name_label.setSize(150, 25);
  560.     winner_name_label.setLocation(260, 210);
  561.     winner_name_label.setVisible(false);
  562.     winner_name = new TextField("");
  563.     winner_name.setSize(200, 30);
  564.     winner_name.setLocation(260, 240);
  565.     winner_name.setVisible(false);
  566.     winner_panel.add(winner_label);
  567.     winner_panel.add(winner_score_label);
  568.     winner_panel.add(winner_top_label);
  569.     winner_panel.add(winner_name_label);
  570.     winner_panel.add(winner_name);
  571.     winner_panel.setVisible(false);
  572.     add(winner_panel);
  573.   }
  574.  
  575.   public void destroy() {
  576.     universe.cleanup();
  577.   }
  578.  
  579.   /**
  580.    * Create the scenegraph for the 3D view.
  581.    */
  582.   public BranchGroup createScene3D() {
  583.  
  584.     // Define colors
  585.     Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
  586.     Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
  587.     Color3f red = new Color3f(0.80f, 0.20f, 0.2f);
  588.     Color3f ambient = new Color3f(0.25f, 0.25f, 0.25f);
  589.     Color3f diffuse = new Color3f(0.7f, 0.7f, 0.7f);
  590.     Color3f specular = new Color3f(0.9f, 0.9f, 0.9f);
  591.     Color3f ambientRed = new Color3f(0.2f, 0.05f, 0.0f);
  592.     Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
  593.  
  594.     // Create the branch group
  595.     BranchGroup branchGroup = new BranchGroup();
  596.  
  597.     // Create the bounding leaf node
  598.     BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
  599.         1000.0);
  600.     BoundingLeaf boundingLeaf = new BoundingLeaf(bounds);
  601.     branchGroup.addChild(boundingLeaf);
  602.  
  603.     // Create the background
  604.     Background bg = new Background(bgColor);
  605.     bg.setApplicationBounds(bounds);
  606.     branchGroup.addChild(bg);
  607.  
  608.     // Create the ambient light
  609.     AmbientLight ambLight = new AmbientLight(white);
  610.     ambLight.setInfluencingBounds(bounds);
  611.     branchGroup.addChild(ambLight);
  612.  
  613.     // Create the directional light
  614.     Vector3f dir = new Vector3f(-1.0f, -1.0f, -1.0f);
  615.     DirectionalLight dirLight = new DirectionalLight(white, dir);
  616.     dirLight.setInfluencingBounds(bounds);
  617.     branchGroup.addChild(dirLight);
  618.  
  619.     // Create the pole appearance
  620.     Material poleMaterial = new Material(ambient, black, diffuse, specular,
  621.         110.f);
  622.     poleMaterial.setLightingEnable(true);
  623.     Appearance poleAppearance = new Appearance();
  624.     poleAppearance.setMaterial(poleMaterial);
  625.  
  626.     // Create the transform group node
  627.     TransformGroup transformGroup = new TransformGroup();
  628.     transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
  629.     transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  630.     branchGroup.addChild(transformGroup);
  631.  
  632.     // Create the poles
  633.     Poles poles = new Poles(poleAppearance);
  634.     transformGroup.addChild(poles.getChild());
  635.  
  636.     // Add the position markers to the transform group
  637.     transformGroup.addChild(positions.getChild());
  638.  
  639.     // Let the positions object know about the transform group
  640.     positions.setTransformGroup(transformGroup);
  641.  
  642.     // Create the mouse pick and drag behavior node
  643.     PickDragBehavior behavior = new PickDragBehavior(canvas2D, canvas3D,
  644.         positions, branchGroup, transformGroup);
  645.     behavior.setSchedulingBounds(bounds);
  646.     transformGroup.addChild(behavior);
  647.  
  648.     return branchGroup;
  649.   }
  650.  
  651.   public void actionPerformed(ActionEvent event) {
  652.  
  653.     Object target = event.getSource();
  654.  
  655.     // Process the button events.
  656.     if (target == skill_return_button) {
  657.       skill_panel.setVisible(false);
  658.       skill_return_button.setVisible(false);
  659.       c_container.setVisible(true);
  660.       b_container.setVisible(true);
  661.       newGame();
  662.     } else if (target == winner_return_button) {
  663.       if (winner_flag) {
  664.         String name = winner_name.getText();
  665.         String tmp_name = new String("");
  666.         int tmp_score = 0;
  667.         boolean insert_flag = false;
  668.         winner_flag = false;
  669.         for (int i = 0; i < 20; i++) {
  670.           if (insert_flag) {
  671.             name = names[i];
  672.             score = scores[i];
  673.             names[i] = tmp_name;
  674.             scores[i] = tmp_score;
  675.             tmp_name = name;
  676.             tmp_score = score;
  677.           }
  678.           if (!insert_flag && score > scores[i]) {
  679.             tmp_name = names[i];
  680.             tmp_score = scores[i];
  681.             scores[i] = score;
  682.             names[i] = name;
  683.             insert_flag = true;
  684.           }
  685.           high_names[i].setText(names[i]);
  686.           high_scores[i].setText(Integer.toString(scores[i]));
  687.         }
  688.         scoresString = new String("");
  689.         int place;
  690.         for (int i = 0; i < 20; i++) {
  691.           place = (int) places[i];
  692.           scoresString += Integer.toString(place);
  693.           scoresString += "\t";
  694.           scoresString += names[i];
  695.           scoresString += "   ";
  696.           scoresString += Integer.toString(scores[i]);
  697.           scoresString += "\n";
  698.         }
  699.  
  700.         if (appletFlag) {
  701.           // Use this section of code when writing the high
  702.           // scores file back to a server. Requires the use
  703.           // of a deamon on the server to receive the socket
  704.           // connection.
  705.           //
  706.           // Create the output stream.
  707.           // try {
  708.           //    Socket socket = new Socket(host, port);
  709.           //    outStream = new BufferedOutputStream
  710.           //       (socket.getOutputStream(), 8192);
  711.           // }
  712.           // catch(IOException ioe) {
  713.           //    System.out.println("Error: " + ioe.toString());
  714.           // }
  715.           // System.out.println("Output stream opened");
  716.           //
  717.           // Write the scores to the file back on the server.
  718.           // outText = scoresString.getBytes();
  719.           // try {
  720.           //    outStream.write(outText);
  721.           //    outStream.flush();
  722.           //    outStream.close();
  723.           //    outStream = null;
  724.           // }
  725.           // catch (IOException ioe) {
  726.           //    System.out.println("Error: " + ioe.toString());
  727.           // }
  728.           // System.out.println("Output stream written");
  729.  
  730.           try {
  731.             OutputStreamWriter outFile = new OutputStreamWriter(
  732.                 new FileOutputStream("scores.txt"));
  733.             outFile.write(scoresString);
  734.             outFile.flush();
  735.             outFile.close();
  736.             outFile = null;
  737.           } catch (IOException ioe) {
  738.             System.out.println("Error: " + ioe.toString());
  739.           } catch (Exception e) {
  740.             System.out.println("Error: " + e.toString());
  741.           }
  742.         } else {
  743.  
  744.           try {
  745.             OutputStreamWriter outFile = new OutputStreamWriter(
  746.                 new FileOutputStream("scores.txt"));
  747.             outFile.write(scoresString);
  748.             outFile.flush();
  749.             outFile.close();
  750.             outFile = null;
  751.           } catch (IOException ioe) {
  752.             System.out.println("Error: " + ioe.toString());
  753.           }
  754.         }
  755.       }
  756.       winner_panel.setVisible(false);
  757.       winner_return_button.setVisible(false);
  758.       winner_label.setVisible(false);
  759.       winner_score_label.setVisible(false);
  760.       winner_name_label.setVisible(false);
  761.       winner_top_label.setVisible(false);
  762.       winner_name.setVisible(false);
  763.       c_container.setVisible(true);
  764.       b_container.setVisible(true);
  765.     } else if (target == high_return_button) {
  766.       high_return_button.setVisible(false);
  767.       high_panel.setVisible(false);
  768.       c_container.setVisible(true);
  769.       b_container.setVisible(true);
  770.     } else if (target == instruct_return_button) {
  771.       instruct_text.setVisible(false);
  772.       instruct_return_button.setVisible(false);
  773.       instruct_text.repaint();
  774.       c_container.setVisible(true);
  775.       b_container.setVisible(true);
  776.     } else if (target == undo_button) {
  777.       board.undo_move();
  778.       canvas2D.repaint();
  779.     } else if (target == instruct_button) {
  780.       c_container.setVisible(false);
  781.       b_container.setVisible(false);
  782.       instruct_text.setVisible(true);
  783.       instruct_return_button.setVisible(true);
  784.     } else if (target == new_button) {
  785.       newGame();
  786.     } else if (target == skill_button) {
  787.       c_container.setVisible(false);
  788.       b_container.setVisible(false);
  789.       skill_panel.setVisible(true);
  790.       skill_return_button.setVisible(true);
  791.     } else if (target == high_button) {
  792.       // Read the high scores file.
  793.       if (appletFlag) {
  794.         try {
  795.           inStream = new BufferedInputStream(new URL(getCodeBase(),
  796.               "scores.txt").openStream(), 8192);
  797.           Reader read = new BufferedReader(new InputStreamReader(
  798.               inStream));
  799.           StreamTokenizer st = new StreamTokenizer(read);
  800.           st.whitespaceChars(32, 44);
  801.           st.eolIsSignificant(false);
  802.  
  803.           int count = 0;
  804.           int token = st.nextToken();
  805.           boolean scoreFlag = true;
  806.           String string;
  807.           while (count < 20) {
  808.             places[count] = (int) st.nval;
  809.             string = new String("");
  810.             token = st.nextToken();
  811.             while (token == StreamTokenizer.TT_WORD) {
  812.               string += st.sval;
  813.               string += " ";
  814.               token = st.nextToken();
  815.             }
  816.             names[count] = string;
  817.             scores[count] = (int) st.nval;
  818.             token = st.nextToken();
  819.             count++;
  820.           }
  821.           inStream.close();
  822.         } catch (Exception ioe) {
  823.           System.out.println("Error: " + ioe.toString());
  824.         }
  825.       } else {
  826.         try {
  827.           inStream = new BufferedInputStream(new FileInputStream(
  828.               "scores.txt"));
  829.           Reader read = new BufferedReader(new InputStreamReader(
  830.               inStream));
  831.           StreamTokenizer st = new StreamTokenizer(read);
  832.           st.whitespaceChars(32, 44);
  833.           st.eolIsSignificant(false);
  834.  
  835.           int count = 0;
  836.           int token = st.nextToken();
  837.           boolean scoreFlag = true;
  838.           String string;
  839.           while (count < 20) {
  840.             places[count] = (int) st.nval;
  841.             string = new String("");
  842.             token = st.nextToken();
  843.             while (token == StreamTokenizer.TT_WORD) {
  844.               string += st.sval;
  845.               string += " ";
  846.               token = st.nextToken();
  847.             }
  848.             names[count] = string;
  849.             scores[count] = (int) st.nval;
  850.             token = st.nextToken();
  851.             count++;
  852.           }
  853.           inStream.close();
  854.         } catch (Exception ioe) {
  855.           System.out.println("Error: " + ioe.toString());
  856.         }
  857.       }
  858.       c_container.setVisible(false);
  859.       b_container.setVisible(false);
  860.       high_panel.setVisible(true);
  861.       high_return_button.setVisible(true);
  862.     }
  863.  
  864.     Checkbox box = group.getSelectedCheckbox();
  865.     String label = box.getLabel();
  866.     if (label.equals("Babe in the Woods        ")) {
  867.       board.set_skill_level(0);
  868.     } else if (label.equals("Walk and Chew Gum        ")) {
  869.       board.set_skill_level(1);
  870.     } else if (label.equals("Jeopardy Contestant      ")) {
  871.       board.set_skill_level(2);
  872.     } else if (label.equals("Rocket Scientist         ")) {
  873.       board.set_skill_level(3);
  874.     } else if (label.equals("Be afraid, be very afraid")) {
  875.       board.set_skill_level(4);
  876.     }
  877.   }
  878.  
  879.   public void newGame() {
  880.     board.newGame();
  881.     canvas2D.repaint();
  882.   }
  883.  
  884.   public void start() {
  885.     if (appletFlag)
  886.       showStatus("FourByFour");
  887.   }
  888.  
  889.   public void winner(int player, int level, int nmoves, long time) {
  890.  
  891.     if (player == 1) {
  892.       score = level * level_weight + (66 - nmoves) * move_weight
  893.           - (int) Math.min(time * time_weight, 5000);
  894.       winner_label.setText("Game over, you win!");
  895.       winner_label.setLocation(290, 90);
  896.       winner_score_label.setText("Score = " + score);
  897.       winner_score_label.setVisible(true);
  898.       winner_score_label.setLocation(315, 120);
  899.       if (score > scores[19]) {
  900.         winner_name_label.setVisible(true);
  901.         winner_top_label.setVisible(true);
  902.         winner_name.setVisible(true);
  903.         winner_flag = true;
  904.       }
  905.     } else {
  906.       winner_label.setText("Game over, the computer wins!");
  907.       winner_label.setLocation(250, 150);
  908.     }
  909.     c_container.setVisible(false);
  910.     b_container.setVisible(false);
  911.     winner_panel.setVisible(true);
  912.     winner_label.setVisible(true);
  913.     winner_return_button.setVisible(true);
  914.     repaint();
  915.   }
  916.  
  917.   /**
  918.    * Inner class used to "kill" the window when running as an application.
  919.    */
  920.   static class killAdapter extends WindowAdapter {
  921.     public void windowClosing(WindowEvent event) {
  922.       System.exit(0);
  923.     }
  924.   }
  925.  
  926.   /**
  927.    * Main method, only used when running as an application.
  928.    */
  929.   public static void main(String[] args) {
  930.     FourByFour.appletFlag = false;
  931.     new MainFrame(new FourByFour(), 730, 450);
  932.   }
  933.  
  934. }
  935.  
  936. /**
  937.  * Class: Poles
  938.  *
  939.  * Description: Creates the "poles" in the 3D window.
  940.  *
  941.  * Version: 1.0
  942.  *  
  943.  */
  944.  
  945. class Poles extends Object {
  946.  
  947.   private Group group;
  948.  
  949.   public Poles(Appearance appearance) {
  950.     float x = -30.0f;
  951.     float z = -30.0f;
  952.     group = new Group();
  953.     for (int i = 0; i < 4; i++) {
  954.       for (int j = 0; j < 4; j++) {
  955.         Cylinder c = new Cylinder(x, z, 1.0f, 60.0f, 10, appearance);
  956.         group.addChild(c.getShape());
  957.         x += 20.0f;
  958.       }
  959.       x = -30.0f;
  960.       z += 20.0f;
  961.     }
  962.   }
  963.  
  964.   public Group getChild() {
  965.     return group;
  966.   }
  967. }
  968.  
  969. /**
  970.  * Class: Board
  971.  *
  972.  * Description: Handles all logic with respect to play. Also renders the 2D
  973.  * window.
  974.  *
  975.  * Version: 1.1
  976.  *  
  977.  */
  978.  
  979. class Board {
  980.  
  981.   final static int UNOCCUPIED = 0;
  982.  
  983.   final static int HUMAN = 1;
  984.  
  985.   final static int MACHINE = 2;
  986.  
  987.   final static int END = 3;
  988.  
  989.   private int[] moves;
  990.  
  991.   private int[] occupied;
  992.  
  993.   private int[][] combinations;
  994.  
  995.   private int[][] outside_four;
  996.  
  997.   private int[][] inside_four;
  998.  
  999.   private int[][] faces;
  1000.  
  1001.   private int[][] pos_to_comb;
  1002.  
  1003.   private int[][] best_picks;
  1004.  
  1005.   private int num_points;
  1006.  
  1007.   private int num_balls;
  1008.  
  1009.   private int num_polygons;
  1010.  
  1011.   private int num_pt_indexes;
  1012.  
  1013.   private int num_normal_indexes;
  1014.  
  1015.   private int pt_start;
  1016.  
  1017.   private int color_index;
  1018.  
  1019.   private int width;
  1020.  
  1021.   private int height;
  1022.  
  1023.   private int center_x;
  1024.  
  1025.   private int center_y;
  1026.  
  1027.   private int player;
  1028.  
  1029.   private int skill_level;
  1030.  
  1031.   private int outside_four_index;
  1032.  
  1033.   private int inside_four_index;
  1034.  
  1035.   private int face_index;
  1036.  
  1037.   private int nmoves;
  1038.  
  1039.   private int current_face;
  1040.  
  1041.   private int min = 1000;
  1042.  
  1043.   private int max = 0;
  1044.  
  1045.   private long[] sort_array;
  1046.  
  1047.   private long time;
  1048.  
  1049.   private long beg_time;
  1050.  
  1051.   private long end_time;
  1052.  
  1053.   private Color[] color_ramp;
  1054.  
  1055.   private Color background;
  1056.  
  1057.   private Color label_color;
  1058.  
  1059.   private Color red;
  1060.  
  1061.   private Color blue;
  1062.  
  1063.   private Color white;
  1064.  
  1065.   private Color gray;
  1066.  
  1067.   private Color yellow;
  1068.  
  1069.   private double max_dist;
  1070.  
  1071.   private FourByFour panel;
  1072.  
  1073.   private boolean debug;
  1074.  
  1075.   private boolean outside_four_flag;
  1076.  
  1077.   private boolean inside_four_flag;
  1078.  
  1079.   private boolean face_flag;
  1080.  
  1081.   private boolean label_flag;
  1082.  
  1083.   private boolean block_chair_flag;
  1084.  
  1085.   private boolean undoFlag;
  1086.  
  1087.   private boolean[] highlight;
  1088.  
  1089.   private int block_chair_next_move;
  1090.  
  1091.   private int block_chair_face;
  1092.  
  1093.   private Positions positions;
  1094.  
  1095.   private Canvas2D canvas;
  1096.  
  1097.   Board(FourByFour panel, Positions positions, int width, int height) {
  1098.  
  1099.     // Set the debug state.
  1100.     debug = false;
  1101.  
  1102.     // Store arguments
  1103.     this.width = width;
  1104.     this.height = height;
  1105.     this.panel = panel;
  1106.     this.positions = positions;
  1107.  
  1108.     // Initialize flags
  1109.     label_flag = false;
  1110.     outside_four_flag = false;
  1111.     inside_four_flag = false;
  1112.     block_chair_flag = false;
  1113.     undoFlag = false;
  1114.  
  1115.     // Total number of board positions.
  1116.     num_points = 64;
  1117.  
  1118.     // Allocate the logic arrays.
  1119.     moves = new int[64];
  1120.     occupied = new int[64];
  1121.     combinations = new int[76][7];
  1122.     outside_four = new int[18][6];
  1123.     inside_four = new int[18][6];
  1124.     faces = new int[18][18];
  1125.     pos_to_comb = new int[64][8];
  1126.     best_picks = new int[64][8];
  1127.     highlight = new boolean[18];
  1128.  
  1129.     // Initialize the logic arrays.
  1130.     init_combinations();
  1131.     init_faces();
  1132.     init_outside_four();
  1133.     init_inside_four();
  1134.  
  1135.     // Set the player with the first move.
  1136.     player = HUMAN;
  1137.  
  1138.     // Set the default skill level.
  1139.     skill_level = 4;
  1140.  
  1141.     // Initialize the number of moves.
  1142.     nmoves = 0;
  1143.  
  1144.     // Define colors
  1145.     background = new Color(13, 13, 51);
  1146.     red = new Color(230, 26, 51);
  1147.     blue = new Color(51, 51, 230);
  1148.     white = new Color(255, 255, 255);
  1149.     gray = new Color(240, 240, 240);
  1150.     yellow = new Color(240, 240, 0);
  1151.  
  1152.     // Record the start time
  1153.     beg_time = System.currentTimeMillis();
  1154.   }
  1155.  
  1156.   public void setCanvas(Canvas2D canvas) {
  1157.     this.canvas = canvas;
  1158.   }
  1159.  
  1160.   public void init_combinations() {
  1161.  
  1162.     // The combination array contains all possible winning combinations.
  1163.     //
  1164.     // Each combination has the following format:
  1165.     //
  1166.     // combinations[x][0] = status: 0 = no player has selected positons in
  1167.     // this row
  1168.     //                              -1 = both players have men in this row
  1169.     //                               1 to 4 = number of positions occupied by player
  1170.     //
  1171.     // combinations[x][1] = player who owns this row (valid only if status =
  1172.     // 1-4)
  1173.     // combinations[x][2] = postion that define the row
  1174.     // combinations[x][3] = postion that define the row
  1175.     // combinations[x][4] = postion that define the row
  1176.     // combinations[x][5] = postion that define the row
  1177.  
  1178.     // Horizontal, Z
  1179.  
  1180.     combinations[0][0] = 0;
  1181.     combinations[1][0] = 0;
  1182.     combinations[2][0] = 0;
  1183.     combinations[3][0] = 0;
  1184.     combinations[0][1] = 0;
  1185.     combinations[1][1] = 0;
  1186.     combinations[2][1] = 0;
  1187.     combinations[3][1] = 0;
  1188.     combinations[0][2] = 0;
  1189.     combinations[1][2] = 4;
  1190.     combinations[2][2] = 8;
  1191.     combinations[3][2] = 12;
  1192.     combinations[0][3] = 1;
  1193.     combinations[1][3] = 5;
  1194.     combinations[2][3] = 9;
  1195.     combinations[3][3] = 13;
  1196.     combinations[0][4] = 2;
  1197.     combinations[1][4] = 6;
  1198.     combinations[2][4] = 10;
  1199.     combinations[3][4] = 14;
  1200.     combinations[0][5] = 3;
  1201.     combinations[1][5] = 7;
  1202.     combinations[2][5] = 11;
  1203.     combinations[3][5] = 15;
  1204.  
  1205.     combinations[4][0] = 0;
  1206.     combinations[5][0] = 0;
  1207.     combinations[6][0] = 0;
  1208.     combinations[7][0] = 0;
  1209.     combinations[4][1] = 0;
  1210.     combinations[5][1] = 0;
  1211.     combinations[6][1] = 0;
  1212.     combinations[7][1] = 0;
  1213.     combinations[4][2] = 16;
  1214.     combinations[5][2] = 20;
  1215.     combinations[6][2] = 24;
  1216.     combinations[7][2] = 28;
  1217.     combinations[4][3] = 17;
  1218.     combinations[5][3] = 21;
  1219.     combinations[6][3] = 25;
  1220.     combinations[7][3] = 29;
  1221.     combinations[4][4] = 18;
  1222.     combinations[5][4] = 22;
  1223.     combinations[6][4] = 26;
  1224.     combinations[7][4] = 30;
  1225.     combinations[4][5] = 19;
  1226.     combinations[5][5] = 23;
  1227.     combinations[6][5] = 27;
  1228.     combinations[7][5] = 31;
  1229.  
  1230.     combinations[8][0] = 0;
  1231.     combinations[9][0] = 0;
  1232.     combinations[10][0] = 0;
  1233.     combinations[11][0] = 0;
  1234.     combinations[8][1] = 0;
  1235.     combinations[9][1] = 0;
  1236.     combinations[10][1] = 0;
  1237.     combinations[11][1] = 0;
  1238.     combinations[8][2] = 32;
  1239.     combinations[9][2] = 36;
  1240.     combinations[10][2] = 40;
  1241.     combinations[11][2] = 44;
  1242.     combinations[8][3] = 33;
  1243.     combinations[9][3] = 37;
  1244.     combinations[10][3] = 41;
  1245.     combinations[11][3] = 45;
  1246.     combinations[8][4] = 34;
  1247.     combinations[9][4] = 38;
  1248.     combinations[10][4] = 42;
  1249.     combinations[11][4] = 46;
  1250.     combinations[8][5] = 35;
  1251.     combinations[9][5] = 39;
  1252.     combinations[10][5] = 43;
  1253.     combinations[11][5] = 47;
  1254.  
  1255.     combinations[12][0] = 0;
  1256.     combinations[13][0] = 0;
  1257.     combinations[14][0] = 0;
  1258.     combinations[15][0] = 0;
  1259.     combinations[12][1] = 0;
  1260.     combinations[13][1] = 0;
  1261.     combinations[14][1] = 0;
  1262.     combinations[15][1] = 0;
  1263.     combinations[12][2] = 48;
  1264.     combinations[13][2] = 52;
  1265.     combinations[14][2] = 56;
  1266.     combinations[15][2] = 60;
  1267.     combinations[12][3] = 49;
  1268.     combinations[13][3] = 53;
  1269.     combinations[14][3] = 57;
  1270.     combinations[15][3] = 61;
  1271.     combinations[12][4] = 50;
  1272.     combinations[13][4] = 54;
  1273.     combinations[14][4] = 58;
  1274.     combinations[15][4] = 62;
  1275.     combinations[12][5] = 51;
  1276.     combinations[13][5] = 55;
  1277.     combinations[14][5] = 59;
  1278.     combinations[15][5] = 63;
  1279.  
  1280.     // Vertical, Z
  1281.  
  1282.     combinations[16][0] = 0;
  1283.     combinations[17][0] = 0;
  1284.     combinations[18][0] = 0;
  1285.     combinations[19][0] = 0;
  1286.     combinations[16][1] = 0;
  1287.     combinations[17][1] = 0;
  1288.     combinations[18][1] = 0;
  1289.     combinations[19][1] = 0;
  1290.     combinations[16][2] = 0;
  1291.     combinations[17][2] = 1;
  1292.     combinations[18][2] = 2;
  1293.     combinations[19][2] = 3;
  1294.     combinations[16][3] = 4;
  1295.     combinations[17][3] = 5;
  1296.     combinations[18][3] = 6;
  1297.     combinations[19][3] = 7;
  1298.     combinations[16][4] = 8;
  1299.     combinations[17][4] = 9;
  1300.     combinations[18][4] = 10;
  1301.     combinations[19][4] = 11;
  1302.     combinations[16][5] = 12;
  1303.     combinations[17][5] = 13;
  1304.     combinations[18][5] = 14;
  1305.     combinations[19][5] = 15;
  1306.  
  1307.     combinations[20][0] = 0;
  1308.     combinations[21][0] = 0;
  1309.     combinations[22][0] = 0;
  1310.     combinations[23][0] = 0;
  1311.     combinations[20][1] = 0;
  1312.     combinations[21][1] = 0;
  1313.     combinations[22][1] = 0;
  1314.     combinations[23][1] = 0;
  1315.     combinations[20][2] = 16;
  1316.     combinations[21][2] = 17;
  1317.     combinations[22][2] = 18;
  1318.     combinations[23][2] = 19;
  1319.     combinations[20][3] = 20;
  1320.     combinations[21][3] = 21;
  1321.     combinations[22][3] = 22;
  1322.     combinations[23][3] = 23;
  1323.     combinations[20][4] = 24;
  1324.     combinations[21][4] = 25;
  1325.     combinations[22][4] = 26;
  1326.     combinations[23][4] = 27;
  1327.     combinations[20][5] = 28;
  1328.     combinations[21][5] = 29;
  1329.     combinations[22][5] = 30;
  1330.     combinations[23][5] = 31;
  1331.  
  1332.     combinations[24][0] = 0;
  1333.     combinations[25][0] = 0;
  1334.     combinations[26][0] = 0;
  1335.     combinations[27][0] = 0;
  1336.     combinations[24][1] = 0;
  1337.     combinations[25][1] = 0;
  1338.     combinations[26][1] = 0;
  1339.     combinations[27][1] = 0;
  1340.     combinations[24][2] = 32;
  1341.     combinations[25][2] = 33;
  1342.     combinations[26][2] = 34;
  1343.     combinations[27][2] = 35;
  1344.     combinations[24][3] = 36;
  1345.     combinations[25][3] = 37;
  1346.     combinations[26][3] = 38;
  1347.     combinations[27][3] = 39;
  1348.     combinations[24][4] = 40;
  1349.     combinations[25][4] = 41;
  1350.     combinations[26][4] = 42;
  1351.     combinations[27][4] = 43;
  1352.     combinations[24][5] = 44;
  1353.     combinations[25][5] = 45;
  1354.     combinations[26][5] = 46;
  1355.     combinations[27][5] = 47;
  1356.  
  1357.     combinations[28][0] = 0;
  1358.     combinations[29][0] = 0;
  1359.     combinations[30][0] = 0;
  1360.     combinations[31][0] = 0;
  1361.     combinations[28][1] = 0;
  1362.     combinations[29][1] = 0;
  1363.     combinations[30][1] = 0;
  1364.     combinations[31][1] = 0;
  1365.     combinations[28][2] = 48;
  1366.     combinations[29][2] = 49;
  1367.     combinations[30][2] = 50;
  1368.     combinations[31][2] = 51;
  1369.     combinations[28][3] = 52;
  1370.     combinations[29][3] = 53;
  1371.     combinations[30][3] = 54;
  1372.     combinations[31][3] = 55;
  1373.     combinations[28][4] = 56;
  1374.     combinations[29][4] = 57;
  1375.     combinations[30][4] = 58;
  1376.     combinations[31][4] = 59;
  1377.     combinations[28][5] = 60;
  1378.     combinations[29][5] = 61;
  1379.     combinations[30][5] = 62;
  1380.     combinations[31][5] = 63;
  1381.  
  1382.     // Diagonal, Z
  1383.  
  1384.     combinations[32][0] = 0;
  1385.     combinations[33][0] = 0;
  1386.     combinations[34][0] = 0;
  1387.     combinations[35][0] = 0;
  1388.     combinations[32][1] = 0;
  1389.     combinations[33][1] = 0;
  1390.     combinations[34][1] = 0;
  1391.     combinations[35][1] = 0;
  1392.     combinations[32][2] = 0;
  1393.     combinations[33][2] = 16;
  1394.     combinations[34][2] = 32;
  1395.     combinations[35][2] = 48;
  1396.     combinations[32][3] = 5;
  1397.     combinations[33][3] = 21;
  1398.     combinations[34][3] = 37;
  1399.     combinations[35][3] = 53;
  1400.     combinations[32][4] = 10;
  1401.     combinations[33][4] = 26;
  1402.     combinations[34][4] = 42;
  1403.     combinations[35][4] = 58;
  1404.     combinations[32][5] = 15;
  1405.     combinations[33][5] = 31;
  1406.     combinations[34][5] = 47;
  1407.     combinations[35][5] = 63;
  1408.  
  1409.     combinations[36][0] = 0;
  1410.     combinations[37][0] = 0;
  1411.     combinations[38][0] = 0;
  1412.     combinations[39][0] = 0;
  1413.     combinations[36][1] = 0;
  1414.     combinations[37][1] = 0;
  1415.     combinations[38][1] = 0;
  1416.     combinations[39][1] = 0;
  1417.     combinations[36][2] = 3;
  1418.     combinations[37][2] = 19;
  1419.     combinations[38][2] = 35;
  1420.     combinations[39][2] = 51;
  1421.     combinations[36][3] = 6;
  1422.     combinations[37][3] = 22;
  1423.     combinations[38][3] = 38;
  1424.     combinations[39][3] = 54;
  1425.     combinations[36][4] = 9;
  1426.     combinations[37][4] = 25;
  1427.     combinations[38][4] = 41;
  1428.     combinations[39][4] = 57;
  1429.     combinations[36][5] = 12;
  1430.     combinations[37][5] = 28;
  1431.     combinations[38][5] = 44;
  1432.     combinations[39][5] = 60;
  1433.  
  1434.     // Horizontal, X
  1435.  
  1436.     combinations[40][0] = 0;
  1437.     combinations[41][0] = 0;
  1438.     combinations[42][0] = 0;
  1439.     combinations[43][0] = 0;
  1440.     combinations[40][1] = 0;
  1441.     combinations[41][1] = 0;
  1442.     combinations[42][1] = 0;
  1443.     combinations[43][1] = 0;
  1444.     combinations[40][2] = 51;
  1445.     combinations[41][2] = 55;
  1446.     combinations[42][2] = 59;
  1447.     combinations[43][2] = 63;
  1448.     combinations[40][3] = 35;
  1449.     combinations[41][3] = 39;
  1450.     combinations[42][3] = 43;
  1451.     combinations[43][3] = 47;
  1452.     combinations[40][4] = 19;
  1453.     combinations[41][4] = 23;
  1454.     combinations[42][4] = 27;
  1455.     combinations[43][4] = 31;
  1456.     combinations[40][5] = 3;
  1457.     combinations[41][5] = 7;
  1458.     combinations[42][5] = 11;
  1459.     combinations[43][5] = 15;
  1460.  
  1461.     combinations[44][0] = 0;
  1462.     combinations[45][0] = 0;
  1463.     combinations[46][0] = 0;
  1464.     combinations[47][0] = 0;
  1465.     combinations[44][1] = 0;
  1466.     combinations[45][1] = 0;
  1467.     combinations[46][1] = 0;
  1468.     combinations[47][1] = 0;
  1469.     combinations[44][2] = 50;
  1470.     combinations[45][2] = 54;
  1471.     combinations[46][2] = 58;
  1472.     combinations[47][2] = 62;
  1473.     combinations[44][3] = 34;
  1474.     combinations[45][3] = 38;
  1475.     combinations[46][3] = 42;
  1476.     combinations[47][3] = 46;
  1477.     combinations[44][4] = 18;
  1478.     combinations[45][4] = 22;
  1479.     combinations[46][4] = 26;
  1480.     combinations[47][4] = 30;
  1481.     combinations[44][5] = 2;
  1482.     combinations[45][5] = 6;
  1483.     combinations[46][5] = 10;
  1484.     combinations[47][5] = 14;
  1485.  
  1486.     combinations[48][0] = 0;
  1487.     combinations[49][0] = 0;
  1488.     combinations[50][0] = 0;
  1489.     combinations[51][0] = 0;
  1490.     combinations[48][1] = 0;
  1491.     combinations[49][1] = 0;
  1492.     combinations[50][1] = 0;
  1493.     combinations[51][1] = 0;
  1494.     combinations[48][2] = 49;
  1495.     combinations[49][2] = 53;
  1496.     combinations[50][2] = 57;
  1497.     combinations[51][2] = 61;
  1498.     combinations[48][3] = 33;
  1499.     combinations[49][3] = 37;
  1500.     combinations[50][3] = 41;
  1501.     combinations[51][3] = 45;
  1502.     combinations[48][4] = 17;
  1503.     combinations[49][4] = 21;
  1504.     combinations[50][4] = 25;
  1505.     combinations[51][4] = 29;
  1506.     combinations[48][5] = 1;
  1507.     combinations[49][5] = 5;
  1508.     combinations[50][5] = 9;
  1509.     combinations[51][5] = 13;
  1510.  
  1511.     combinations[52][0] = 0;
  1512.     combinations[53][0] = 0;
  1513.     combinations[54][0] = 0;
  1514.     combinations[55][0] = 0;
  1515.     combinations[52][1] = 0;
  1516.     combinations[53][1] = 0;
  1517.     combinations[54][1] = 0;
  1518.     combinations[55][1] = 0;
  1519.     combinations[52][2] = 48;
  1520.     combinations[53][2] = 52;
  1521.     combinations[54][2] = 56;
  1522.     combinations[55][2] = 60;
  1523.     combinations[52][3] = 32;
  1524.     combinations[53][3] = 36;
  1525.     combinations[54][3] = 40;
  1526.     combinations[55][3] = 44;
  1527.     combinations[52][4] = 16;
  1528.     combinations[53][4] = 20;
  1529.     combinations[54][4] = 24;
  1530.     combinations[55][4] = 28;
  1531.     combinations[52][5] = 0;
  1532.     combinations[53][5] = 4;
  1533.     combinations[54][5] = 8;
  1534.     combinations[55][5] = 12;
  1535.  
  1536.     // Diagonal, X
  1537.  
  1538.     combinations[56][0] = 0;
  1539.     combinations[57][0] = 0;
  1540.     combinations[58][0] = 0;
  1541.     combinations[59][0] = 0;
  1542.     combinations[56][1] = 0;
  1543.     combinations[57][1] = 0;
  1544.     combinations[58][1] = 0;
  1545.     combinations[59][1] = 0;
  1546.     combinations[56][2] = 51;
  1547.     combinations[57][2] = 50;
  1548.     combinations[58][2] = 49;
  1549.     combinations[59][2] = 48;
  1550.     combinations[56][3] = 39;
  1551.     combinations[57][3] = 38;
  1552.     combinations[58][3] = 37;
  1553.     combinations[59][3] = 36;
  1554.     combinations[56][4] = 27;
  1555.     combinations[57][4] = 26;
  1556.     combinations[58][4] = 25;
  1557.     combinations[59][4] = 24;
  1558.     combinations[56][5] = 15;
  1559.     combinations[57][5] = 14;
  1560.     combinations[58][5] = 13;
  1561.     combinations[59][5] = 12;
  1562.  
  1563.     combinations[60][0] = 0;
  1564.     combinations[61][0] = 0;
  1565.     combinations[62][0] = 0;
  1566.     combinations[63][0] = 0;
  1567.     combinations[60][1] = 0;
  1568.     combinations[61][1] = 0;
  1569.     combinations[62][1] = 0;
  1570.     combinations[63][1] = 0;
  1571.     combinations[60][2] = 3;
  1572.     combinations[61][2] = 2;
  1573.     combinations[62][2] = 1;
  1574.     combinations[63][2] = 0;
  1575.     combinations[60][3] = 23;
  1576.     combinations[61][3] = 22;
  1577.     combinations[62][3] = 21;
  1578.     combinations[63][3] = 20;
  1579.     combinations[60][4] = 43;
  1580.     combinations[61][4] = 42;
  1581.     combinations[62][4] = 41;
  1582.     combinations[63][4] = 40;
  1583.     combinations[60][5] = 63;
  1584.     combinations[61][5] = 62;
  1585.     combinations[62][5] = 61;
  1586.     combinations[63][5] = 60;
  1587.  
  1588.     // Diagonal, Y
  1589.  
  1590.     combinations[64][0] = 0;
  1591.     combinations[65][0] = 0;
  1592.     combinations[66][0] = 0;
  1593.     combinations[67][0] = 0;
  1594.     combinations[64][1] = 0;
  1595.     combinations[65][1] = 0;
  1596.     combinations[66][1] = 0;
  1597.     combinations[67][1] = 0;
  1598.     combinations[64][2] = 63;
  1599.     combinations[65][2] = 59;
  1600.     combinations[66][2] = 55;
  1601.     combinations[67][2] = 51;
  1602.     combinations[64][3] = 46;
  1603.     combinations[65][3] = 42;
  1604.     combinations[66][3] = 38;
  1605.     combinations[67][3] = 34;
  1606.     combinations[64][4] = 29;
  1607.     combinations[65][4] = 25;
  1608.     combinations[66][4] = 21;
  1609.     combinations[67][4] = 17;
  1610.     combinations[64][5] = 12;
  1611.     combinations[65][5] = 8;
  1612.     combinations[66][5] = 4;
  1613.     combinations[67][5] = 0;
  1614.  
  1615.     combinations[68][0] = 0;
  1616.     combinations[69][0] = 0;
  1617.     combinations[70][0] = 0;
  1618.     combinations[71][0] = 0;
  1619.     combinations[68][1] = 0;
  1620.     combinations[69][1] = 0;
  1621.     combinations[70][1] = 0;
  1622.     combinations[71][1] = 0;
  1623.     combinations[68][2] = 15;
  1624.     combinations[69][2] = 11;
  1625.     combinations[70][2] = 7;
  1626.     combinations[71][2] = 3;
  1627.     combinations[68][3] = 30;
  1628.     combinations[69][3] = 26;
  1629.     combinations[70][3] = 22;
  1630.     combinations[71][3] = 18;
  1631.     combinations[68][4] = 45;
  1632.     combinations[69][4] = 41;
  1633.     combinations[70][4] = 37;
  1634.     combinations[71][4] = 33;
  1635.     combinations[68][5] = 60;
  1636.     combinations[69][5] = 56;
  1637.     combinations[70][5] = 52;
  1638.     combinations[71][5] = 48;
  1639.  
  1640.     // Corner to Corner
  1641.  
  1642.     combinations[72][0] = 0;
  1643.     combinations[73][0] = 0;
  1644.     combinations[74][0] = 0;
  1645.     combinations[75][0] = 0;
  1646.     combinations[72][1] = 0;
  1647.     combinations[73][1] = 0;
  1648.     combinations[74][1] = 0;
  1649.     combinations[75][1] = 0;
  1650.     combinations[72][2] = 0;
  1651.     combinations[73][2] = 3;
  1652.     combinations[74][2] = 12;
  1653.     combinations[75][2] = 15;
  1654.     combinations[72][3] = 21;
  1655.     combinations[73][3] = 22;
  1656.     combinations[74][3] = 25;
  1657.     combinations[75][3] = 26;
  1658.     combinations[72][4] = 42;
  1659.     combinations[73][4] = 41;
  1660.     combinations[74][4] = 38;
  1661.     combinations[75][4] = 37;
  1662.     combinations[72][5] = 63;
  1663.     combinations[73][5] = 60;
  1664.     combinations[74][5] = 51;
  1665.     combinations[75][5] = 48;
  1666.  
  1667.     // Initialize the combination flags to zero.
  1668.     for (int i = 0; i < 76; i++)
  1669.       combinations[i][6] = 0;
  1670.  
  1671.     // Set up the pos_to_comb array to point to every winning combination
  1672.     // that a given
  1673.     // position may have.
  1674.     setup_pos_to_comb();
  1675.  
  1676.     // Set up the best_picks array.
  1677.     update_best_picks();
  1678.   }
  1679.  
  1680.   /**
  1681.    * Initialize the "outside four" array.
  1682.    */
  1683.   public void init_outside_four() {
  1684.     for (int i = 0; i < 18; i++) {
  1685.       outside_four[i][0] = 0;
  1686.       outside_four[i][1] = 0;
  1687.       outside_four[i][2] = faces[i][2];
  1688.       outside_four[i][3] = faces[i][5];
  1689.       outside_four[i][4] = faces[i][14];
  1690.       outside_four[i][5] = faces[i][17];
  1691.     }
  1692.   }
  1693.  
  1694.   /**
  1695.    * Initialize the "inside four" array.
  1696.    */
  1697.   public void init_inside_four() {
  1698.     for (int i = 0; i < 18; i++) {
  1699.       inside_four[i][0] = 0;
  1700.       inside_four[i][1] = 0;
  1701.       inside_four[i][2] = faces[i][7];
  1702.       inside_four[i][3] = faces[i][8];
  1703.       inside_four[i][4] = faces[i][11];
  1704.       inside_four[i][5] = faces[i][12];
  1705.     }
  1706.   }
  1707.  
  1708.   /**
  1709.    * Initialize the "faces" array.
  1710.    */
  1711.   public void init_faces() {
  1712.  
  1713.     faces[0][0] = 0;
  1714.     faces[0][1] = 0;
  1715.     faces[0][2] = 12;
  1716.     faces[0][6] = 13;
  1717.     faces[0][10] = 14;
  1718.     faces[0][14] = 15;
  1719.     faces[0][3] = 8;
  1720.     faces[0][7] = 9;
  1721.     faces[0][11] = 10;
  1722.     faces[0][15] = 11;
  1723.     faces[0][4] = 4;
  1724.     faces[0][8] = 5;
  1725.     faces[0][12] = 6;
  1726.     faces[0][16] = 7;
  1727.     faces[0][5] = 0;
  1728.     faces[0][9] = 1;
  1729.     faces[0][13] = 2;
  1730.     faces[0][17] = 3;
  1731.  
  1732.     faces[1][0] = 0;
  1733.     faces[1][1] = 0;
  1734.     faces[1][2] = 28;
  1735.     faces[1][6] = 29;
  1736.     faces[1][10] = 30;
  1737.     faces[1][14] = 31;
  1738.     faces[1][3] = 24;
  1739.     faces[1][7] = 25;
  1740.     faces[1][11] = 26;
  1741.     faces[1][15] = 27;
  1742.     faces[1][4] = 20;
  1743.     faces[1][8] = 21;
  1744.     faces[1][12] = 22;
  1745.     faces[1][16] = 23;
  1746.     faces[1][5] = 16;
  1747.     faces[1][9] = 17;
  1748.     faces[1][13] = 18;
  1749.     faces[1][17] = 19;
  1750.  
  1751.     faces[2][0] = 0;
  1752.     faces[2][1] = 0;
  1753.     faces[2][2] = 44;
  1754.     faces[2][6] = 45;
  1755.     faces[2][10] = 46;
  1756.     faces[2][14] = 47;
  1757.     faces[2][3] = 40;
  1758.     faces[2][7] = 41;
  1759.     faces[2][11] = 42;
  1760.     faces[2][15] = 43;
  1761.     faces[2][4] = 36;
  1762.     faces[2][8] = 37;
  1763.     faces[2][12] = 38;
  1764.     faces[2][16] = 39;
  1765.     faces[2][5] = 32;
  1766.     faces[2][9] = 33;
  1767.     faces[2][13] = 34;
  1768.     faces[2][17] = 35;
  1769.  
  1770.     faces[3][0] = 0;
  1771.     faces[3][1] = 0;
  1772.     faces[3][2] = 60;
  1773.     faces[3][6] = 61;
  1774.     faces[3][10] = 62;
  1775.     faces[3][14] = 63;
  1776.     faces[3][3] = 56;
  1777.     faces[3][7] = 57;
  1778.     faces[3][11] = 58;
  1779.     faces[3][15] = 59;
  1780.     faces[3][4] = 52;
  1781.     faces[3][8] = 53;
  1782.     faces[3][12] = 54;
  1783.     faces[3][16] = 55;
  1784.     faces[3][5] = 48;
  1785.     faces[3][9] = 49;
  1786.     faces[3][13] = 50;
  1787.     faces[3][17] = 51;
  1788.  
  1789.     faces[4][0] = 0;
  1790.     faces[4][1] = 0;
  1791.     faces[4][2] = 12;
  1792.     faces[4][6] = 28;
  1793.     faces[4][10] = 44;
  1794.     faces[4][14] = 60;
  1795.     faces[4][3] = 8;
  1796.     faces[4][7] = 24;
  1797.     faces[4][11] = 40;
  1798.     faces[4][15] = 56;
  1799.     faces[4][4] = 4;
  1800.     faces[4][8] = 20;
  1801.     faces[4][12] = 36;
  1802.     faces[4][16] = 52;
  1803.     faces[4][5] = 0;
  1804.     faces[4][9] = 16;
  1805.     faces[4][13] = 32;
  1806.     faces[4][17] = 48;
  1807.  
  1808.     faces[5][0] = 0;
  1809.     faces[5][1] = 0;
  1810.     faces[5][2] = 13;
  1811.     faces[5][6] = 29;
  1812.     faces[5][10] = 45;
  1813.     faces[5][14] = 61;
  1814.     faces[5][3] = 9;
  1815.     faces[5][7] = 25;
  1816.     faces[5][11] = 41;
  1817.     faces[5][15] = 57;
  1818.     faces[5][4] = 5;
  1819.     faces[5][8] = 21;
  1820.     faces[5][12] = 37;
  1821.     faces[5][16] = 53;
  1822.     faces[5][5] = 1;
  1823.     faces[5][9] = 17;
  1824.     faces[5][13] = 33;
  1825.     faces[5][17] = 49;
  1826.  
  1827.     faces[6][0] = 0;
  1828.     faces[6][1] = 0;
  1829.     faces[6][2] = 14;
  1830.     faces[6][6] = 30;
  1831.     faces[6][10] = 46;
  1832.     faces[6][14] = 62;
  1833.     faces[6][3] = 10;
  1834.     faces[6][7] = 26;
  1835.     faces[6][11] = 42;
  1836.     faces[6][15] = 58;
  1837.     faces[6][4] = 6;
  1838.     faces[6][8] = 22;
  1839.     faces[6][12] = 38;
  1840.     faces[6][16] = 54;
  1841.     faces[6][5] = 2;
  1842.     faces[6][9] = 18;
  1843.     faces[6][13] = 34;
  1844.     faces[6][17] = 50;
  1845.  
  1846.     faces[7][0] = 0;
  1847.     faces[7][1] = 0;
  1848.     faces[7][2] = 15;
  1849.     faces[7][6] = 31;
  1850.     faces[7][10] = 47;
  1851.     faces[7][14] = 63;
  1852.     faces[7][3] = 11;
  1853.     faces[7][7] = 27;
  1854.     faces[7][11] = 43;
  1855.     faces[7][15] = 59;
  1856.     faces[7][4] = 7;
  1857.     faces[7][8] = 23;
  1858.     faces[7][12] = 39;
  1859.     faces[7][16] = 55;
  1860.     faces[7][5] = 3;
  1861.     faces[7][9] = 19;
  1862.     faces[7][13] = 35;
  1863.     faces[7][17] = 51;
  1864.  
  1865.     faces[8][0] = 0;
  1866.     faces[8][1] = 0;
  1867.     faces[8][2] = 12;
  1868.     faces[8][6] = 28;
  1869.     faces[8][10] = 44;
  1870.     faces[8][14] = 60;
  1871.     faces[8][3] = 13;
  1872.     faces[8][7] = 29;
  1873.     faces[8][11] = 45;
  1874.     faces[8][15] = 61;
  1875.     faces[8][4] = 14;
  1876.     faces[8][8] = 30;
  1877.     faces[8][12] = 46;
  1878.     faces[8][16] = 62;
  1879.     faces[8][5] = 15;
  1880.     faces[8][9] = 31;
  1881.     faces[8][13] = 47;
  1882.     faces[8][17] = 63;
  1883.  
  1884.     faces[9][0] = 0;
  1885.     faces[9][1] = 0;
  1886.     faces[9][2] = 8;
  1887.     faces[9][6] = 24;
  1888.     faces[9][10] = 40;
  1889.     faces[9][14] = 56;
  1890.     faces[9][3] = 9;
  1891.     faces[9][7] = 25;
  1892.     faces[9][11] = 41;
  1893.     faces[9][15] = 57;
  1894.     faces[9][4] = 10;
  1895.     faces[9][8] = 26;
  1896.     faces[9][12] = 42;
  1897.     faces[9][16] = 58;
  1898.     faces[9][5] = 11;
  1899.     faces[9][9] = 27;
  1900.     faces[9][13] = 43;
  1901.     faces[9][17] = 59;
  1902.  
  1903.     faces[10][0] = 0;
  1904.     faces[10][1] = 0;
  1905.     faces[10][2] = 4;
  1906.     faces[10][6] = 20;
  1907.     faces[10][10] = 36;
  1908.     faces[10][14] = 52;
  1909.     faces[10][3] = 5;
  1910.     faces[10][7] = 21;
  1911.     faces[10][11] = 37;
  1912.     faces[10][15] = 53;
  1913.     faces[10][4] = 6;
  1914.     faces[10][8] = 22;
  1915.     faces[10][12] = 38;
  1916.     faces[10][16] = 54;
  1917.     faces[10][5] = 7;
  1918.     faces[10][9] = 23;
  1919.     faces[10][13] = 39;
  1920.     faces[10][17] = 55;
  1921.  
  1922.     faces[11][0] = 0;
  1923.     faces[11][1] = 0;
  1924.     faces[11][2] = 0;
  1925.     faces[11][6] = 16;
  1926.     faces[11][10] = 32;
  1927.     faces[11][14] = 48;
  1928.     faces[11][3] = 1;
  1929.     faces[11][7] = 17;
  1930.     faces[11][11] = 33;
  1931.     faces[11][15] = 49;
  1932.     faces[11][4] = 2;
  1933.     faces[11][8] = 18;
  1934.     faces[11][12] = 34;
  1935.     faces[11][16] = 50;
  1936.     faces[11][5] = 3;
  1937.     faces[11][9] = 19;
  1938.     faces[11][13] = 35;
  1939.     faces[11][17] = 51;
  1940.  
  1941.     faces[12][0] = 0;
  1942.     faces[12][1] = 0;
  1943.     faces[12][2] = 12;
  1944.     faces[12][6] = 13;
  1945.     faces[12][10] = 14;
  1946.     faces[12][14] = 15;
  1947.     faces[12][3] = 24;
  1948.     faces[12][7] = 25;
  1949.     faces[12][11] = 26;
  1950.     faces[12][15] = 27;
  1951.     faces[12][4] = 36;
  1952.     faces[12][8] = 37;
  1953.     faces[12][12] = 38;
  1954.     faces[12][16] = 39;
  1955.     faces[12][5] = 48;
  1956.     faces[12][9] = 49;
  1957.     faces[12][13] = 50;
  1958.     faces[12][17] = 51;
  1959.  
  1960.     faces[13][0] = 0;
  1961.     faces[13][1] = 0;
  1962.     faces[13][2] = 0;
  1963.     faces[13][6] = 1;
  1964.     faces[13][10] = 2;
  1965.     faces[13][14] = 3;
  1966.     faces[13][3] = 20;
  1967.     faces[13][7] = 21;
  1968.     faces[13][11] = 22;
  1969.     faces[13][15] = 23;
  1970.     faces[13][4] = 40;
  1971.     faces[13][8] = 41;
  1972.     faces[13][12] = 42;
  1973.     faces[13][16] = 43;
  1974.     faces[13][5] = 60;
  1975.     faces[13][9] = 61;
  1976.     faces[13][13] = 62;
  1977.     faces[13][17] = 63;
  1978.  
  1979.     faces[14][0] = 0;
  1980.     faces[14][1] = 0;
  1981.     faces[14][2] = 12;
  1982.     faces[14][6] = 28;
  1983.     faces[14][10] = 44;
  1984.     faces[14][14] = 60;
  1985.     faces[14][3] = 9;
  1986.     faces[14][7] = 25;
  1987.     faces[14][11] = 41;
  1988.     faces[14][15] = 57;
  1989.     faces[14][4] = 6;
  1990.     faces[14][8] = 22;
  1991.     faces[14][12] = 38;
  1992.     faces[14][16] = 54;
  1993.     faces[14][5] = 3;
  1994.     faces[14][9] = 19;
  1995.     faces[14][13] = 35;
  1996.     faces[14][17] = 51;
  1997.  
  1998.     faces[15][0] = 0;
  1999.     faces[15][1] = 0;
  2000.     faces[15][2] = 15;
  2001.     faces[15][6] = 31;
  2002.     faces[15][10] = 47;
  2003.     faces[15][14] = 63;
  2004.     faces[15][3] = 10;
  2005.     faces[15][7] = 26;
  2006.     faces[15][11] = 42;
  2007.     faces[15][15] = 58;
  2008.     faces[15][4] = 5;
  2009.     faces[15][8] = 21;
  2010.     faces[15][12] = 37;
  2011.     faces[15][16] = 53;
  2012.     faces[15][5] = 0;
  2013.     faces[15][9] = 16;
  2014.     faces[15][13] = 32;
  2015.     faces[15][17] = 48;
  2016.  
  2017.     faces[16][0] = 0;
  2018.     faces[16][1] = 0;
  2019.     faces[16][2] = 12;
  2020.     faces[16][6] = 29;
  2021.     faces[16][10] = 46;
  2022.     faces[16][14] = 63;
  2023.     faces[16][3] = 8;
  2024.     faces[16][7] = 25;
  2025.     faces[16][11] = 42;
  2026.     faces[16][15] = 59;
  2027.     faces[16][4] = 4;
  2028.     faces[16][8] = 21;
  2029.     faces[16][12] = 38;
  2030.     faces[16][16] = 55;
  2031.     faces[16][5] = 0;
  2032.     faces[16][9] = 17;
  2033.     faces[16][13] = 34;
  2034.     faces[16][17] = 51;
  2035.  
  2036.     faces[17][0] = 0;
  2037.     faces[17][1] = 0;
  2038.     faces[17][2] = 15;
  2039.     faces[17][6] = 30;
  2040.     faces[17][10] = 45;
  2041.     faces[17][14] = 60;
  2042.     faces[17][3] = 11;
  2043.     faces[17][7] = 26;
  2044.     faces[17][11] = 41;
  2045.     faces[17][15] = 56;
  2046.     faces[17][4] = 7;
  2047.     faces[17][8] = 22;
  2048.     faces[17][12] = 37;
  2049.     faces[17][16] = 52;
  2050.     faces[17][5] = 3;
  2051.     faces[17][9] = 18;
  2052.     faces[17][13] = 33;
  2053.     faces[17][17] = 48;
  2054.   }
  2055.  
  2056.   /**
  2057.    * Render the current face set in the 2D window.
  2058.    */
  2059.   public void render2D(Graphics gc) {
  2060.  
  2061.     gc.setColor(background);
  2062.     gc.fillRect(0, 0, width, height);
  2063.  
  2064.     int id;
  2065.     int x, y;
  2066.  
  2067.     float begX;
  2068.     float begY;
  2069.  
  2070.     for (int l = 0; l < 3; l++) {
  2071.       begY = 28.0f + l * (5.f * 23.3f);
  2072.       for (int k = 0; k < 6; k++) {
  2073.         begX = 11.65f + k * (5.f * 11.65f);
  2074.         int count = 0;
  2075.         int face = l * 6 + k;
  2076.         for (int i = 0; i < 4; i++) {
  2077.           for (int j = 0; j < 4; j++) {
  2078.             x = (int) begX + i * 12;
  2079.             y = (int) begY + j * 12;
  2080.             id = faces[face][count + 2];
  2081.             if (occupied[id] == HUMAN) {
  2082.               x -= 2;
  2083.               y -= 2;
  2084.               gc.setColor(red);
  2085.               gc.fillRect(x, y, 5, 5);
  2086.             } else if (occupied[id] == MACHINE) {
  2087.               x -= 2;
  2088.               y -= 2;
  2089.               gc.setColor(blue);
  2090.               gc.fillRect(x, y, 5, 5);
  2091.             } else {
  2092.               x -= 1;
  2093.               y -= 1;
  2094.               gc.setColor(gray);
  2095.               gc.fillRect(x, y, 2, 2);
  2096.             }
  2097.             if (highlight[face]) {
  2098.               gc.setColor(yellow);
  2099.               positions.setHighlight(faces[face][count + 2]);
  2100.             }
  2101.             count++;
  2102.           }
  2103.         }
  2104.         if (highlight[face])
  2105.           gc.setColor(yellow);
  2106.         else
  2107.           gc.setColor(white);
  2108.         if ((face + 1) < 10)
  2109.           gc.drawString("Face " + (face + 1), (int) begX - 2,
  2110.               (int) begY + 60);
  2111.         else
  2112.           gc.drawString("Face " + (face + 1), (int) begX - 4,
  2113.               (int) begY + 60);
  2114.       }
  2115.     }
  2116.   }
  2117.  
  2118.   /**
  2119.    * Determine what position has been selected in the 2D window.
  2120.    */
  2121.   public void checkSelection2D(int x, int y, int player) {
  2122.  
  2123.     int id;
  2124.     int posX, posY;
  2125.  
  2126.     float begX;
  2127.     float begY;
  2128.  
  2129.     for (int l = 0; l < 3; l++) {
  2130.       begY = 28.0f + l * (5.f * 23.3f);
  2131.       for (int k = 0; k < 6; k++) {
  2132.         begX = 11.65f + k * (5.f * 11.65f);
  2133.         int count = 0;
  2134.         int face = l * 6 + k;
  2135.         for (int i = 0; i < 4; i++) {
  2136.           for (int j = 0; j < 4; j++) {
  2137.             posX = (int) begX + i * 12;
  2138.             posY = (int) begY + j * 12;
  2139.             if (x > posX - 4 && x < posX + 4 && y > posY - 4
  2140.                 && y < posY + 4) {
  2141.  
  2142.               id = faces[face][count + 2];
  2143.  
  2144.               if (occupied[id] == UNOCCUPIED) {
  2145.                 positions.set(id, player);
  2146.                 selection(id, player);
  2147.                 canvas.repaint();
  2148.               }
  2149.               return;
  2150.             }
  2151.             count++;
  2152.           }
  2153.         }
  2154.         if ((x > begX - 4 && x < begX + 40)
  2155.             && (y > begY + 45 && y < begY + 60)) {
  2156.  
  2157.           count = 0;
  2158.           for (int i = 0; i < 4; i++) {
  2159.             for (int j = 0; j < 4; j++) {
  2160.               if (highlight[face])
  2161.                 positions
  2162.                     .clearHighlight(faces[face][count + 2]);
  2163.               count++;
  2164.             }
  2165.           }
  2166.           if (highlight[face])
  2167.             highlight[face] = false;
  2168.           else
  2169.             highlight[face] = true;
  2170.           canvas.repaint();
  2171.         }
  2172.       }
  2173.     }
  2174.  
  2175.   }
  2176.  
  2177.   /**
  2178.    * Record the player's move.
  2179.    */
  2180.   public void selection(int pos, int player) {
  2181.  
  2182.     int num_combinations;
  2183.     int comb;
  2184.  
  2185.     this.player = player;
  2186.  
  2187.     if (player == HUMAN) {
  2188.  
  2189.       // If position is already occupied, return.
  2190.       if (occupied[pos] != 0)
  2191.         return;
  2192.  
  2193.       // Mark the position as HUMAN.
  2194.       occupied[pos] = HUMAN;
  2195.  
  2196.       // Update the logic arrays.
  2197.       this.player = update_logic_arrays(pos);
  2198.  
  2199.       // Have the computer determine its move.
  2200.       choose_move();
  2201.     }
  2202.   }
  2203.  
  2204.   /**
  2205.    * Determine the computer's move.
  2206.    */
  2207.   public void choose_move() {
  2208.  
  2209.     if (player == MACHINE) {
  2210.  
  2211.       // Babe in the woods.
  2212.       if (skill_level == 0) {
  2213.         if (!block_winning_move()) {
  2214.           if (!pick_7()) {
  2215.             if (!check_outside_four()) {
  2216.               pick_best_position();
  2217.             }
  2218.           }
  2219.         }
  2220.       }
  2221.  
  2222.       // Walk and chew gum.
  2223.       else if (skill_level == 1) {
  2224.         if (!block_winning_move()) {
  2225.           if (!block_intersecting_rows()) {
  2226.             if (!block_inside_four()) {
  2227.               if (!block_outside_four()) {
  2228.                 pick_best_position();
  2229.               }
  2230.             }
  2231.           }
  2232.         }
  2233.       }
  2234.  
  2235.       // Jeopordy contestant.
  2236.       else if (skill_level == 2) {
  2237.         if (!block_winning_move()) {
  2238.           if (!block_intersecting_rows()) {
  2239.             if (!block_inside_four()) {
  2240.               if (!block_outside_four()) {
  2241.                 if (!pick_7()) {
  2242.                   pick_best_position();
  2243.                 }
  2244.               }
  2245.             }
  2246.           }
  2247.         }
  2248.       }
  2249.  
  2250.       // Rocket scientist.
  2251.       else if (skill_level == 3) {
  2252.         if (!block_winning_move()) {
  2253.           if (!block_intersecting_rows()) {
  2254.             if (!block_chair_move()) {
  2255.               if (!check_face_three()) {
  2256.                 if (!block_central_four()) {
  2257.                   if (!block_inside_four()) {
  2258.                     if (!block_outside_four()) {
  2259.                       if (!take_inside_four()) {
  2260.                         if (!take_outside_four()) {
  2261.                           if (!pick_7()) {
  2262.                             if (!check_outside_four()) {
  2263.                               pick_best_position();
  2264.                             }
  2265.                           }
  2266.                         }
  2267.                       }
  2268.                     }
  2269.                   }
  2270.                 }
  2271.               }
  2272.             }
  2273.           }
  2274.         }
  2275.       }
  2276.  
  2277.       // Be afraid, be very afraid.
  2278.       else if (skill_level == 4) {
  2279.         if (!block_winning_move()) {
  2280.           if (!block_intersecting_rows()) {
  2281.             if (!block_chair_move()) {
  2282.               if (!block_walk_move()) {
  2283.                 if (!block_central_four()) {
  2284.                   if (!block_inside_four()) {
  2285.                     if (!block_outside_four()) {
  2286.                       if (!check_face_three()) {
  2287.                         if (!check_intersecting_rows2()) {
  2288.                           if (!take_inside_four()) {
  2289.                             if (!take_outside_four()) {
  2290.                               if (!pick_7()) {
  2291.                                 if (!check_outside_four()) {
  2292.                                   pick_best_position();
  2293.                                 }
  2294.                               }
  2295.                             }
  2296.                           }
  2297.                         }
  2298.                       }
  2299.                     }
  2300.                   }
  2301.                 }
  2302.               }
  2303.             }
  2304.           }
  2305.         }
  2306.       }
  2307.     }
  2308.   }
  2309.  
  2310.   /**
  2311.    * Check for a winning move.
  2312.    */
  2313.   public boolean block_winning_move() {
  2314.  
  2315.     // Loop through each combination and see if any player occupies
  2316.     // three positions. If so, take the last remaining position.
  2317.     int pos;
  2318.     for (int i = 0; i < 76; i++) {
  2319.       if (combinations[i][0] == 3) {
  2320.         for (int j = 2; j < 6; j++) {
  2321.           pos = combinations[i][j];
  2322.           if (occupied[pos] == 0) {
  2323.             occupied[pos] = MACHINE;
  2324.             positions.set(pos, MACHINE);
  2325.             player = update_logic_arrays(pos);
  2326.             if (debug)
  2327.               System.out.println("block_winning_move:  true");
  2328.             return true;
  2329.           }
  2330.         }
  2331.       }
  2332.     }
  2333.     if (debug)
  2334.       System.out.println("check_winning_move:  false");
  2335.     return false;
  2336.   }
  2337.  
  2338.   /**
  2339.    * Block outside four
  2340.    */
  2341.   public boolean block_outside_four() {
  2342.  
  2343.     int pos;
  2344.     int index = 0;
  2345.     int max = 0;
  2346.  
  2347.     // Block the opponent, if necessary.
  2348.     for (int i = 0; i < 18; i++) {
  2349.       if (outside_four[i][0] > 0 && outside_four[i][1] == HUMAN) {
  2350.         if (outside_four[i][0] > max) {
  2351.           index = i;
  2352.           max = outside_four[i][0];
  2353.         }
  2354.       }
  2355.     }
  2356.  
  2357.     if (max > 0) {
  2358.       for (int j = 2; j < 6; j++) {
  2359.         pos = outside_four[index][j];
  2360.         if (occupied[pos] == 0) {
  2361.           occupied[pos] = MACHINE;
  2362.           positions.set(pos, MACHINE);
  2363.           player = update_logic_arrays(pos);
  2364.           if (debug)
  2365.             System.out.println("block_outside_four:  true");
  2366.           return true;
  2367.         }
  2368.       }
  2369.     }
  2370.  
  2371.     if (debug)
  2372.       System.out.println("block_outside_four:  false");
  2373.     return false;
  2374.   }
  2375.  
  2376.   /**
  2377.    * Block central four
  2378.    */
  2379.   public boolean block_central_four() {
  2380.  
  2381.     int pos;
  2382.     int index = 0;
  2383.     int max = 0;
  2384.  
  2385.     // Block the opponent, if necessary.
  2386.     for (int i = 1; i < 3; i++) {
  2387.       if (inside_four[i][0] > 0 && inside_four[i][1] == HUMAN) {
  2388.         if (inside_four[i][0] > max) {
  2389.           index = i;
  2390.           max = inside_four[i][0];
  2391.         }
  2392.       }
  2393.     }
  2394.  
  2395.     if (max > 0) {
  2396.       for (int j = 2; j < 6; j++) {
  2397.         pos = inside_four[index][j];
  2398.         if (occupied[pos] == 0) {
  2399.           occupied[pos] = MACHINE;
  2400.           positions.set(pos, MACHINE);
  2401.           player = update_logic_arrays(pos);
  2402.           if (debug)
  2403.             System.out.println("block_central_four:  true");
  2404.           return true;
  2405.         }
  2406.       }
  2407.     }
  2408.  
  2409.     if (debug)
  2410.       System.out.println("block_central_four:  false");
  2411.     return false;
  2412.   }
  2413.  
  2414.   /**
  2415.    * Check each face for a forced win.
  2416.    */
  2417.   public boolean check_face_three() {
  2418.  
  2419.     int pos;
  2420.     int index = 0;
  2421.     int human = 0;
  2422.     int machine = 0;
  2423.  
  2424.     // Block the opponent from a forced win.
  2425.     for (int i = 0; i < 18; i++) {
  2426.       if (outside_four[i][0] == -1) {
  2427.         human = 0;
  2428.         machine = 0;
  2429.         for (int j = 2; j < 6; j++) {
  2430.           if (occupied[outside_four[i][j]] == MACHINE)
  2431.             machine++;
  2432.           else if (occupied[outside_four[i][j]] == HUMAN)
  2433.             human++;
  2434.         }
  2435.         if (debug)
  2436.           System.out.println("machine = " + machine);
  2437.         if (debug)
  2438.           System.out.println("human   = " + human);
  2439.         if (human == 3 && machine == 1) {
  2440.           if (debug)
  2441.             System.out.println("human == 3 && machine == 1");
  2442.           for (int j = 2; j < 18; j++) {
  2443.             pos = faces[i][j];
  2444.             if (occupied[pos] == 0) {
  2445.               for (int k = 0; k < 76; k++) {
  2446.                 if (combinations[i][0] == 2
  2447.                     & combinations[i][1] == HUMAN) {
  2448.                   for (int l = 0; l < 4; l++) {
  2449.                     if (combinations[i][l] == pos) {
  2450.                       occupied[pos] = MACHINE;
  2451.                       positions.set(pos, MACHINE);
  2452.                       player = update_logic_arrays(pos);
  2453.                       if (debug)
  2454.                         System.out
  2455.                             .println("check_face_three:  true");
  2456.                       return true;
  2457.                     }
  2458.                   }
  2459.                 }
  2460.               }
  2461.             }
  2462.           }
  2463.         }
  2464.       }
  2465.     }
  2466.  
  2467.     if (debug)
  2468.       System.out.println("check_face_three:  false");
  2469.     return false;
  2470.   }
  2471.  
  2472.   /**
  2473.    * Block inside four
  2474.    */
  2475.   public boolean block_inside_four() {
  2476.  
  2477.     int pos;
  2478.     int index = 0;
  2479.     int max = 0;
  2480.  
  2481.     // Block the opponent, if necessary.
  2482.     for (int i = 0; i < 18; i++) {
  2483.       if (inside_four[i][0] > 0 && inside_four[i][1] == HUMAN) {
  2484.         if (inside_four[i][0] > max) {
  2485.           index = i;
  2486.           max = inside_four[i][0];
  2487.         }
  2488.       }
  2489.     }
  2490.  
  2491.     if (max > 0) {
  2492.       for (int j = 2; j < 6; j++) {
  2493.         pos = inside_four[index][j];
  2494.         if (occupied[pos] == 0) {
  2495.           occupied[pos] = MACHINE;
  2496.           positions.set(pos, MACHINE);
  2497.           player = update_logic_arrays(pos);
  2498.           if (debug)
  2499.             System.out.println("block_inside_four:  true");
  2500.           return true;
  2501.         }
  2502.       }
  2503.     }
  2504.  
  2505.     if (debug)
  2506.       System.out.println("block_inside_four:  false");
  2507.     return false;
  2508.   }
  2509.  
  2510.   public boolean block_chair_move() {
  2511.  
  2512.     int pos;
  2513.  
  2514.     int ncorners = 0; // Number of corners owned by human
  2515.     int corner = 0; // Corner owned by machine
  2516.  
  2517.     if (debug)
  2518.       System.out.println("inside block_chair_move");
  2519.  
  2520.     // Loop through all of the faces.
  2521.     for (int i = 0; i < 18; i++) {
  2522.  
  2523.       // Determine which corners the human owns.
  2524.       if (occupied[faces[i][2]] == HUMAN)
  2525.         ncorners++;
  2526.       else if (occupied[faces[i][2]] == MACHINE)
  2527.         corner = 2;
  2528.       if (occupied[faces[i][5]] == HUMAN)
  2529.         ncorners++;
  2530.       else if (occupied[faces[i][5]] == MACHINE)
  2531.         corner = 5;
  2532.       if (occupied[faces[i][14]] == HUMAN)
  2533.         ncorners++;
  2534.       else if (occupied[faces[i][14]] == MACHINE)
  2535.         corner = 14;
  2536.       if (occupied[faces[i][17]] == HUMAN)
  2537.         ncorners++;
  2538.       else if (occupied[faces[i][17]] == MACHINE)
  2539.         corner = 17;
  2540.  
  2541.       // If the human owns three corners, continue with the search.
  2542.       if (ncorners == 3) {
  2543.         if (corner == 2) {
  2544.           if (occupied[faces[i][3]] == HUMAN
  2545.               && occupied[faces[i][7]] == 0
  2546.               && occupied[faces[i][8]] == 0
  2547.               && occupied[faces[i][11]] == 0
  2548.               && occupied[faces[i][15]] == 0
  2549.               && occupied[faces[i][16]] == 0) {
  2550.             pos = faces[i][11];
  2551.             occupied[pos] = MACHINE;
  2552.             positions.set(pos, MACHINE);
  2553.             player = update_logic_arrays(pos);
  2554.             if (debug)
  2555.               System.out.println("block_chair_move: found");
  2556.             return true;
  2557.           }
  2558.           if (occupied[faces[i][4]] == HUMAN
  2559.               && occupied[faces[i][8]] == 0
  2560.               && occupied[faces[i][11]] == 0
  2561.               && occupied[faces[i][12]] == 0
  2562.               && occupied[faces[i][15]] == 0
  2563.               && occupied[faces[i][16]] == 0) {
  2564.             pos = faces[i][12];
  2565.             occupied[pos] = MACHINE;
  2566.             positions.set(pos, MACHINE);
  2567.             player = update_logic_arrays(pos);
  2568.             if (debug)
  2569.               System.out.println("block_chair_move: found");
  2570.             return true;
  2571.           }
  2572.           if (occupied[faces[i][6]] == HUMAN
  2573.               && occupied[faces[i][7]] == 0
  2574.               && occupied[faces[i][8]] == 0
  2575.               && occupied[faces[i][9]] == 0
  2576.               && occupied[faces[i][11]] == 0
  2577.               && occupied[faces[i][13]] == 0) {
  2578.             pos = faces[i][8];
  2579.             occupied[pos] = MACHINE;
  2580.             positions.set(pos, MACHINE);
  2581.             player = update_logic_arrays(pos);
  2582.             if (debug)
  2583.               System.out.println("block_chair_move: found");
  2584.             return true;
  2585.           }
  2586.           if (occupied[faces[i][10]] == HUMAN
  2587.               && occupied[faces[i][8]] == 0
  2588.               && occupied[faces[i][9]] == 0
  2589.               && occupied[faces[i][11]] == 0
  2590.               && occupied[faces[i][12]] == 0
  2591.               && occupied[faces[i][13]] == 0) {
  2592.             pos = faces[i][11];
  2593.             occupied[pos] = MACHINE;
  2594.             positions.set(pos, MACHINE);
  2595.             player = update_logic_arrays(pos);
  2596.             if (debug)
  2597.               System.out.println("block_chair_move: found");
  2598.             return true;
  2599.           }
  2600.           if (occupied[faces[i][7]] == HUMAN
  2601.               && occupied[faces[i][3]] == 0
  2602.               && occupied[faces[i][8]] == 0
  2603.               && occupied[faces[i][11]] == 0
  2604.               && occupied[faces[i][15]] == 0
  2605.               && occupied[faces[i][16]] == 0) {
  2606.             pos = faces[i][11];
  2607.             occupied[pos] = MACHINE;
  2608.             positions.set(pos, MACHINE);
  2609.             player = update_logic_arrays(pos);
  2610.             if (debug)
  2611.               System.out.println("block_chair_move: found");
  2612.             return true;
  2613.           }
  2614.           if (occupied[faces[i][12]] == HUMAN
  2615.               && occupied[faces[i][4]] == 0
  2616.               && occupied[faces[i][8]] == 0
  2617.               && occupied[faces[i][11]] == 0
  2618.               && occupied[faces[i][15]] == 0
  2619.               && occupied[faces[i][16]] == 0) {
  2620.             pos = faces[i][16];
  2621.             occupied[pos] = MACHINE;
  2622.             positions.set(pos, MACHINE);
  2623.             player = update_logic_arrays(pos);
  2624.             if (debug)
  2625.               System.out.println("block_chair_move: found");
  2626.             return true;
  2627.           }
  2628.         } else if (corner == 5) {
  2629.           if (occupied[faces[i][9]] == HUMAN
  2630.               && occupied[faces[i][6]] == 0
  2631.               && occupied[faces[i][7]] == 0
  2632.               && occupied[faces[i][8]] == 0
  2633.               && occupied[faces[i][10]] == 0
  2634.               && occupied[faces[i][12]] == 0) {
  2635.             pos = faces[i][7];
  2636.             occupied[pos] = MACHINE;
  2637.             positions.set(pos, MACHINE);
  2638.             player = update_logic_arrays(pos);
  2639.             if (debug)
  2640.               System.out.println("block_chair_move: found");
  2641.             return true;
  2642.           }
  2643.           if (occupied[faces[i][13]] == HUMAN
  2644.               && occupied[faces[i][7]] == 0
  2645.               && occupied[faces[i][7]] == 0
  2646.               && occupied[faces[i][10]] == 0
  2647.               && occupied[faces[i][11]] == 0
  2648.               && occupied[faces[i][12]] == 0) {
  2649.             pos = faces[i][12];
  2650.             occupied[pos] = MACHINE;
  2651.             positions.set(pos, MACHINE);
  2652.             player = update_logic_arrays(pos);
  2653.             if (debug)
  2654.               System.out.println("block_chair_move: found");
  2655.             return true;
  2656.           }
  2657.           if (occupied[faces[i][4]] == HUMAN
  2658.               && occupied[faces[i][8]] == 0
  2659.               && occupied[faces[i][11]] == 0
  2660.               && occupied[faces[i][12]] == 0
  2661.               && occupied[faces[i][15]] == 0
  2662.               && occupied[faces[i][16]] == 0) {
  2663.             pos = faces[i][12];
  2664.             occupied[pos] = MACHINE;
  2665.             positions.set(pos, MACHINE);
  2666.             player = update_logic_arrays(pos);
  2667.             if (debug)
  2668.               System.out.println("block_chair_move: found");
  2669.             return true;
  2670.           }
  2671.           if (occupied[faces[i][3]] == HUMAN
  2672.               && occupied[faces[i][7]] == 0
  2673.               && occupied[faces[i][11]] == 0
  2674.               && occupied[faces[i][12]] == 0
  2675.               && occupied[faces[i][15]] == 0
  2676.               && occupied[faces[i][16]] == 0) {
  2677.             pos = faces[i][7];
  2678.             occupied[pos] = MACHINE;
  2679.             positions.set(pos, MACHINE);
  2680.             player = update_logic_arrays(pos);
  2681.             if (debug)
  2682.               System.out.println("block_chair_move: found");
  2683.             return true;
  2684.           }
  2685.           if (occupied[faces[i][8]] == HUMAN
  2686.               && occupied[faces[i][4]] == 0
  2687.               && occupied[faces[i][11]] == 0
  2688.               && occupied[faces[i][12]] == 0
  2689.               && occupied[faces[i][15]] == 0
  2690.               && occupied[faces[i][16]] == 0) {
  2691.             pos = faces[i][12];
  2692.             occupied[pos] = MACHINE;
  2693.             positions.set(pos, MACHINE);
  2694.             player = update_logic_arrays(pos);
  2695.             if (debug)
  2696.               System.out.println("block_chair_move: found");
  2697.             return true;
  2698.           }
  2699.           if (occupied[faces[i][11]] == HUMAN
  2700.               && occupied[faces[i][3]] == 0
  2701.               && occupied[faces[i][7]] == 0
  2702.               && occupied[faces[i][12]] == 0
  2703.               && occupied[faces[i][15]] == 0
  2704.               && occupied[faces[i][16]] == 0) {
  2705.             pos = faces[i][7];
  2706.             occupied[pos] = MACHINE;
  2707.             positions.set(pos, MACHINE);
  2708.             player = update_logic_arrays(pos);
  2709.             if (debug)
  2710.               System.out.println("block_chair_move: found");
  2711.             return true;
  2712.           }
  2713.         } else if (corner == 14) {
  2714.           if (occupied[faces[i][6]] == HUMAN
  2715.               && occupied[faces[i][7]] == 0
  2716.               && occupied[faces[i][8]] == 0
  2717.               && occupied[faces[i][9]] == 0
  2718.               && occupied[faces[i][11]] == 0
  2719.               && occupied[faces[i][13]] == 0) {
  2720.             pos = faces[i][7];
  2721.             occupied[pos] = MACHINE;
  2722.             positions.set(pos, MACHINE);
  2723.             player = update_logic_arrays(pos);
  2724.             if (debug)
  2725.               System.out.println("block_chair_move: found");
  2726.             return true;
  2727.           }
  2728.           if (occupied[faces[i][10]] == HUMAN
  2729.               && occupied[faces[i][8]] == 0
  2730.               && occupied[faces[i][9]] == 0
  2731.               && occupied[faces[i][11]] == 0
  2732.               && occupied[faces[i][12]] == 0
  2733.               && occupied[faces[i][13]] == 0) {
  2734.             pos = faces[i][12];
  2735.             occupied[pos] = MACHINE;
  2736.             positions.set(pos, MACHINE);
  2737.             player = update_logic_arrays(pos);
  2738.             if (debug)
  2739.               System.out.println("block_chair_move: found");
  2740.             return true;
  2741.           }
  2742.           if (occupied[faces[i][15]] == HUMAN
  2743.               && occupied[faces[i][3]] == 0
  2744.               && occupied[faces[i][4]] == 0
  2745.               && occupied[faces[i][7]] == 0
  2746.               && occupied[faces[i][11]] == 0
  2747.               && occupied[faces[i][12]] == 0) {
  2748.             pos = faces[i][3];
  2749.             occupied[pos] = MACHINE;
  2750.             positions.set(pos, MACHINE);
  2751.             player = update_logic_arrays(pos);
  2752.             if (debug)
  2753.               System.out.println("block_chair_move: found");
  2754.             return true;
  2755.           }
  2756.           if (occupied[faces[i][16]] == HUMAN
  2757.               && occupied[faces[i][3]] == 0
  2758.               && occupied[faces[i][4]] == 0
  2759.               && occupied[faces[i][7]] == 0
  2760.               && occupied[faces[i][8]] == 0
  2761.               && occupied[faces[i][12]] == 0) {
  2762.             pos = faces[i][12];
  2763.             occupied[pos] = MACHINE;
  2764.             positions.set(pos, MACHINE);
  2765.             player = update_logic_arrays(pos);
  2766.             if (debug)
  2767.               System.out.println("block_chair_move: found");
  2768.             return true;
  2769.           }
  2770.           if (occupied[faces[i][11]] == HUMAN
  2771.               && occupied[faces[i][3]] == 0
  2772.               && occupied[faces[i][4]] == 0
  2773.               && occupied[faces[i][7]] == 0
  2774.               && occupied[faces[i][12]] == 0
  2775.               && occupied[faces[i][15]] == 0) {
  2776.             pos = faces[i][7];
  2777.             occupied[pos] = MACHINE;
  2778.             positions.set(pos, MACHINE);
  2779.             player = update_logic_arrays(pos);
  2780.             if (debug)
  2781.               System.out.println("block_chair_move: found");
  2782.             return true;
  2783.           }
  2784.           if (occupied[faces[i][8]] == HUMAN
  2785.               && occupied[faces[i][6]] == 0
  2786.               && occupied[faces[i][7]] == 0
  2787.               && occupied[faces[i][9]] == 0
  2788.               && occupied[faces[i][12]] == 0
  2789.               && occupied[faces[i][13]] == 0) {
  2790.             pos = faces[i][7];
  2791.             occupied[pos] = MACHINE;
  2792.             positions.set(pos, MACHINE);
  2793.             player = update_logic_arrays(pos);
  2794.             if (debug)
  2795.               System.out.println("block_chair_move: found");
  2796.             return true;
  2797.           }
  2798.         } else if (corner == 17) {
  2799.           if (occupied[faces[i][9]] == HUMAN
  2800.               && occupied[faces[i][6]] == 0
  2801.               && occupied[faces[i][7]] == 0
  2802.               && occupied[faces[i][8]] == 0
  2803.               && occupied[faces[i][10]] == 0
  2804.               && occupied[faces[i][11]] == 0) {
  2805.             pos = faces[i][8];
  2806.             occupied[pos] = MACHINE;
  2807.             positions.set(pos, MACHINE);
  2808.             player = update_logic_arrays(pos);
  2809.             if (debug)
  2810.               System.out.println("block_chair_move: found");
  2811.             return true;
  2812.           }
  2813.           if (occupied[faces[i][13]] == HUMAN
  2814.               && occupied[faces[i][6]] == 0
  2815.               && occupied[faces[i][8]] == 0
  2816.               && occupied[faces[i][10]] == 0
  2817.               && occupied[faces[i][11]] == 0
  2818.               && occupied[faces[i][12]] == 0) {
  2819.             pos = faces[i][11];
  2820.             occupied[pos] = MACHINE;
  2821.             positions.set(pos, MACHINE);
  2822.             player = update_logic_arrays(pos);
  2823.             if (debug)
  2824.               System.out.println("block_chair_move: found");
  2825.             return true;
  2826.           }
  2827.           if (occupied[faces[i][15]] == HUMAN
  2828.               && occupied[faces[i][3]] == 0
  2829.               && occupied[faces[i][4]] == 0
  2830.               && occupied[faces[i][7]] == 0
  2831.               && occupied[faces[i][8]] == 0
  2832.               && occupied[faces[i][11]] == 0) {
  2833.             pos = faces[i][11];
  2834.             occupied[pos] = MACHINE;
  2835.             positions.set(pos, MACHINE);
  2836.             player = update_logic_arrays(pos);
  2837.             if (debug)
  2838.               System.out.println("block_chair_move: found");
  2839.             return true;
  2840.           }
  2841.           if (occupied[faces[i][16]] == HUMAN
  2842.               && occupied[faces[i][3]] == 0
  2843.               && occupied[faces[i][4]] == 0
  2844.               && occupied[faces[i][8]] == 0
  2845.               && occupied[faces[i][11]] == 0
  2846.               && occupied[faces[i][12]] == 0) {
  2847.             pos = faces[i][8];
  2848.             occupied[pos] = MACHINE;
  2849.             positions.set(pos, MACHINE);
  2850.             player = update_logic_arrays(pos);
  2851.             if (debug)
  2852.               System.out.println("block_chair_move: found");
  2853.             return true;
  2854.           }
  2855.           if (occupied[faces[i][12]] == HUMAN
  2856.               && occupied[faces[i][3]] == 0
  2857.               && occupied[faces[i][4]] == 0
  2858.               && occupied[faces[i][8]] == 0
  2859.               && occupied[faces[i][11]] == 0
  2860.               && occupied[faces[i][16]] == 0) {
  2861.             pos = faces[i][8];
  2862.             occupied[pos] = MACHINE;
  2863.             positions.set(pos, MACHINE);
  2864.             player = update_logic_arrays(pos);
  2865.             if (debug)
  2866.               System.out.println("block_chair_move: found");
  2867.             return true;
  2868.           }
  2869.           if (occupied[faces[i][7]] == HUMAN
  2870.               && occupied[faces[i][3]] == 0
  2871.               && occupied[faces[i][4]] == 0
  2872.               && occupied[faces[i][8]] == 0
  2873.               && occupied[faces[i][11]] == 0
  2874.               && occupied[faces[i][15]] == 0) {
  2875.             pos = faces[i][11];
  2876.             occupied[pos] = MACHINE;
  2877.             positions.set(pos, MACHINE);
  2878.             player = update_logic_arrays(pos);
  2879.             if (debug)
  2880.               System.out.println("block_chair_move: found");
  2881.             return true;
  2882.           }
  2883.         }
  2884.       }
  2885.       ncorners = 0;
  2886.       corner = -1;
  2887.     }
  2888.     if (debug)
  2889.       System.out.println("block_chair_move: false");
  2890.     return false;
  2891.   }
  2892.  
  2893.   public boolean block_walk_move() {
  2894.  
  2895.     int pos;
  2896.  
  2897.     if (debug)
  2898.       System.out.println("inside block_walk_move");
  2899.  
  2900.     // Loop through all of the faces.
  2901.     for (int i = 0; i < 18; i++) {
  2902.  
  2903.       // Look for a matching pattern.
  2904.       if (occupied[faces[i][2]] == HUMAN
  2905.           && occupied[faces[i][14]] == HUMAN
  2906.           && occupied[faces[i][3]] == HUMAN
  2907.           && occupied[faces[i][15]] == HUMAN
  2908.           && occupied[faces[i][6]] == 0
  2909.           && occupied[faces[i][10]] == 0
  2910.           && occupied[faces[i][7]] == 0
  2911.           && occupied[faces[i][11]] == 0) {
  2912.  
  2913.         if (occupied[faces[i][8]] == HUMAN
  2914.             && occupied[faces[i][9]] == 0) {
  2915.           pos = faces[i][6];
  2916.           occupied[pos] = MACHINE;
  2917.           positions.set(pos, MACHINE);
  2918.           player = update_logic_arrays(pos);
  2919.           return true;
  2920.         } else if (occupied[faces[i][12]] == HUMAN
  2921.             && occupied[faces[i][13]] == 0) {
  2922.           pos = faces[i][10];
  2923.           occupied[pos] = MACHINE;
  2924.           positions.set(pos, MACHINE);
  2925.           player = update_logic_arrays(pos);
  2926.           return true;
  2927.         }
  2928.       }
  2929.  
  2930.       // Look for a matching pattern.
  2931.       if (occupied[faces[i][14]] == HUMAN
  2932.           && occupied[faces[i][17]] == HUMAN
  2933.           && occupied[faces[i][10]] == HUMAN
  2934.           && occupied[faces[i][13]] == HUMAN
  2935.           && occupied[faces[i][15]] == 0
  2936.           && occupied[faces[i][16]] == 0
  2937.           && occupied[faces[i][11]] == 0
  2938.           && occupied[faces[i][12]] == 0) {
  2939.  
  2940.         if (occupied[faces[i][7]] == HUMAN
  2941.             && occupied[faces[i][3]] == 0) {
  2942.           pos = faces[i][15];
  2943.           occupied[pos] = MACHINE;
  2944.           positions.set(pos, MACHINE);
  2945.           player = update_logic_arrays(pos);
  2946.           return true;
  2947.         } else if (occupied[faces[i][8]] == HUMAN
  2948.             && occupied[faces[i][4]] == 0) {
  2949.           pos = faces[i][16];
  2950.           occupied[pos] = MACHINE;
  2951.           positions.set(pos, MACHINE);
  2952.           player = update_logic_arrays(pos);
  2953.           return true;
  2954.         }
  2955.       }
  2956.  
  2957.       // Look for a matching pattern.
  2958.       if (occupied[faces[i][4]] == HUMAN
  2959.           && occupied[faces[i][16]] == HUMAN
  2960.           && occupied[faces[i][5]] == HUMAN
  2961.           && occupied[faces[i][17]] == HUMAN
  2962.           && occupied[faces[i][8]] == 0
  2963.           && occupied[faces[i][12]] == 0
  2964.           && occupied[faces[i][9]] == 0
  2965.           && occupied[faces[i][13]] == 0) {
  2966.  
  2967.         if (occupied[faces[i][11]] == HUMAN
  2968.             && occupied[faces[i][10]] == 0) {
  2969.           pos = faces[i][18];
  2970.           occupied[pos] = MACHINE;
  2971.           positions.set(pos, MACHINE);
  2972.           player = update_logic_arrays(pos);
  2973.           return true;
  2974.         } else if (occupied[faces[i][7]] == HUMAN
  2975.             && occupied[faces[i][6]] == 0) {
  2976.           pos = faces[i][9];
  2977.           occupied[pos] = MACHINE;
  2978.           positions.set(pos, MACHINE);
  2979.           player = update_logic_arrays(pos);
  2980.           return true;
  2981.         }
  2982.       }
  2983.  
  2984.       // Look for a matching pattern.
  2985.       if (occupied[faces[i][6]] == HUMAN
  2986.           && occupied[faces[i][9]] == HUMAN
  2987.           && occupied[faces[i][2]] == HUMAN
  2988.           && occupied[faces[i][5]] == HUMAN
  2989.           && occupied[faces[i][7]] == 0 && occupied[faces[i][8]] == 0
  2990.           && occupied[faces[i][3]] == 0 && occupied[faces[i][4]] == 0) {
  2991.  
  2992.         if (occupied[faces[i][11]] == HUMAN
  2993.             && occupied[faces[i][15]] == 0) {
  2994.           pos = faces[i][3];
  2995.           occupied[pos] = MACHINE;
  2996.           positions.set(pos, MACHINE);
  2997.           player = update_logic_arrays(pos);
  2998.           return true;
  2999.         } else if (occupied[faces[i][12]] == HUMAN
  3000.             && occupied[faces[i][16]] == 0) {
  3001.           pos = faces[i][4];
  3002.           occupied[pos] = MACHINE;
  3003.           positions.set(pos, MACHINE);
  3004.           player = update_logic_arrays(pos);
  3005.           return true;
  3006.         }
  3007.       }
  3008.  
  3009.       // Look for a matching pattern.
  3010.       if (occupied[faces[i][2]] == HUMAN
  3011.           && occupied[faces[i][14]] == HUMAN
  3012.           && occupied[faces[i][4]] == HUMAN
  3013.           && occupied[faces[i][16]] == HUMAN
  3014.           && occupied[faces[i][6]] == 0
  3015.           && occupied[faces[i][10]] == 0
  3016.           && occupied[faces[i][8]] == 0
  3017.           && occupied[faces[i][12]] == 0) {
  3018.  
  3019.         if ((occupied[faces[i][7]] == HUMAN && occupied[faces[i][9]] == 0)
  3020.             || (occupied[faces[i][9]] == HUMAN && occupied[faces[i][7]] == 0)) {
  3021.           pos = faces[i][6];
  3022.           occupied[pos] = MACHINE;
  3023.           positions.set(pos, MACHINE);
  3024.           player = update_logic_arrays(pos);
  3025.           return true;
  3026.         } else if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][13]] == 0)
  3027.             || (occupied[faces[i][13]] == HUMAN && occupied[faces[i][11]] == 0)) {
  3028.           pos = faces[i][10];
  3029.           occupied[pos] = MACHINE;
  3030.           positions.set(pos, MACHINE);
  3031.           player = update_logic_arrays(pos);
  3032.           return true;
  3033.         }
  3034.       }
  3035.  
  3036.       // Look for a matching pattern.
  3037.       if (occupied[faces[i][14]] == HUMAN
  3038.           && occupied[faces[i][17]] == HUMAN
  3039.           && occupied[faces[i][6]] == HUMAN
  3040.           && occupied[faces[i][9]] == HUMAN
  3041.           && occupied[faces[i][15]] == 0
  3042.           && occupied[faces[i][16]] == 0
  3043.           && occupied[faces[i][7]] == 0 && occupied[faces[i][8]] == 0) {
  3044.  
  3045.         if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][3]] == 0)
  3046.             || (occupied[faces[i][3]] == HUMAN && occupied[faces[i][11]] == 0)) {
  3047.           pos = faces[i][15];
  3048.           occupied[pos] = MACHINE;
  3049.           positions.set(pos, MACHINE);
  3050.           player = update_logic_arrays(pos);
  3051.           return true;
  3052.         } else if ((occupied[faces[i][12]] == HUMAN && occupied[faces[i][4]] == 0)
  3053.             || (occupied[faces[i][4]] == HUMAN && occupied[faces[i][12]] == 0)) {
  3054.           pos = faces[i][16];
  3055.           occupied[pos] = MACHINE;
  3056.           positions.set(pos, MACHINE);
  3057.           player = update_logic_arrays(pos);
  3058.           return true;
  3059.         }
  3060.       }
  3061.  
  3062.       // Look for a matching pattern.
  3063.       if (occupied[faces[i][3]] == HUMAN
  3064.           && occupied[faces[i][15]] == HUMAN
  3065.           && occupied[faces[i][5]] == HUMAN
  3066.           && occupied[faces[i][17]] == HUMAN
  3067.           && occupied[faces[i][7]] == 0
  3068.           && occupied[faces[i][11]] == 0
  3069.           && occupied[faces[i][9]] == 0
  3070.           && occupied[faces[i][13]] == 0) {
  3071.  
  3072.         if ((occupied[faces[i][6]] == HUMAN && occupied[faces[i][8]] == 0)
  3073.             || (occupied[faces[i][8]] == HUMAN && occupied[faces[i][6]] == 0)) {
  3074.           pos = faces[i][9];
  3075.           occupied[pos] = MACHINE;
  3076.           positions.set(pos, MACHINE);
  3077.           player = update_logic_arrays(pos);
  3078.           return true;
  3079.         } else if ((occupied[faces[i][10]] == HUMAN && occupied[faces[i][12]] == 0)
  3080.             || (occupied[faces[i][12]] == HUMAN && occupied[faces[i][10]] == 0)) {
  3081.           pos = faces[i][13];
  3082.           occupied[pos] = MACHINE;
  3083.           positions.set(pos, MACHINE);
  3084.           player = update_logic_arrays(pos);
  3085.           return true;
  3086.         }
  3087.       }
  3088.  
  3089.       // Look for a matching pattern.
  3090.       if (occupied[faces[i][10]] == HUMAN
  3091.           && occupied[faces[i][13]] == HUMAN
  3092.           && occupied[faces[i][2]] == HUMAN
  3093.           && occupied[faces[i][5]] == HUMAN
  3094.           && occupied[faces[i][11]] == 0
  3095.           && occupied[faces[i][12]] == 0
  3096.           && occupied[faces[i][3]] == 0 && occupied[faces[i][4]] == 0) {
  3097.  
  3098.         if ((occupied[faces[i][7]] == HUMAN && occupied[faces[i][15]] == 0)
  3099.             || (occupied[faces[i][15]] == HUMAN && occupied[faces[i][7]] == 0)) {
  3100.           pos = faces[i][3];
  3101.           occupied[pos] = MACHINE;
  3102.           positions.set(pos, MACHINE);
  3103.           player = update_logic_arrays(pos);
  3104.           return true;
  3105.         } else if ((occupied[faces[i][8]] == HUMAN && occupied[faces[i][16]] == 0)
  3106.             || (occupied[faces[i][16]] == HUMAN && occupied[faces[i][8]] == 0)) {
  3107.           pos = faces[i][4];
  3108.           occupied[pos] = MACHINE;
  3109.           positions.set(pos, MACHINE);
  3110.           player = update_logic_arrays(pos);
  3111.           return true;
  3112.         }
  3113.       }
  3114.  
  3115.     }
  3116.  
  3117.     if (debug)
  3118.       System.out.println("block_walk_move: false");
  3119.     return false;
  3120.   }
  3121.  
  3122.   public boolean check_chair_move() {
  3123.  
  3124.     int pos;
  3125.  
  3126.     // If the "block chair flag" is set, all we need to do is
  3127.     // block the winning path...
  3128.     if (block_chair_flag) {
  3129.       pos = faces[block_chair_face][block_chair_next_move];
  3130.       occupied[pos] = MACHINE;
  3131.       positions.set(pos, MACHINE);
  3132.       player = update_logic_arrays(pos);
  3133.       if (debug)
  3134.         System.out.println("block_chair_move: march");
  3135.       return true;
  3136.     }
  3137.  
  3138.     int ncorners = 0; // Number of corners owned by human
  3139.     int corner = 0; // Corner owned by machine
  3140.  
  3141.     // Loop through all of the faces.
  3142.     for (int i = 0; i < 18; i++) {
  3143.  
  3144.       // Determine which corners the human owns.
  3145.       if (faces[i][2] == HUMAN)
  3146.         ncorners++;
  3147.       else
  3148.         corner = 2;
  3149.       if (faces[i][5] == HUMAN)
  3150.         ncorners++;
  3151.       else
  3152.         corner = 5;
  3153.       if (faces[i][14] == HUMAN)
  3154.         ncorners++;
  3155.       else
  3156.         corner = 14;
  3157.       if (faces[i][17] == HUMAN)
  3158.         ncorners++;
  3159.       else
  3160.         corner = 17;
  3161.  
  3162.       // If the human owns three corners, continue with the search.
  3163.       if (ncorners == 3) {
  3164.         if (corner == 2) {
  3165.           if (faces[i][3] == HUMAN && faces[i][7] == 0
  3166.               && faces[i][8] == 0 && faces[i][11] == 0
  3167.               && faces[i][15] == 0 && faces[i][16] == 0) {
  3168.             block_chair_flag = true;
  3169.             block_chair_next_move = 11;
  3170.             block_chair_face = i;
  3171.             pos = faces[i][15];
  3172.             occupied[pos] = MACHINE;
  3173.             positions.set(pos, MACHINE);
  3174.             player = update_logic_arrays(pos);
  3175.             if (debug)
  3176.               System.out.println("block_chair_move: found");
  3177.             return true;
  3178.           }
  3179.           if (faces[i][4] == HUMAN && faces[i][8] == 0
  3180.               && faces[i][11] == 0 && faces[i][12] == 0
  3181.               && faces[i][15] == 0 && faces[i][16] == 0) {
  3182.             block_chair_flag = true;
  3183.             block_chair_next_move = 16;
  3184.             block_chair_face = i;
  3185.             pos = faces[i][8];
  3186.             occupied[pos] = MACHINE;
  3187.             positions.set(pos, MACHINE);
  3188.             player = update_logic_arrays(pos);
  3189.             if (debug)
  3190.               System.out.println("block_chair_move: found");
  3191.             return true;
  3192.           }
  3193.         } else if (corner == 5) {
  3194.           block_chair_flag = true;
  3195.           block_chair_next_move = 11;
  3196.           block_chair_face = i;
  3197.           pos = faces[i][15];
  3198.           occupied[pos] = MACHINE;
  3199.           positions.set(pos, MACHINE);
  3200.           player = update_logic_arrays(pos);
  3201.           if (debug)
  3202.             System.out.println("check_face_three:  true");
  3203.           return true;
  3204.         } else if (corner == 14) {
  3205.           block_chair_flag = true;
  3206.           block_chair_next_move = 11;
  3207.           block_chair_face = i;
  3208.           pos = faces[i][15];
  3209.           occupied[pos] = MACHINE;
  3210.           positions.set(pos, MACHINE);
  3211.           player = update_logic_arrays(pos);
  3212.           if (debug)
  3213.             System.out.println("check_face_three:  true");
  3214.           return true;
  3215.         } else if (corner == 17) {
  3216.           block_chair_flag = true;
  3217.           block_chair_next_move = 11;
  3218.           block_chair_face = i;
  3219.           pos = faces[i][15];
  3220.           occupied[pos] = MACHINE;
  3221.           positions.set(pos, MACHINE);
  3222.           player = update_logic_arrays(pos);
  3223.           if (debug)
  3224.             System.out.println("check_face_three:  true");
  3225.           return true;
  3226.         }
  3227.       }
  3228.     }
  3229.     return false;
  3230.   }
  3231.  
  3232.   /**
  3233.    * Take inside four
  3234.    */
  3235.   public boolean take_inside_four() {
  3236.  
  3237.     int pos = 0;
  3238.     boolean found = false;
  3239.  
  3240.     if (occupied[21] == 0) {
  3241.       found = true;
  3242.       pos = 21;
  3243.     } else if (occupied[22] == 0) {
  3244.       found = true;
  3245.       pos = 22;
  3246.     } else if (occupied[25] == 0) {
  3247.       found = true;
  3248.       pos = 25;
  3249.     } else if (occupied[26] == 0) {
  3250.       found = true;
  3251.       pos = 26;
  3252.     } else if (occupied[37] == 0) {
  3253.       found = true;
  3254.       pos = 37;
  3255.     } else if (occupied[38] == 0) {
  3256.       found = true;
  3257.       pos = 38;
  3258.     } else if (occupied[41] == 0) {
  3259.       found = true;
  3260.       pos = 41;
  3261.     } else if (occupied[42] == 0) {
  3262.       found = true;
  3263.       pos = 42;
  3264.     }
  3265.  
  3266.     if (found) {
  3267.       occupied[pos] = MACHINE;
  3268.       positions.set(pos, MACHINE);
  3269.       player = update_logic_arrays(pos);
  3270.       if (debug)
  3271.         System.out.println("take_inside_four:  true");
  3272.       return true;
  3273.     }
  3274.  
  3275.     if (debug)
  3276.       System.out.println("take_inside_four:  false");
  3277.     return false;
  3278.   }
  3279.  
  3280.   /**
  3281.    * Check occupancy of outside four.
  3282.    */
  3283.   public boolean check_outside_four() {
  3284.  
  3285.     int pos = 0;
  3286.  
  3287.     // Finish off the four corner combination.
  3288.     if (outside_four_flag) {
  3289.       if (occupied[faces[face_index][7]] == 0) {
  3290.         pos = faces[face_index][7];
  3291.       } else if (occupied[faces[face_index][6]] == 0) {
  3292.         pos = faces[face_index][6];
  3293.       }
  3294.  
  3295.       if (occupied[pos] == 0) {
  3296.         occupied[pos] = MACHINE;
  3297.         positions.set(pos, MACHINE);
  3298.         player = update_logic_arrays(pos);
  3299.         return true;
  3300.       }
  3301.     }
  3302.  
  3303.     // Look for a four corner combination.
  3304.     for (int i = 0; i < 18; i++) {
  3305.       if (outside_four[i][0] == 4 && outside_four[i][1] == MACHINE) {
  3306.         if (faces[i][0] > 0 && faces[i][1] == MACHINE) {
  3307.           if (occupied[faces[i][8]] == 0) {
  3308.             pos = faces[i][8];
  3309.             outside_four_flag = true;
  3310.             face_index = i;
  3311.           }
  3312.           if (occupied[pos] == 0) {
  3313.             occupied[pos] = MACHINE;
  3314.             positions.set(pos, MACHINE);
  3315.             player = update_logic_arrays(pos);
  3316.             if (debug)
  3317.               System.out.println("check_outside_four:  true");
  3318.             return true;
  3319.           }
  3320.         }
  3321.       }
  3322.     }
  3323.  
  3324.     // Take the corners, if available.
  3325.     for (int i = 0; i < 18; i++) {
  3326.       if (outside_four[i][0] > 0 && outside_four[i][1] == MACHINE) {
  3327.         if (faces[i][0] > 0 && faces[i][1] == MACHINE) {
  3328.           for (int j = 2; j < 6; j++) {
  3329.             pos = outside_four[i][j];
  3330.             if (occupied[pos] == 0) {
  3331.               occupied[pos] = MACHINE;
  3332.               positions.set(pos, MACHINE);
  3333.               player = update_logic_arrays(pos);
  3334.               if (debug)
  3335.                 System.out.println("check_outside_four:  true");
  3336.               return true;
  3337.             }
  3338.           }
  3339.         }
  3340.       }
  3341.     }
  3342.  
  3343.     // Look for an "outside four" combination in a face in which the
  3344.     // opponent holds no positions.
  3345.     for (int i = 0; i < 18; i++) {
  3346.       if (outside_four[i][0] == 0
  3347.           || (outside_four[i][0] > 0 && outside_four[i][1] == MACHINE)) {
  3348.  
  3349.         if (outside_four[i][1] == MACHINE)
  3350.           outside_four_flag = true;
  3351.         for (int j = 2; j < 6; j++) {
  3352.           pos = outside_four[i][j];
  3353.           if (occupied[pos] == 0) {
  3354.             occupied[pos] = MACHINE;
  3355.             positions.set(pos, MACHINE);
  3356.             player = update_logic_arrays(pos);
  3357.             if (debug)
  3358.               System.out.println("check_outside_four:  true");
  3359.             return true;
  3360.           }
  3361.         }
  3362.       }
  3363.     }
  3364.  
  3365.     if (debug)
  3366.       System.out.println("check_outside_four:  false");
  3367.     return false;
  3368.   }
  3369.  
  3370.   /**
  3371.    * Take outside four
  3372.    */
  3373.   public boolean take_outside_four() {
  3374.  
  3375.     int pos = 0;
  3376.     boolean found = false;
  3377.  
  3378.     if (occupied[0] == 0) {
  3379.       found = true;
  3380.       pos = 0;
  3381.     } else if (occupied[3] == 0) {
  3382.       found = true;
  3383.       pos = 3;
  3384.     } else if (occupied[12] == 0) {
  3385.       found = true;
  3386.       pos = 12;
  3387.     } else if (occupied[15] == 0) {
  3388.       found = true;
  3389.       pos = 15;
  3390.     } else if (occupied[48] == 0) {
  3391.       found = true;
  3392.       pos = 48;
  3393.     } else if (occupied[51] == 0) {
  3394.       found = true;
  3395.       pos = 51;
  3396.     } else if (occupied[60] == 0) {
  3397.       found = true;
  3398.       pos = 60;
  3399.     } else if (occupied[63] == 0) {
  3400.       found = true;
  3401.       pos = 63;
  3402.     }
  3403.  
  3404.     if (found) {
  3405.       occupied[pos] = MACHINE;
  3406.       positions.set(pos, MACHINE);
  3407.       player = update_logic_arrays(pos);
  3408.       if (debug)
  3409.         System.out.println("take_outside_four:  true");
  3410.       return true;
  3411.     }
  3412.  
  3413.     if (debug)
  3414.       System.out.println("take_outside_four:  false");
  3415.     return false;
  3416.   }
  3417.  
  3418.   /**
  3419.    * Check for a forced win by intersecting rows. Block if necessary.
  3420.    */
  3421.   public boolean block_intersecting_rows() {
  3422.  
  3423.     int pos;
  3424.  
  3425.     // Loop through each row and check for rows that have two
  3426.     // positions occupied by the human and two positions which are empty.
  3427.     // Make sure that none of the empty positions in this row intersect
  3428.     // with another row that also contains two positions held by the human.
  3429.     // If so, block the row by taking the position at the intersection
  3430.     // of these two row.
  3431.  
  3432.     // Loop through each row.
  3433.     for (int i = 0; i < 76; i++) {
  3434.  
  3435.       // Look for a row that has two positions held by the human.
  3436.       if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) {
  3437.  
  3438.         if (debug)
  3439.           System.out.println("   row " + i
  3440.               + "has 2 positions occupied by the human");
  3441.  
  3442.         // Mark this row with a flag.
  3443.         combinations[i][6] = 1;
  3444.  
  3445.         // Check each position in the row.
  3446.         for (int j = 2; j < 6; j++) {
  3447.  
  3448.           // Look for the empty positions in the row.
  3449.           pos = combinations[i][j];
  3450.           if (occupied[pos] == 0) {
  3451.  
  3452.             // Loop through the rows again.
  3453.             for (int k = 0; k < 76; k++) {
  3454.  
  3455.               if (debug)
  3456.                 System.out.println("   row " + k);
  3457.  
  3458.               // Look for another row that has two positions held
  3459.               // by the human (and which is unmarked.) modified
  3460.               if (combinations[k][0] == 2
  3461.                   && combinations[k][1] == HUMAN
  3462.                   && combinations[k][6] == 0) {
  3463.  
  3464.                 if (debug)
  3465.                   System.out
  3466.                       .println("found an intersecting row:   row "
  3467.                           + k);
  3468.  
  3469.                 // Check the positions in this row and see if
  3470.                 // any match the position we're looking for. If
  3471.                 // we find a match, grab the position and
  3472.                 // return.
  3473.                 for (int l = 2; l < 6; l++) {
  3474.                   if (pos == combinations[k][l]) {
  3475.                     combinations[i][6] = 0;
  3476.                     occupied[pos] = MACHINE;
  3477.                     positions.set(pos, MACHINE);
  3478.                     player = update_logic_arrays(pos);
  3479.                     if (debug)
  3480.                       System.out
  3481.                           .println("block_intersecting_rows:  true");
  3482.                     return true;
  3483.                   }
  3484.                 }
  3485.               }
  3486.             }
  3487.           }
  3488.         }
  3489.  
  3490.         // Unmark the combination before moving on.
  3491.         combinations[i][6] = 0;
  3492.       }
  3493.  
  3494.     }
  3495.     if (debug)
  3496.       System.out.println("block_intersecting_rows:  false");
  3497.     return false;
  3498.   }
  3499.  
  3500.   /**
  3501.    * Check for a forced win by intersecting rows. Block if necessary.
  3502.    */
  3503.   public boolean check_intersecting_rows2() {
  3504.  
  3505.     int pos;
  3506.  
  3507.     // Loop through each row and check for rows that have two
  3508.     // positions occupied by the human and two positions which are empty.
  3509.     // Make sure that none of the empty positions in this row intersect
  3510.     // with another row that also contains two positions held by the human.
  3511.     // If so, block the row by taking the position at the intersection
  3512.     // of these two row.
  3513.  
  3514.     // Loop through each row.
  3515.     for (int i = 0; i < 76; i++) {
  3516.  
  3517.       // Look for a row that has two positions held by the human.
  3518.       if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) {
  3519.  
  3520.         if (debug) {
  3521.           System.out.println("   row " + i
  3522.               + "has 2 positions occupied by the human");
  3523.         }
  3524.  
  3525.         // Mark this row with a flag.
  3526.         combinations[i][6] = 1;
  3527.  
  3528.         // Check each position in the row.
  3529.         for (int j = 2; j < 6; j++) {
  3530.  
  3531.           // Look for the empty positions in the row.
  3532.           pos = combinations[i][j];
  3533.           if (occupied[pos] == 0) {
  3534.  
  3535.             // Loop through the rows again.
  3536.             for (int k = 0; k < 76; k++) {
  3537.  
  3538.               if (debug)
  3539.                 System.out.println("   row " + k);
  3540.  
  3541.               // Look for another row that has two positions held
  3542.               // by the human (and which is unmarked.) modified
  3543.               if (combinations[k][0] == 1
  3544.                   && combinations[k][1] == HUMAN
  3545.                   && combinations[k][6] == 0) {
  3546.  
  3547.                 if (debug)
  3548.                   System.out
  3549.                       .println("found an intersecting row:   row "
  3550.                           + k);
  3551.  
  3552.                 // Check the positions in this row and see if
  3553.                 // any match the position we're looking for. If
  3554.                 // we find a match, grab the position and
  3555.                 // return.
  3556.                 for (int l = 2; l < 6; l++) {
  3557.                   if (pos == combinations[k][l]) {
  3558.                     combinations[i][6] = 0;
  3559.                     occupied[pos] = MACHINE;
  3560.                     positions.set(pos, MACHINE);
  3561.                     player = update_logic_arrays(pos);
  3562.                     if (debug)
  3563.                       System.out
  3564.                           .println("check_intersecting_rows:  true");
  3565.                     return true;
  3566.                   }
  3567.                 }
  3568.               }
  3569.             }
  3570.           }
  3571.         }
  3572.  
  3573.         // Unmark the combination before moving on.
  3574.         combinations[i][6] = 0;
  3575.       }
  3576.  
  3577.     }
  3578.     if (debug)
  3579.       System.out.println("check_intersecting_rows:  false");
  3580.     return false;
  3581.   }
  3582.  
  3583.   /**
  3584.    * Check for a forced win by intersecting rows. Block if necessary.
  3585.    */
  3586.   public boolean check_for_two() {
  3587.  
  3588.     int pos;
  3589.  
  3590.     // Loop through the rows.
  3591.     for (int i = 0; i < 76; i++) {
  3592.  
  3593.       // Look for a row that has two positions held
  3594.       // by the human (and which is unmarked.)
  3595.       if (combinations[i][0] == 2 && combinations[i][1] == HUMAN
  3596.           && combinations[i][6] == 0) {
  3597.  
  3598.         // Take the first available spot.
  3599.         for (int j = 2; j < 6; j++) {
  3600.           pos = combinations[i][j];
  3601.           if (occupied[pos] == 0) {
  3602.             occupied[pos] = MACHINE;
  3603.             positions.set(pos, MACHINE);
  3604.             player = update_logic_arrays(pos);
  3605.             if (debug)
  3606.               System.out.println("check_for_two:  true");
  3607.             return true;
  3608.           }
  3609.         }
  3610.  
  3611.       }
  3612.     }
  3613.     if (debug)
  3614.       System.out.println("check_for_two:  false");
  3615.     return false;
  3616.   }
  3617.  
  3618.   public void undo_move() {
  3619.  
  3620.     // Return if no moves are recorded
  3621.     if (nmoves == 0)
  3622.       return;
  3623.  
  3624.     // Set the undo flag
  3625.     undoFlag = true;
  3626.  
  3627.     // Undo the last two moves
  3628.     positions.clear(moves[--nmoves]);
  3629.     positions.clear(moves[--nmoves]);
  3630.  
  3631.     // Undo the winner flag in the positions object
  3632.     positions.noWinner();
  3633.  
  3634.     // Repaint the 2D canvas.
  3635.     canvas.repaint();
  3636.  
  3637.     // Reset the inside/outside flags
  3638.     inside_four_flag = false;
  3639.     outside_four_flag = false;
  3640.     block_chair_flag = false;
  3641.  
  3642.     // Reset the board
  3643.     for (int i = 0; i < 64; i++) {
  3644.       occupied[i] = 0;
  3645.     }
  3646.  
  3647.     // Reset the inside/outside arrays
  3648.     for (int i = 0; i < 18; i++) {
  3649.       inside_four[i][0] = 0;
  3650.       inside_four[i][1] = 0;
  3651.       outside_four[i][0] = 0;
  3652.       outside_four[i][1] = 0;
  3653.     }
  3654.  
  3655.     // Reset the faces array
  3656.     for (int i = 0; i < 18; i++) {
  3657.       faces[i][0] = 0;
  3658.       faces[i][1] = 0;
  3659.     }
  3660.  
  3661.     // Reset the combinations array
  3662.     for (int i = 0; i < 76; i++) {
  3663.       combinations[i][0] = 0;
  3664.       combinations[i][1] = 0;
  3665.     }
  3666.  
  3667.     if (nmoves == 0) {
  3668.       undoFlag = false;
  3669.       player = HUMAN;
  3670.       return;
  3671.     }
  3672.  
  3673.     // Update the logic arrays
  3674.     int pos;
  3675.     player = HUMAN;
  3676.     for (int i = 0; i < nmoves; i++) {
  3677.       pos = moves[i];
  3678.       occupied[pos] = player;
  3679.       player = update_logic_arrays(pos);
  3680.     }
  3681.  
  3682.     // Reset the "best picks" array
  3683.     update_best_picks();
  3684.  
  3685.     // Reset the player and undo flag
  3686.     player = HUMAN;
  3687.     undoFlag = false;
  3688.   }
  3689.  
  3690.   /**
  3691.    * Update the logic arrays that keep track of positions and status. If we
  3692.    * have a winner, stop the game.
  3693.    */
  3694.   public int update_logic_arrays(int pos) {
  3695.  
  3696.     // Record the move.
  3697.     if (!undoFlag) {
  3698.       moves[nmoves++] = pos;
  3699.     }
  3700.  
  3701.     // Get the number of combinations that this position has.
  3702.     int num_combinations = pos_to_comb[pos][0];
  3703.  
  3704.     // Go through each combination associated with this position
  3705.     // and update the status. If we have a winner, stop the game.
  3706.     int comb;
  3707.     for (int j = 0; j < num_combinations; j++) {
  3708.       comb = pos_to_comb[pos][j + 1];
  3709.       if (combinations[comb][1] != player && combinations[comb][1] != 0) {
  3710.         combinations[comb][0] = -1;
  3711.       } else {
  3712.         combinations[comb][0]++;
  3713.         if (combinations[comb][0] == 4) {
  3714.           end_time = System.currentTimeMillis();
  3715.           time = (end_time - beg_time) / 1000;
  3716.           panel.winner(player, skill_level, nmoves, time);
  3717.           panel.repaint();
  3718.           canvas.repaint();
  3719.           positions.winner();
  3720.           return END;
  3721.         } else {
  3722.           combinations[comb][1] = player;
  3723.         }
  3724.       }
  3725.     }
  3726.  
  3727.     // Update the best_picks array.
  3728.     update_best_picks();
  3729.  
  3730.     // Update the inside_four array.
  3731.     for (int i = 0; i < 18; i++) {
  3732.       for (int j = 2; j < 6; j++) {
  3733.         if (pos == inside_four[i][j]) {
  3734.           if (inside_four[i][0] == 0) {
  3735.             inside_four[i][0] = 1;
  3736.             inside_four[i][1] = player;
  3737.           } else if (inside_four[i][1] == player) {
  3738.             inside_four[i][0]++;
  3739.             inside_four[i][1] = player;
  3740.           } else {
  3741.             inside_four[i][0] = -1;
  3742.           }
  3743.         }
  3744.       }
  3745.     }
  3746.  
  3747.     // Update the outside_four array.
  3748.     for (int i = 0; i < 18; i++) {
  3749.       for (int j = 2; j < 6; j++) {
  3750.         if (pos == outside_four[i][j]) {
  3751.           if (outside_four[i][0] == 0) {
  3752.             outside_four[i][0] = 1;
  3753.             outside_four[i][1] = player;
  3754.           } else if (outside_four[i][1] == player) {
  3755.             outside_four[i][0]++;
  3756.             outside_four[i][1] = player;
  3757.           } else {
  3758.             outside_four[i][0] = -1;
  3759.           }
  3760.         }
  3761.       }
  3762.     }
  3763.  
  3764.     // Update the faces array.
  3765.     for (int i = 0; i < 18; i++) {
  3766.       for (int j = 2; j < 18; j++) {
  3767.         if (pos == faces[i][j]) {
  3768.           if (faces[i][0] == 0) {
  3769.             faces[i][0] = 1;
  3770.             faces[i][1] = player;
  3771.           } else if (faces[i][1] == player) {
  3772.             faces[i][0]++;
  3773.           } else {
  3774.             faces[i][0] = -1;
  3775.           }
  3776.         }
  3777.       }
  3778.  
  3779.     }
  3780.  
  3781.     // Switch players.
  3782.     if (player == HUMAN)
  3783.       return MACHINE;
  3784.     else
  3785.       return HUMAN;
  3786.   }
  3787.  
  3788.   /**
  3789.    * Start a new game.
  3790.    */
  3791.   public void newGame() {
  3792.  
  3793.     // Initialize the inside/outside flags.
  3794.     inside_four_flag = false;
  3795.     outside_four_flag = false;
  3796.     block_chair_flag = false;
  3797.  
  3798.     // Initialize the inside/outside arrays.
  3799.     for (int i = 0; i < 18; i++) {
  3800.       inside_four[i][0] = 0;
  3801.       inside_four[i][1] = 0;
  3802.       outside_four[i][0] = 0;
  3803.       outside_four[i][1] = 0;
  3804.     }
  3805.  
  3806.     // Initialize the faces array.
  3807.     for (int i = 0; i < 18; i++) {
  3808.       faces[i][0] = 0;
  3809.       faces[i][1] = 0;
  3810.     }
  3811.  
  3812.     // Initialize the board.
  3813.     for (int i = 0; i < 64; i++) {
  3814.       occupied[i] = 0;
  3815.     }
  3816.     for (int i = 0; i < 76; i++) {
  3817.       combinations[i][0] = 0;
  3818.       combinations[i][1] = 0;
  3819.     }
  3820.  
  3821.     // Reset the best_picks array.
  3822.     update_best_picks();
  3823.  
  3824.     // Set the player with the first move.
  3825.     player = HUMAN;
  3826.  
  3827.     // Initialize the number of moves.
  3828.     nmoves = 0;
  3829.  
  3830.     // Reset the playing positions.
  3831.     positions.newGame();
  3832.   }
  3833.  
  3834.   /**
  3835.    * Set the skill level.
  3836.    */
  3837.   public void set_skill_level(int level) {
  3838.     skill_level = level;
  3839.   }
  3840.  
  3841.   /**
  3842.    * Set up the pos_to_comb array.
  3843.    */
  3844.   public void setup_pos_to_comb() {
  3845.  
  3846.     // Set up the pos_to_comb array to point to every winning
  3847.     // combination a given position may have.
  3848.     int count;
  3849.     for (int i = 0; i < 64; i++) {
  3850.       count = 1;
  3851.       pos_to_comb[i][0] = 0;
  3852.       for (int j = 0; j < 76; j++) {
  3853.         for (int k = 2; k < 6; k++) {
  3854.           if (combinations[j][k] == i) {
  3855.             pos_to_comb[i][0]++;
  3856.             pos_to_comb[i][count++] = j;
  3857.           }
  3858.         }
  3859.       }
  3860.     }
  3861.  
  3862.     if (debug) {
  3863.       for (int i = 0; i < 64; i++) {
  3864.         System.out.println("");
  3865.         for (int j = 0; j < 8; j++) {
  3866.           System.out.println("pos_to_comb[" + i + "][" + j + "] = "
  3867.               + pos_to_comb[i][j]);
  3868.         }
  3869.       }
  3870.     }
  3871.  
  3872.   }
  3873.  
  3874.   /**
  3875.    * Update the best_picks array.
  3876.    */
  3877.   public void update_best_picks() {
  3878.  
  3879.     // Re-calculate the best_picks array to point to every (current) winning
  3880.     // combination a given position may have.
  3881.     int count;
  3882.     for (int i = 0; i < 64; i++) {
  3883.  
  3884.       count = 1;
  3885.       best_picks[i][0] = 0;
  3886.       if (occupied[i] == 0) {
  3887.         for (int j = 0; j < 76; j++) {
  3888.  
  3889.           if (combinations[j][0] == 0
  3890.               || combinations[j][1] == MACHINE) {
  3891.  
  3892.             for (int k = 2; k < 6; k++) {
  3893.               if (combinations[j][k] == i) {
  3894.                 best_picks[i][0]++;
  3895.                 best_picks[i][count++] = j;
  3896.               }
  3897.             }
  3898.           }
  3899.         }
  3900.       }
  3901.     }
  3902.  
  3903.     if (debug) {
  3904.       for (int i = 0; i < 64; i++) {
  3905.         System.out.println("");
  3906.         for (int j = 0; j < 8; j++) {
  3907.           System.out.println("best_picks[" + i + "][" + j + "] = "
  3908.               + best_picks[i][j]);
  3909.         }
  3910.       }
  3911.     }
  3912.   }
  3913.  
  3914.   /**
  3915.    * Pick the computer's best possible move based on the number of
  3916.    * combinations per position. Choose the position with the most
  3917.    * combinations.
  3918.    */
  3919.   public void pick_best_position() {
  3920.  
  3921.     int pos = 0;
  3922.     int max_num = 0;
  3923.     for (int i = 0; i < 64; i++) {
  3924.       if (best_picks[i][0] > max_num && occupied[i] == 0) {
  3925.         pos = i;
  3926.         max_num = best_picks[i][0];
  3927.       }
  3928.     }
  3929.  
  3930.     // Mark the position as MACHINE.
  3931.     occupied[pos] = MACHINE;
  3932.  
  3933.     positions.set(pos, MACHINE);
  3934.  
  3935.     // Udate the logic arrays and reset the player.
  3936.     player = update_logic_arrays(pos);
  3937.   }
  3938.  
  3939.   public boolean pick_7() {
  3940.  
  3941.     for (int i = 0; i < 64; i++) {
  3942.       if (best_picks[i][0] == 7) {
  3943.         occupied[i] = MACHINE;
  3944.         positions.set(i, MACHINE);
  3945.         player = update_logic_arrays(i);
  3946.         return true;
  3947.       }
  3948.     }
  3949.     return false;
  3950.  
  3951.   }
  3952.  
  3953.   public void change_face() {
  3954.     current_face = ++current_face % 18;
  3955.   }
  3956.  
  3957.   public void label() {
  3958.     label_flag ^= true;
  3959.   }
  3960.  
  3961.   public boolean unoccupied(int pos) {
  3962.     if (occupied[pos] == UNOCCUPIED)
  3963.       return true;
  3964.     else
  3965.       return false;
  3966.   }
  3967. }
  3968.  
  3969. /**
  3970.  * Class: Canvas2D
  3971.  *
  3972.  * Description: Used to respond to mouse events in the 2D window.
  3973.  *
  3974.  * Version: 1.0
  3975.  *  
  3976.  */
  3977.  
  3978. class Canvas2D extends Canvas implements MouseListener {
  3979.  
  3980.   Image backbuffer; // Backbuffer image
  3981.  
  3982.   Graphics gc; // Graphics context of backbuffer
  3983.  
  3984.   Board board; // Game board
  3985.  
  3986.   Canvas2D(Board board) {
  3987.     this.board = board;
  3988.   }
  3989.  
  3990.   public void setBuffer(Image backbuffer) {
  3991.     this.backbuffer = backbuffer;
  3992.     gc = backbuffer.getGraphics();
  3993.   }
  3994.  
  3995.   public void update(Graphics g) {
  3996.     paint(g);
  3997.   }
  3998.  
  3999.   public void paint(Graphics g) {
  4000.     if (board != null) {
  4001.       board.render2D(gc);
  4002.       g.drawImage(backbuffer, 0, 0, this);
  4003.     }
  4004.   }
  4005.  
  4006.   public void mousePressed(MouseEvent e) {
  4007.     board.checkSelection2D(e.getX(), e.getY(), 1);
  4008.     repaint();
  4009.   }
  4010.  
  4011.   public void mouseClicked(MouseEvent e) {
  4012.   }
  4013.  
  4014.   public void mouseReleased(MouseEvent e) {
  4015.   }
  4016.  
  4017.   public void mouseEntered(MouseEvent e) {
  4018.   }
  4019.  
  4020.   public void mouseExited(MouseEvent e) {
  4021.   }
  4022. }
  4023.  
  4024. class Cube extends Object {
  4025.  
  4026.   private Shape3D shape3D;
  4027.  
  4028.   private static final float[] verts = {
  4029.   // Front Face
  4030.       1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
  4031.       -1.0f, 1.0f,
  4032.       // Back Face
  4033.       -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
  4034.       -1.0f, -1.0f,
  4035.       // Right Face
  4036.       1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
  4037.       -1.0f, 1.0f,
  4038.       // Left Face
  4039.       -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
  4040.       -1.0f, -1.0f,
  4041.       // Top Face
  4042.       1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
  4043.       1.0f, 1.0f,
  4044.       // Bottom Face
  4045.       -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
  4046.       -1.0f, 1.0f, };
  4047.  
  4048.   private static final float[] normals = {
  4049.   // Front Face
  4050.       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
  4051.       1.0f,
  4052.       // Back Face
  4053.       0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
  4054.       0.0f, -1.0f,
  4055.       // Right Face
  4056.       1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
  4057.       0.0f,
  4058.       // Left Face
  4059.       -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
  4060.       0.0f, 0.0f,
  4061.       // Top Face
  4062.       0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
  4063.       0.0f,
  4064.       // Bottom Face
  4065.       0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
  4066.       -1.0f, 0.0f, };
  4067.  
  4068.   public Cube(Appearance appearance) {
  4069.  
  4070.     QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES
  4071.         | QuadArray.NORMALS | QuadArray.TEXTURE_COORDINATE_2);
  4072.     quadArray.setCoordinates(0, verts);
  4073.     quadArray.setNormals(0, normals);
  4074.  
  4075.     shape3D = new Shape3D(quadArray, appearance);
  4076.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
  4077.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
  4078.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
  4079.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
  4080.   }
  4081.  
  4082.   public Cube(Appearance appearance, float size) {
  4083.  
  4084.     QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES
  4085.         | QuadArray.NORMALS);
  4086.     for (int i = 0; i < 72; i++)
  4087.       verts[i] *= size;
  4088.  
  4089.     quadArray.setCoordinates(0, verts);
  4090.     quadArray.setNormals(0, normals);
  4091.  
  4092.     shape3D = new Shape3D(quadArray, appearance);
  4093.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
  4094.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
  4095.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
  4096.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
  4097.   }
  4098.  
  4099.   public Shape3D getChild() {
  4100.     return shape3D;
  4101.   }
  4102. }
  4103.  
  4104. /**
  4105.  * Class BigCube
  4106.  *
  4107.  * Description: Creates the "big" cube used to mark the computer's position.
  4108.  *
  4109.  * Version: 1.0
  4110.  *
  4111.  * Copyright (C) 1998 Sun Microsystems, Inc. All Rights Reserved.
  4112.  */
  4113.  
  4114. class BigCube extends Object {
  4115.  
  4116.   private Shape3D shape3D;
  4117.  
  4118.   private static final float[] verts = {
  4119.   // Front Face
  4120.       5.0f, -5.0f, 5.0f, 5.0f, 5.0f, 5.0f, -5.0f, 5.0f, 5.0f, -5.0f,
  4121.       -5.0f, 5.0f,
  4122.       // Back Face
  4123.       -5.0f, -5.0f, -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, 5.0f, -5.0f, 5.0f,
  4124.       -5.0f, -5.0f,
  4125.       // Right Face
  4126.       5.0f, -5.0f, -5.0f, 5.0f, 5.0f, -5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
  4127.       -5.0f, 5.0f,
  4128.       // Left Face
  4129.       -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, 5.0f, -5.0f, 5.0f, -5.0f, -5.0f,
  4130.       -5.0f, -5.0f,
  4131.       // Top Face
  4132.       5.0f, 5.0f, 5.0f, 5.0f, 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, -5.0f,
  4133.       5.0f, 5.0f,
  4134.       // Bottom Face
  4135.       -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, 5.0f,
  4136.       -5.0f, 5.0f, };
  4137.  
  4138.   private static final float[] normals = {
  4139.   // Front Face
  4140.       0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
  4141.       1.0f,
  4142.       // Back Face
  4143.       0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
  4144.       0.0f, -1.0f,
  4145.       // Right Face
  4146.       1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
  4147.       0.0f,
  4148.       // Left Face
  4149.       -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
  4150.       0.0f, 0.0f,
  4151.       // Top Face
  4152.       0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
  4153.       0.0f,
  4154.       // Bottom Face
  4155.       0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
  4156.       -1.0f, 0.0f, };
  4157.  
  4158.   public BigCube(Appearance appearance) {
  4159.  
  4160.     QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES
  4161.         | QuadArray.NORMALS);
  4162.     quadArray.setCoordinates(0, verts);
  4163.     quadArray.setNormals(0, normals);
  4164.  
  4165.     shape3D = new Shape3D(quadArray, appearance);
  4166.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
  4167.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
  4168.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
  4169.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
  4170.   }
  4171.  
  4172.   public BigCube(Appearance appearance, float size) {
  4173.  
  4174.     QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES
  4175.         | QuadArray.NORMALS);
  4176.  
  4177.     for (int i = 0; i < 72; i++)
  4178.       verts[i] *= size;
  4179.  
  4180.     quadArray.setCoordinates(0, verts);
  4181.     quadArray.setNormals(0, normals);
  4182.  
  4183.     shape3D = new Shape3D(quadArray, appearance);
  4184.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
  4185.     shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
  4186.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
  4187.     shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
  4188.   }
  4189.  
  4190.   public Shape3D getChild() {
  4191.     return shape3D;
  4192.   }
  4193. }
  4194.  
  4195. /**
  4196.  * Class: Positions
  4197.  *
  4198.  * Description: Creates the position markers.
  4199.  *
  4200.  * Version: 1.0
  4201.  *  
  4202.  */
  4203.  
  4204. class Positions extends Object {
  4205.  
  4206.   final static int UNOCCUPIED = 0;
  4207.  
  4208.   final static int HUMAN = 1;
  4209.  
  4210.   final static int MACHINE = 2;
  4211.  
  4212.   final static int END = 3;
  4213.  
  4214.   private Vector3f point[];
  4215.  
  4216.   private Switch posSwitch;
  4217.  
  4218.   private Switch humanSwitch;
  4219.  
  4220.   private Switch machineSwitch;
  4221.  
  4222.   private BitSet posMask;
  4223.  
  4224.   private BitSet humanMask;
  4225.  
  4226.   private BitSet machineMask;
  4227.  
  4228.   private Group group;
  4229.  
  4230.   private Material redMat;
  4231.  
  4232.   private Material blueMat;
  4233.  
  4234.   private Material yellowMat;
  4235.  
  4236.   private Material whiteMat;
  4237.  
  4238.   private Appearance redApp;
  4239.  
  4240.   private Appearance blueApp;
  4241.  
  4242.   private Appearance yellowApp;
  4243.  
  4244.   private Appearance whiteApp;
  4245.  
  4246.   private Board board;
  4247.  
  4248.   private Sphere posSphere[];
  4249.  
  4250.   private BigCube cube[];
  4251.  
  4252.   private TransformGroup tgroup;
  4253.  
  4254.   private boolean winnerFlag = false;
  4255.  
  4256.   public Positions() {
  4257.  
  4258.     // Define colors for lighting
  4259.     Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
  4260.     Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
  4261.     Color3f red = new Color3f(0.9f, 0.1f, 0.2f);
  4262.     Color3f blue = new Color3f(0.3f, 0.3f, 0.8f);
  4263.     Color3f yellow = new Color3f(1.0f, 1.0f, 0.0f);
  4264.     Color3f ambRed = new Color3f(0.3f, 0.03f, 0.03f);
  4265.     Color3f ambBlue = new Color3f(0.03f, 0.03f, 0.3f);
  4266.     Color3f ambYellow = new Color3f(0.3f, 0.3f, 0.03f);
  4267.     Color3f ambWhite = new Color3f(0.3f, 0.3f, 0.3f);
  4268.     Color3f specular = new Color3f(1.0f, 1.0f, 1.0f);
  4269.  
  4270.     // Create the red appearance node
  4271.     redMat = new Material(ambRed, black, red, specular, 100.f);
  4272.     redMat.setLightingEnable(true);
  4273.     redApp = new Appearance();
  4274.     redApp.setMaterial(redMat);
  4275.  
  4276.     // Create the blue appearance node
  4277.     blueMat = new Material(ambBlue, black, blue, specular, 100.f);
  4278.     blueMat.setLightingEnable(true);
  4279.     blueApp = new Appearance();
  4280.     blueApp.setMaterial(blueMat);
  4281.  
  4282.     // Create the yellow appearance node
  4283.     yellowMat = new Material(ambYellow, black, yellow, specular, 100.f);
  4284.     yellowMat.setLightingEnable(true);
  4285.     yellowApp = new Appearance();
  4286.     yellowApp.setMaterial(yellowMat);
  4287.  
  4288.     // Create the white appearance node
  4289.     whiteMat = new Material(ambWhite, black, white, specular, 100.f);
  4290.     whiteMat.setLightingEnable(true);
  4291.     whiteApp = new Appearance();
  4292.     whiteApp.setMaterial(whiteMat);
  4293.  
  4294.     // Load the point array with the offset (coordinates) for each of
  4295.     // the 64 positions.
  4296.     point = new Vector3f[64];
  4297.     int count = 0;
  4298.     for (int i = -30; i < 40; i += 20) {
  4299.       for (int j = -30; j < 40; j += 20) {
  4300.         for (int k = -30; k < 40; k += 20) {
  4301.           point[count] = new Vector3f((float) k, (float) j, (float) i);
  4302.           count++;
  4303.         }
  4304.       }
  4305.     }
  4306.  
  4307.     // Create the switch nodes
  4308.     posSwitch = new Switch(Switch.CHILD_MASK);
  4309.     humanSwitch = new Switch(Switch.CHILD_MASK);
  4310.     machineSwitch = new Switch(Switch.CHILD_MASK);
  4311.  
  4312.     // Set the capability bits
  4313.     posSwitch.setCapability(Switch.ALLOW_SWITCH_READ);
  4314.     posSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
  4315.  
  4316.     humanSwitch.setCapability(Switch.ALLOW_SWITCH_READ);
  4317.     humanSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
  4318.  
  4319.     machineSwitch.setCapability(Switch.ALLOW_SWITCH_READ);
  4320.     machineSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
  4321.  
  4322.     // Create the bit masks
  4323.     posMask = new BitSet();
  4324.     humanMask = new BitSet();
  4325.     machineMask = new BitSet();
  4326.  
  4327.     // Create the small white spheres that mark unoccupied
  4328.     // positions.
  4329.     posSphere = new Sphere[64];
  4330.     for (int i = 0; i < 64; i++) {
  4331.       Transform3D transform3D = new Transform3D();
  4332.       transform3D.set(point[i]);
  4333.       TransformGroup transformGroup = new TransformGroup(transform3D);
  4334.       posSphere[i] = new Sphere(2.0f, Sphere.GENERATE_NORMALS
  4335.           | Sphere.ENABLE_APPEARANCE_MODIFY, 12, whiteApp);
  4336.       Shape3D shape = posSphere[i].getShape();
  4337.       ID id = new ID(i);
  4338.       shape.setUserData(id);
  4339.       transformGroup.addChild(posSphere[i]);
  4340.       posSwitch.addChild(transformGroup);
  4341.       posMask.set(i);
  4342.     }
  4343.  
  4344.     // Create the red spheres that mark the user's positions.
  4345.     for (int i = 0; i < 64; i++) {
  4346.       Transform3D transform3D = new Transform3D();
  4347.       transform3D.set(point[i]);
  4348.       TransformGroup transformGroup = new TransformGroup(transform3D);
  4349.       transformGroup.addChild(new Sphere(7.0f, redApp));
  4350.       humanSwitch.addChild(transformGroup);
  4351.       humanMask.clear(i);
  4352.     }
  4353.  
  4354.     // Create the blue cubes that mark the computer's positions.
  4355.     for (int i = 0; i < 64; i++) {
  4356.       Transform3D transform3D = new Transform3D();
  4357.       transform3D.set(point[i]);
  4358.       TransformGroup transformGroup = new TransformGroup(transform3D);
  4359.       BigCube cube = new BigCube(blueApp);
  4360.       transformGroup.addChild(cube.getChild());
  4361.       machineSwitch.addChild(transformGroup);
  4362.       machineMask.clear(i);
  4363.     }
  4364.  
  4365.     // Set the positions mask
  4366.     posSwitch.setChildMask(posMask);
  4367.     humanSwitch.setChildMask(humanMask);
  4368.     machineSwitch.setChildMask(machineMask);
  4369.  
  4370.     // Throw everything into a single group
  4371.     group = new Group();
  4372.     group.addChild(posSwitch);
  4373.     group.addChild(humanSwitch);
  4374.     group.addChild(machineSwitch);
  4375.   }
  4376.  
  4377.   public void setTransformGroup(TransformGroup transformGroup) {
  4378.     tgroup = transformGroup;
  4379.   }
  4380.  
  4381.   public Group getChild() {
  4382.     return group;
  4383.   }
  4384.  
  4385.   public void setBoard(Board board) {
  4386.     this.board = board;
  4387.   }
  4388.  
  4389.   public void winner() {
  4390.     winnerFlag = true;
  4391.   }
  4392.  
  4393.   public void noWinner() {
  4394.     winnerFlag = false;
  4395.   }
  4396.  
  4397.   public void setHighlight(int pos) {
  4398.     posSphere[pos].setAppearance(yellowApp);
  4399.   }
  4400.  
  4401.   public void clearHighlight(int pos) {
  4402.     posSphere[pos].setAppearance(whiteApp);
  4403.   }
  4404.  
  4405.   public void newGame() {
  4406.  
  4407.     // Clear the board
  4408.     for (int i = 0; i < 64; i++) {
  4409.       posMask.set(i);
  4410.       humanMask.clear(i);
  4411.       machineMask.clear(i);
  4412.     }
  4413.     posSwitch.setChildMask(posMask);
  4414.     humanSwitch.setChildMask(humanMask);
  4415.     machineSwitch.setChildMask(machineMask);
  4416.  
  4417.     // The following three lines fix a bug in J3D
  4418.     Transform3D t = new Transform3D();
  4419.     tgroup.getTransform(t);
  4420.     tgroup.setTransform(t);
  4421.  
  4422.     // Reset the winner flag
  4423.     winnerFlag = false;
  4424.   }
  4425.  
  4426.   public void set(int pos, int player) {
  4427.  
  4428.     // Stop accepting selections when the game
  4429.     // is over.
  4430.     if (winnerFlag)
  4431.       return;
  4432.  
  4433.     // Make sure the position is not occupied.
  4434.     if (player == HUMAN)
  4435.       if (!board.unoccupied(pos))
  4436.         return;
  4437.  
  4438.     // Turn off the position marker for the given position
  4439.     posMask.clear(pos);
  4440.     posSwitch.setChildMask(posMask);
  4441.  
  4442.     // Turn on the player marker
  4443.     if (player == Positions.HUMAN) {
  4444.       humanMask.set(pos);
  4445.       humanSwitch.setChildMask(humanMask);
  4446.       board.selection(pos, Positions.HUMAN);
  4447.     } else {
  4448.       machineMask.set(pos);
  4449.       machineSwitch.setChildMask(machineMask);
  4450.     }
  4451.  
  4452.     // The following three lines fix a bug in J3D
  4453.     Transform3D t = new Transform3D();
  4454.     tgroup.getTransform(t);
  4455.     tgroup.setTransform(t);
  4456.   }
  4457.  
  4458.   public void clear(int pos) {
  4459.  
  4460.     // Turn on the position marker
  4461.     posMask.set(pos);
  4462.     posSwitch.setChildMask(posMask);
  4463.  
  4464.     // Turn off the player marker
  4465.     humanMask.clear(pos);
  4466.     humanSwitch.setChildMask(humanMask);
  4467.     machineMask.clear(pos);
  4468.     machineSwitch.setChildMask(machineMask);
  4469.  
  4470.     // The following three lines are a workaround for a bug
  4471.     // in dev09 in which the transform3D of certain items are
  4472.     // not updated properly. Scheduled to be fixed in dev10
  4473.     Transform3D t = new Transform3D();
  4474.     tgroup.getTransform(t);
  4475.     tgroup.setTransform(t);
  4476.   }
  4477.  
  4478. }
  4479.  
  4480. /**
  4481.  * Class: PickDragBehavior
  4482.  *
  4483.  * Description: Used to respond to mouse pick and drag events in the 3D window.
  4484.  *
  4485.  * Version: 1.0
  4486.  *  
  4487.  */
  4488.  
  4489. class PickDragBehavior extends Behavior {
  4490.  
  4491.   WakeupCriterion[] mouseEvents;
  4492.  
  4493.   WakeupOr mouseCriterion;
  4494.  
  4495.   int x, y;
  4496.  
  4497.   int x_last, y_last;
  4498.  
  4499.   double x_angle, y_angle;
  4500.  
  4501.   double x_factor, y_factor;
  4502.  
  4503.   Transform3D modelTrans;
  4504.  
  4505.   Transform3D transformX;
  4506.  
  4507.   Transform3D transformY;
  4508.  
  4509.   TransformGroup transformGroup;
  4510.  
  4511.   BranchGroup branchGroup;
  4512.  
  4513.   Canvas2D canvas2D;
  4514.  
  4515.   Canvas3D canvas3D;
  4516.  
  4517.   Positions positions;
  4518.  
  4519.   PickRay pickRay = new PickRay();
  4520.  
  4521.   SceneGraphPath sceneGraphPath[];
  4522.  
  4523.   Appearance highlight;
  4524.  
  4525.   boolean parallel;
  4526.  
  4527.   PickDragBehavior(Canvas2D canvas2D, Canvas3D canvas3D, Positions positions,
  4528.       BranchGroup branchGroup, TransformGroup transformGroup) {
  4529.  
  4530.     this.canvas2D = canvas2D;
  4531.     this.canvas3D = canvas3D;
  4532.     this.positions = positions;
  4533.     this.branchGroup = branchGroup;
  4534.     this.transformGroup = transformGroup;
  4535.  
  4536.     modelTrans = new Transform3D();
  4537.     transformX = new Transform3D();
  4538.     transformY = new Transform3D();
  4539.  
  4540.     Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
  4541.     Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
  4542.     Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
  4543.  
  4544.     highlight = new Appearance();
  4545.     highlight.setMaterial(new Material(green, black, green, white, 80.f));
  4546.  
  4547.     parallel = true;
  4548.   }
  4549.  
  4550.   public void initialize() {
  4551.     x = 0;
  4552.     y = 0;
  4553.     x_last = 0;
  4554.     y_last = 0;
  4555.     x_angle = 0;
  4556.     y_angle = 0;
  4557.     x_factor = .02;
  4558.     y_factor = .02;
  4559.  
  4560.     mouseEvents = new WakeupCriterion[2];
  4561.     mouseEvents[0] = new WakeupOnAWTEvent(MouseEvent.MOUSE_DRAGGED);
  4562.     mouseEvents[1] = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
  4563.     mouseCriterion = new WakeupOr(mouseEvents);
  4564.     wakeupOn(mouseCriterion);
  4565.   }
  4566.  
  4567.   public void processStimulus(Enumeration criteria) {
  4568.     WakeupCriterion wakeup;
  4569.     AWTEvent[] event;
  4570.     int id;
  4571.     int dx, dy;
  4572.  
  4573.     while (criteria.hasMoreElements()) {
  4574.       wakeup = (WakeupCriterion) criteria.nextElement();
  4575.       if (wakeup instanceof WakeupOnAWTEvent) {
  4576.         event = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
  4577.         for (int i = 0; i < event.length; i++) {
  4578.           id = event[i].getID();
  4579.           if (id == MouseEvent.MOUSE_DRAGGED) {
  4580.  
  4581.             x = ((MouseEvent) event[i]).getX();
  4582.             y = ((MouseEvent) event[i]).getY();
  4583.  
  4584.             dx = x - x_last;
  4585.             dy = y - y_last;
  4586.  
  4587.             x_angle = dy * y_factor;
  4588.             y_angle = dx * x_factor;
  4589.  
  4590.             transformX.rotX(x_angle);
  4591.             transformY.rotY(y_angle);
  4592.  
  4593.             modelTrans.mul(transformX, modelTrans);
  4594.             modelTrans.mul(transformY, modelTrans);
  4595.  
  4596.             transformGroup.setTransform(modelTrans);
  4597.  
  4598.             x_last = x;
  4599.             y_last = y;
  4600.           } else if (id == MouseEvent.MOUSE_PRESSED) {
  4601.  
  4602.             x = x_last = ((MouseEvent) event[i]).getX();
  4603.             y = y_last = ((MouseEvent) event[i]).getY();
  4604.  
  4605.             Point3d eyePos = new Point3d();
  4606.             canvas3D.getCenterEyeInImagePlate(eyePos);
  4607.  
  4608.             Point3d mousePos = new Point3d();
  4609.             canvas3D.getPixelLocationInImagePlate(x, y, mousePos);
  4610.  
  4611.             Transform3D transform3D = new Transform3D();
  4612.             canvas3D.getImagePlateToVworld(transform3D);
  4613.  
  4614.             transform3D.transform(eyePos);
  4615.             transform3D.transform(mousePos);
  4616.  
  4617.             Vector3d mouseVec;
  4618.             if (parallel) {
  4619.               mouseVec = new Vector3d(0.f, 0.f, -1.f);
  4620.             } else {
  4621.               mouseVec = new Vector3d();
  4622.               mouseVec.sub(mousePos, eyePos);
  4623.               mouseVec.normalize();
  4624.             }
  4625.  
  4626.             pickRay.set(mousePos, mouseVec);
  4627.             sceneGraphPath = branchGroup.pickAllSorted(pickRay);
  4628.  
  4629.             if (sceneGraphPath != null) {
  4630.               for (int j = 0; j < sceneGraphPath.length; j++) {
  4631.                 if (sceneGraphPath[j] != null) {
  4632.                   Node node = sceneGraphPath[j].getObject();
  4633.                   if (node instanceof Shape3D) {
  4634.                     try {
  4635.                       ID posID = (ID) node.getUserData();
  4636.                       if (posID != null) {
  4637.                         int pos = posID.get();
  4638.                         positions.set(pos,
  4639.                             Positions.HUMAN);
  4640.                         canvas2D.repaint();
  4641.                         break;
  4642.                       }
  4643.                     } catch (CapabilityNotSetException e) {
  4644.                       // Catch all CapabilityNotSet
  4645.                       // exceptions and
  4646.                       // throw them away, prevents
  4647.                       // renderer from
  4648.                       // locking up when encountering
  4649.                       // "non-selectable"
  4650.                       // objects.
  4651.                     }
  4652.                   }
  4653.                 }
  4654.               }
  4655.             }
  4656.           }
  4657.         }
  4658.       }
  4659.     }
  4660.     wakeupOn(mouseCriterion);
  4661.   }
  4662. }
  4663.  
  4664. class ID {
  4665.   int id;
  4666.  
  4667.   public ID(int id) {
  4668.     this.id = id;
  4669.   }
  4670.  
  4671.   public int get() {
  4672.     return id;
  4673.   }
  4674.  
  4675.   public void set(int id) {
  4676.     this.id = id;
  4677.   }
  4678. }
  4679.  
  4680. class Cylinder {
  4681.  
  4682.   float verts[];
  4683.  
  4684.   float normals[];
  4685.  
  4686.   QuadArray quad = null;
  4687.  
  4688.   float div = 3.0f;
  4689.  
  4690.   Shape3D shape;
  4691.  
  4692.   public Cylinder(float x, float z, float radius, float length, int quality,
  4693.       Appearance a) {
  4694.  
  4695.     if (quality < 3)
  4696.       quality = 3;
  4697.  
  4698.     div = (float) quality;
  4699.  
  4700.     verts = new float[quality * 12];
  4701.     normals = new float[quality * 12];
  4702.  
  4703.     double inc = 2.0 * Math.PI / (double) div;
  4704.     for (int i = 0; i < quality; i++) {
  4705.       float z1 = radius * (float) Math.sin((double) i * inc) + z;
  4706.       float x1 = radius * (float) Math.cos((double) i * inc) + x;
  4707.       float z2 = radius * (float) Math.sin((double) (i + 1) * inc) + z;
  4708.       float x2 = radius * (float) Math.cos((double) (i + 1) * inc) + x;
  4709.  
  4710.       verts[12 * i] = x1;
  4711.       verts[12 * i + 1] = -length / 2.f;
  4712.       verts[12 * i + 2] = z1;
  4713.       verts[12 * i + 3] = x1;
  4714.       verts[12 * i + 4] = length / 2.f;
  4715.       verts[12 * i + 5] = z1;
  4716.       verts[12 * i + 6] = x2;
  4717.       verts[12 * i + 7] = length / 2.f;
  4718.       verts[12 * i + 8] = z2;
  4719.       verts[12 * i + 9] = x2;
  4720.       verts[12 * i + 10] = -length / 2.f;
  4721.       verts[12 * i + 11] = z2;
  4722.  
  4723.       float nz1 = (float) Math.sin((double) i * inc);
  4724.       float nx1 = (float) Math.cos((double) i * inc);
  4725.       float nz2 = (float) Math.sin((double) (i + 1) * inc);
  4726.       float nx2 = (float) Math.cos((double) (i + 1) * inc);
  4727.  
  4728.       normals[12 * i] = nx1;
  4729.       normals[12 * i + 1] = 0.0f;
  4730.       normals[12 * i + 2] = nz1;
  4731.       normals[12 * i + 3] = nx1;
  4732.       normals[12 * i + 4] = 0.0f;
  4733.       normals[12 * i + 5] = nz1;
  4734.       normals[12 * i + 6] = nx2;
  4735.       normals[12 * i + 7] = 0.0f;
  4736.       normals[12 * i + 8] = nz2;
  4737.       normals[12 * i + 9] = nx2;
  4738.       normals[12 * i + 10] = 0.0f;
  4739.       normals[12 * i + 11] = nz2;
  4740.     }
  4741.  
  4742.     quad = new QuadArray(quality * 4, QuadArray.COORDINATES
  4743.         | QuadArray.NORMALS);
  4744.     quad.setCoordinates(0, verts);
  4745.     quad.setNormals(0, normals);
  4746.     shape = new Shape3D(quad, a);
  4747.   }
  4748.  
  4749.   Shape3D getShape() {
  4750.     return shape;
  4751.   }
  4752. }
  4753. For more information visit this site:
  4754. https://www.youtube.com/channel/UCJ0nVqHF9lBebRXugUOin4A
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement