001 package jagafa;
002
003 import jagafa.ai.JassAI;
004 import jagafa.ai.ProbabilityAI;
005 import jagafa.flags.TestingFlags;
006 import jagafa.object.Card;
007 import jagafa.object.Player;
008 import jagafa.rule.RuleSet;
009
010 import java.awt.event.ActionEvent;
011 import java.awt.event.ActionListener;
012
013 import javax.swing.Timer;
014
015 public class JassRound extends JassRoundCore {
016
017 /**
018 * Constructor: init the game with the ruleSet given
019 */
020 public JassRound(RuleSet rules) {
021 super(rules);
022
023 }
024
025 /**
026 * Initialize all the players
027 * TODO: initPlayers() should be externalized or at least parameterized
028 */
029 protected void initPlayers() {
030 Player.resetPlayerCount();
031 for (int i = 0; i < 4; i++) {
032 Player newPlayer = null;
033 /* Add human or ai-driven player */
034 if (TestingFlags.playerIsHuman_[i]) {
035 newPlayer = new Player(9, true);
036
037 } else {
038 newPlayer = new Player(9, false, new ProbabilityAI());
039 newPlayer.getAI().init(newPlayer, this);
040 }
041 addPlayer(newPlayer);
042
043 }
044 }
045
046 public void start(Player startPlayer) {
047 if (this.running_) {
048 return;
049 }
050 this.setLastTurnWinner(startPlayer);
051 this.setActivePlayer(startPlayer);
052 start();
053 }
054
055 /**
056 * Start the game by installing the main and refresh timers
057 * Only if the RuleSet is set!
058 */
059 public void start() {
060
061 if (this.running_) {
062 return;
063 }
064
065 if (this.getRules() != null) {
066
067 this.running_ = true;
068 installTimer();
069 }
070 }
071
072 /**
073 * Adds a card of Player p to the active Board, if valid
074 */
075 public synchronized void playCard(Card card, Player player) {
076
077 this.activeBoard().addCard(card, player);
078
079 this.nextPlayer();
080
081 /*
082 * If four cards are on the board, update scores, cleanup and refresh
083 * Otherwise do some AI processing
084 */
085 if (this.activeBoard().cardsPlayed() == 4) {
086
087 Player winner = getWinner(this.activeBoard());
088 this.getGoneHeap().addTurn(this.activeBoard(), winner);
089 winner.addScore(this.getScore(this.activeBoard()));
090
091 /* if round is over, add lastRound score, stop the ai timer and report
092 * scores to the top-level score table if there is any
093 */
094 if (isRoundOver()) {
095 winner.addScore(5);
096
097 reportScores();
098 aiTimer_.stop();
099
100 } else {
101 this.getRules().updateAfterTurn();
102 }
103
104 /* Set the active Player to the winner */
105 this.setLastTurnWinner(winner);
106 this.setActivePlayer(winner);
107
108 /* Start the refresh timer */
109 refreshTimer_.start();
110 } else {
111
112 aiTimer_.start();
113 this.toggleNotify();
114 }
115
116 }
117
118 /**
119 * Do all computer movements
120 */
121 public synchronized void doComputer() {
122
123 if (activePlayer().isComputer()) {
124 JassAI ai = activePlayer().getAI();
125 ai.init(activePlayer(), this);
126 activePlayer().playCard(ai.computeCard(), this);
127 toggleNotify();
128
129 }
130 /* If the game is over, repeat the ai timer only once to cleanup */
131 if (this.isRoundOver()) {
132 aiTimer_.setRepeats(false);
133 }
134
135 }
136
137 /**
138 * Print the score to stdout
139 */
140 public void printScores() {
141 int sum1 = this.getPlayer(0).getScore() + this.getPlayer(2).getScore();
142 int sum2 = this.getPlayer(1).getScore() + this.getPlayer(3).getScore();
143 System.out.println("Player 0 and 2: " + sum1);
144 System.out.println("Player 1 and 3: " + sum2);
145 }
146
147 /**
148 * Install the ai- and refresh-timers
149 */
150 private void installTimer() {
151 /**
152 * The refresh timer updates the ui every 1.5 seconds
153 * In addition he clears the board if a turn/round is over
154 */
155 int uiDelay = TestingFlags.UI_REFRESH_DELAY;
156 if (TestingFlags.speedUp_) {
157 uiDelay = TestingFlags.FAST_UI_REFRESH_DELAY;
158 }
159 refreshTimer_ = new Timer(uiDelay, new ActionListener() {
160
161 public void actionPerformed(ActionEvent e) {
162
163 if (activePlayer() == getLastTurnWinner()) {
164 activeBoard().clearBoard();
165 toggleNotify();
166 }
167
168 }
169
170 });
171 refreshTimer_.setRepeats(false);
172
173 /**
174 * The AI timer does a computer move and restarts the game if needed
175 */
176 int aiDelay = TestingFlags.NORMAL_AI_DELAY;
177 if (TestingFlags.speedUp_) {
178 aiDelay = TestingFlags.FAST_AI_DELAY;
179 }
180
181 aiTimer_ = new Timer(aiDelay, new ActionListener() {
182
183 public void actionPerformed(ActionEvent e) {
184 if (TestingFlags.paused_) {
185 return;
186 }
187 if (!refreshTimer_.isRunning()) {
188 //for (int i = 0; i < 4; i++) {
189 doComputer();
190 // }
191 }
192 if (isRoundOver()) {
193 running_ = false;
194 //restartTimer_.start();
195 //restartTimer_.setRepeats(false);
196 }
197
198 }
199
200 });
201 aiTimer_.setRepeats(true);
202 aiTimer_.start();
203 }
204 }