JAVA期末大作业 中国跳棋

  PS:这学期期末成绩差不多出完了,接下来会陆续把这学期课程中的代码陆续扔到这里来以便后人****,同时自己也留个纪念。

  本学期选了java选修,期末大作业面向GitHub编程写了个中国跳棋。代码中还有写小bug,不过懒得调了...

  update:github

   

 1.游戏介绍

  中国跳棋,简称跳棋,是一种可以让二至六人一起玩的棋,棋盘为六角星形状,棋子一般分为六种颜色,每种颜色有1015枚棋子(或弹珠),每一位玩家占一个角,执一种颜色的棋子,如果玩的人数较,也能每人执两种颜色的棋子玩。

游戏规则如下:

先将一种颜色的棋子按规则全部放在一个角上,各人循顺时针或逆时针方向轮流走子,每次只能动一枚棋子,全部棋子先到达对角那一边的为赢家。棋子有两种走法:

1)一枚棋子移动到相邻六格其中一格。

2)“搭桥”:自己的棋子(A)同一条直线上还有一枚棋子(B),不限属于哪一方,大家之间没有任何棋子阻隔。如果B的另一方也没有棋子阻隔,A就可以跳到B的相反方向,而且和两枚棋子原来的距离一样。跳跃可以一直进行下去,直到没有前进的路径为止。如果有循环情况,可在任意一处停下。

