home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 14 / IOPROG_14.ISO / soft / sdkjava / sdkjava.exe / SDKJava.cab / Samples / AFC / Puzzle15 / Src / Pz15ControlPanel.java < prev    next >
Encoding:
Java Source  |  1998-03-05  |  7.1 KB  |  300 lines

  1. //
  2. // (c) 1998 Microsoft Corporation.  All rights reserved.
  3. //
  4. import java.awt.Event;
  5. import com.ms.ui.*;
  6. import com.ms.fx.*;
  7.  
  8. class Pz15ControlPanel extends UIPanel implements Pz15Consts, Pz15Callbacks, Runnable
  9. {
  10.     private Pz15GamePanel    gameboard;
  11.     private    UIFrame            frame;
  12.     private Pz15Options        props;
  13.     private Pz15Data        puzzle;
  14.     private Pz15Menu        menu;
  15.     private Pz15InfoPanel    info;
  16.     private Pz15Solver        pzsolver;
  17.     private Thread            solver;
  18.     private boolean            can_undo, can_restart;
  19.  
  20.     public Pz15ControlPanel(UIApplet applet, UIFrame frame)
  21.     {
  22.         setLayout(new UIBorderLayout(0,0));
  23.  
  24.         // Options Property Pages
  25.         if ( applet != null )
  26.             this.frame = FxToolkit.getHelperUIFrame();
  27.         else
  28.             this.frame = frame;
  29.  
  30.         props = new Pz15Options(this.frame, "Game...", true, UIPropertyDialog.MEDIUM);
  31.         props.addPage("...Options", new Pz15PropGame(props));
  32.         props.addPage("...Navigation", new Pz15PropNav(props));
  33.  
  34.         can_undo = false; can_restart = false;
  35.  
  36.         puzzle = new Pz15Data();
  37.  
  38.         // Initialized load on demand images
  39.         Pz15Images.init(applet, frame);
  40.  
  41.         gameboard = new Pz15GamePanel(puzzle, this);
  42.         gameboard.drawBlank();
  43.         menu = new Pz15Menu(this, applet == null);
  44.         info = new Pz15InfoPanel();
  45.  
  46.         //
  47.         // Create instance of solver whether he is used or not.
  48.         //   pzsolver will always be instantiated, solver (the thread )
  49.         //   will only be instantiated if needed.
  50.         //
  51.         pzsolver = new Pz15Solver();
  52.         pzsolver.registerCallback(this, this.frame);
  53.  
  54.         add(menu, "North");
  55.         UIPanel pnl = new UIPanel();
  56.         pnl.setLayout(new UISplitLayout(UISplitLayout.HORIZONTAL,300));
  57.         pnl.add(gameboard, "nw"); pnl.add(info, "se");
  58.         add(pnl, "Center");
  59.     }
  60.  
  61.     public void run()
  62.     {
  63.         // Display Options
  64.         Object ret = props.display();
  65.         if ( (ret instanceof IUIComponent) && 
  66.                 (((IUIComponent)ret).getID() != UIButtonBar.ID_CANCEL) ) {
  67.             // Scramble puzzle according to user input
  68.             puzzle.genNew(props.numscramble);
  69.             // Start new game
  70.             newGame();
  71.         }
  72.         else
  73.             setMarqueeString(MRQ_START, S_RESET);
  74.         // Turn on marquee
  75.         info.marquee.is_on = true;
  76.         // give focus to gameboard
  77.         gameboard.requestFocus();
  78.     }
  79.  
  80.     public void initialize()
  81.     {
  82.         Thread th = new Thread(this);
  83.         th.start();
  84.     }
  85.  
  86.     public void hideProperties()
  87.     {
  88.         if ( props != null )
  89.             props.setVisible(false);
  90.     }
  91.  
  92.     public void restartGame()
  93.     {
  94.         puzzle.init();
  95.         reset();
  96.         // If solver hasn't solved the puzzle, it will update marquee with progress.
  97.         if ( pzsolver.solved ) 
  98.             setMarqueeString(MRQ_OPTIMALFND, S_OPTFND);
  99.     }
  100.  
  101.     public void newGame()
  102.     {
  103.         stopSolver(); // You can call stop on an already stopped thread
  104.         puzzle.genNew(props.numscramble);
  105.         reset();
  106.         enableShowSolution(false);
  107.         setOptMoves(puzzle.initial_cost, puzzle.solved);
  108.         startSolver();
  109.     }
  110.  
  111.     private void reset()
  112.     {
  113.         gameboard.removeAll();
  114.         gameboard.draw();
  115.         gameboard.setVisible(true);
  116.         gameboard.setInitialFocus();
  117.         setNumMoves(0);
  118.         setMinMoves(puzzle.initial_cost);
  119.         enableUndo(false);
  120.         enableRestart(false);
  121.     }
  122.  
  123.     private void initSolver()
  124.     {
  125.         pzsolver.genNew(puzzle.original);
  126.         solver = new Thread(pzsolver, "Solver");
  127.         solver.setPriority(Thread.MIN_PRIORITY);
  128.         solver.start();
  129.         setMarqueeString(MRQ_SEARCHING + " 0 nodes.", S_RESET);
  130.     }
  131.  
  132.     private void startSolver()
  133.     {
  134.         if ( props.cpuactive ) {
  135.             if ( solver != null ) {
  136.                 // you can't start a thread that has been stopped, you need 
  137.                 //  to create a new instance
  138.                 stopSolver();
  139.                 initSolver();
  140.             }
  141.             else if ( !pzsolver.solved )
  142.                 initSolver();
  143.         }
  144.         else {
  145.             stopSolver();
  146.             solver = null;
  147.             setMarqueeString(MRQ_NOTSEARCHING, S_RESET);
  148.         }
  149.     }
  150.  
  151.     public void stopSolver()
  152.     {
  153.         if ( solver != null )
  154.             solver.stop();
  155.     }
  156.  
  157.     public void undoMove()
  158.     {
  159.         if ( puzzle.solved ) 
  160.             return;
  161.  
  162.         if ( puzzle.movstk.size() > 0 ) {
  163.             Object move = puzzle.movstk.peek();
  164.             if ( move instanceof Integer ) {
  165.                 int mov = -((Integer)move).intValue();
  166.                 gameboard.update(mov);
  167.             }
  168.         }
  169.     }
  170.  
  171.     public void displayOptionsDialog()
  172.     {
  173.         boolean solversuspended = false;
  174.         if ( solver != null ) {
  175.             synchronized (this) {
  176.                 if ( solver.isAlive() ) {
  177.                     solver.suspend();
  178.                     solversuspended = true;
  179.                 }
  180.             }
  181.         }
  182.         
  183.         info.marquee.is_on = false;
  184.         props.display();
  185.         info.marquee.is_on = true;
  186.         gameboard.requestFocus();
  187.  
  188.         if ( props.cpuactive ) {
  189.             if ( !pzsolver.solved ) {
  190.                 if ( solversuspended )
  191.                     solver.resume();
  192.                 else
  193.                     startSolver();
  194.             }
  195.         }
  196.         else {
  197.             if ( solversuspended )
  198.                 solver.stop();
  199.             pzsolver.solved = false;
  200.         }
  201.     }
  202.  
  203.     public void setOptMoves(int nmoves, boolean optimal)    
  204.     { 
  205.         if ( optimal )
  206.             info.optmoves.setName("Exactly " + nmoves + " moves");
  207.         else
  208.             info.optmoves.setName("At least " + nmoves + " moves"); 
  209.     }
  210.  
  211.     public void displayOptimalSolution()
  212.     { 
  213.         info.marquee.is_on = false;
  214.         pzsolver.displayOptimalSolution();
  215.         info.marquee.is_on = true;
  216.         gameboard.requestFocus();
  217.     }
  218.  
  219.     public void setMarqueeString(String str, int state)
  220.     {
  221.         info.mrqstr = str;
  222.         // if we are already displaying the correct string do not reset
  223.         if ( (state == S_RESET) || ((state != S_NORESET) && (state != info.marquee.state)) )
  224.             info.marquee.reset = true;
  225.         info.marquee.state = state;
  226.     }
  227.  
  228.     public void congratulate()
  229.     {
  230.         String str = new String(CONGRATS_STR1);
  231.  
  232.         if ( pzsolver.solved )
  233.             str += CONGRATS_OPT;
  234.         else
  235.             str += CONGRATS_STR2;
  236.  
  237.         UIMessageBox mbox = new UIMessageBox(frame, "Congratulations!", str, 
  238.                                                 Pz15Images.get(CONGRATS),
  239.                                                 new UIButtonBar(UIButtonBar.OK, 
  240.                                                                 UIButtonBar.RAISED));
  241.         mbox.setFont(new FxFont("Dialog", FxFont.PLAIN, 14));
  242.         info.marquee.is_on = false;
  243.         mbox.doModal();
  244.         info.marquee.is_on = true;
  245.     }
  246.  
  247.     public void setNumMoves(int nmoves)    { info.nummoves.setName("" + nmoves); }
  248.  
  249.     public void setMinMoves(int nmoves)    { info.minmoves.setName("" + nmoves); }
  250.  
  251.     public void enableUndo(boolean enable)
  252.     {
  253.         can_undo = enable;
  254.         menu.enable(ID_UNDO, enable);
  255.     }
  256.  
  257.     public void enableRestart(boolean enable)
  258.     {
  259.         can_restart = enable;
  260.         menu.enable(ID_RESTART, enable);
  261.     }
  262.  
  263.     public int getNavMode() { return props.navmode; }
  264.  
  265.     public boolean getSolverStatus() { return pzsolver.solved; }
  266.  
  267.     public int getOptimalCost() { return pzsolver.costbound; }
  268.  
  269.     public void enableShowSolution(boolean enable) { menu.enable(ID_SOLUTION, enable); }
  270.  
  271.     public boolean keyDown(Event e, int key)
  272.     {
  273.         if ( e.modifiers == 0 ) {
  274.             switch ( key ) {
  275.             case Event.F2: newGame(); break;
  276.             case Event.F4: if ( can_restart ) restartGame(); break;
  277.             case Event.F3: if ( pzsolver.solved ) displayOptimalSolution(); break;
  278.             case Event.F7: displayOptionsDialog(); break;
  279.             default: return super.keyDown(e, key);
  280.             }
  281.         }
  282.         else if ( e.modifiers == Event.CTRL_MASK ) {
  283.             switch ( key ) {
  284.             case 'x'-'a'+1:
  285.                 stopSolver();
  286.                 System.exit(0);
  287.                 break;
  288.             case 'z'-'a'+1:
  289.                 if ( can_undo ) undoMove();
  290.                 return true;
  291.             default:
  292.                 return super.keyDown(e, key);
  293.             }
  294.         }
  295.         return true; // keyDown was handled if we get to here
  296.     }
  297.  
  298.     public void requestFocus() { gameboard.requestFocus(); }
  299. }
  300.