📄 tacagent.java
字号:
long currentTime = getServerTime(); isGameStarted = true; d.addTask(currentTime + INFO_UPDATE_PERIOD, "quotes", connection, this); d.addTask(currentTime + (int) (1.5 * INFO_UPDATE_PERIOD), "bids", connection, this); if (printOwnDelay > 0) { d.addTask(currentTime + printOwnDelay, "printOwn", connection, this); } // Start the hotel quote fetch (one second after update) long nextHotelTime = startTime + 61000; if (nextHotelTime < currentTime) { nextHotelTime += 60000 * ((currentTime - nextHotelTime) / 60000); } long nextFlightTime = startTime + 11000; if (nextFlightTime < currentTime) { nextFlightTime += 10000 * ((currentTime - nextFlightTime) / 10000); } TimeDispatcher.getDefault().addTask(nextHotelTime, "hotelQuotes", connection, this); TimeDispatcher.getDefault().addTask(nextFlightTime, "flightQuotes", connection, this); requestQuotes(connection, true, true); } } } swapTransactions(); } private synchronized void swapTransactions() { if (waitActionsNum == 0) { transActionsNum = 0; // Do nothing more... } else { // Set up actions to call after next transaction transActionsNum = waitActionsNum; int[] tmp = transActions; transActions = waitActions; waitActions = tmp; waitActionsNum = 0; // Request new transaction!!! TACMessage msg = new TACMessage("transIDs"); msg.setParameter("earliestTransID", earliestTransID); sendMessage(msg, this); } } private void handleQuote(TACMessage msg) { Object obj = msg.getUserData(); Quote quote; int auction; if (obj instanceof Quote) { quote = (Quote) obj; auction = quote.getAuction(); } else { Bid bid = (Bid) obj; auction = bid.getAuction(); quote = quotes[auction]; quote.setHQW(-1); quote.setBid(bid); } // Quote is no longer pending pendingQuotes[auction] = 0L; int oldAuctionStatus = quote.getAuctionStatus(); while (msg.nextTag()) { if (msg.isTag("lastAskPrice")) { quote.setAskPrice(msg.getValueAsFloat(0f)); } else if (msg.isTag("lastBidPrice")) { quote.setBidPrice(msg.getValueAsFloat(0f)); } else if (msg.isTag("hypotheticalQuantityWon")) { quote.setHQW(msg.getValueAsInt(-1)); } else if (msg.isTag("auctionStatus")) { quote.setAuctionStatus(msg.getValueAsInt(Quote.AUCTION_INITIALIZING)); } else if (msg.isTag("nextQuoteTime")) { quote.setNextQuoteTime(1000 * msg.getValueAsLong(0)); } else if (msg.isTag("auctionStatus")) { quote.setLastQuoteTime(1000 * msg.getValueAsLong(0)); } } try { agent.quoteUpdated(quote); } catch (Exception e) { log.log(Level.SEVERE, "agent could not handle quoteUpdated for " + quote, e); } try { if (isLastAuction(quote)) { agent.quoteUpdated(getAuctionCategory(auction)); } } catch (Exception e) { log.log(Level.SEVERE, "agent could not handle quoteUpdated for " + quote, e); } if (quote.isAuctionClosed() && (oldAuctionStatus != Quote.AUCTION_CLOSED)) { requestTransactions(OP_CLOSE_AUCTION + auction); } if (tableModel != null) { tableModel.fireTableRowsUpdated(auction, auction); } } private boolean isLastAuction(Quote quote) { int auction = quote.getAuction(); int category = getAuctionCategory(auction); long serverTime, quoteTime; if (category == CAT_ENTERTAINMENT) { return auction == MAX_ENTERTAINMENT; } else if (category == CAT_FLIGHT) { return auction == MAX_FLIGHT; } else if (!quote.isAuctionClosed() && (quoteTime = quote.getNextQuoteTime()) > 0 && (serverTime = getServerTime()) > quoteTime) { lastHotelAuction = auction; log.fine("rerequesting hotel quote for auction " + auction); TimeDispatcher.getDefault() .addTask(serverTime + 1000, quote, connection, this); return false; } else { return auction == lastHotelAuction; } } private void handleBidInfo(TACMessage msg) { Bid bid = (Bid) msg.getUserData(); String bidHash = null; String bidString = null; int rejectReason = Bid.NOT_REJECTED; int processingState = Bid.UNPROCESSED; long timeClosed = 0L; long timeProcessed = 0L; int commandStatus = NO_ERROR; while (msg.nextTag()) { if (msg.isTag("bidString")) { bidString = msg.getValue(); } else if (msg.isTag("bidHash")) { bidHash = msg.getValue(); } else if (msg.isTag("rejectReason")) { rejectReason = Bid.mapRejectReason(msg.getValueAsInt(rejectReason)); } else if (msg.isTag("processingState")) { processingState = Bid.mapProcessingState(msg.getValueAsInt(processingState)); } else if (msg.isTag("timeClosed")) { timeClosed = msg.getValueAsLong(0); } else if (msg.isTag("timeProcessed")) { timeProcessed = msg.getValueAsLong(0); } else if (msg.isTag("commandStatus")) { commandStatus = msg.getValueAsInt(NO_ERROR); } } // Potential problem 1: // 1. BidInfo is sent by return of submitBid // 2. BidInfo is sent pga 45 second period bid info requesting // 3. BidInfo is received with changed bidHash // 4. BidInfo is received with same bidHash as 3 but different from msg.Bid // Potential problem 2: // 1. Bid is submitted with submitBid // 2. BidInfo is requested // 3. Bid is submitted with submitBid // 4. BidInfo for 2 is received if (commandStatus != NO_ERROR) { log.warning("could not retrieve bidInfo for bid " + bid.getID() + " in auction " + bid.getAuction() + ": " + commandStatusToString(commandStatus)); } else { // Bid is ok (not preliminary or rejected)! bid.setReplacing(null); bid.setProcessingState(processingState); bid.setRejectReason(rejectReason); bid.setTimeProcessed(timeProcessed); bid.setTimeClosed(timeClosed); String oldHash = bid.getBidHash(); if (oldHash == null && !isGameStarted) { // The bid is being recovered at startup bid.setBidHash(bidHash); bid.setBidString(bidString); recoverBid(bid); } else if (!bidHash.equals(oldHash)) { int auction = bid.getAuction(); int clearID = this.clearID++; log.finest("Requesting transactions for bid " + bid.getID() + " ClearID=" + clearID); requestTransactions(OP_CLEAR_BID + (clearID << 5) + auction); bid.setBidTransacted(clearID, bidHash, bidString); } else { try { agent.bidUpdated(bid); } catch (Exception e) { log.log(Level.SEVERE, "agent could not handle bidUpdated", e); } } int row = bid.getAuction(); if (tableModel != null) { tableModel.fireTableRowsUpdated(row, row); } } } private synchronized void clearBid(int transID) { int auction = transID & 31; int clearID = transID >> 5; Bid activeBid = getBid(auction); while (activeBid != null) { if (activeBid.getClearID() == clearID) { String bidString = activeBid.getClearString(); Bid newBid = new Bid(activeBid, bidString, activeBid.getClearHash()); boolean isActiveBid = activeBid == getBid(auction); if (bidString.equals(Bid.EMPTY_BID_STRING)) { removeBid(auction, activeBid); } else { changeBid(auction, activeBid, newBid); } if (isActiveBid) { try { agent.bidUpdated(newBid); } catch (Exception e) { log.log(Level.SEVERE, "agent could not handle bidUpdated", e); } if (tableModel != null) { tableModel.fireTableRowsUpdated(auction, auction); } } activeBid = null; } else { activeBid = activeBid.getReplacing(); } } } private synchronized void recoverBid(Bid bid) { int auction = bid.getAuction(); if (bids[auction] != null) { log.warning("bid already exist for auction " + getAuctionTypeAsString(auction) + " when recovering bid"); } else { bids[auction] = bid; log.finer("bid " + bid.getID() + " for " + getAuctionTypeAsString(auction) + " has been recovered"); } } private synchronized void updateBid(Bid bid) { int auction = bid.getAuction(); bid.setReplacing(bids[auction]); bids[auction] = bid; } private synchronized void changeBid(int auction, Bid bid, Bid newBid) { Bid activeBid = getBid(auction); if (activeBid != null) { if (activeBid.same(bid)) { bids[auction] = newBid; } else { Bid child; while ((child = activeBid.getReplacing()) != null && !child.same(bid)) { activeBid = child; } if (child != null && child.same(bid)) { activeBid.setReplacing(newBid); } } } } private void removeBid(int auction, Bid bid) { changeBid(auction, bid, null); } private void handleGetAuctions(TACMessage msg) { while (msg.nextTag()) { if (msg.isTag("auctionIDs")) { int cat = -1; int type = -1; int day = -1; int id = -1; while (msg.nextTag() && !msg.isTag("/auctionIDs")) { if (msg.isTag("/TACAuctionTuple")) { if (cat < 0 || id < 0) { // Missing information about this auction. // What should we do here??? FIX THIS!!! log.severe("missing information for auction" + " category: " + cat + " type: " + type + " day: " + day + " id: " + id); } else { addAuction(cat, type, day, id); } } else if (msg.isTag("type")) { type = msg.getValueAsInt(-1); } else if (msg.isTag("day")) { day = msg.getValueAsInt(-1); } else if (msg.isTag("category")) { cat = getAuctionCategory(msg.getValue()); } else if (msg.isTag("ID")) { id = msg.getValueAsInt(-1); } } } else if (msg.isTag("commandStatus")) { int status = mapCommandStatus(msg.getValueAsInt(NO_ERROR)); if (status == GAME_FUTURE) { // Wait a second and retry! try { Thread.sleep(1000); } catch (Exception e) { } log.fine("handleGetAuctions: Game future, retrying"); nextGameStarts(connection); return; } else if (status == GAME_COMPLETE) { log.fine("handleGetAuctions: Game completed, ending"); gameEnds(); } else if (status != NO_ERROR) { fatalError("could not get auctions for game " + nextGameID + ": status=" + commandStatusToString(status), 5000); } } } // Check if the agent already have any bids in the game i.e. // if the agent has been restarted during a game if ((getServerTime() - startTime) > 2500) { msg = new TACMessage("recoverBidIDs"); sendMessage(msg, this); } // Extension!!! msg = new TACMessage("getGameConsts"); msg.setParameter("gameID", nextGameID); sendMessage(msg, this); msg = new TACMessage("getGameParams"); msg.setParameter("gameID", nextGameID); sendMessage(msg, this); } private void handleGetConstants(TACMessage msg) { // The status code will be NOT_SUPPORTED and the message will contain // no other fields if the server did not support this command // => does not need to check it while (msg.nextTag()) { if (msg.isTag("gameLength")) { int len = msg.getValueAsInt(-1); if (len > 0) { this.gameLength = len * 1000; } } else if (msg.isTag("gameType")) { this.playingGameType = msg.getValue(); } } } private void handleGetGame(TACMessage msg) { boolean gameRunning = true; while (msg.nextTag()) { if (msg.isTag("clientPreferences")) { msg.nextTag(); // Ignore list... int client = -1; int arr = 0; int dep = 0; int hotel = 0; int type = -1; int[] events = new int[3]; int price = 0; while (msg.nextTag() && !msg.isTag("/clientPreferences")) { if (msg.isTag("/clientPrefTuple")) { if (client != -1) { setClient(client - 1, arr, dep, hotel, events); } } else if (msg.isTag("client")) { client = msg.getValueAsInt(-1); } else if (msg.isTag("arrival")) { arr = msg.getValueAsInt(-1); } else if (msg.isTag("departure")) { dep = msg.getValueAsInt(-1); } else if (msg.isTag("hotel")) { hotel = (int) msg.getValueAsFloat(-1f); } else if (msg.isTag("ticketPreferences")) { while (msg.nextTag() && !msg.isTag("/ticketPreferences")) { if (msg.isTag("type")) { type = msg.getValueAsInt(-1); } else if (msg.isTag("price")) { price = (int) msg.getValueAsFloat(-1f); } else if (msg.isTag("/typePriceTuple")) { events[type - 1] = price; } } } } } else if (msg.isTag("ticketEndowments")) { int day = -1; int type = -1; int quantity = -1; while (msg.nextTag() && !msg.isTag("/ticketEndowments")) { if (msg.isTag("/ticketEndowmentTuple")) { addOwn(CAT_ENTERTAINMENT, type, day, quantity); } else if (msg.isTag("type")) { type = msg.getValueAsInt(-1); } else if (msg.isTag("day")) { day = msg.getValueAsInt(-1); } else if (msg.isTag("quantity")) { quantity = msg.getValueAsInt(-1); } } } else if (msg.isTag("commandStatus")) { int status = msg.getValueAsInt(NO_ERROR); if (status != NO_ERROR) { if (status == GAME_COMPLETE) { log.fine("handleGetGame: Game completed, ending"); gameRunning = false; gameEnds(); } else { fatalError("could not get game parameters for game " + nextGameID + ": status=" + commandStatusToString(status), 5000); gameRunning = false; } } } } if (gameRunning) { TimeDispatcher.getDefault() .addTask(startTime + 1000 + gameLength, "gameEnds", connection, this); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -