/** * Hands a canvas to the chief. * * @param thiefId the thief id * @param teamId the team where that thief belongs * @param rolledCanvas true if a canvas was stolen, false otherwise */ @Override public void handACanvas(int thiefId, int teamId, boolean rolledCanvas) { Team team = (Team) this.teamsHash.get(teamId); if (team == null) { throw new IllegalArgumentException("Unknown team with id #" + teamId); } MessageBroker broker = (MessageBroker) this.teamsBroker.get(teamId); synchronized (this.chiefBroker) { synchronized (broker) { this.logger.setThiefStatus(thiefId, Logger.THIEF_STATUS.OUTSIDE); team.removeThief(thiefId); } this.chiefBroker.writeMessage(new Message(THIEF_ARRIVE_ACTION, thiefId)); this.chiefBroker.writeMessage( new HandCanvasMessage(THIEF_HAND_CANVAS_ACTION, thiefId, team.getId(), rolledCanvas)); if (this.multipleMasters) { this.chiefBroker.notifyAll(); } else { this.chiefBroker.notify(); } } }
/** * Collects the canvas of thief that arrived. * * @param chiefId the id of the chief * @param thiefId the id of the thief that handed the canvas */ @Override public void collectCanvas(int chiefId, int thiefId) { while (true) { HandCanvasMessage message = (HandCanvasMessage) this.chiefBroker.readMessage(THIEF_HAND_CANVAS_ACTION, thiefId); if (message != null) { Team team = (Team) this.teamsHash.get(message.getTeamId()); if (team == null) { throw new IllegalArgumentException("Unknown team with id #" + message.getTeamId()); } synchronized (this.chiefBroker) { if (message.rolledCanvas()) this.nrCollectedCanvas++; Room room = team.getAssignedRoom(); if ((boolean) this.roomsStatus.get(room.getId()) && !message.rolledCanvas()) { this.roomsStatus.put(room.getId(), false); this.nrRoomsToBeRobed--; } } break; } } }
/** * Prepares the thief for the excursion. This method should signal the master that the thief is * ready and only depart when notified. * * @param thiefId the thief id * @param teamId the team in which the thief belongs * @return the room assigned to the team */ @Override public ITargetRoom prepareExcursion(int thiefId, int teamId) { MessageBroker broker = (MessageBroker) this.teamsBroker.get(teamId); if (broker == null) { throw new IllegalArgumentException("Unknown team with id #" + teamId); } boolean sentMessage = false; while (true) { Team team; synchronized (broker) { if (!sentMessage) { sentMessage = true; broker.writeMessage(new Message(THIEF_READY_FOR_DEPARTURE_ACTION)); } team = (Team) this.teamsHash.get(teamId); team.addThief(thiefId); try { broker.wait(); } catch (InterruptedException ex) { } } Message message = broker.readMessage(SEND_ASSAULT_PARTY_ACTION); if (message != null) { return team.getAssignedRoom(); } } }
/** * Method that sends a previously prepared team to rob the designated room. This method guarantees * that all the thieves depart at the same time. * * @param chiefId the id of the chief * @param teamId the team to be sent */ @Override public void sendAssaultParty(int chiefId, int teamId) { Team team = (Team) this.teamsHash.get(teamId); if (team == null) { throw new IllegalArgumentException("Unknown team with id #" + teamId); } synchronized (this.chiefBroker) { if (!team.isBeingPrepared()) { throw new IllegalStateException("Team with id #" + teamId + " is not being prepared."); } MessageBroker broker = (MessageBroker) this.teamsBroker.get(teamId); int nrThieves = team.getCapacity(); for (int x = 0; x < nrThieves; x++) { while (broker.readMessage(THIEF_READY_FOR_DEPARTURE_ACTION) == null) { Thread.yield(); } broker.writeMessage(new Message(SEND_ASSAULT_PARTY_ACTION)); } // System.out.println("[Chief] Notifying all thieves of the party to start crawling to room #" // + team.getAssignedRoom().getId() + ".."); synchronized (broker) { broker.notifyAll(); } } }