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 |
< |
**/ |
484 |
< |
|
481 |
> |
*/ |
482 |
|
static final class Board { |
483 |
|
|
484 |
|
/* |
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 |
|
} |
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 |
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 |
|
} |
848 |
|
} |
849 |
|
|
850 |
|
/** |
851 |
< |
* User builds moves via instructions/clicks by users |
852 |
< |
**/ |
858 |
< |
|
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 |
< |
**/ |
914 |
< |
|
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 |
< |
**/ |
968 |
< |
|
960 |
> |
*/ |
961 |
|
static class Finder extends RecursiveAction { |
962 |
|
|
963 |
|
static final int NOMOVE = Integer.MIN_VALUE; |
1062 |
|
|
1063 |
|
/** |
1064 |
|
* Join all subtasks and evaluate moves. Default is sub-finder version. |
1065 |
< |
* Overridden in RootFinder |
1066 |
< |
**/ |
1075 |
< |
|
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 |
< |
**/ |
1108 |
< |
|
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 |
< |
**/ |
1121 |
< |
|
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); |