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.*; |
19 |
|
* Microscope</a> version for instructions. |
20 |
|
* <p> |
21 |
|
* The code has been mangled beyond recognition |
22 |
< |
* as a test of ForkJoin |
23 |
< |
**/ |
24 |
< |
|
22 |
> |
* as a test of ForkJoin. |
23 |
> |
*/ |
24 |
|
public class Microscope extends JPanel { |
25 |
|
|
26 |
|
static final CountDownLatch cd = new CountDownLatch(1); |
229 |
|
boardPanel.repaint(); |
230 |
|
} |
231 |
|
|
232 |
< |
public void init() { |
232 |
> |
public void init() { |
233 |
|
initializeBoard(); |
234 |
|
if (autostart) { |
235 |
|
startMover(auto); |
242 |
|
if (lookAheads <= 1) lookAheads = 2; |
243 |
|
} |
244 |
|
|
245 |
< |
public int level () { return Microscope.lookAheads; } |
245 |
> |
public int level() { return Microscope.lookAheads; } |
246 |
|
|
247 |
|
|
248 |
|
// process a move (called only from mover) |
437 |
|
|
438 |
|
/** |
439 |
|
* Player is just a glorified enumeration |
440 |
< |
**/ |
442 |
< |
|
440 |
> |
*/ |
441 |
|
static final class Player { |
442 |
|
|
443 |
|
public static final int EMPTY = 0; |
478 |
|
* Boards are not immutable, but are never passed around across |
479 |
|
* threads (instead new ones are constructed), so don't |
480 |
|
* need any synch. |
481 |
< |
**/ |
482 |
< |
|
485 |
< |
static final class Board { |
481 |
> |
*/ |
482 |
> |
static final class Board { |
483 |
|
|
484 |
|
/* |
485 |
|
First, some Constants and utilities that might as well be here |
581 |
|
public void occupy(Player player, int row, int col) { |
582 |
|
long m = 1L << (row + col * RANKS); |
583 |
|
long nm = ~m; |
584 |
< |
if (player.code_ == Player.BLUE) { |
584 |
> |
if (player.code_ == Player.BLUE) { |
585 |
|
blue_ |= m; |
586 |
|
green_ &= nm; |
587 |
|
} |
606 |
|
// place a tile, taking all adjacent tiles of opponent |
607 |
|
|
608 |
|
public void take(Player player, int row, int col) { |
609 |
< |
int k = (row + col * RANKS); |
609 |
> |
int k = row + col * RANKS; |
610 |
|
long dest = 1L << k; |
611 |
|
long nbrMask = adjacentMasks[k]; |
612 |
|
long sourceBlue = blue_; |
617 |
|
} |
618 |
|
else { |
619 |
|
blue_ = sourceBlue & ~(sourceBlue & nbrMask); |
620 |
< |
green_ = sourceGreen | dest | (sourceBlue & nbrMask); |
620 |
> |
green_ = sourceGreen | dest | (sourceBlue & nbrMask); |
621 |
|
} |
622 |
|
} |
623 |
|
|
696 |
|
|
697 |
|
/** |
698 |
|
* Moves represent transitions across Board states |
699 |
< |
**/ |
700 |
< |
|
704 |
< |
|
705 |
< |
static final class Move { |
699 |
> |
*/ |
700 |
> |
static final class Move { |
701 |
|
|
702 |
|
static final int NO_VALUE = -1; // row/col value if not yet set |
703 |
|
static final int PASS_VALUE = -2; // special value for pass moves |
751 |
|
|
752 |
|
// setters: |
753 |
|
|
754 |
< |
synchronized void player(Player p) { player_ = p; } |
755 |
< |
synchronized void board(Board b) { board_ = b; } |
756 |
< |
synchronized void from(int sr, int sc) { fromRow = sr; fromCol = sc; } |
754 |
> |
synchronized void player(Player p) { player_ = p; } |
755 |
> |
synchronized void board(Board b) { board_ = b; } |
756 |
> |
synchronized void from(int sr, int sc) { fromRow = sr; fromCol = sc; } |
757 |
|
synchronized void to(int dr, int dc) { toRow = dr; toCol = dc; } |
758 |
|
|
759 |
|
// accessors: |
761 |
|
synchronized boolean isFrom(int r, int c) { |
762 |
|
return fromRow== r && fromCol == c; |
763 |
|
} |
764 |
< |
synchronized boolean isTo(int r, int c) { |
764 |
> |
synchronized boolean isTo(int r, int c) { |
765 |
|
return toRow == r && toCol == c; |
766 |
|
} |
767 |
|
synchronized Board board() { |
816 |
|
synchronized void commit() { // update board to reflect move |
817 |
|
if (!committed) { |
818 |
|
committed = true; |
819 |
< |
if (isLegal() && !isPass()) { |
819 |
> |
if (isLegal() && !isPass()) { |
820 |
|
if (isJump()) board_.occupy(Player.Empty, fromRow, fromCol); |
821 |
|
board_.take(player_, toRow, toCol); |
822 |
|
} |
828 |
|
/** |
829 |
|
* Mover is an abstract class to simplify code dealing with |
830 |
|
* either user moves or auto moves. |
831 |
< |
**/ |
832 |
< |
|
838 |
< |
|
839 |
< |
static abstract class Mover { |
831 |
> |
*/ |
832 |
> |
abstract static class Mover { |
833 |
|
|
834 |
|
// caller for move callbacks |
835 |
|
protected Microscope game; |
848 |
|
} |
849 |
|
|
850 |
|
/** |
851 |
< |
* User builds moves via instructions/clicks by users |
852 |
< |
**/ |
860 |
< |
|
851 |
> |
* User builds moves via instructions/clicks by users |
852 |
> |
*/ |
853 |
|
static class User extends Mover { |
854 |
|
|
855 |
|
private Move current; |
903 |
|
|
904 |
|
|
905 |
|
/** |
906 |
< |
* AutoMover constructs Finders that compute actual moves |
907 |
< |
**/ |
916 |
< |
|
906 |
> |
* AutoMover constructs Finders that compute actual moves |
907 |
> |
*/ |
908 |
|
static class AutoMover extends Mover { |
909 |
|
|
910 |
|
boolean cancelled = false; |
925 |
|
|
926 |
|
|
927 |
|
public synchronized void cancel() { |
928 |
< |
if (placing()) { |
928 |
> |
if (placing()) { |
929 |
|
currentFinder.cancel(false); |
930 |
|
stopPlacing(); |
931 |
|
} |
957 |
|
* since most expansions are duplicates of others. It could also |
958 |
|
* be changed to prune moves, although this is unlikely to work |
959 |
|
* well without better partial evaluation functions. |
960 |
< |
**/ |
970 |
< |
|
960 |
> |
*/ |
961 |
|
static class Finder extends RecursiveAction { |
962 |
|
|
963 |
|
static final int NOMOVE = Integer.MIN_VALUE; |
1005 |
|
Finder forked = null; // list of forked subtasks when level > 1 |
1006 |
|
|
1007 |
|
long open = ~(ours | theirs); // currently empty cells |
1008 |
< |
long here = 1; // travserse through bits |
1008 |
> |
long here = 1; // traverse through bits |
1009 |
|
|
1010 |
|
for (int k = 0; k < Board.CELLS; ++k, here <<= 1) { |
1011 |
|
if ((here & ours) != 0) { |
1062 |
|
|
1063 |
|
/** |
1064 |
|
* Join all subtasks and evaluate moves. Default is sub-finder version. |
1065 |
< |
* Overridden in RootFinder |
1066 |
< |
**/ |
1077 |
< |
|
1065 |
> |
* Overridden in RootFinder. |
1066 |
> |
*/ |
1067 |
|
void collect(Finder forked) { |
1068 |
|
int best = NOMOVE; |
1069 |
|
while (forked != null) { |
1094 |
|
} |
1095 |
|
|
1096 |
|
/** |
1097 |
< |
* Cancel all forked subtasks in list |
1098 |
< |
**/ |
1110 |
< |
|
1097 |
> |
* Cancels all forked subtasks in list. |
1098 |
> |
*/ |
1099 |
|
void cancelAll(Finder forked) { |
1100 |
|
while (forked != null) { |
1101 |
|
forked.cancel(false); |
1107 |
|
|
1108 |
|
/** |
1109 |
|
* Root Finder class -- wait out other finders and issue callback to game. |
1110 |
< |
**/ |
1123 |
< |
|
1110 |
> |
*/ |
1111 |
|
static class RootFinder extends Finder { |
1112 |
|
final AutoMover automover; |
1113 |
|
final Player player; |
1114 |
|
RootFinder(Board board, Player p, int level, AutoMover automover) { |
1115 |
< |
super( (p.isBlue()? (board.getBlue()| Board.BLUEBIT) : board.getGreen()), |
1116 |
< |
(p.isBlue()? board.getGreen() : (board.getBlue()| Board.BLUEBIT)), |
1115 |
> |
super( (p.isBlue() ? (board.getBlue()| Board.BLUEBIT) : board.getGreen()), |
1116 |
> |
(p.isBlue() ? board.getGreen() : (board.getBlue()| Board.BLUEBIT)), |
1117 |
|
level, |
1118 |
|
null); |
1119 |
|
|
1125 |
|
/** |
1126 |
|
* This differs from default version by recording |
1127 |
|
* and calling back with best move |
1128 |
< |
**/ |
1128 |
> |
*/ |
1129 |
|
void collect(Finder forked) { |
1130 |
|
int best = NOMOVE; |
1131 |
|
Finder bestFinder = null; |
1172 |
|
|
1173 |
|
long nextOurs = bestFinder.theirs; |
1174 |
|
long nextTheirs = bestFinder.ours; |
1175 |
< |
long blue = (player.isBlue())? nextOurs : nextTheirs; |
1176 |
< |
long green = (player.isBlue())? nextTheirs: nextOurs; |
1175 |
> |
long blue = player.isBlue() ? nextOurs : nextTheirs; |
1176 |
> |
long green = player.isBlue() ? nextTheirs : nextOurs; |
1177 |
|
move = new Move(player, new Board(blue, green), true); |
1178 |
|
} |
1179 |
|
automover.relay(move); |