1 importjava.awt.Color;2 importjava.awt.Font;3 importjava.awt.Image;4 importjava.awt.event.ActionEvent;5 importjava.awt.event.ActionListener;6 importjava.awt.event.KeyEvent;7 importjava.awt.event.MouseAdapter;8 importjava.awt.event.MouseEvent;9 importjava.io.File;10 importjava.io.FileNotFoundException;11 importjava.io.IOException;12 importjava.io.PrintWriter;13 importjava.text.SimpleDateFormat;14 importjava.util.Date;15 importjava.util.Scanner;16
17 importjavax.imageio.ImageIO;18 importjavax.management.MBeanOperationInfo;19 importjavax.swing.ImageIcon;20 importjavax.swing.JFileChooser;21 importjavax.swing.JFrame;22 importjavax.swing.JLabel;23 importjavax.swing.JLayeredPane;24 importjavax.swing.JMenu;25 importjavax.swing.JMenuBar;26 importjavax.swing.JMenuItem;27 importjavax.swing.JOptionPane;28
29
30
31 public classChineseChecker {32
33 public staticMyFrame myFrame;34 public static int numberOfPlayers; //游戏玩家的数量
35 public static boolean numbersDone = false;//游戏玩家数量是否设定完毕
36 public static boolean gameStatus = false;//游戏状态(是否暂停)
37 public static char[] series = new char[6];//六种棋子
38 public static int currentIndex = 0;//当前下标
39 public static String pieceToMove;//将要移动的棋子
40 public static int []piecePos;//记录棋子位置
41 public static boolean isPieceToMoveAcquired = false;//是否已经选中将要移动的棋子
42 public static boolean isTheStartingOfTheGame = false;//游戏是否开始
43 public static boolean isPositionToGoToAcquired = false;//将要去的位置是否设定完毕
44 public static int[] posToGoTo;45 public static boolean isANewGame = false;46
47 public static voidmain(String[] args) {48 //TODO Auto-generated method stub
49 myFrame = new MyFrame();//实例化窗口
50 myFrame.setSize(710, 870);//设置窗口大小
51 myFrame.setVisible(true);//窗口可见
52 Pieces pieces = new Pieces();//实例化棋子类
53
54 /**等待设定游戏玩家数量**/
55 while(!numbersDone){56 try{57 Thread.sleep(500);58 } catch(InterruptedException e) {59 //TODO Auto-generated catch block
60 e.printStackTrace();61 }62 }63 numbersDone = false;64
65 /*
66 * 游戏分为双人对战,四人对战和六人对战67 */
68 switch(numberOfPlayers) {69 case 2:70 series[0] = 'D';series[1] = 'A';71 break;72 case 4:73 series[0] = 'F';series[1] = 'B';series[2] = 'C';series[3] = 'E';74 break;75 case 6:76 series[0] = 'F';series[1] = 'A';series[2] = 'B';series[3] = 'C';series[4] = 'D';series[5] = 'E';77 break;78 default:79 break;80 }81 //pieces.init();
82 myFrame.init(series);83 initPlayers(series);84
85 pieces.init();86
87 /**一旦玩家数量设定完成,游戏开始**/
88 isTheStartingOfTheGame = true;89
90 while (true) {91 Trace.isSkipped = false;92
93 Trace.nextStep();94
95 //展示当前玩家
96 myFrame.showCurrent();97 myFrame.showCurrentPlayer();98 MyFrame.timer = newTimer();99
100
101 while (!isPositionToGoToAcquired) {102
103 if (MyFrame.timer.listen() <= 0) {//如果玩家超时
104 if (isPieceToMoveAcquired) //如果将要移动的的棋子设定过
105 PieceActionListener.clearPossiblePos();//清除之前的可能移动到的合法位置标记
106 pieceToMove = series[currentIndex] + "0";107 piecePos = Pieces.getPiecePos("A0 ");108 posToGoTo =piecePos ;109 Services.msg("Player " + series[currentIndex] + " time exceeded!");//提示玩家超时
110 break;111 }112 if (Trace.isSkipped)//如果已经跳过了,就退出
113 break;114 try{115 Thread.sleep(0500);116 } catch(InterruptedException e) {117 //TODO Auto-generated catch block
118 e.printStackTrace();119 }120 }121 if (Trace.isSkipped) continue;//如果已经跳过了,就到下一次循环
122 isPositionToGoToAcquired = false;123 if(isANewGame) {124 isANewGame = false;125 continue;126 }127 /*记录轨迹*/
128 Pieces.moveAward(pieceToMove, piecePos, posToGoTo);129 Trace.recordStep(pieceToMove, piecePos, posToGoTo);130
131 /*判断是否出现胜利者*/
132 for (int order = 0; order < numberOfPlayers; order++) {133 if(isWinner(series[order])) {134 Services.msg("Player " + series[order] + " wins!");135 System.exit(0);136 }137 }138 Trace.step = Trace.step + 1;139 }140 }141
142 public static void setNumber(int number){//设定游戏玩家数量
143 ChineseChecker.numbersDone = true;144 ChineseChecker.gameStatus = true;145 ChineseChecker.numberOfPlayers =number;146 ChineseChecker.myFrame.mNewGame.setEnabled(false);147 }148
149 public static void initPlayers(char[] players) {//初始化players
150 for (charplayer : players) {151 if (player == 0)152 return;153 int[][] initPositions = myFrame.zoneOfPlayer[player - 'A'];154 for (int index = 0; index < 10; index++) {155 Pieces.cell[initPositions[index][0]][initPositions[index][1]] = "" + player + index + " ";156 }157 }158 }159
160 public static boolean isWinner(char player) {//判断player是否已经获胜
161 char opponentPlayer = player < 'D' ? (char) ((int) player + 3) : (char) ((int) player - 3);162
163 int[][] positionsBelongedToThePlayer = MyFrame.zoneOfPlayer[opponentPlayer - 'A'];164
165 for (int index = 0; index < 10; index++) {166 int[] position =positionsBelongedToThePlayer[index];167 if (Pieces.cell[position[0]][position[1]].charAt(0) !=player)168 return false;169 }170 return true;171 }172
173 }174
175 class MyFrame extendsJFrame{176
177 publicImage image;178
179 publicImageIcon imgBoard;180 public staticJLayeredPane panel;181 public staticJLabel lblBoard,lblPlayer,lblTime,lblCurrent;182 publicJMenuBar menuBar;183 public JMenu mControl = new JMenu("control"),184 mNewGame = new JMenu("New Game");185 public JMenuItem mTwoPlayers = new JMenuItem("Two players"),186 mFourPlayers = new JMenuItem("Four players"),187 mSixPlayers = new JMenuItem("Six players"),188 mExit = new JMenuItem("Exit", KeyEvent.VK_X),189 mPauseGame = new JMenuItem("Pause Game", KeyEvent.VK_P),190 mOpen = new JMenuItem("Open",KeyEvent.VK_O),191 mSave = new JMenuItem("Save",KeyEvent.VK_S);192 public JLabel[][] pieces = new JLabel[6][10];193 public static final int[][][] zoneOfPlayer ={194 {{5, 1}, {5, 2}, {6, 2}, {5, 3}, {6, 3}, {7, 3}, {5, 4}, {6, 4}, {7, 4}, {8, 4}},195 {{1, 5}, {2, 6}, {2, 5}, {3, 7}, {3, 6}, {3, 5}, {4, 8}, {4, 7}, {4, 6}, {4, 5}},196 {{5, 13}, {6, 13}, {5, 12}, {7, 13}, {6, 12}, {5, 11}, {8, 13}, {7, 12}, {6, 11}, {5, 10}},197 {{13, 17}, {13, 16}, {12, 16}, {13, 15}, {12, 15}, {11, 15}, {13, 14}, {12, 14}, {11, 14}, {10, 14}},198 {{17, 13}, {16, 12}, {16, 13}, {15, 11}, {15, 12}, {15, 13}, {14, 10}, {14, 11}, {14, 12}, {14, 13}},199 {{13, 5}, {12, 5}, {13, 6}, {11, 5}, {12, 6}, {13, 7}, {10, 5}, {11, 6}, {12, 7}, {13, 8}}};200 public staticTimer timer;201 publicMyFrame(){202
203 imgBoard = new ImageIcon("Board.jpg");204 lblTime = newJLabel();205 lblTime.setForeground(Color.BLUE);206 lblTime.setFont(new Font("黑体", Font.BOLD, 20));207 lblTime.setBounds(50, 50, 280, 30);208
209 lblCurrent = new JLabel("当前玩家");210 lblCurrent.setFont(new Font("当前玩家", 20, 20));211 lblCurrent.setBounds(40, 80, 200, 30);212
213 lblBoard = newJLabel(imgBoard);214 lblBoard.setBounds(0, 20, 685, 800);215
216 lblPlayer = new JLabel(newImageIcon());217 lblPlayer.setBounds(50, 100, 50, 50);218
219 panel = newJLayeredPane();220 panel.add(lblBoard,JLayeredPane.DEFAULT_LAYER);221 panel.add(lblPlayer, JLayeredPane.MODAL_LAYER);222 panel.add(lblTime, JLayeredPane.MODAL_LAYER);223
224
225 setLayeredPane(panel);226
227 mControl.setMnemonic(KeyEvent.VK_C);228 mControl.add(mOpen);229 mControl.add(mSave);230 mControl.add(mNewGame);231 mControl.add(mPauseGame);232
233 mNewGame.add(mTwoPlayers);234 mNewGame.add(mFourPlayers);235 mNewGame.add(mSixPlayers);236
237 menuBar = newJMenuBar();238 menuBar.add(mControl);239 setJMenuBar(menuBar);240
241 /**设置两个玩家、四个玩家或六个玩家**/
242 mTwoPlayers.addActionListener(newActionListener() {243 @Override244 public voidactionPerformed(ActionEvent e) {245 //TODO Auto-generated method stub
246 ChineseChecker.setNumber(2);247 }248 });249 mFourPlayers.addActionListener(newActionListener() {250 @Override251 public voidactionPerformed(ActionEvent e) {252 //TODO Auto-generated method stub
253 ChineseChecker.setNumber(4);254 }255 });256 mSixPlayers.addActionListener(newActionListener() {257 @Override258 public voidactionPerformed(ActionEvent e) {259 //TODO Auto-generated method stub
260 ChineseChecker.setNumber(6);261 }262 });263 /**暂停游戏**/
264 mPauseGame.addActionListener(newActionListener() {265 @Override266 public voidactionPerformed(ActionEvent e) {267 //TODO Auto-generated method stub
268 ChineseChecker.gameStatus = false;269 }270 });271
272 mOpen.addActionListener(new ActionListener() {//打开已保存过的游戏
273 @Override274 public voidactionPerformed(ActionEvent arg0) {275 JFileChooser chooser = newJFileChooser();276 chooser.showOpenDialog(null);277
278 try{279 File file =chooser.getSelectedFile();280 if (file == null) {281 throw new Exception("FileNotExisted");282 }283 Scanner scanner = newScanner(file);284 String[] temp = scanner.nextLine().split(",");285 int num = Integer.parseInt(temp[0]);286 char cur = temp[1].charAt(0);287 int curIndex = Integer.parseInt(temp[2]);288 int step = Integer.parseInt(temp[3]);289
290 ChineseChecker.numbersDone = true;291 if (!(ChineseChecker.numberOfPlayers == num) && !ChineseChecker.isTheStartingOfTheGame)292 throw new Exception("PlayersNumberUnmatched");293 ChineseChecker.numberOfPlayers =num;294 System.out.println(num);295 ChineseChecker.currentIndex =curIndex;296 ChineseChecker.series[curIndex] =cur;297 Trace.step =step;298 //Diagram.getDiagram().init();
299
300 while (!ChineseChecker.isTheStartingOfTheGame) {301 }302 while(scanner.hasNext()) {303 in(scanner.nextLine());304 }305 ChineseChecker.myFrame.mNewGame.setEnabled(false);306 ChineseChecker.isANewGame = true;307 ChineseChecker.isPositionToGoToAcquired = true;308 } catch(FileNotFoundException e) {309 //e.printStackTrace();
310 } catch(Exception e) {311 Services.msg("Import failed: " +e.getMessage());312 }313 }314
315 public voidin(String line) {316 String[] temp = line.split(",");317 String piece = temp[0] + " ";318 int i = Integer.parseInt(temp[1]), j = Integer.parseInt(temp[2]);319 int player = piece.charAt(0) - 65;320 int index = piece.charAt(1) - 48;321 Pieces.pieces[player][index][0] =i;322 Pieces.pieces[player][index][1] =j;323 Pieces.cell[i][j] =piece;324 int[] pos ={i, j};325 ChineseChecker.myFrame.move(piece,pos);326 }327 });328
329 mSave.addActionListener(new ActionListener() {//保存当前游戏
330
331 @Override332 public voidactionPerformed(ActionEvent arg0) {333 JFileChooser chooser = newJFileChooser();334 chooser.showOpenDialog(null);335 File file =chooser.getSelectedFile();336
337 PrintWriter writer;338 try{339 writer = newPrintWriter(file);340 writer.write(newOutput().s);341 writer.close();342 } catch(FileNotFoundException e) {343 //e.printStackTrace();
344 } catch(Exception e) {345 Services.msg("Export failed!");346 }347 }348
349 classOutput {350 String s = "";351
352 Output() {353 out();354 }355
356 voidout() {357 int num =ChineseChecker.numberOfPlayers;358 System.out.println(num);359 int[] position;360 s +=num;361 char cur =ChineseChecker.series[ChineseChecker.currentIndex];362 s += "," +cur;363 int curIndex =ChineseChecker.currentIndex;364 s += "," +curIndex;365 int step =Trace.step;366 s += "," +step;367 char[][] player = {null, null, {'A', 'D'}, {'A', 'C', 'E'},368 {'B', 'C', 'E', 'F'}, null,369 {'A', 'B', 'C', 'D', 'E', 'F'}};370 for (int i = 0; i < 10; i++) {371 for (charj : player[num]) {372 position = Pieces.getPiecePos(j - 65, i);373 s += "\n" + j + i + "," + position[0] + "," + position[1];374 }375 }376 }377 }378 });379
380 TimerThread timerThread = new TimerThread("Timer");381 timerThread.start();382
383 }384
385 public voidshowCurrent() {386 panel.add(lblCurrent, JLayeredPane.MODAL_LAYER);387 }388
389 public void move(String pieceToMove, int[] targetPosition) {390 char playerOnTheMove = pieceToMove.charAt(0);391 int index = pieceToMove.charAt(1) - '0';392 int x = Map.map[targetPosition[0]][targetPosition[1]][0];393 int y = Map.map[targetPosition[0]][targetPosition[1]][1];394
395 pieces[playerOnTheMove - 'A'][index].setBounds(x, y, 39, 39);396 }397
398 public void init(char[] playerSeries) {399 for (charplayer : playerSeries) {400 if (player == 0)401 return;402 initPlayer(player);403 }404 }405
406 private void initPlayer(charplayer) {407 for (int pieceIndex = 0; pieceIndex < 10; pieceIndex++) {408 initPiece(player, pieceIndex);409 }410 }411
412 private void initPiece(char player, intpieceIndex) {413 //Image image =
414 Map myMap = newMap();415 int playerIndex = player - 'A';416 int[] pieceSeries = zoneOfPlayer[player - 'A'][pieceIndex];417 int x = myMap.map[pieceSeries[0]][pieceSeries[1]][0];418 int y = myMap.map[pieceSeries[0]][pieceSeries[1]][1];419
420 pieces[playerIndex][pieceIndex] = new JLabel(new ImageIcon("Piece_" + player + ".PNG"));421 pieces[playerIndex][pieceIndex]422 .addMouseListener(new PieceActionListener("" + player +pieceIndex));423
424 pieces[playerIndex][pieceIndex].setBounds(x, y, 39, 39);425 panel.add(pieces[playerIndex][pieceIndex], JLayeredPane.MODAL_LAYER);426 }427
428 public static voidshowCurrentPlayer() {429
430 lblPlayer.setIcon(new ImageIcon("Piece_" + ChineseChecker.series[ChineseChecker.currentIndex] + ".PNG"));431 panel.repaint();432 }433
434
435 class TimerThread extendsThread {436 TimerThread(String name) {437 super(name);438 }439
440 @Override441 public voidrun() {442 while (true) {443 lblTime.setText(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(newDate()));444 panel.repaint();445 try{446 Thread.sleep(0500);447 } catch(InterruptedException e) {448 e.printStackTrace();449 }450 }451 }452 }453
454 }455
456 class Map {//map记录棋盘上每个点在myFrame中的坐标457 //map[i][j][0]表示点(i,j)在棋盘中的横坐标,map[i][j][1]表示点(i,j)在棋盘中的纵坐标
458 public static int [][][] map = new int[18][18][2];459 public Map(){//计算各点坐标,并将其存入map中
460 for (int i = 5; i <= 5; i++)461 setSinglePosition(i, 1, 325 + 51 * (i - 5), 780 + 0 * (i - 5));462 for (int i = 5; i <= 6; i++)463 setSinglePosition(i, 2, 325 - 28 + 54 * (i - 5), 780 - 47);464 for (int i = 5; i <= 7; i++)465 setSinglePosition(i, 3, 325 - 28 * 2 + 54 * (i - 5), 780 - 47*2);466 for (int i = 5; i <= 8; i++)467 setSinglePosition(i, 4, 325 - 28 * 3 + 54 * (i - 5), 780 - 47*3);468 for (int i = 1; i <= 13; i++)469 setSinglePosition(i, 5, 0 + 28 * 0 + 54 * (i - 1), 780 - 47*4);470 for (int i = 2; i <= 13; i++)471 setSinglePosition(i, 6, 0 + 28 * 1 + 54 * (i - 2), 780 - 47*5);472 for (int i = 3; i <= 13; i++)473 setSinglePosition(i, 7, 0 + 28 * 2 + 54 * (i - 3), 780 - 47*6);474 for (int i = 4; i <= 13; i++)475 setSinglePosition(i, 8, 0 + 28 * 3 + 54 * (i - 4), 780 - 47*7);476 for (int i = 5; i <= 13; i++)477 setSinglePosition(i, 9, 0 + 28 * 4 + 54 * (i - 5), 780 - 47*8);478 for (int i = 5; i <= 14; i++)479 setSinglePosition(i, 10, 0 + 28 * 3 + 54 * (i - 5), 780 - 47*9);480 for (int i = 5; i <= 15; i++)481 setSinglePosition(i, 11, 0 + 28 * 2 + 54 * (i - 5), 780 - 47*10);482 for (int i = 5; i <= 16; i++)483 setSinglePosition(i, 12, 0 + 28 * 1 + 54 * (i - 5), 780 - 47*11);484 for (int i = 5; i <= 17; i++)485 setSinglePosition(i, 13, 0 + 28 * 0 + 54 * (i - 5), 780 - 47*12);486 for (int i = 10; i <= 13; i++)487 setSinglePosition(i, 14, 325 - 28 * 3 + 54 * (i - 10), 780 - 47*13);488 for (int i = 11; i <= 13; i++)489 setSinglePosition(i, 15, 325 - 28 * 2 + 54 * (i - 11),780 - 47*14);490 for (int i = 12; i <= 13; i++)491 setSinglePosition(i, 16, 325 - 28 * 1 + 54 * (i - 12), 780 - 47*15);492 for (int i = 13; i <= 13; i++)493 setSinglePosition(i, 17, 325 - 28 * 0 + 54 * (i - 13), 780 - 47*16);494 }495 public void setSinglePosition(int i,int j,double x,doubley){496 map[i][j][0] = (int)x;497 map[i][j][1] = (int)y;498 }499 }500
501 class Pieces {//棋子类
502 public static int [][][] pieces = new int [6][10][2];503 public static String [][] cell = new String[20][20];504 public final static String EMPTY_MARK = "** ";505 public final static String OUTSIDE_MARK = " ";506 public final static String SPACE_MARK = " ";507
508 publicPieces(){509
510 for (int i = 1; i <= 17; i++)511 for (int j = 1; j <= 17; j++)512 cell[i][j]= OUTSIDE_MARK;//初始化认为所有cell都在棋盘外
513
514 /**将所有在棋盘内的cell标记为EMPTY_MARK**/
515 for (int j = 1; j <= 4; j++)516 for (int i = 5; i <= j + 4; i++)517 cell[i][j]=EMPTY_MARK;518 for (int j = 5; j <= 8; j++)519 for (int i = j - 4; i <= 13; i++)520 cell[i][j]=EMPTY_MARK;521 for (int j = 9; j <= 13; j++)522 for (int i = 5; i <= j + 4; i++)523 cell[i][j]=EMPTY_MARK;524 for (int j = 14; j <= 17; j++)525 for (int i = j - 4; i <= 13; i++)526 cell[i][j]=EMPTY_MARK;527 }528 public void init(){//初始化
529 for (int i = 1;i <= 17;++i){530 for (int j = 1;j <= 17;++j){531 if (cell[i][j].charAt(0) >= 65 && cell[i][j].charAt(0) <= 70){532 setPosition(cell[i][j],i,j);533 }534 }535 }536 }537
538 public void setPosition(String s,int x,inty){539 int player = s.charAt(0) - 65;540 int index = s.charAt(1) -48;541 pieces[player][index][0] =x;542 pieces[player][index][1] =y;543 }544
545 public static void setPiecePos(String piece, int[] value) {546 int player = piece.charAt(0) - 65;547 int index = piece.charAt(1) - 48;548 pieces[player][index] =value;549 }550
551 public static int[] getPiecePos(String piece) {552 int player = piece.charAt(0) - 65;553 int index = piece.charAt(1) - 48;554 return new int[]{pieces[player][index][0], pieces[player][index][1]};555 }556
557 public static int[] getPiecePos(int player, intindex) {558 return new int[]{pieces[player][index][0], pieces[player][index][1]};559 }560
561 public static void moveAward(String piece, int[] prevPos, int[] postPos) {//前进
562 setPiecePos(piece, postPos);563 cell[prevPos[0]][prevPos[1]] =EMPTY_MARK;564 cell[postPos[0]][postPos[1]] = piece +SPACE_MARK;565 }566
567 public static classNext {568
569
570 public static int[][] getPossiblePosition(String pieceToMove) {571 /**
572 * get all possible positions via adjacent hop/distant/consecutive hops.573 */
574 int[] piecePosition =Pieces.getPiecePos(pieceToMove);575 int[][] possiblePosition =distantHopping(piecePosition);576
577
578 cell[piecePosition[0]][piecePosition[1]] = " ";579 //apply Breadth-First-Search to accomplish consecutive hops
580 for (int k = 0; possiblePosition[k][0] != 0; k++) {581 int[][] recursion =distantHopping(possiblePosition[k]);582 possiblePosition =Services.concatTwoArrays(possiblePosition, recursion);583 }584 possiblePosition =Services.concatTwoArrays(possiblePosition, adjacentHopping(piecePosition));585
586 cell[piecePosition[0]][piecePosition[1]] =pieceToMove;587 returnpossiblePosition;588 }589
590 public static intgetPossiblePositionCount(String pieceToMove) {591 int count = 0;592 int[][] possiblePosition =getPossiblePosition(pieceToMove);593
594 for (int k = 0; possiblePosition[k][0] != 0; k++) {595 count++;596 }597 returncount;598 }599
600 private static int[][] adjacentHopping(int[] piecePosition) {601
602 int[][] possiblePositions = new int[100][2];603 int pointer = 0;604 int[] displacementAdjacent = {-1, 0, 1};605 //(-1,-1)(-1,0)(0,-1)(0,1)(1,0)(1,1)
606
607 for (inti : displacementAdjacent) {608 for (intj : displacementAdjacent) {609 //check whether the adjacent position is empty
610 String current = cell[piecePosition[0] + i][piecePosition[1] +j];611 if (current == EMPTY_MARK && i != -j) {612 possiblePositions[pointer][0] = piecePosition[0] +i;613 possiblePositions[pointer][1] = piecePosition[1] +j;614 pointer++;615 }616 }617 }618 returnpossiblePositions;619 }620
621 private static int[][] distantHopping(int[] piecePosition) {622 int[][] possiblePos = new int[100][2];623 int[] displacement = {-1, 0, 1};624 //stores possible direction
625
626 for (intx : displacement) {627 for (inty : displacement) {628 possiblePos =Services.concatTwoArrays(possiblePos,629 distantHoppingForOneDirection(x, y, piecePosition, true));630 }631 }632
633 returnpossiblePos;634 }635
636 public static booleanisPosInsideDiagram(String position) {637 return !(position == OUTSIDE_MARK || position == null);638 }639
640 private static int[][] distantHoppingForOneDirection(int x, inty,641 int[] piecePos, booleanisDistantHoppingDisabled) {642 /*
643 * x: indicates up or down moveAward in x direction. y: indicates up or down644 * moveAward in x direction645 */
646 int[][] possiblePos = new int[100][2];647 int[] displacement = (isDistantHoppingDisabled)?new int[]{1}:new int[]{1, 2, 3, 4, 5, 6, 7, 8};648 //stores possible displacements of coordinates in each direction
649 int pointer = 0;650 booleanisDeadDirection;651
652 for (inti : displacement) {653 //avoid illegal direction
654 if (x * y == -1)655 continue;656 //avoid array index out of bound
657 boolean isiInside = (x == 0) || ((x == -1) ? piecePos[0] > 1 + 1 : piecePos[0] < 17 - 1);658 boolean isjInside = (y == 0) || ((y == -1) ? piecePos[1] > 1 + 1 : piecePos[1] < 17 - 1);659 boolean isInside =isiInside660 &&isjInside661 && isPosInsideDiagram(cell[piecePos[0] + i * 2 * x - 1 * x][piecePos[1] + i* 2 * y - 1 *y])662 && isPosInsideDiagram(cell[piecePos[0] + i * 2 * x][piecePos[1] + i * 2 *y]);663 if (!isInside)664 break;665 boolean isAvailable = (isDeadDirection = !(cell[piecePos[0] + i * x][piecePos[1] + i * y] ==EMPTY_MARK)666 && cell[piecePos[0] + i * 2 * x][ piecePos[1] + i * 2 * y] ==EMPTY_MARK);667
668 label1:669 if(isAvailable) {670 //position between object position and hopped piece671 //ought to be empty
672 for (int ii = i + 1; ii < 2 * i; ii++) {673 if (cell[piecePos[0] + ii * x][piecePos[1] + ii * y] !=EMPTY_MARK) {674 isDeadDirection = true;675 breaklabel1;676 }677 }678 possiblePos[pointer][0] = piecePos[0] + i * 2 *x;679 possiblePos[pointer][1] = piecePos[1] + i * 2 *y;680 pointer++;681 }682
683 if(isDeadDirection)684 break;685 }686 returnpossiblePos;687 }688
689 }690 }691
692 class PieceActionListener extends MouseAdapter{//棋子事件侦听
693 private final static ImageIcon imgPossiblePosition = new ImageIcon("Piece_Transparant.PNG");694 private static booleanisPieceSelected;695 private static JLabel[] lblPossible = new JLabel[50];696 private int[][] possiblePos = new int[50][2];697 privateString piece;698
699 publicPieceActionListener(String piece) {700 this.piece = piece + " ";701 }702
703 public static void clearPossiblePos() {//清空可能到达的位置
704 for (int index = 0; lblPossible[index] != null; index++) {705 ChineseChecker.myFrame.panel.remove(lblPossible[index]);706 }707 ChineseChecker.myFrame.repaint();708 isPieceSelected = false;709 }710
711 @Override712 public void mouseClicked(MouseEvent arg0) {//鼠标点击事件处理
713 if (ChineseChecker.series[ChineseChecker.currentIndex] != piece.charAt(0))714 return;715 if (!ChineseChecker.gameStatus)716 return;717
718 clearPossiblePos();719 showPossiblePos();720 isPieceSelected = true;721 ChineseChecker.pieceToMove = piece.substring(0, 2);722 ChineseChecker.piecePos = new int[]{Pieces.pieces[piece.charAt(0) - 65][piece.charAt(1) - 48][0],723 Pieces.pieces[piece.charAt(0) - 65][piece.charAt(1) - 48][1]};724 ChineseChecker.isPieceToMoveAcquired = true;725 }726
727 @Override728 public void mouseEntered(MouseEvent arg0) {//鼠标移动事件处理
729 if (!ChineseChecker.gameStatus)730 return;731 if (ChineseChecker.series[ChineseChecker.currentIndex] != piece.charAt(0))732 return;733 if(isPieceSelected)734 return;735 showPossiblePos();736 }737
738 @Override739 public void mouseExited(MouseEvent arg0) {//鼠标挪开事件处理
740 if(isPieceSelected)741 return;742 for (int k = 0; lblPossible[k] != null; k++) {743 ChineseChecker.myFrame.panel.remove(lblPossible[k]);744 ChineseChecker.myFrame.repaint();745 }746 }747
748 public void showPossiblePos() {//展示可能到达的位置
749 possiblePos =Pieces.Next.getPossiblePosition(piece);750 for (int k = 0; k < possiblePos.length && possiblePos[k][0] != 0; k++) {751 lblPossible[k] = newJLabel(imgPossiblePosition);752 lblPossible[k].addMouseListener(newPossiblePositionListener(piece,753 possiblePos[k]));754 ChineseChecker.myFrame.panel.add(lblPossible[k], JLayeredPane.MODAL_LAYER);755 int[] positionInCanvas = Map.map[possiblePos[k][0]][possiblePos[k][1]];756 lblPossible[k].setBounds(positionInCanvas[0], positionInCanvas[1], 39, 39);757 }758 }759 }760
761 class PossiblePositionListener extendsMouseAdapter {762
763 public staticString piece;764 public int[] position = new int[2];765 public final static String EMPTY_MARK = "** ";766 public final static String OUTSIDE_MARK = " ";767 public final static String SPACE_MARK = " ";768 PossiblePositionListener(String piece, int[] position) {769 this.piece =piece;770 this.position =position;771 }772
773 @Override774 public voidmouseClicked(MouseEvent arg0) {775 if (!ChineseChecker.gameStatus)776 return;777
778 Pieces.cell[Pieces.getPiecePos(piece)[0]][Pieces.getPiecePos(piece)[1]] =EMPTY_MARK;779 Pieces.cell[position[0]][position[1]] = piece +SPACE_MARK;780
781 ChineseChecker.myFrame.move(piece, position);782 PieceActionListener.clearPossiblePos();783 ChineseChecker.posToGoTo =position;784 ChineseChecker.isPositionToGoToAcquired = true;785 }786
787 }788
789 classServices {790
791 public static voidmsg(String content) {792 JOptionPane.showMessageDialog(null, content, "Chinese Checkers",793 JOptionPane.INFORMATION_MESSAGE);794 }795
796 public staticString in(String content) {797 return JOptionPane.showInputDialog(null, content, "Chinese Checkers",798 JOptionPane.INFORMATION_MESSAGE);799 }800
801
802 public static int[][] concatTwoArrays(int[][] targetArray, int[][] temporaryArray) {803 /**combine two 2D arrays into one.*/
804 int pointer = 0;//point to the operating index of a1
805 while (targetArray[pointer][0] != 0) {806 pointer++;807 }808 for (int j = 0; ; j++) {809 boolean isRepeated = false;810 if (temporaryArray[j][0] == 0)811 break;812 for (int i = 0; i < pointer; i++)813 if (temporaryArray[j][0] == targetArray[i][0] && temporaryArray[j][1] == targetArray[i][1]) {814 isRepeated = true;815 break;816 }817 if (!isRepeated)818 targetArray[pointer++] =temporaryArray[j];819 }820 returntargetArray;821 }822 }823
824 classTimer {825
826 private longstartingTime;827 private longinterruptedTime;828 private booleanpaused;829
830 publicTimer() {831 this.startingTime =System.currentTimeMillis();832 }833
834 public longlisten() {835 if(paused)836 return (30000 - interruptedTime + startingTime) / 1000;837 long cur =System.currentTimeMillis();838 return (30000 - cur + startingTime) / 1000;839 }840
841 public voidpause() {842 this.interruptedTime =System.currentTimeMillis();843 this.paused = true;844 }845 }846
847 classTrace {848
849 public static final int MAX_STACK_SIZE = 1000;850 public static int step = 1;851 public static booleanisSkipped;852 public static String[] pieceStack = newString[MAX_STACK_SIZE];853 public static int[][] prevPosStack = new int[MAX_STACK_SIZE][2];854 public static int[][] postPosStack = new int[MAX_STACK_SIZE][2];855
856 public booleanisSkipped() {857 returnisSkipped;858 }859
860 public static void recordStep(String piece, int[] prev, int[] post) {861 pieceStack[step] =piece;862 prevPosStack[step] =prev;863 postPosStack[step] =post;864 }865
866 public static voidnextStep() {867 ChineseChecker.currentIndex= Trace.step %ChineseChecker.numberOfPlayers;868 }869 }