2.项目介绍

    1)本跳棋project支持两人、四人、六人跳棋对战

    2)具有计时功能,可显示当前时间,同时也可判断当前玩家是否超时

    3)游戏可暂停

    4)可保存当前局面,从本地打开已有文件(文件I/O

 3.游戏界面

  4.工程布局(太懒了直接把所有class写在了一个文件里)

 

   5.代码

  

  1 import java.awt.Color;
  2 import java.awt.Font;
  3 import java.awt.Image;
  4 import java.awt.event.ActionEvent;
  5 import java.awt.event.ActionListener;
  6 import java.awt.event.KeyEvent;
  7 import java.awt.event.MouseAdapter;
  8 import java.awt.event.MouseEvent;
  9 import java.io.File;
 10 import java.io.FileNotFoundException;
 11 import java.io.IOException;
 12 import java.io.PrintWriter;
 13 import java.text.SimpleDateFormat;
 14 import java.util.Date;
 15 import java.util.Scanner;
 16 
 17 import javax.imageio.ImageIO;
 18 import javax.management.MBeanOperationInfo;
 19 import javax.swing.ImageIcon;
 20 import javax.swing.JFileChooser;
 21 import javax.swing.JFrame;
 22 import javax.swing.JLabel;
 23 import javax.swing.JLayeredPane;
 24 import javax.swing.JMenu;
 25 import javax.swing.JMenuBar;
 26 import javax.swing.JMenuItem;
 27 import javax.swing.JOptionPane;
 28 
 29 
 30 
 31 public class ChineseChecker {
 32     
 33     public static MyFrame 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 void main(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 = new Timer();
 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 (char player : 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 extends JFrame{
176     
177     public Image image;
178     
179     public ImageIcon imgBoard;
180     public static JLayeredPane panel;
181     public static JLabel lblBoard,lblPlayer,lblTime,lblCurrent;
182     public JMenuBar 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 static Timer timer;
201     public MyFrame(){
202         
203         imgBoard = new ImageIcon("Board.jpg");
204         lblTime = new JLabel();
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 = new JLabel(imgBoard);
214         lblBoard.setBounds(0, 20, 685, 800);
215         
216         lblPlayer = new JLabel(new ImageIcon());
217         lblPlayer.setBounds(50, 100, 50, 50);
218         
219         panel = new JLayeredPane();
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 = new JMenuBar();
238         menuBar.add(mControl);
239         setJMenuBar(menuBar);
240         
241         /**设置两个玩家、四个玩家或六个玩家**/
242         mTwoPlayers.addActionListener(new ActionListener() {
243             @Override
244             public void actionPerformed(ActionEvent e) {
245                 // TODO Auto-generated method stub
246                 ChineseChecker.setNumber(2);
247             }
248         });
249         mFourPlayers.addActionListener(new ActionListener() {
250             @Override
251             public void actionPerformed(ActionEvent e) {
252                 // TODO Auto-generated method stub
253                 ChineseChecker.setNumber(4);
254             }
255         });
256         mSixPlayers.addActionListener(new ActionListener() {
257             @Override
258             public void actionPerformed(ActionEvent e) {
259                 // TODO Auto-generated method stub
260                 ChineseChecker.setNumber(6);
261             }
262         });
263         /**暂停游戏**/
264         mPauseGame.addActionListener(new ActionListener() {
265             @Override
266             public void actionPerformed(ActionEvent e) {
267                 // TODO Auto-generated method stub
268                 ChineseChecker.gameStatus = false;
269             }
270         });
271         
272         mOpen.addActionListener(new ActionListener() {//打开已保存过的游戏
273             @Override
274             public void actionPerformed(ActionEvent arg0) {
275                 JFileChooser chooser = new JFileChooser();
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 = new Scanner(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 void in(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             @Override
332             public void actionPerformed(ActionEvent arg0) {
333                 JFileChooser chooser = new JFileChooser();
334                 chooser.showOpenDialog(null);
335                 File file = chooser.getSelectedFile();
336 
337                 PrintWriter writer;
338                 try {
339                     writer = new PrintWriter(file);
340                     writer.write(new Output().s);
341                     writer.close();
342                 } catch (FileNotFoundException e) {
343                     // e.printStackTrace();
344                 } catch (Exception e) {
345                     Services.msg("Export failed!");
346                 }
347             }
348 
349             class Output {
350                 String s = "";
351 
352                 Output() {
353                     out();
354                 }
355 
356                 void out() {
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 (char j : 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 void showCurrent() {
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 (char player : playerSeries) {
400             if (player == 0)
401                 return;
402             initPlayer(player);
403         }
404     }
405 
406     private void initPlayer(char player) {
407         for (int pieceIndex = 0; pieceIndex < 10; pieceIndex++) {
408             initPiece(player, pieceIndex);
409         }
410     }
411 
412     private void initPiece(char player, int pieceIndex) {
413         //Image image = 
414         Map myMap = new Map();
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 void showCurrentPlayer() {
429         
430         lblPlayer.setIcon(new ImageIcon("Piece_" + ChineseChecker.series[ChineseChecker.currentIndex] + ".PNG"));
431         panel.repaint();
432     }
433     
434     
435     class TimerThread extends Thread {
436         TimerThread(String name) {
437             super(name);
438         }
439 
440         @Override
441         public void run() {
442             while (true) {
443                 lblTime.setText(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
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,double y){
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     public Pieces(){
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,int y){
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, int index) {
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 class Next {
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             return possiblePosition;
588         }
589 
590         public static int getPossiblePositionCount(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             return count;
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 (int i : displacementAdjacent) {
608                 for (int j : 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             return possiblePositions;
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 (int x : displacement) {
627                 for (int y : displacement) {
628                     possiblePos = Services.concatTwoArrays(possiblePos,
629                             distantHoppingForOneDirection(x, y, piecePosition, true));
630                 }
631             }
632 
633             return possiblePos;
634         }
635 
636         public static boolean isPosInsideDiagram(String position) {
637             return !(position == OUTSIDE_MARK || position == null);
638         }
639         
640         private static int[][] distantHoppingForOneDirection(int x, int y,
641                                                              int[] piecePos, boolean isDistantHoppingDisabled) {
642             /*
643              * x: indicates up or down moveAward in x direction. y: indicates up or down
644              * moveAward in x direction
645              */
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             boolean isDeadDirection;
651 
652             for (int i : 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 = isiInside
660                         && isjInside
661                         && 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 piece
671                     // 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                             break label1;
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             return possiblePos;
687         }
688 
689     }
690 }
691 
692 class PieceActionListener extends MouseAdapter{//棋子事件侦听
693     private final static ImageIcon imgPossiblePosition = new ImageIcon("Piece_Transparant.PNG");
694     private static boolean isPieceSelected;
695     private static JLabel[] lblPossible = new JLabel[50];
696     private int[][] possiblePos = new int[50][2];
697     private String piece;
698     
699     public PieceActionListener(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     @Override
712     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     @Override
728     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     @Override
739     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] = new JLabel(imgPossiblePosition);
752             lblPossible[k].addMouseListener(new PossiblePositionListener(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 extends MouseAdapter {
762 
763     public static String 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     @Override
774     public void mouseClicked(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 class Services {
790 
791     public static void msg(String content) {
792         JOptionPane.showMessageDialog(null, content, "Chinese Checkers",
793                 JOptionPane.INFORMATION_MESSAGE);
794     }
795 
796     public static String 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         return targetArray;
821     }
822 }
823 
824 class Timer {
825 
826     private long startingTime;
827     private long interruptedTime;
828     private boolean paused;
829 
830     public Timer() {
831         this.startingTime = System.currentTimeMillis();
832     }
833 
834     public long listen() {
835         if (paused)
836             return (30000 - interruptedTime + startingTime) / 1000;
837         long cur = System.currentTimeMillis();
838         return (30000 - cur + startingTime) / 1000;
839     }
840 
841     public void pause() {
842         this.interruptedTime = System.currentTimeMillis();
843         this.paused = true;
844     }
845 }
846 
847 class Trace {
848 
849     public static final int MAX_STACK_SIZE = 1000;
850     public static int step = 1;
851     public static boolean isSkipped;
852     public static String[] pieceStack = new String[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 boolean isSkipped() {
857         return isSkipped;
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 void nextStep() {
867         ChineseChecker.currentIndex= Trace.step % ChineseChecker.numberOfPlayers;
868     }
869 }

 

posted @ 2019-02-01 09:50  mizersy  阅读(6560)  评论(8编辑  收藏  举报