ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/Microscope.java
(Generate patch)

Comparing jsr166/src/test/loops/Microscope.java (file contents):
Revision 1.2 by jsr166, Mon Sep 20 20:42:37 2010 UTC vs.
Revision 1.16 by jsr166, Sat Sep 12 19:09:00 2015 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6  
7   import java.awt.*;
8 import javax.swing.*;
9 import java.util.*;
8   import java.awt.event.*;
9 < import javax.swing.event.*;
9 > import java.util.*;
10   import java.util.concurrent.*;
11 <
11 > import javax.swing.*;
12 > import javax.swing.event.*;
13  
14   /**
15   * Microscope implements a version of the 7th Guest
# Line 19 | Line 18 | import java.util.concurrent.*;
18   * Microscope</a> version for instructions.
19   * <p>
20   * The code has been mangled beyond recognition
21 < * as a test of ForkJoin
22 < **/
24 <
21 > * as a test of ForkJoin.
22 > */
23   public class Microscope extends JPanel {
24  
25      static final CountDownLatch cd = new CountDownLatch(1);
# Line 116 | Line 114 | public class Microscope extends JPanel {
114      synchronized Player getPlayer() { return player; }
115      synchronized void setPlayer(Player p) { player = p; }
116  
119
117      final AutoMover auto;                  // The move finder.
118      final User user;                       // Mover for user moves
119      Mover mover = null;    // the current Mover (always == auto or user or null)
# Line 177 | Line 174 | public class Microscope extends JPanel {
174                  public synchronized void actionPerformed(ActionEvent e) {
175                      toggleDemoMode();
176                      updateStatus();
180
177                  }});
178  
179          undoButton.addActionListener(new ActionListener() {
# Line 195 | Line 191 | public class Microscope extends JPanel {
191          //        scoreLabel.setMinimumSize(labDim);
192          //        scoreLabel.setPreferredSize(labDim);
193  
198
194          topPanel.add(autoButton);
195          topPanel.add(modeButton);
196          topPanel.add(undoButton);
197          topPanel.add(scoreLabel);
198          add(topPanel);
199  
205
200          levelSlider.setLabelTable(levelSlider.createStandardLabels(1));
201          levelSlider.setPaintLabels(true);
202  
# Line 230 | Line 224 | public class Microscope extends JPanel {
224              boardPanel.repaint();
225      }
226  
227 <    public void init()  {
227 >    public void init() {
228          initializeBoard();
229          if (autostart) {
230              startMover(auto);
231          }
232      }
233  
240
234      synchronized void setLevel(int l) {
235          lookAheads = l;
236          if (lookAheads <= 1) lookAheads = 2;
237      }
238  
239 <    public int level () { return Microscope.lookAheads; }
247 <
239 >    public int level() { return Microscope.lookAheads; }
240  
241      // process a move (called only from mover)
250
242      public void move(Move m, Mover mvr) {
243          if (mvr != mover ||
244              m == null ||
# Line 304 | Line 295 | public class Microscope extends JPanel {
295          }
296      }
297  
307
298      // handle Undo button
299      synchronized void undo() {
300          if (mover == null) {
# Line 349 | Line 339 | public class Microscope extends JPanel {
339  
340      }
341  
352
342      static final int CELL_SIZE = 40; // size of a tile/cell
343  
344      static final Color paleGreen = new Color(152, 251, 152);
# Line 357 | Line 346 | public class Microscope extends JPanel {
346  
347      static final Color possibleMoveColor = Color.yellow;
348  
360
349      public static Color displayColor(Player pl) {
350          if (pl.isBlue()) return Color.blue;
351          else if (pl.isGreen()) return darkGreen;
# Line 370 | Line 358 | public class Microscope extends JPanel {
358          else return Color.gray;
359      }
360  
373
361      class BoardPanel extends Canvas implements MouseListener {
362  
363          BoardPanel() {
# Line 438 | Line 425 | public class Microscope extends JPanel {
425  
426      /**
427       *  Player is just a glorified enumeration
428 <     **/
442 <
428 >     */
429      static final class Player {
430  
431          public static final int EMPTY = 0;
# Line 480 | Line 466 | public class Microscope extends JPanel {
466       * Boards are not immutable, but are never passed around across
467       * threads (instead new ones are constructed), so don't
468       * need any synch.
469 <     **/
470 <
485 <    static final class Board   {
469 >     */
470 >    static final class Board {
471  
472          /*
473             First, some Constants and utilities that might as well be here
# Line 538 | Line 523 | public class Microscope extends JPanel {
523  
524          }
525  
541
526          public static boolean inBounds(int row, int col) {
527              return (0 <= row)  && (row < RANKS) && (0 <= col) && (col < RANKS);
528          }
# Line 566 | Line 550 | public class Microscope extends JPanel {
550          long getBlue() { return blue_; }
551          long getGreen() { return green_; }
552  
569
553          public Player occupant(int row, int col) {
554              if ((0 <= row)  && (row < RANKS) && (0 <= col) && (col < RANKS)) {
555                  long m = 1L << (row + col * RANKS);
# Line 578 | Line 561 | public class Microscope extends JPanel {
561                  return Player.Illegal;
562          }
563  
564 <
582 <        // place a tile without taking opponent tiles
583 <
564 >        /** Places a tile without taking opponent tiles. */
565          public void occupy(Player player, int row, int col) {
566              long m = 1L << (row + col * RANKS);
567              long nm = ~m;
568 <            if (player.code_ == Player.BLUE)  {
568 >            if (player.code_ == Player.BLUE) {
569                  blue_ |= m;
570                  green_ &= nm;
571              }
# Line 604 | Line 585 | public class Microscope extends JPanel {
585              green_ &= nm;
586          }
587  
588 <
608 <
609 <        // place a tile, taking all adjacent tiles of opponent
610 <
588 >        /** Places a tile, taking all adjacent tiles of opponent. */
589          public void take(Player player, int row, int col) {
590 <            int k =  (row + col * RANKS);
590 >            int k = row + col * RANKS;
591              long dest = 1L << k;
592              long nbrMask = adjacentMasks[k];
593              long sourceBlue = blue_;
# Line 620 | Line 598 | public class Microscope extends JPanel {
598              }
599              else {
600                  blue_ = sourceBlue & ~(sourceBlue & nbrMask);
601 <                green_ =  sourceGreen | dest | (sourceBlue & nbrMask);
601 >                green_ = sourceGreen | dest | (sourceBlue & nbrMask);
602              }
603          }
604  
# Line 631 | Line 609 | public class Microscope extends JPanel {
609                  ((green_ & ~BLUEBIT) == 0);
610          }
611  
634
612          public int score(Player player) {
613              if (player.isBlue()) {
614                  return score(blue_, green_);
# Line 681 | Line 658 | public class Microscope extends JPanel {
658              return hb - ((lg + hg) & 0xff);
659          }
660  
684
685
661          static int slowscore(long b, long g) {
662              int score = 0;
663              for (int l = 0; l < CELLS; ++l) {
# Line 693 | Line 668 | public class Microscope extends JPanel {
668              }
669              return score;
670          }
696
697
671      }
672  
673      /**
674       * Moves represent transitions across Board states
675 <     **/
676 <
704 <
705 <    static final class Move  {
675 >     */
676 >    static final class Move {
677  
678          static final int NO_VALUE = -1;     // row/col value if not yet set
679          static final int PASS_VALUE = -2;   // special value for pass moves
# Line 756 | Line 727 | public class Microscope extends JPanel {
727  
728          // setters:
729  
730 <        synchronized void player(Player p)       { player_ = p;  }
731 <        synchronized void board(Board b)         { board_ = b;  }
732 <        synchronized void from(int sr, int sc)   { fromRow = sr; fromCol = sc;  }
730 >        synchronized void player(Player p)       { player_ = p; }
731 >        synchronized void board(Board b)         { board_ = b; }
732 >        synchronized void from(int sr, int sc)   { fromRow = sr; fromCol = sc; }
733          synchronized void to(int dr, int dc)     { toRow = dr;   toCol = dc; }
734  
735          //  accessors:
# Line 766 | Line 737 | public class Microscope extends JPanel {
737          synchronized boolean isFrom(int r, int c) {
738              return fromRow== r && fromCol == c;
739          }
740 <        synchronized boolean isTo(int r, int c)   {
740 >        synchronized boolean isTo(int r, int c) {
741              return toRow == r && toCol == c;
742          }
743          synchronized Board board() {
# Line 797 | Line 768 | public class Microscope extends JPanel {
768              return toRow != NO_VALUE && toCol != NO_VALUE;
769          }
770  
800
771          synchronized boolean possibleTo(int r, int c) { // is (r, c) a legal `to'?
772              return hasFrom() &&
773                  withinTwo(fromRow, r) &&
# Line 821 | Line 791 | public class Microscope extends JPanel {
791          synchronized void commit() { // update board to reflect move
792              if (!committed) {
793                  committed = true;
794 <                if (isLegal() && !isPass())  {
794 >                if (isLegal() && !isPass()) {
795                      if (isJump()) board_.occupy(Player.Empty, fromRow, fromCol);
796                      board_.take(player_, toRow, toCol);
797                  }
# Line 833 | Line 803 | public class Microscope extends JPanel {
803      /**
804       *  Mover is an abstract class to simplify code dealing with
805       *  either user moves or auto moves.
806 <     **/
807 <
838 <
839 <    static abstract class Mover {
806 >     */
807 >    abstract static class Mover {
808  
809          // caller for move callbacks
810          protected Microscope game;
# Line 855 | Line 823 | public class Microscope extends JPanel {
823      }
824  
825      /**
826 <     *  User builds moves via instructions/clicks by users
827 <     **/
860 <
826 >     * User builds moves via instructions/clicks by users
827 >     */
828      static class User extends Mover {
829  
830          private Move current;
# Line 909 | Line 876 | public class Microscope extends JPanel {
876  
877      }
878  
912
879      /**
880 <     *     AutoMover constructs Finders that compute actual moves
881 <     **/
916 <
880 >     * AutoMover constructs Finders that compute actual moves
881 >     */
882      static class AutoMover extends Mover {
883  
884          boolean cancelled = false;
# Line 923 | Line 888 | public class Microscope extends JPanel {
888              super(ap);
889          }
890  
926
891          public synchronized boolean placing() {
892              return currentFinder != null;
893          }
# Line 932 | Line 896 | public class Microscope extends JPanel {
896              currentFinder = null;
897          }
898  
935
899          public synchronized void cancel() {
900 <            if (placing())  {
900 >            if (placing()) {
901                  currentFinder.cancel(false);
902                  stopPlacing();
903              }
# Line 957 | Line 920 | public class Microscope extends JPanel {
920  
921      }
922  
960
923      /**
924 <     * Implements a classic all-possible-move search algorith using
924 >     * Implements a classic all-possible-move search algorithm using
925       * ForkJoinTasks.  The move finder is not all that smart. Among
926       * other possible improvements, it could keep a cache of explored
927       * moves and avoid repeating them. This would likely speed it up
928       * since most expansions are duplicates of others. It could also
929       * be changed to prune moves, although this is unlikely to work
930       * well without better partial evaluation functions.
931 <     **/
970 <
931 >     */
932      static class Finder extends RecursiveAction {
933  
934          static final int NOMOVE = Integer.MIN_VALUE;
# Line 1009 | Line 970 | public class Microscope extends JPanel {
970                  search();
971          }
972  
1012
973          final void search() {
974              int best = NOMOVE;    // For direct evaluation when level == 1
975              Finder forked = null; // list of forked subtasks when level > 1
976  
977              long open = ~(ours | theirs);  // currently empty cells
978 <            long here = 1;                 // travserse through bits
978 >            long here = 1;                 // traverse through bits
979  
980              for (int k = 0; k < Board.CELLS; ++k, here <<= 1) {
981                  if ((here & ours) != 0) {
# Line 1072 | Line 1032 | public class Microscope extends JPanel {
1032  
1033          /**
1034           * Join all subtasks and evaluate moves. Default is sub-finder version.
1035 <         * Overridden in RootFinder
1036 <         **/
1077 <
1035 >         * Overridden in RootFinder.
1036 >         */
1037          void collect(Finder forked) {
1038              int best = NOMOVE;
1039              while (forked != null) {
# Line 1105 | Line 1064 | public class Microscope extends JPanel {
1064          }
1065  
1066          /**
1067 <         * Cancel all forked subtasks in list
1068 <         **/
1110 <
1067 >         * Cancels all forked subtasks in list.
1068 >         */
1069          void cancelAll(Finder forked) {
1070              while (forked != null) {
1071                  forked.cancel(false);
# Line 1119 | Line 1077 | public class Microscope extends JPanel {
1077  
1078      /**
1079       * Root Finder class -- wait out other finders and issue callback to game.
1080 <     **/
1123 <
1080 >     */
1081      static class RootFinder extends Finder {
1082          final AutoMover automover;
1083          final Player player;
1084          RootFinder(Board board, Player p, int level, AutoMover automover) {
1085 <            super( (p.isBlue()? (board.getBlue()| Board.BLUEBIT) : board.getGreen()),
1086 <                   (p.isBlue()? board.getGreen() : (board.getBlue()| Board.BLUEBIT)),
1085 >            super( (p.isBlue() ? (board.getBlue()| Board.BLUEBIT) : board.getGreen()),
1086 >                   (p.isBlue() ? board.getGreen() : (board.getBlue()| Board.BLUEBIT)),
1087                     level,
1088                     null);
1089  
# Line 1134 | Line 1091 | public class Microscope extends JPanel {
1091              this.automover = automover;
1092          }
1093  
1137
1094          /**
1095           * This differs from default version by recording
1096           * and calling back with best move
1097 <         **/
1097 >         */
1098          void collect(Finder forked) {
1099              int best = NOMOVE;
1100              Finder bestFinder = null;
# Line 1185 | Line 1141 | public class Microscope extends JPanel {
1141  
1142                  long nextOurs = bestFinder.theirs;
1143                  long nextTheirs = bestFinder.ours;
1144 <                long blue = (player.isBlue())? nextOurs : nextTheirs;
1145 <                long green = (player.isBlue())? nextTheirs: nextOurs;
1144 >                long blue = player.isBlue() ? nextOurs : nextTheirs;
1145 >                long green = player.isBlue() ? nextTheirs : nextOurs;
1146                  move = new Move(player, new Board(blue, green), true);
1147              }
1148              automover.relay(move);
1149          }
1150      }
1195
1196
1151   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines