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 package com.buckosoft.fibs.BuckoFIBS;
146
147 import java.util.LinkedList;
148
149 import org.slf4j.Logger;
150 import org.slf4j.LoggerFactory;
151
152 import com.buckosoft.fibs.BuckoFIBS.AudioManager.Cue;
153 import com.buckosoft.fibs.BuckoFIBS.gui.MainDialog;
154 import com.buckosoft.fibs.BuckoFIBS.gui.MainDialogI;
155 import com.buckosoft.fibs.BuckoFIBS.gui.boardTab.ReplayToolbarI;
156 import com.buckosoft.fibs.domain.Board;
157 import com.buckosoft.fibs.domain.CookieString;
158 import com.buckosoft.fibs.domain.gameEvent.GameEvent;
159 import com.buckosoft.fibs.domain.gameEvent.GameEventAcceptAndWin;
160 import com.buckosoft.fibs.domain.gameEvent.GameEventBoard;
161 import com.buckosoft.fibs.domain.gameEvent.GameEventCantMove;
162 import com.buckosoft.fibs.domain.gameEvent.GameEventDouble;
163 import com.buckosoft.fibs.domain.gameEvent.GameEventFirstMove;
164 import com.buckosoft.fibs.domain.gameEvent.GameEventFirstRoll;
165 import com.buckosoft.fibs.domain.gameEvent.GameEventMove;
166 import com.buckosoft.fibs.domain.gameEvent.GameEventPleaseAcceptOrRejectDouble;
167 import com.buckosoft.fibs.domain.gameEvent.GameEventPleaseAcceptOrRejectResign;
168 import com.buckosoft.fibs.domain.gameEvent.GameEventPleaseMove;
169 import com.buckosoft.fibs.domain.gameEvent.GameEventPleaseRollOrDouble;
170 import com.buckosoft.fibs.domain.gameEvent.GameEventRejectResign;
171 import com.buckosoft.fibs.domain.gameEvent.GameEventResign;
172 import com.buckosoft.fibs.domain.gameEvent.GameEventRoll;
173 import com.buckosoft.fibs.domain.gameEvent.GameEventYouDouble;
174 import com.buckosoft.fibs.domain.gameEvent.GameEvent.Life;
175 import com.buckosoft.fibs.domain.gameEvent.GameEvent.Type;
176 import com.buckosoft.fibs.net.FIBSMessages;
177
178
179
180
181
182
183
184
185
186 public class GameManager implements FIBSMessages {
187 private final static boolean DEBUG = true;
188 private final static boolean DEBUGsend = true;
189 private final static boolean DEBUGpos = true;
190 private final static boolean DEBUGJibsBoard = true;
191
192 private Logger logger = LoggerFactory.getLogger(getClass());
193
194 private int position;
195 private ReplayToolbarI replayToolbar;
196 private MainDialogI mainDialog;
197 private BFProperties bfProps;
198
199 private final static int Undo = -2;
200 private final static int Backward = -1;
201 private final static int Start = 0;
202 private final static int Forward = 1;
203
204 private LinkedList<GameEvent> preStartList = new LinkedList<GameEvent>();
205
206
207
208 public GameManager() {
209 }
210
211
212
213
214 public void setReplayToolbar(ReplayToolbarI replayToolbar) {
215 this.replayToolbar = replayToolbar;
216 }
217
218
219
220
221 public void setMainDialog(MainDialog mainDialog) {
222 this.mainDialog = mainDialog;
223 }
224
225
226
227
228 public void setProperties(BFProperties bfProperties) {
229 this.bfProps = bfProperties;
230 }
231
232
233
234
235 public void reset(boolean resumeMatch) {
236
237 gameEvents.clear();
238 preStartList.clear();
239 position = 0;
240 if (DEBUGpos)
241 logger.info("reset: pos = " + this.position);
242 updateToolbarButtons();
243 }
244
245
246
247 public void onRollOrDouble() {
248 queueGameEvent(new GameEventPleaseRollOrDouble());
249 }
250
251
252
253 public void youMoved() {
254 this.mainDialog.playSound(Cue.PickUpDice);
255 this.mainDialog.updateBoard();
256
257
258
259
260
261
262
263
264
265 }
266
267
268
269
270 public void addEvent(CookieString cs) {
271 if (DEBUG)
272 logger.info("addEvent: " + cs.getCookie() + " " + cs.getString());
273 switch (cs.getCookie()) {
274 case FIBS_Board:
275 addBoardLine(cs.getString());
276 break;
277 case FIBS_PlayerMoves:
278 addMove(cs.getString());
279 break;
280 case FIBS_BearingOff:
281 addBearingOff(cs.getString());
282 break;
283 case FIBS_YouRoll:
284 case FIBS_PlayerRolls:
285 addRoll(cs.getString());
286 break;
287 case FIBS_CantMove:
288 addCantMove(cs.getString());
289 break;
290 case FIBS_YouCantMove:
291 addYouCantMove(cs.getString());
292 break;
293 case FIBS_PleaseMove:
294 addPleaseMove(cs.getString());
295 break;
296 case FIBS_YourTurnToMove:
297 addYourTurnToMove(cs.getString());
298 break;
299 case FIBS_MakesFirstMove:
300 addFirstMove(cs.getString());
301 break;
302 case FIBS_FirstRoll:
303 addFirstRoll(cs.getString());
304 break;
305 case FIBS_StartingNewGame:
306 addStartNewGame(cs.getString());
307 break;
308 case FIBS_NewMatchAck2:
309 addPlayerJoinsYou(cs.getString());
310 break;
311 case FIBS_Turn:
312 addResumeYourTurn(cs.getString());
313 break;
314 case FIBS_AcceptRejectDouble:
315 addAcceptRejectDouble(cs.getString());
316 break;
317 case FIBS_PlayerWantsToResign:
318 case FIBS_WatchResign:
319 case FIBS_YouResign:
320 addResign(cs.getString());
321 break;
322 case FIBS_ResignRefused:
323 addResignRefused(cs.getString());
324 break;
325 case FIBS_AcceptWins:
326 addAcceptsAndWins(cs.getString());
327 break;
328 case FIBS_YouDouble:
329 addYouDouble(cs.getString());
330 break;
331 case FIBS_Doubles:
332 addOtherDoubles(cs.getString());
333 break;
334 default:
335 logger.warn("Unhandled event: (" + cs.getCookie() + ") "+ cs.getString());
336 break;
337 }
338 }
339
340
341
342
343
344
345 private void addStartNewGame(String s) {
346 reset(false);
347 GameEventBoard gb = new GameEventBoard();
348 Board b = gb.getBoard();
349 b.setStartPositions();
350 b.setPlayerName(Board.O, "You");
351 String ss[] = s.split(" ");
352 b.setPlayerName(Board.X, ss[5]);
353 if (DEBUG)
354 logger.info("addStartNewGame: opponent=" + ss[5]);
355 queueGameEvent(gb);
356 }
357
358
359
360
361 private void addPlayerJoinsYou(String s) {
362 reset(false);
363 GameEventBoard gb = new GameEventBoard();
364 Board b = gb.getBoard();
365 b.setStartPositions();
366 b.setPlayerName(Board.O, "You");
367 String ss[] = s.split(" ");
368 b.setPlayerName(Board.X, ss[2]);
369 if (DEBUG)
370 logger.info("addPlayerJoinsYou: opponent=" + ss[2]);
371 queueGameEvent(gb);
372 }
373
374
375
376 private void addResumeYourTurn(String s) {
377 GameEventRoll gr = new GameEventRoll();
378 String[] ss = s.split(" ");
379 gr.setPlayerName(ss[1].substring(0, ss[1].length()-1));
380 this.preStartList.add(gr);
381 if (DEBUG)
382 logger.info("addResumeYourTurn: addPreStart: " + gr.toString());
383 if (gr.getPlayerName().equals(this.mainDialog.getDocument().getName())) {
384 GameEventPleaseMove gpm = new GameEventPleaseMove();
385 gpm.setCheckersToMove(2);
386 gpm.setDice(gr.getDice());
387 this.preStartList.add(gpm);
388 if (DEBUG)
389 logger.info("addResumeYourTurn: addPreStart: " + gpm.toString());
390 }
391
392 }
393
394
395
396 private void addBoardLine(String s) {
397 GameEventBoard gb = new GameEventBoard(s);
398 queueGameEvent(gb);
399 if (!this.preStartList.isEmpty()) {
400 Board b = gb.getBoard();
401 if (DEBUGJibsBoard)
402 this.mainDialog.writeGameMessageln("board:" + b.getPlayerName()[0] + ":" + b.getPlayerName()[1]);
403
404 b.setSortDice(this.bfProps.isHighDieLeft());
405 this.mainDialog.getDocument().setBoard(b);
406 for (GameEvent ge : this.preStartList) {
407 if (DEBUG)
408 logger.info("Sending preStart: " + ge.toString());
409 if (ge.getType() == Type.Roll) {
410 GameEventRoll gr = (GameEventRoll)ge;
411 if (gr.getDice()[0] == 0) {
412 if (this.bfProps.isHighDieLeft())
413 gr.getDice()[0] = b.getDice()[Board.O][0];
414 gr.getDice()[1] = b.getDice()[Board.O][1];
415 }
416 }
417 queueGameEvent(ge);
418 }
419
420 this.preStartList.clear();
421 }
422 }
423 private void addMove(String s) {
424 GameEventMove gm = new GameEventMove();
425 gm.parse(s);
426 gm.setWho(this.mainDialog.getDocument().getBoard().getXOFromName(gm.getPlayerName()));
427 gm.setDirection(this.mainDialog.getDocument().getBoard().getDirectionFromName(gm.getPlayerName()));
428 if (DEBUG)
429 logger.info("addMove: " + s);
430 queueGameEvent(gm);
431 }
432
433
434
435
436 private void addBearingOff(String s) {
437 GameEventRoll gr = (GameEventRoll)getLastOf(Type.Roll);
438 if (!gr.getPlayerName().equals("You"))
439 return;
440 GameEventMove gm = new GameEventMove();
441 gm.parseBearingOff(s);
442 gm.setWho(Board.O);
443 if (DEBUG)
444 logger.info("addBearingOff: " + s);
445 queueGameEvent(gm);
446
447 }
448 private void addRoll(String s) {
449 GameEventRoll gr = new GameEventRoll();
450 gr.parse(s);
451 gr.setWho(this.mainDialog.getDocument().getBoard().getXOFromName(gr.getPlayerName()));
452 if (DEBUG) {
453 logger.info("addRoll: " + s + " who:" + gr.getWho());
454 }
455 queueGameEvent(gr);
456 }
457 private void addFirstRoll(String s) {
458 GameEventFirstRoll gfr = new GameEventFirstRoll();
459 gfr.parse(s);
460
461 if (DEBUG) {
462 logger.info("addRoll: " + s + " who:" + gfr.getWho());
463 }
464 queueGameEvent(gfr);
465 }
466 private void addYouCantMove(String unused) {
467 GameEventCantMove gcm = new GameEventCantMove();
468 gcm.setWho(Board.O);
469 if (DEBUG)
470 logger.info("addYouCantMove: " + " who:" + gcm.getWho());
471 queueGameEvent(gcm);
472
473 }
474 private void addCantMove(String s) {
475 GameEventCantMove gcm = new GameEventCantMove();
476 gcm.parse(s);
477 gcm.setWho(this.mainDialog.getDocument().getBoard().getXOFromName(gcm.getPlayerName()));
478 if (DEBUG)
479 logger.info("addCantMove: " + s + " who:" + gcm.getWho());
480 queueGameEvent(gcm);
481 }
482
483
484
485 private void addPleaseMove(String s) {
486 GameEventPleaseMove gpm = new GameEventPleaseMove();
487 gpm.parse(s);
488 GameEventRoll gr = (GameEventRoll)getLastOf(Type.Roll);
489 gpm.setDice(gr.getDice());
490 if (DEBUG)
491 logger.info("addPleaseMove: toMove=" + gpm.getCheckersToMove());
492 queueGameEvent(gpm);
493 }
494
495
496
497 private void addYourTurnToMove(String s) {
498 addFirstMove(s);
499 GameEventPleaseMove gpm = new GameEventPleaseMove();
500
501 gpm.setCheckersToMove(2);
502 GameEventRoll gr = (GameEventRoll)getLastOf(Type.Roll);
503 if (gr == null)
504 gr = (GameEventRoll)getLastOf(Type.FirstRoll);
505 gpm.setDice(gr.getDice());
506 if (DEBUG)
507 logger.info("addYourTurnToMove: toMove=" + gpm.getCheckersToMove());
508 queueGameEvent(gpm);
509 }
510 private void addFirstMove(String s) {
511 GameEventFirstMove gefm = new GameEventFirstMove();
512 GameEventFirstRoll gefr = (GameEventFirstRoll)getLastOf(Type.FirstRoll);
513 GameEventBoard geb = (GameEventBoard)getLastOf(Type.Board);
514 gefm.parse(s, gefr, geb.getBoard());
515 if (DEBUG)
516 logger.info("addFirstMove:");
517 queueGameEvent(gefm);
518
519 }
520 private void addResign(String s) {
521 GameEventResign ger = new GameEventResign();
522 GameEventBoard geb = (GameEventBoard)getLastOf(Type.Board);
523 Board b = geb.getBoard();
524 ger.parse(s, b);
525
526 if (DEBUG)
527 logger.info("addResign: s=" + s);
528 queueGameEvent(ger);
529 GameEventPleaseAcceptOrRejectResign geparr = new GameEventPleaseAcceptOrRejectResign();
530 geparr.setWho(ger.getWho());
531 geparr.setResigningPoints(ger.getResigningPoints());
532 queueGameEvent(geparr);
533 }
534 private void addResignRefused(String unused) {
535 GameEventPleaseAcceptOrRejectResign geparr =
536 (GameEventPleaseAcceptOrRejectResign)getLastOf(Type.PleaseAcceptOrRejectResign);
537 if (geparr == null)
538 return;
539 GameEventRejectResign gerr = new GameEventRejectResign();
540 gerr.setWho(geparr.getWho() == Board.X ? Board.O : Board.X);
541 GameEventPleaseAcceptOrRejectResign gepaorr = (GameEventPleaseAcceptOrRejectResign)getLastOf(Type.PleaseAcceptOrRejectResign);
542 gerr.setResigningPoints(gepaorr.getResigningPoints());
543 queueGameEvent(gerr);
544 }
545 private void addAcceptsAndWins(String s) {
546 GameEventAcceptAndWin geaaw = new GameEventAcceptAndWin();
547 GameEventBoard geb = (GameEventBoard)getLastOf(Type.Board);
548 Board b = geb.getBoard();
549 geaaw.parse(s, b);
550 queueGameEvent(geaaw);
551 }
552 private void addYouDouble(String s) {
553 GameEventYouDouble geyd = new GameEventYouDouble();
554 GameEventBoard geb = (GameEventBoard)getLastOf(Type.Board);
555 Board b = geb.getBoard();
556 b.setWasDoubled(b.getXO());
557 geyd.setCubeBefore(b.getCube());
558 geyd.setWhoDoubled(b.getXO());
559 logger.info("who = " + geb.getBoard().getXOAsText());
560 logger.info("geyd.whoDoubled = " + geyd.getWhoDoubled());
561 queueGameEvent(geyd);
562 GameEventPleaseAcceptOrRejectDouble gepard = new GameEventPleaseAcceptOrRejectDouble();
563 gepard.setGuiEvent(false);
564 gepard.setWhoDoubled(geyd.getWhoDoubled());
565 logger.info("gepard.setWhoDoubled = " + gepard.getWhoDoubled());
566 queueGameEvent(gepard);
567
568 }
569
570 private void addOtherDoubles(String s) {
571 GameEventDouble ged = new GameEventDouble();
572 GameEventBoard geb = (GameEventBoard)getLastOf(Type.Board);
573 Board b = geb.getBoard();
574 ged.parse(s, b);
575 b.setWasDoubled(ged.getWhoDoubled());
576 if (DEBUG)
577 logger.info("addOtherDoubles: s=" + s);
578 queueGameEvent(ged);
579 GameEventPleaseAcceptOrRejectDouble gepard = new GameEventPleaseAcceptOrRejectDouble();
580 gepard.setGuiEvent(false);
581 gepard.setWhoDoubled(ged.getWhoDoubled());
582 queueGameEvent(gepard);
583 }
584 private void addAcceptRejectDouble(String s) {
585 GameEventDouble ged = new GameEventDouble();
586 GameEventBoard geb = (GameEventBoard)getLastOf(Type.Board);
587 Board b = geb.getBoard();
588 ged.parse(s, b);
589 b.setWasDoubled(ged.getWhoDoubled());
590
591 if (DEBUG)
592 logger.info("addDoubles to You: s=" + s);
593 queueGameEvent(ged);
594 GameEventPleaseAcceptOrRejectDouble gepard = new GameEventPleaseAcceptOrRejectDouble();
595
596 if (DEBUG)
597 logger.info("addAcceptRejectDouble: add PleaseAcceptRejectDouble");
598 queueGameEvent(gepard);
599 }
600
601
602
603
604 public void goFirst() {
605 this.position = 1;
606 if (DEBUGpos)
607 logger.info("goFirst: pos = " + this.position);
608 sendGameEvent(Start);
609 updateToolbarButtons();
610 }
611
612
613
614 public void goPrev() {
615 if (this.position > 1)
616 this.position--;
617 if (DEBUGpos)
618 logger.info("goPrev: pos = " + this.position);
619 sendGameEvent(Backward);
620 updateToolbarButtons();
621 }
622
623
624
625 public void goNext() {
626 if (this.position < this.gameEvents.size())
627 this.position++;
628 if (DEBUGpos)
629 logger.info("goNext: pos = " + this.position);
630 sendGameEvent(Forward);
631 updateToolbarButtons();
632 }
633
634
635
636 public void goLast() {
637 this.position = this.gameEvents.size();
638 if (DEBUGpos)
639 logger.info("goLast: pos = " + this.position);
640 sendGameEvent(Forward);
641 updateToolbarButtons();
642 }
643
644
645
646 public void goUndo() {
647 sendGameEvent(Undo);
648 }
649
650
651 public void goPlayPaused() {
652
653 }
654
655
656
657
658
659
660
661
662 private synchronized void sendGameEvent(int dir) {
663
664 if (DEBUGsend || DEBUGpos)
665 logger.info("sendGameEvent: position=" + this.position + " size=" + this.gameEvents.size());
666 if (dir == Undo) {
667
668
669 boolean lastBoardWasSeen = false;
670 GameEvent ge = null;
671 int k;
672 for (k = this.gameEvents.size()-1; k >= 0; k--) {
673 ge = this.gameEvents.get(k);
674 if (ge.getType() == Type.Board) {
675 if (lastBoardWasSeen) {
676 break;
677 }
678 lastBoardWasSeen = true;
679 }
680 ge = null;
681 }
682 if (ge != null) {
683 for (position = k; position < this.gameEvents.size(); position++) {
684 ge = this.gameEvents.get(position);
685 this.mainDialog.moveEvent(ge);
686 }
687 }
688 }
689 if (dir == Forward && this.replayToolbar.isPlayPause()) {
690
691 }
692 while (true) {
693 GameEvent ge = this.gameEvents.get(this.position-1);
694 if (DEBUGsend)
695 logger.debug("send: loop top: pos=" + this.position + " ge=" + ge.getType().toString());
696 if (ge.getType() == Type.Board) {
697
698
699
700
701 if (DEBUGsend) {
702 logger.debug("sendToAnimate a: pos=" + position + " size=" + this.gameEvents.size());
703 logger.debug("sendToAnimtate a: " + ge.getType().toString());
704 }
705 this.mainDialog.moveEvent(ge);
706 if ((bfProps.isAnimateMoves() && this.position == gameEvents.size())
707 || dir == Start) {
708 return;
709 }
710 if (this.position >= gameEvents.size()) {
711 if (DEBUGsend || DEBUGpos)
712 logger.info("send: End of list: Don't bump pos " + this.position + " after sending board");
713 updateToolbarButtons();
714 return;
715 }
716 this.position += dir;
717 if (DEBUGsend || DEBUGpos)
718 logger.info("send: Set pos to " + this.position + " after sending board");
719 updateToolbarButtons();
720 } else {
721 if (bfProps.isAnimateMoves()) {
722 if (DEBUGsend) {
723 logger.info("sendToAnimate b: pos=" + position + " size=" + this.gameEvents.size());
724 logger.info("sendToAnimate b: " + ge.getType().toString());
725 }
726 this.mainDialog.moveEvent(ge);
727 updateToolbarButtons();
728 return;
729 }
730 if (dir == Forward) {
731 if (this.position < gameEvents.size()) {
732 this.position++;
733 }
734 if (DEBUGsend || DEBUGpos)
735 logger.info("send: skip position to " + this.position + " gameEvents.size=" + gameEvents.size());
736 if (this.position >= gameEvents.size()) {
737 if (DEBUGsend || DEBUGpos) {
738 logger.info("sendToAnimate c: pos=" + position + " size=" + this.gameEvents.size());
739 logger.info("sendToAnimate c: " + ge.getType().toString());
740 }
741 this.mainDialog.moveEvent(ge);
742
743 if (DEBUGsend || DEBUGpos)
744 logger.info("send: pos = " + this.position + " and send nothing");
745 updateToolbarButtons();
746 return;
747 }
748 if (DEBUGsend)
749 logger.info("send: Skipping this event");
750 continue;
751 }
752 this.position--;
753 if (this.position < 1) {
754 this.position = 1;
755 if (DEBUGsend) {
756 logger.info("sendToAnimate d: pos=" + position + " size=" + this.gameEvents.size());
757 logger.info("sendToAnimate d: " + ge.getType().toString());
758 }
759 this.mainDialog.moveEvent(ge);
760 updateToolbarButtons();
761 return;
762 }
763 }
764 }
765 }
766
767 private LinkedList<GameEvent> gameEvents = new LinkedList<GameEvent>();
768
769
770
771
772 private void queueGameEvent(GameEvent gameEvent) {
773 if (DEBUG)
774 logger.debug("queueGameEvent: a position=" + this.position + " size=" + this.gameEvents.size());
775 if (!gameEvents.isEmpty()) {
776 GameEvent old = gameEvents.getLast();
777 if (old.getLife() == Life.Transient) {
778 if (this.position == gameEvents.size())
779 this.position--;
780 gameEvents.removeLast();
781 if (DEBUG) {
782 logger.debug("queueGameEvent: b position=" + this.position + " size=" + this.gameEvents.size());
783 logger.debug("queueGameEvent: b remove old=" + old.getType().toString());
784 }
785
786
787
788
789
790
791 }
792 }
793 gameEvents.add(gameEvent);
794 if (DEBUG)
795 logger.debug("queueGameEvent: queued: " + gameEvent.toString());
796 if (DEBUG)
797 logger.debug("queueGameEvent: c position=" + this.position + " size=" + this.gameEvents.size());
798 boolean shouldMove = this.replayToolbar.isPlayPause();
799 if (shouldMove) {
800 this.position++;
801 sendGameEvent(Forward);
802 } else {
803 updateToolbarButtons();
804 }
805 }
806
807 private GameEvent getLastOf(Type eventType) {
808 GameEvent ret = null;
809 for (GameEvent ge : gameEvents) {
810 if (ge.getType() == eventType)
811 ret = ge;
812 }
813 return(ret);
814 }
815
816 private void updateToolbarButtons() {
817 this.replayToolbar.getJButtonFirst().setEnabled(position > 1);
818 this.replayToolbar.getJButtonBack().setEnabled( position > 1);
819 this.replayToolbar.getJButtonNext().setEnabled( position < gameEvents.size());
820 this.replayToolbar.getJButtonEnd().setEnabled( position < gameEvents.size());
821 }
822
823
824 }