1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 package com.buckosoft.fibs.BuckoFIBS.gui.boardTab.boardPane;
208
209 import java.awt.Color;
210 import java.awt.Dimension;
211 import java.awt.Font;
212 import java.awt.FontMetrics;
213 import java.awt.Graphics;
214 import java.awt.Point;
215
216 import javax.swing.JPanel;
217
218 import org.slf4j.Logger;
219 import org.slf4j.LoggerFactory;
220
221 import com.buckosoft.fibs.BuckoFIBS.BFProperties;
222 import com.buckosoft.fibs.BuckoFIBS.gui.boardTab.BoardTab;
223 import com.buckosoft.fibs.BuckoFIBS.gui.boardTab.boardPane.AnimateEvent.Type;
224 import com.buckosoft.fibs.domain.Board;
225
226
227
228
229
230
231
232
233
234
235
236
237 public class BoardPane extends JPanel {
238 private final static boolean DEBUG = false;
239 private final static boolean DEBUGa = false;
240 private Logger logger = LoggerFactory.getLogger(getClass());
241 private static final long serialVersionUID = 1L;
242
243
244
245
246 protected Board board = new Board();
247
248 private BoardTab boardTab = null;
249 protected BFProperties properties = null;
250
251
252 public BoardSpecs bs = new BoardSpecs();
253
254 private Color boxColor = Color.darkGray;
255 private Color boardColor = Color.lightGray;
256 private Color bPointColor = Color.pink;
257 private Color wPointColor = Color.red;
258 private Color bCheckerColor = Color.black;
259 private Color bTrimColor = Color.white;
260 private Color wCheckerColor = Color.white;
261 private Color wGreyColor = Color.gray;
262 private Color wTrimColor = Color.black;
263
264
265 private Color hoverColor = new Color(200,200,200,192);
266
267 private Color hoverToColor = new Color(255,255,0,150);
268
269 protected static final int POINT_UNKNOWN = -1;
270 protected static final int POINT_BAR = -2;
271 protected static final int POINT_DICE = -3;
272 protected static final int POINT_DOUBLE = -4;
273 protected static final int POINT_BAR_DICE = -5;
274 protected static final int POINT_REJECT = -6;
275
276
277
278 protected int hoverPoint = POINT_UNKNOWN;
279
280
281 protected int[] hoverTo = new int[26];
282
283
284 private int[] xPoints = new int[4];
285
286 private int[] yPoints = new int[4];
287
288 protected boolean[] diceUsed = new boolean[2];
289
290 protected AnimateManager animateManager;
291
292
293 public BoardPane() {
294 super();
295 initialize();
296 this.animateManager = new AnimateManager();
297 this.animateManager.setBoardPane(this);
298 this.animateManager.setProperties(properties);
299 }
300
301
302
303
304
305
306
307 public class BoardSpecs {
308
309 public int w;
310
311 public int h;
312
313 public int checkerSize;
314
315 public int c15;
316
317 public int c2;
318
319 public int checkerHeight;
320 public int dieSize;
321 public int extra;
322 public int barWidth;
323
324 public int pointHeight;
325
326
327 }
328
329
330
331
332 public void setBoard(Board board) {
333 this.board = board;
334 this.boardTab.setMatchStatusPanelBoard(board);
335 }
336
337 public void setBoardTab(BoardTab boardTab) {
338 this.boardTab = boardTab;
339 }
340
341
342
343
344
345 private void initialize() {
346 this.setSize(400, 300);
347 this.setPreferredSize(new Dimension(400, 300));
348 this.addMouseListener(new java.awt.event.MouseAdapter() {
349 public void mousePressed(java.awt.event.MouseEvent e) {
350 onMousePressed(e);
351 }
352 });
353 this.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
354 public void mouseMoved(java.awt.event.MouseEvent e) {
355 onMouseMoved(e);
356 }
357 });
358 }
359
360 protected void setHoverPoint(int p) {
361 if (DEBUG)
362 System.out.println("setHoverPoint(" + p + ")");
363 hoverPoint = p;
364 int i;
365 for (i=0; i<hoverTo.length; i++)
366 hoverTo[i] = 0;
367 }
368
369 protected void onMouseClicked(java.awt.event.MouseEvent e) {
370 System.out.println("onMouseClicked: Should be overridden");
371 }
372
373 protected void onMousePressed(java.awt.event.MouseEvent e) {
374 System.out.println("onMousePressed: Should be overridden");
375 }
376
377 protected void onMouseMoved(java.awt.event.MouseEvent e) {
378 System.out.println("onMouseMoved: Should be overridden");
379 }
380
381
382
383
384 public void paint(Graphics g) {
385 super.paint(g);
386 bs.w = this.getWidth();
387 bs.h = this.getHeight();
388 bs.checkerSize = (int)(((double)bs.w)/16.5);
389 bs.c2 = bs.checkerSize / 2;
390 bs.c15 = (int)((double)bs.checkerSize * 1.5);
391 bs.checkerHeight = bs.checkerSize/3;
392 bs.extra = bs.w-((bs.checkerSize*12)+(bs.c15*3));
393 bs.barWidth = bs.checkerSize + bs.extra;
394 bs.pointHeight = bs.h/2-bs.c15;
395
396
397 g.setColor(boardColor);
398 g.fillRect(0, 0, bs.w, bs.h);
399
400
401 g.setColor(boxColor);
402 g.fillRect(0, 0, bs.c15, bs.h);
403
404 g.fillRect(bs.w-bs.c15, 0, bs.w, bs.h);
405
406 g.fillRect(bs.w/2-bs.barWidth/2, 0, bs.barWidth, bs.h);
407 int x, y, w;
408 y = bs.pointHeight;
409 int p;
410 for (p=1; p<=12; p++) {
411 x = getPointX(p);
412 if ((p & 1) != 0)
413 g.setColor(wPointColor);
414 else
415 g.setColor(bPointColor);
416 xPoints[0] = x;
417 yPoints[0] = bs.h;
418 xPoints[1] = x+bs.c2;
419 yPoints[1] = bs.h-y;
420 xPoints[2] = x+bs.checkerSize;
421 yPoints[2] = bs.h;
422 xPoints[3] = x;
423 yPoints[3] = bs.h;
424 g.fillPolygon(xPoints, yPoints, 4);
425 g.setColor(Color.black);
426 g.drawLine(x, bs.h, x+bs.c2, bs.h-y);
427 g.drawLine(x+bs.c2, bs.h-y, x+bs.checkerSize, bs.h);
428 }
429 for (p=13; p<=24; p++) {
430 x = getPointX(p);
431 if ((p & 1) == 1)
432 g.setColor(wPointColor);
433 else
434 g.setColor(bPointColor);
435 xPoints[0] = x;
436 yPoints[0] = 0;
437 xPoints[1] = x+bs.c2;
438 yPoints[1] = y;
439 xPoints[2] = x+bs.checkerSize;
440 yPoints[2] = 0;
441 xPoints[3] = x;
442 yPoints[3] = 0;
443 g.fillPolygon(xPoints, yPoints, 4);
444 g.setColor(Color.black);
445 g.drawLine(x, 0, x+bs.c2, y);
446 g.drawLine(x+bs.c2, y, x+bs.checkerSize, 0);
447 }
448 paintCheckers(g);
449 paintDice(g);
450 paintDoubleCube(g);
451 paintPointNumbers(g);
452 if (this.board.isYourTurnToRollOrDouble()) {
453 int miniDieSize = bs.barWidth/2;
454 x = bs.w/2-bs.barWidth/2;
455 y = bs.h-miniDieSize-2;
456 paintDie(g, miniDieSize, x, y, 6, Color.white, Color.white, Color.black);
457 paintDie(g, miniDieSize, x+miniDieSize, y, 6, Color.white, Color.white, Color.black);
458 g.setColor(Color.yellow);
459 g.drawRoundRect(x-2, y-2, miniDieSize*2+2, miniDieSize+2, miniDieSize/4+2, miniDieSize/4+2);
460 g.drawRoundRect(x-1, y-1, miniDieSize*2+1, miniDieSize+1, miniDieSize/4+1, miniDieSize/4+1);
461
462 }
463 if (board.isAcceptDeclineDouble() || board.isAcceptDeclineResign()) {
464 g.setColor(Color.red);
465 x = getDeclineX();
466 y = getDeclineY();
467 w = bs.c15;
468 g.drawLine(x, y, x+w, y+w);
469 g.drawLine(x+w, y, x, y+w);
470 g.drawLine(x+1, y, x+w+1, y+w);
471 g.drawLine(x+w+1, y, x+1, y+w);
472
473 }
474 paintResign(g);
475 paintAnimatedCheckers(g);
476 }
477
478 protected int getDeclineX() {
479 return(bs.w-bs.c15);
480 }
481 protected int getDeclineY() {
482 return(bs.h/2 - bs.c15/2);
483 }
484 private void paintCheckers(Graphics g) {
485 int[] p = this.board.getPoints();
486 int i;
487 int j;
488 int c;
489 if (p == null)
490 return;
491 if (DEBUG)
492 System.out.println("xo=" + board.getXO() + " dir=" + board.getDirection());
493 for (i=1; i<=24; i++) {
494 c = Math.abs(p[i]);
495 if (c == 0 && hoverTo[i] == 0)
496 continue;
497 Color cColor = bCheckerColor;
498 Color tColor = bTrimColor;
499
500 if (p[i] < 0) {
501 if (DEBUG)
502 System.out.println("p[" + i + "]=" + p[i]);
503 cColor = wCheckerColor;
504 tColor = wTrimColor;
505 }
506 int x = getPointX(i);
507 for (j=0; j<c+hoverTo[i]; j++) {
508 int y = getNthCheckerY(i, j);
509 if (i == hoverPoint && j == c-1)
510 cColor = hoverColor;
511 if (j>=c)
512 cColor = hoverToColor;
513 g.setColor(cColor);
514 g.fillArc(x, y, bs.checkerSize, bs.checkerSize, 0, 360);
515 g.setColor(tColor);
516 g.drawArc(x, y, bs.checkerSize, bs.checkerSize, 0, 360);
517 }
518 }
519 p = this.board.getHome();
520 for (j=0; j<p[1]; j++)
521 paintCheckerInHome(g, Board.X, j, bCheckerColor, bTrimColor);
522 for (j=0; j<p[0]; j++)
523 paintCheckerInHome(g, Board.O, j, wCheckerColor, wTrimColor);
524 if (hoverTo[0] > 0)
525 paintCheckerInHome(g, Board.O, j, hoverToColor, wTrimColor);
526 int[] bar = board.getBar();
527 for (j=0; j<bar[Board.O]; j++)
528 paintCheckerOnBar(g, Board.O, j, wCheckerColor, wTrimColor);
529 for (j=0; j<bar[Board.X]; j++)
530 paintCheckerOnBar(g, Board.X, j, bCheckerColor, bTrimColor);
531 }
532
533 protected int getCheckerYOnBar(int who, int checker) {
534 int y = bs.h/2 + bs.checkerSize + ((checker % 5) * bs.checkerSize);
535 y -= (checker/5*bs.checkerHeight);
536 if (who == Board.O)
537 y = bs.h - bs.checkerSize -y;
538
539 return(y);
540 }
541
542 private void paintCheckerOnBar(Graphics g,
543 int who, int c, Color cColor, Color tColor) {
544 if (hoverPoint == POINT_BAR && c == 0)
545 cColor = hoverColor;
546 int x = bs.w/2 - bs.checkerSize/2;
547 int y = getCheckerYOnBar(who, c);
548 g.setColor(cColor);
549 g.fillArc(x, y, bs.checkerSize, bs.checkerSize, 0, 360);
550 g.setColor(tColor);
551 g.drawArc(x, y, bs.checkerSize, bs.checkerSize, 0, 360);
552 }
553
554 protected int getCheckerYInHome(int who, int checker) {
555 int y;
556 y = checker * bs.checkerHeight;
557 if (who == Board.O)
558 y = bs.h - (checker+1) * bs.checkerHeight;
559 return(y);
560 }
561
562 private void paintCheckerInHome(Graphics g,
563 int who, int checker, Color cColor, Color tColor) {
564 int x = bs.w-(bs.c15/2)-(bs.checkerSize/2);
565 int y = getCheckerYInHome(who, checker);
566 g.setColor(cColor);
567 g.fillArc(x, y, bs.checkerSize, bs.checkerHeight, 0, 180);
568 g.setColor(tColor);
569 g.drawArc(x, y, bs.checkerSize, bs.checkerHeight, 0, 180);
570 }
571
572
573
574
575
576 protected int getPointX(int p) {
577 if (p == Board.Bar)
578 return(bs.w/2-bs.c2);
579 if (p == Board.Home)
580 return(bs.w-(bs.c15/2)-(bs.checkerSize/2));
581
582 if (p > 12)
583 p = 25 - p;
584 p--;
585 int x = (bs.w - bs.c15 - bs.checkerSize) - ((bs.checkerSize+1)*p) - 2;
586 if (p > 5)
587 x -= bs.barWidth + 2;
588 return(x);
589 }
590
591
592
593
594
595
596
597
598 protected int getNthCheckerY(int p, int c) {
599 if (board.getDirection() > 0)
600 p = 25-p;
601 int y = (c % 5) * bs.checkerSize;
602 y += (c/5*bs.checkerHeight);
603 if (p <= 12)
604 y = bs.h - bs.checkerSize -y;
605 return(y);
606 }
607
608
609
610
611
612 private void paintDice(Graphics g) {
613 Color cColor = bCheckerColor;
614 Color tColor = bTrimColor;
615 Color gColor = wGreyColor;
616
617 bs.dieSize = bs.checkerSize;
618 int y = bs.h/2-bs.c2;
619 int x0 = this.getPointX(9) - bs.c15;
620 int x1 = x0+bs.c15;
621 int size = bs.dieSize;
622 int[][] dice = board.getDice();
623
624 AnimateEvent ae = this.animateManager.getHeadEvent();
625 if (ae != null) {
626 if (ae.getType() == Type.Roll) {
627 AnimateEventDiceRoll aedr = (AnimateEventDiceRoll)ae;
628 for (int i=0; i<diceUsed.length; i++)
629 diceUsed[i] = false;
630 if (aedr.getWho() == Board.X){
631 int miniSize = bs.barWidth/2;
632 int miniX = bs.w/2-bs.barWidth/2;
633 int miniY = 0;
634 int[] pos = aedr.getDiceParms(miniX, miniX+miniSize, miniY, miniSize, x0, x1, y, bs.dieSize);
635 x0 = pos[AnimateEventDiceRoll.XL];
636 x1 = pos[AnimateEventDiceRoll.XR];
637 y = pos[AnimateEventDiceRoll.Y];
638 size = pos[AnimateEventDiceRoll.SIZE];
639 dice[Board.X][0] = aedr.dice[0];
640 dice[Board.X][1] = aedr.dice[1];
641 }
642 }
643 if (ae.getType() == Type.FirstRoll) {
644 AnimateEventFirstRoll aefr = (AnimateEventFirstRoll)ae;
645 for (int i=0; i<diceUsed.length; i++)
646 diceUsed[i] = false;
647
648 int miniSize = bs.barWidth/2;
649 int miniX = bs.w/2-bs.barWidth/2;
650 int miniY = 0;
651 x0 = (int)(((x0-miniX)*ae.offset)+miniX);
652 y = (int)(((y-miniY)*ae.offset)+miniY);
653 size = (int)(((bs.dieSize-miniSize)*ae.offset)+miniSize);
654
655 paintDie(g, size, x0, y, aefr.getBlackDie(), cColor, cColor, tColor);
656
657 }
658 if (ae.getType() == Type.CantMove){
659 cColor = Color.red;
660 }
661 if (ae instanceof AnimateEventResign) {
662 cColor = makeTranslucent(cColor);
663 tColor = makeTranslucent(tColor);
664 }
665 }
666
667 if (ae == null || ae.getType() != Type.FirstRoll) {
668 if (dice[Board.X][0] != 0)
669 paintDie(g, size, x0, y, dice[Board.X][0], cColor, cColor, tColor);
670 if (dice[Board.X][1] != 0)
671 paintDie(g, size, x1, y, dice[Board.X][1], cColor, cColor, tColor);
672 }
673 if (ae != null && ae.getType() == Type.CantMove && ae.getWho() == Board.X) {
674 g.setColor(Color.red);
675 y = y + size + size/2;
676 g.drawLine(x0, y, x1+size, y-size*2);
677 g.drawLine(x0-1, y, x1+size-1, y-size*2);
678 g.drawLine(x0, y-size*2, x1+size, y);
679 g.drawLine(x0-1, y-size*2, x1+size-1, y);
680
681 }
682
683 Color luColor = wCheckerColor;
684 Color ldColor = wCheckerColor;
685 Color ruColor = wCheckerColor;
686 Color rdColor = wCheckerColor;
687 tColor = wTrimColor;
688
689 if (diceUsed.length == 2) {
690 if (diceUsed[0]) {
691 luColor = gColor;
692 ldColor = gColor;
693 }
694 if (diceUsed[1]) {
695 ruColor = gColor;
696 rdColor = gColor;
697 }
698 }
699 if (diceUsed.length == 4) {
700 if (diceUsed[3])
701 luColor = gColor;
702 if (diceUsed[2])
703 ldColor = gColor;
704 if (diceUsed[1])
705 ruColor = gColor;
706 if (diceUsed[0])
707 rdColor = gColor;
708 }
709 x0 = this.getPointX(4);
710 x1 = x0+bs.c15;
711 y = bs.h/2-bs.c2;
712 size = bs.dieSize;
713 if (ae != null) {
714 if (ae.getType() == Type.Roll) {
715 AnimateEventDiceRoll aedr = (AnimateEventDiceRoll)ae;
716 if (aedr.getWho() == Board.O){
717 int miniSize = bs.barWidth/2;
718 int miniX = bs.w/2-bs.barWidth/2;
719 int miniY = bs.h-miniSize-2;
720 int[] pos = aedr.getDiceParms(miniX, miniX+miniSize, miniY, miniSize, x0, x1, y, bs.dieSize);
721 x0 = pos[0];
722 x1 = pos[1];
723 y = pos[2];
724 size = pos[3];
725 dice[Board.O][0] = aedr.dice[0];
726 dice[Board.O][1] = aedr.dice[1];
727 }
728 }
729 if (ae.getType() == Type.CantMove) {
730 luColor = Color.red;
731 ldColor = Color.red;
732 ruColor = Color.red;
733 rdColor = Color.red;
734 }
735 if (ae.getType() == Type.FirstRoll) {
736 AnimateEventFirstRoll aefr = (AnimateEventFirstRoll)ae;
737
738 int miniSize = bs.barWidth/2;
739 int miniX = bs.w/2-bs.barWidth/2;
740 int miniY = bs.h-miniSize-2;
741 x0 = (int)(((x0-miniX)*ae.offset)+miniX);
742 y = (int)(((y-miniY)*ae.offset)+miniY);
743 size = (int)(((bs.dieSize-miniSize)*ae.offset)+miniSize);
744
745 paintDie(g, size, x0, y, aefr.getWhiteDie(), luColor, ldColor, tColor);
746
747 }
748 if (ae instanceof AnimateEventResign) {
749 luColor = makeTranslucent(luColor);
750 ldColor = makeTranslucent(ldColor);
751 ruColor = makeTranslucent(ruColor);
752 rdColor = makeTranslucent(rdColor);
753 tColor = makeTranslucent(tColor);
754 }
755 }
756 if (ae == null || ae.getType() != Type.FirstRoll) {
757 if (dice[Board.O][0] != 0)
758 paintDie(g, size, x0, y, dice[Board.O][0], luColor, ldColor, tColor);
759 if (dice[Board.O][1] != 0)
760 paintDie(g, size, x1, y, dice[Board.O][1], ruColor, rdColor, tColor);
761 }
762 if (ae != null && ae.getType() == Type.CantMove && ae.getWho() == Board.O){
763 g.setColor(Color.red);
764 y = y + size + size/2;
765 g.drawLine(x0, y, x1+size, y-size*2);
766 g.drawLine(x0-1, y, x1+size-1, y-size*2);
767 g.drawLine(x0, y-size*2, x1+size, y);
768 g.drawLine(x0-1, y-size*2, x1+size-1, y);
769 }
770 }
771
772
773
774
775
776 private final static boolean[][] diePoints = new boolean[][] {
777 {false,false,false,false,false,false,false},
778 {false,false,false,true,false,false,false},
779 {false,false,true,false,true,false,false},
780 {false,false,true,true,true,false,false},
781 {true,false,true,false,true,false,true},
782 {true,false,true,true,true,false,true},
783 {true,true,true,false,true,true,true},
784 };
785 private final static double y0m = 25.0/100.0;
786 private final static double y2m = 75.0/100.0;
787
788
789
790
791
792
793
794
795
796
797
798 private void paintDie(Graphics g, int dieSize,
799 int x, int y, int n, Color uColor, Color dColor, Color tColor) {
800 int dotSize = dieSize/4;
801 int dotSize2 = dotSize/2;
802 g.setColor(uColor);
803 g.setClip(x-1, y+0, dieSize+1, dieSize/2+1);
804 g.fillRoundRect(x, y, dieSize, dieSize, dieSize/4, dieSize/4);
805 g.setColor(dColor);
806 g.setClip(x-1, y+dieSize/2+1, dieSize+1, dieSize/2+1);
807 g.fillRoundRect(x, y, dieSize, dieSize, dieSize/4, dieSize/4);
808 g.setClip(null);
809 g.setColor(tColor);
810 g.drawRoundRect(x, y, dieSize, dieSize, dieSize/4, dieSize/4);
811 int dX[] = new int[3];
812 int dY[] = new int[3];
813 dX[0] = (int)(x + ((double)dieSize * y0m)) - dotSize2;
814 dX[1] = (int)(x + ((double)dieSize / 2.0)) - dotSize2;
815 dX[2] = (int)(x + ((double)dieSize * y2m)) - dotSize2;
816 dY[0] = (int)(y + ((double)dieSize * y0m)) - dotSize2;
817 dY[1] = (int)(y + ((double)dieSize / 2.0)) - dotSize2;
818 dY[2] = (int)(y + ((double)dieSize * y2m)) - dotSize2;
819
820
821
822
823 if (diePoints[n][0])
824 g.fillArc(dX[0], dY[0], dotSize, dotSize, 0, 360);
825 if (diePoints[n][1])
826 g.fillArc(dX[0], dY[1], dotSize, dotSize, 0, 360);
827 if (diePoints[n][2])
828 g.fillArc(dX[0], dY[2], dotSize, dotSize, 0, 360);
829 if (diePoints[n][3])
830 g.fillArc(dX[1], dY[1], dotSize, dotSize, 0, 360);
831 if (diePoints[n][4])
832 g.fillArc(dX[2], dY[0], dotSize, dotSize, 0, 360);
833 if (diePoints[n][5])
834 g.fillArc(dX[2], dY[1], dotSize, dotSize, 0, 360);
835 if (diePoints[n][6])
836 g.fillArc(dX[2], dY[2], dotSize, dotSize, 0, 360);
837 }
838
839
840 Font doubleCubeFont = new Font("Arial", Font.BOLD, 18);
841
842 private void paintDoubleCube(Graphics g) {
843 Point p = getDoubleCubeXY();
844 int w2 = getDoubleCubeWidth()/2;
845 int x = p.x - w2;
846 int y = p.y - w2;
847 AnimateEvent ae = animateManager.getHeadEvent();
848 if (ae != null) {
849 AnimateEventDouble aed = null;
850 if (ae.getType() == Type.Double) {
851 aed = (AnimateEventDouble)ae;
852 if (properties.isDEBUG_ShowAnimatePath()) {
853 aed.calculate(board);
854 g.setColor(Color.blue);
855 for (double d = 0.0; d <= 1.0; d += 0.002) {
856 int pp[] = aed.getXY(d);
857 g.drawRect(pp[0]-1, pp[1]-1, 3, 3);
858 }
859 g.setColor(Color.green);
860 for (int i=0; i<aed.x.length; i++ ) {
861 g.drawRect((int)aed.x[i]-3, (int)aed.y[i]-3, 6, 6);
862 }
863 }
864 int[] xy = aed.getXY(aed.getOffset());
865 x = xy[0] - w2;
866 y = xy[1] - w2;
867 }
868 }
869
870 int cubeValue = board.getCube();
871 int w = getDoubleCubeWidth();
872 if (board.getWasDoubled()[0] || board.getWasDoubled()[1]) {
873 cubeValue *= 2;
874 if (cubeValue > 64)
875 cubeValue = 1;
876 }
877 g.setColor(Color.white);
878 g.fillRoundRect(x, y, w, w, w/4, w/4);
879 g.setColor(Color.black);
880 g.drawRoundRect(x, y, w, w, w/4, w/4);
881 g.setColor(Color.yellow);
882 if (this.board.isYourTurnToRollOrDouble()) {
883 g.drawRoundRect(x, y, w, w, w/4, w/4);
884 g.drawRoundRect(x-1, y-1, w+2, w+2, w/4+1, w/4+1);
885 }
886
887 g.setColor(Color.black);
888 g.setFont(doubleCubeFont);
889 FontMetrics fm = g.getFontMetrics();
890 String s = "" + cubeValue;
891 int sw = fm.stringWidth(s);
892 x = x + w/2 - sw/2;
893 y = y + w/2 - fm.getAscent()/2 + fm.getAscent();
894 g.drawString(s, x, y);
895 }
896
897 protected Point getDoubleCubeXY() {
898 int w = getDoubleCubeWidth();
899 int x = bs.c15/2;
900 int y = bs.h/2;
901 if (board.getHasCube() == Board.O)
902 y = 0 + w;
903 if (board.getHasCube() == Board.X)
904 y = bs.h - w*2;
905 if (board.getWasDoubled()[0]) {
906 logger.info("wasDoubled[0]");
907 return(getDoubleCubePushXY());
908 }
909 if (board.getWasDoubled()[1]) {
910 logger.info("wasDoubled[1]");
911 return(getDoubleCubePushXY());
912 }
913 return(new Point(x,y));
914 }
915
916
917 protected Point getDoubleCubePushXY() {
918 int[] bp = board.getPoints();
919
920
921 final int[] points1 = new int[] { 4, 5, 3, 2, 8, 9,10,11, 1, 7,12,19};
922 final int[] points0 = new int[] {21,20,22,23,17,16,15,14,24,18,13,6};
923 int[] check = points1;
924 int dir = Board.turnO;
925 AnimateEvent ae = animateManager.getHeadEvent();
926 if (ae != null) {
927 AnimateEventDouble aed;
928 if (ae.getType() == Type.Double) {
929 aed = (AnimateEventDouble)ae;
930 board.setWasDoubled(aed.getWhoDoubled());
931 logger.info("(aed) set board.wasdoubled(" + Board.getXOAsText(aed.getWhoDoubled()) + ")");
932
933
934
935
936
937 }
938 }
939 logger.info("wasDoubled[0/1] = " + board.getWasDoubled()[0] + "/" + board.getWasDoubled()[1] + " dir = " + Board.getTurnAsText(board.getDirection()));
940 if ((board.getWasDoubled()[Board.X] && board.getDirection() == Board.turnO)
941 || (board.getWasDoubled()[Board.O] && board.getDirection() == Board.turnX)) {
942 check = points0;
943 dir = Board.turnX;
944 logger.info("use other points0;");
945 }
946 int f = 0;
947 int h = 0;
948 for (h = 0; h < 2; h++) {
949 for (int i : check) {
950 if (bp[i] == 0) {
951 f = i;
952 break;
953 }
954 }
955 if (f != 0)
956 break;
957 }
958 int x = getPointX(f);
959 logger.info("f = " + f + " h = " + h);
960 x += bs.c2;
961 int y = bs.checkerSize * (h+1) + getDoubleCubeWidth()/2;
962 if (dir == Board.turnX) {
963 y = bs.h - y;
964 logger.info("dir = turnX");
965 }
966
967 return(new Point(x,y));
968 }
969
970 protected int getDoubleCubeWidth() {
971 return((bs.c15 + bs.dieSize) / 2);
972 }
973
974 Font pointNumbersFont = new Font("Arial", Font.BOLD, 11);
975 private void paintPointNumbers(Graphics g) {
976 if (!this.properties.isShowPointNumbers())
977 return;
978 int p;
979 int x,y;
980 String s;
981 int f = 0;
982 int t;
983 boolean reverse = board.getDirection() > 0;
984 g.setFont(pointNumbersFont);
985 FontMetrics fm = g.getFontMetrics();
986 for (p=1; p<=12; p++) {
987 f = p;
988 if (reverse)
989 f = 25-p;
990 s = "" + f;
991 int sw = fm.stringWidth(s);
992 x = getPointX(p) + bs.c2 - sw/2;
993 y = bs.h - bs.c2 + fm.getAscent()/2;
994 t = board.getPoints()[f];
995 if (t < -5 || t > 5)
996 y = this.getNthCheckerY(f, 5) + bs.c2 + fm.getAscent()/2;
997
998
999 if (t > 0)
1000 g.setColor(Color.white);
1001 else
1002 g.setColor(Color.blue);
1003 g.drawString(s, x, y);
1004 }
1005 for (p=13; p<=24; p++) {
1006 f = p;
1007 if (reverse)
1008 f = 25-p;
1009 s = "" + f;
1010 int sw = fm.stringWidth(s);
1011 x = getPointX(p) + bs.c2 - sw/2;
1012 y = bs.c2 + fm.getAscent()/2;
1013 t = board.getPoints()[f];
1014 if (t < -5 || t > 5)
1015 y = this.getNthCheckerY(f, 5) + bs.c2 + fm.getAscent()/2;
1016 if (t < -10 || t > 10)
1017 y = this.getNthCheckerY(f, 10) + bs.c2 + fm.getAscent()/2;
1018
1019 if (t > 0)
1020 g.setColor(Color.white);
1021 else
1022 g.setColor(Color.blue);
1023 g.drawString(s, x, y);
1024 }
1025 }
1026
1027
1028
1029 public void updateBoardTab() {
1030 this.boardTab.updateBoard();
1031 }
1032
1033
1034
1035
1036
1037 private Color makeTranslucent(Color c) {
1038 return(new Color(c.getRed(), c.getGreen(), c.getBlue(), 48));
1039 }
1040
1041 private static final Color endColor = new Color(20,255,20,150);
1042 private void paintAnimatedCheckers(Graphics g) {
1043 AnimateEvent ae = animateManager.getHeadEvent();
1044 if (ae != null) {
1045 AnimateEventMove aem = null;
1046 if (ae.getType() == Type.Move) {
1047 aem = (AnimateEventMove)ae;
1048 if (properties.isDEBUG_ShowAnimatePath()) {
1049 aem.calculate();
1050 g.setColor(Color.blue);
1051 for (double d = 0.0; d <= 1.0; d += 0.002) {
1052 int p[] = aem.getXY(d);
1053 g.drawRect(p[0]-1, p[1]-1, 3, 3);
1054 }
1055 g.setColor(Color.green);
1056 for (int i=0; i<aem.x.length; i++ ) {
1057 g.drawRect((int)aem.x[i]-3, (int)aem.y[i]-3, 6, 6);
1058 }
1059 }
1060 g.setColor(aem.getColor(aem.getOffset()));
1061 int[] xy = aem.getXY(aem.getOffset());
1062 g.fillArc(xy[0]-bs.c2, xy[1]-bs.c2, bs.checkerSize, bs.checkerSize, 0, 360);
1063 }
1064 }
1065 if (animateManager.extraCheckersIndex != 0) {
1066 if (DEBUGa) {
1067 logger.debug("extraCheckers: " + (animateManager.extraCheckersIndex/2));
1068 for (int i=0; i<animateManager.extraCheckersIndex; i+=2)
1069 logger.debug("checker[" + i + "]=" + animateManager.extraCheckers[i] + "/" + animateManager.extraCheckers[i+1]);
1070 }
1071 g.setColor(endColor);
1072 for (int i=0; i<animateManager.extraCheckersIndex; i+=2) {
1073 if (animateManager.extraCheckers[i] == Board.Home) {
1074 paintCheckerInHome(g, animateManager.extraCheckersWho, animateManager.extraCheckers[i+1], endColor, endColor);
1075
1076
1077 } else {
1078 int x = getPointX(animateManager.extraCheckers[i]);
1079 int y = this.getNthCheckerY(animateManager.extraCheckers[i], animateManager.extraCheckers[i+1]);
1080 g.fillArc(x, y, bs.checkerSize, bs.checkerSize, 0, 360);
1081 }
1082 }
1083 }
1084
1085
1086 }
1087
1088 private void paintResign(Graphics g) {
1089 AnimateEvent ae = this.animateManager.getHeadEvent();
1090 if (ae != null && ae instanceof AnimateEventResign) {
1091 AnimateEventResign aer = (AnimateEventResign)ae;
1092 int flagSize = (int)(bs.checkerSize*2.5);
1093 int miniSize = bs.barWidth/2;
1094 int miniX = bs.w/2-bs.barWidth/2;
1095 int miniY = 0;
1096
1097 int y = (int)(bs.h-bs.pointHeight-(flagSize*0.75));
1098 int x = this.getPointX(4);
1099 if (aer.getWho() == Board.O){
1100 miniY = bs.h-miniSize-2;
1101 x = this.getPointX(9) - bs.c15;
1102 y = (int)(0+bs.pointHeight-(flagSize*0.25));
1103 }
1104 int[] pos = aer.getFlagParms(miniX, miniY, miniSize, x, y, flagSize);
1105 g.drawImage(aer.getIcon().getImage(), pos[AnimateEventResign.X], pos[AnimateEventResign.Y],
1106 pos[AnimateEventResign.WIDTH], pos[AnimateEventResign.HEIGHT], null);
1107 Font f = doubleCubeFont;
1108 g.setFont(f);
1109 g.setColor(Color.black);
1110 g.drawString("" + aer.getResigningPoints(),
1111 (int)(pos[AnimateEventResign.X]+pos[AnimateEventResign.WIDTH]*0.25),
1112 (int)(pos[AnimateEventResign.Y]+pos[AnimateEventResign.HEIGHT]*0.30));
1113 if (ae instanceof AnimateEventRejectResign) {
1114 g.setColor(Color.red);
1115 g.drawLine(pos[AnimateEventResign.X],
1116 pos[AnimateEventResign.Y],
1117 pos[AnimateEventResign.X]+pos[AnimateEventResign.WIDTH],
1118 pos[AnimateEventResign.Y]+pos[AnimateEventResign.HEIGHT]);
1119 g.drawLine(pos[AnimateEventResign.X]+1,
1120 pos[AnimateEventResign.Y],
1121 pos[AnimateEventResign.X]+pos[AnimateEventResign.WIDTH]+1,
1122 pos[AnimateEventResign.Y]+pos[AnimateEventResign.HEIGHT]);
1123 if (ae.getOffset() > 0.5) {
1124 g.drawLine(pos[AnimateEventResign.X]+pos[AnimateEventResign.WIDTH],
1125 pos[AnimateEventResign.Y],
1126 pos[AnimateEventResign.X],
1127 pos[AnimateEventResign.Y]+pos[AnimateEventResign.HEIGHT]);
1128 g.drawLine(pos[AnimateEventResign.X]+pos[AnimateEventResign.WIDTH]+1,
1129 pos[AnimateEventResign.Y],
1130 pos[AnimateEventResign.X]+1,
1131 pos[AnimateEventResign.Y]+pos[AnimateEventResign.HEIGHT]);
1132 }
1133 } else if (ae instanceof AnimateEventAcceptAndWin) {
1134 AnimateEventAcceptAndWin aeaaw = (AnimateEventAcceptAndWin)ae;
1135 pos = aeaaw.getFlagParms(miniX, miniY, miniSize, x, y, flagSize);
1136 g.drawImage(aer.getIcon().getImage(), pos[AnimateEventResign.X], pos[AnimateEventResign.Y],
1137 pos[AnimateEventResign.WIDTH], pos[AnimateEventResign.HEIGHT], null);
1138
1139 }
1140 }
1141 }
1142 }