2-APL UPC project.
1package cardtable;
2
3// 2APL imports
4import apapl.Environment;
5import apapl.ExternalActionFailedException;
6import apapl.data.*;
7
8// Standard java imports
9import java.awt.Point;
10import java.util.*;
11import javax.swing.SwingUtilities;
12import java.awt.Dimension;
13
14import java.io.IOException;
15import java.io.InputStream;
16import java.io.ObjectInputStream;
17import java.io.ObjectOutputStream;
18import java.io.OutputStream;
19
20public class Env extends Environment
21{
22 final protected Table table;
23
24 private HashMap<String,Agent> agentmap = new HashMap<String,Agent>();
25
26 private int numberOfPlayers, numberOfNotaries, numberOfGatekeepers, numberOfDealers;
27
28 private Deck deck;
29
30 private Scoreboard sb;
31
32 // The default constructor
33 public Env()
34 {
35 super();
36 numberOfPlayers=0;
37 numberOfNotaries=0;
38 numberOfGatekeepers=0;
39
40 deck = new Deck();
41 sb = new Scoreboard();
42
43 //Create the window
44 table = new Table();
45 }
46
47 public Term enterAsNotary(String sAgent) throws ExternalActionFailedException {
48 Agent agent = getAgent(sAgent);
49 writeToLog("Notary sit: " +agent.getName());
50
51 if(numberOfNotaries>0)
52 throw new ExternalActionFailedException("There is already a notary at the table.");
53 else
54 numberOfNotaries++;
55
56 agent._type=2;
57 agent._position=-1; /* notary hasn't a real position, but it needs a value in order to be sit at the table */
58
59 return wrapBoolean(true);
60 }
61
62 public Term enterAsDealer(String sAgent) throws ExternalActionFailedException {
63 Agent agent = getAgent(sAgent);
64 writeToLog("Dealer sit: " +agent.getName());
65
66 if(numberOfDealers>0)
67 throw new ExternalActionFailedException("There is already a dealer at the table.");
68 else
69 numberOfDealers++;
70
71 agent._type=3;
72 agent._position=-1; /* dealer hasn't a real position, but it needs a value in order to be sit at the table */
73
74 return wrapBoolean(true);
75 }
76
77 public Term enterAsGatekeeper(String sAgent) throws ExternalActionFailedException {
78 Agent agent = getAgent(sAgent);
79 writeToLog("Gatekeeper in the system: " +agent.getName());
80
81 if(numberOfGatekeepers>0)
82 throw new ExternalActionFailedException("There is already a gatekeeper in the system.");
83 else
84 numberOfGatekeepers++;
85
86 agent._type=1;
87 agent._position=-1; /* gk hasn't a real position, but it needs a value in order to be sit at the table */
88
89 return wrapBoolean(true);
90 }
91
92 // Sit the player at the table
93 public Term sit(String sAgent, APLIdent player) throws ExternalActionFailedException
94 {
95 String player_name = player.toString();
96
97 Agent agent = getAgent(player_name);
98
99 // is already sit?
100 if(agent.isSit())
101 {
102 writeToLog( "agent already sit" );
103 throw new ExternalActionFailedException("Agent \""+agent.getName()+"\" is already sit.");
104 }
105
106 // are there already 5 players at the table?
107 if (getNumberOfPlayers()==5)
108 {
109 throw new ExternalActionFailedException("Already 5 players sit at the table.");
110 }
111
112 // Update the agent his position
113 agent._position = getPosition();
114 agent._type=0; // is a player
115
116 // Increase number of players
117 increaseNumberOfPlayers();
118
119 // Add it to the scoreboard
120 sb.addPlayer(agent.getName());
121
122 // Add it to the gui
123 table.addPlayer(player_name, agent._position, 0, 0);
124 validatewindow();
125 table.repaint();
126
127 writeToLog("Player sit: " +agent.getName());
128
129 return new APLNum(agent._position);
130 }
131
132 public Term chooseDealer(String sAgent) throws ExternalActionFailedException
133 {
134 if (getNumberOfPlayers()!=5)
135 {
136 throw new ExternalActionFailedException("There are not 5 players sit at the table.");
137 }
138
139 Random rand = new Random();
140 int n = 5;
141 int randnum = rand.nextInt(n+1);
142
143 Agent a = getAgent(randnum);
144
145 return new APLIdent(a.getName());
146 }
147
148 public Term shuffleDeck(String sAgent) throws ExternalActionFailedException {
149 Agent agent = getAgent(sAgent);
150
151 if (agent.getType()!=3)
152 {
153 throw new ExternalActionFailedException("Only the dealer can shuffle the deck.");
154 }
155
156 deck.shuffle();
157
158 Agent d = getDealer();
159 notifyEvent("deckShuffled", deck, d);
160
161 return wrapBoolean(true);
162 }
163
164 public Term playCard(String sAgent, APLIdent suit, APLIdent rank) throws ExternalActionFailedException {
165 Agent agent = getAgent(sAgent);
166 notifyEvent("cardPlayed", suit, rank, agent);
167 Card played_card = deck.getCard(suit.toString(), rank.toString());
168 table.playedCard(agent.getName(), agent._position, played_card);
169 return wrapBoolean(true);
170 }
171
172 public Term updateScore(String sAgent, APLIdent player_name, APLNum score) throws ExternalActionFailedException {
173 Agent agent = getAgent(player_name.toString());
174 sb.updateScore(player_name.toString(), score.toInt());
175 table.updateScore(agent.getName(), agent._position, score.toInt());
176 notifyEvent("scoreUpdated", player_name, score);
177 return wrapBoolean(true);
178 }
179
180 public Term updatePoints(String sAgent, APLIdent player_name, APLNum points) throws ExternalActionFailedException {
181 Agent agent = getAgent(player_name.toString());
182 table.updatePoints(agent.getName(), agent._position, points.toInt());
183 return wrapBoolean(true);
184 }
185
186 public Term updateBid(String sAgent, APLNum bid) throws ExternalActionFailedException {
187 Agent agent = getAgent(sAgent);
188 table.updateBid(agent.getName(), agent._position, bid.toInt());
189 return wrapBoolean(true);
190 }
191
192 public Term briscolaDeclared(String sAgent, APLIdent suit, APLIdent rank) throws ExternalActionFailedException {
193 Agent agent = getAgent(sAgent);
194 Card played_card = deck.getCard(suit.toString(), rank.toString());
195 table.briscolaDeclared(agent.getName(), agent._position, played_card);
196 return wrapBoolean(true);
197 }
198
199 public Term handDealt(String sAgent, APLList cards, APLIdent player_name) throws ExternalActionFailedException {
200 Agent agent = getAgent(sAgent);
201
202 if (agent.getType()!=3)
203 {
204 throw new ExternalActionFailedException("Only the dealer can deal cards.");
205 }
206
207 LinkedList<Term> ll = cards.toLinkedList();
208 Hand hand = new Hand();
209 for(int i=0, j=0; i<8; i++, j+=2) {
210 hand.addCard(deck.getCard(ll.get(j).toString(), ll.get(j+1).toString()));
211 //System.out.println(hand[i].getSuit().getName()+" "+hand[i].getRank().getName());
212 }
213
214 Agent player_agent = getAgent(player_name.toString());
215
216 table.displayHand(player_name.toString(), player_agent._position, hand);
217
218 return wrapBoolean(true);
219 }
220
221 /* Standard functions --------------------------------------*/
222
223 private void notifyAgents(APLFunction event, String... receivers) {
224 throwEvent(event, receivers);
225 }
226
227 private void notifyEvent(String parm1, Deck deck, Agent d)
228 {
229 LinkedList returnList = new LinkedList();
230 List deckList = deck.getDeck();
231
232 String deckStr = new String("[ ");
233
234 for (Iterator<Card> i = deckList.iterator( ); i.hasNext( ); ) {
235 Card card = i.next();
236 Suit suit = card.getSuit();
237 APLIdent id = new APLIdent(suit.getName());
238 deckStr += "<" + suit.getName() + ", ";
239 returnList.add(id);
240 Rank rank = card.getRank();
241 id = new APLIdent(rank.getName());
242 deckStr += rank.getName() + ">";
243 returnList.add(id);
244 if(i.hasNext())
245 deckStr += ", ";
246 }
247 deckStr += " ]";
248
249 if (d!=null)
250 {
251 notifyAgents(new APLFunction(parm1,new APLList(returnList)), d.getName());
252 writeToLog("EVENT: "+parm1+" "+deckStr+" "+" to "+d.getName());
253 }
254 }
255
256 private void notifyEvent(String parm1, APLIdent suit, APLIdent rank, Agent player) {
257 ArrayList<String> targetAgents = new ArrayList<String>();
258 for (Agent a : agentmap.values())
259 {
260 if ((a.isSit() && a.getType()==0) || (a.isSit() && a.getType()==2)) // player or notary
261 targetAgents.add(a.getName());
262 }
263 APLIdent player_name = new APLIdent(player.getName());
264 if (!targetAgents.isEmpty())
265 {
266 notifyAgents(new APLFunction(parm1,suit,rank,player_name),targetAgents.toArray(new String[0]));
267 writeToLog("EVENT: "+parm1+"("+suit.toString()+","+rank.toString()+","+player.getName()+")"+" to "+targetAgents);
268 }
269 }
270
271 private void notifyEvent(String parm1, APLIdent name, APLNum score) {
272 ArrayList<String> targetAgents = new ArrayList<String>();
273 for (Agent a : agentmap.values())
274 {
275 if ((a.isSit() && a.getType()==0)) // player
276 targetAgents.add(a.getName());
277 }
278
279 if (!targetAgents.isEmpty())
280 {
281 notifyAgents(new APLFunction(parm1,name,score),targetAgents.toArray(new String[0]));
282 writeToLog("EVENT: "+parm1+"("+name.toString()+","+score.toString()+")"+" to "+targetAgents);
283 }
284 }
285
286 // Add an agent to the environment
287 public synchronized void addAgent(String sAgent) {
288 String sAgentMain = getMainModule(sAgent);
289 // Agent not yet in the environment
290 if (agentmap.keySet().contains(sAgentMain)) {
291 agentmap.put(sAgent,agentmap.get(sAgentMain));
292 writeToLog("linking " + sAgent + "");
293 } else{
294 final Agent agent = new Agent(sAgentMain);
295 //_agents.add(agent);
296 agentmap.put(sAgent, agent);
297 writeToLog("agent " + agent + " added");
298 }
299 }
300
301 // Remove the agent from the environment
302 public synchronized void removeAgent(String sAgent)
303 {
304 try
305 {
306 //String sAgentMain = getMainModule(sAgent);
307
308 Agent a = getAgent(sAgent);
309 agentmap.remove( sAgent );
310
311 // there can be several agent
312 if (!agentmap.containsValue(a)) {
313 //_agents.remove(a);
314 //a.reset();
315 }
316
317 writeToLog("Agent removed: " + sAgent);
318
319 synchronized( this )
320 {
321 notifyAll();
322 }
323 }
324 catch (ExternalActionFailedException e) {}
325 }
326
327 /* END Standard functions --------------------------------------*/
328
329 /* Helper functions --------------------------------------*/
330
331 // Get the agent from its name
332 private synchronized Agent getAgent(String name) throws ExternalActionFailedException
333 {
334 Agent a = null;
335 //a = agentmap.get(getMainModule(name));
336 a = agentmap.get(name);
337 if (a==null) throw new ExternalActionFailedException("No such agent: "+name);
338 else return a;
339
340 }
341
342 // Get the agent from its position
343 private synchronized Agent getAgent(int position) throws ExternalActionFailedException
344 {
345 Agent a = null;
346 Iterator it = agentmap.keySet().iterator();
347 while(it.hasNext()) {
348 Object name = it.next();
349 a = agentmap.get(name);
350 if(a!=null) {
351 if(a.getPosition()!=null) {
352 if(a.getPosition().intValue()==position) {
353 return a;
354 }
355 }
356 }
357 }
358 if (a==null) throw new ExternalActionFailedException("No such agent at position: "+position);
359
360 return a;
361 }
362
363 private synchronized Agent getDealer() throws ExternalActionFailedException {
364 Agent a = null;
365 Iterator it = agentmap.keySet().iterator();
366 while(it.hasNext()) {
367 Object name = it.next();
368 a = agentmap.get(name);
369 if(a!=null) {
370 if(a.getType()==3) {
371 return a;
372 }
373 }
374 }
375 if (a==null) throw new ExternalActionFailedException("There is no dealer at the moment.");
376
377 return a;
378 }
379
380 private static String getMainModule(String sAgent)
381 {
382 int dotPos;
383 if ((dotPos = sAgent.indexOf('.')) == -1)
384 return sAgent;
385 else
386 return sAgent.substring(0, dotPos);
387 }
388
389 public void writeToLog(String message) {
390 System.out.println("cardtable: " + message);
391 table.writeLog(message);
392 }
393
394 // helper function to wrap a boolean value inside a ListPar.
395 static public APLListVar wrapBoolean( boolean b )
396 {
397 return new APLList(new APLIdent(b ? "true" : "false"));
398 }
399 /* END Helper functions --------------------------------------*/
400
401
402 private int getNumberOfPlayers() {
403 return numberOfPlayers;
404 }
405
406 private void increaseNumberOfPlayers() {
407 numberOfPlayers++;
408 }
409
410 private void decreaseNumberOfPlayers() {
411 numberOfPlayers--;
412 }
413
414 private Integer getPosition() {
415 return new Integer(numberOfPlayers);
416 }
417
418 private void validatewindow()
419 {
420 Runnable repaint = new Runnable()
421 {
422 public void run()
423 {
424 //try {Thread.sleep(500);} catch(Exception e) {}
425 table.doLayout();
426
427 /*if (!m_window.isVisible())
428 {
429 m_window.setVisible( true );
430 }*/
431 }
432 };
433 SwingUtilities.invokeLater(repaint);
434 }
435}