Changeset 19 for src/main/webapp
- Timestamp:
- 09/28/20 09:29:02 (4 years ago)
- Location:
- src/main/webapp
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/main/webapp/newsession.xhtml
r18 r19 40 40 <br /> Domain/Profile Server: 41 41 <input type="url" name="url" id="profilesserverurl" 42 value="localhost:8080/profilesserver-1.5. 1"42 value="localhost:8080/profilesserver-1.5.2" 43 43 pattern=".*:[0-9]+/profilesserver" size="30" 44 44 onchange="connectDomain()"> </input> … … 54 54 <br /> <b>Participants</b> <br /> Parties Server: <input type="url" 55 55 name="url" id="partiesserverurl" 56 value="localhost:8080/partiesserver-1.5. 1"56 value="localhost:8080/partiesserver-1.5.2" 57 57 pattern=".*:[0-9]+/partiesserver" size="30" 58 58 onchange="connectParties()"> </input> <br /> <br /> <b>Party … … 294 294 refresh table: copy all parties elements in there. 295 295 Typically parties is something like 296 [{"uri":"http:130.161.180.1:8080/partiesserver/run/randomparty-1.5. 1",296 [{"uri":"http:130.161.180.1:8080/partiesserver/run/randomparty-1.5.2", 297 297 "capabilities":{"protocols":["SAOP"]}, 298 298 "description":"places random bids until it can accept an offer with utility >0.6", 299 "id":"randomparty-1.5. 1",299 "id":"randomparty-1.5.2", 300 300 "partyClass":"geniusweb.exampleparties.randomparty.RandomParty"}, 301 301 ...] … … 632 632 function init() { 633 633 selectProtocol(); 634 document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.5. 1"635 document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.5. 1"634 document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.5.2" 635 document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.5.2" 636 636 connectDomain(); 637 637 connectParties(); -
src/main/webapp/newtournament.xhtml
r18 r19 585 585 */ 586 586 function init() { 587 document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.5. 1";588 document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.5. 1";587 document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.5.2"; 588 document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.5.2"; 589 589 590 590 selectProtocol(); -
src/main/webapp/plotlog.xhtml
r18 r19 87 87 */ 88 88 function processLogFile(json) { 89 89 90 if (json['SAOPState']!=undefined) { 90 processS AOP(json['SAOPState']);91 processStandard(json['SAOPState'], 'SAOP'); 91 92 } else if (json['SHAOPState']!=undefined) { 92 93 processSHAOP(json['SHAOPState']); … … 94 95 // just use the SAOP processor, which shows the 95 96 // utilities of all Offers in sequence. 96 processS AOP(json['MOPACState']);97 processStandard(json['MOPACState'], 'MOPAC'); 97 98 } else{ 98 99 setStatus("Unknown log file contents "+Object.keys(json)); … … 101 102 102 103 /** 103 Handle SAOP protocol result. 104 */ 105 function processSAOP(json) { 104 Handle standard protocol result. 105 @param protocol either SAOP or MOPAC or another SAOP-like protocol 106 */ 107 function processStandard(json, protocol) { 106 108 var partyprofiles={} 107 109 var profs=json['partyprofiles']; … … 110 112 } 111 113 112 getProfiles(json, partyprofiles );114 getProfiles(json, partyprofiles, protocol); 113 115 } 114 116 … … 129 131 130 132 131 getProfiles(json, partyprofiles );133 getProfiles(json, partyprofiles, "SHAOP"); 132 134 } 133 135 … … 148 150 /** 149 151 Get the partyprofiles. 150 @json the json protocol result 151 @partyprofileURIs dict with the websocket addresses for each party'as profile 152 @partyprofiles dict with each party's profile. Initially should be {} 153 */ 154 function getProfiles(json, partyprofileURIs, partyprofiles={}) { 152 @param json the json protocol result 153 @param partyprofileURIs dict with the websocket addresses for each party'as profile 154 @param partyprofiles dict with each party's profile. Initially should be {} 155 @param protocol protocolname, eg "SAOP" 156 */ 157 function getProfiles(json, partyprofileURIs, protocol, partyprofiles={} ) { 155 158 var keys = Object.keys(partyprofileURIs); 156 159 if (keys.length==0) { 157 plotResults(computeUtils(json, partyprofiles), isAgreement(json ));160 plotResults(computeUtils(json, partyprofiles), isAgreement(json, protocol)); 158 161 return; 159 162 } … … 178 181 } 179 182 partyprofiles[party]=profile['LinearAdditiveUtilitySpace']; 180 getProfiles(json, partyprofileURIs, p artyprofiles);183 getProfiles(json, partyprofileURIs, protocol, partyprofiles); 181 184 }; 182 185 ws.onerror=function(event) { … … 186 189 187 190 /** 188 @return true if there is agreement 189 */ 190 function isAgreement(logfile) { 191 var actions=logfile['actions']; 192 var lastact = actions[actions.length -1]; 193 return 'accept' in lastact; 191 @param logfile the logfile content, but below the protocol header 192 @param protocol the protocol name, eg SAOP, SHAOP, MOPAC 193 @return 'Yes' if there is agreement, 'No' if there is no agreement at all, 194 or 'Partial' if part of the parties agreed and part did not. 195 or '?' if unsupported protocol 196 */ 197 function isAgreement(logfile, protocol) { 198 switch (protocol) { 199 case "SAOP": 200 case "SHAOP": 201 var actions=logfile['actions']; 202 var lastact = actions[actions.length -1]; 203 return 'accept' in lastact ? 'Yes':'No'; 204 case "MOPAC": 205 var finalstate=logfile['phase']['partyStates']; 206 var nagrees=Object.keys(finalstate['agreements']).length; 207 var nparties=Object.keys(finalstate['powers']).length; 208 if (nagrees==nparties) return "Yes"; 209 if (nagrees==0) return "No" 210 return "Partial"; 211 default: 212 return "?"; 213 } 194 214 } 195 215 /** … … 235 255 /** 236 256 @param utilities the dict with key=party id of the utilities of all steps for each party ) 237 @param isAgreement true iff there is agreement reached257 @param isAgreement either Yes, No, Partial or ? 238 258 */ 239 259 … … 241 261 setStatus("Plotting" ) 242 262 243 document.getElementById('agreement').innerHTML=isAgreement ?"Yes":"No";263 document.getElementById('agreement').innerHTML=isAgreement; 244 264 245 265 var parties=Object.keys(utilities); … … 287 307 scaleLabel: { 288 308 display: true, 289 labelString: ' Turn'309 labelString: 'Offer' 290 310 } 291 311 }], -
src/main/webapp/utilstable.xhtml
r18 r19 27 27 <thead> 28 28 <tr> 29 <th align="center"> run nr</th>30 <th align="center">accepted bid (s)</th>29 <th align="center">sess / agree</th> 30 <th align="center">accepted bid in session</th> 31 31 <th align="center">party utility - penalty</th> 32 32 </tr> … … 206 206 for (var nr in results) { 207 207 var result = results[nr]; 208 var row = table.insertRow(-1); //-1 = end 209 fillRow(row, nr, results[nr]); 208 fillBids(table, nr, result); 210 209 } 211 210 setStatus("done"); 212 211 } 213 212 214 /** 215 @return true if object1, object2 are 'deep equal'. That means, 216 if they are dicts then we check that the keys and their values are equal, 217 recursively. 218 */ 219 function deepEqual(object1, object2) { 220 const keys1 = Object.keys(object1); 221 const keys2 = Object.keys(object2); 222 223 if (keys1.length !== keys2.length) { 224 return false; 225 } 226 227 for (const key of keys1) { 228 const val1 = object1[key]; 229 const val2 = object2[key]; 230 const areObjects = isObject(val1) && isObject(val2); 231 if ( 232 areObjects && !deepEqual(val1, val2) || !areObjects && val1 !== val2 233 ) { 234 return false; 235 } 236 } 237 238 return true; 239 } 240 241 function isObject(object) { 242 return object != null && typeof object === 'object'; 243 } 244 245 /** 246 @param list the list to add value to 247 @param value the value to add 248 @return list with the value added, but only if not already in list. 249 Uses deepEqual to check equality of list members 250 */ 251 function addSet(list, value) { 252 for (const v of list) { 253 if (deepEqual(v, value)) 254 return list; 255 } 256 return list.concat(value); 257 } 213 /** 214 @param table the table to add the bid results to 215 @param nr the session number 216 @param results the results for this sess 217 Add rows for all the bids 218 */ 219 function fillBids(table, nr, result) { 220 // collect unique bids in agreements. 221 var agreements = result['agreements']; 222 223 if (Object.keys(agreements).length == 0) { 224 fillRow(table.insertRow(-1), nr, result, {}); 225 return; 226 } 227 228 var bids = []; 229 for (const pid in agreements) { 230 bids=addSet(bids, agreements[pid]['issuevalues']); 231 } 232 233 var dealnr='A'.charCodeAt(0); 234 for (const bid of bids) { 235 fillRow(table.insertRow(-1), nr+String.fromCharCode(dealnr++), result, bid); 236 } 237 } 238 239 240 258 241 259 242 /** … … 262 245 @param result a single json result from the APP results section. 263 246 Contains participants, agreements and error 264 */ 265 function fillRow(row, nr, result) { 247 @param agreedbid the bid to show in this row. If {}, no agreement was reached. 248 */ 249 function fillRow(row, nr, result, agreedbid) { 266 250 row.insertCell(0).innerHTML = nr; 267 251 … … 275 259 return; 276 260 } 277 278 // collect unique bids in agreements. 279 var agreements = result['agreements']; 280 var bids = []; 281 for (const pid in agreements) { 282 bids=addSet(bids, agreements[pid]['issuevalues']); 283 } 284 285 261 286 262 // a dict, keys are party ids. 287 // FIXME this does not work ok with MOPAC. 288 row.insertCell(-1).innerHTML = JSON.stringify(bids); 289 var agreedbid={}; 290 if (bids.length>0) agreedbid = bids[0]; 263 row.insertCell(-1).innerHTML = JSON.stringify(agreedbid); 291 264 292 265 // fill in the columns. If SHAOP, only the even parties 293 var stepsize = SHAOP? 2:1; 294 for (var n=0; n<result['participants'].length; n=n+stepsize) { 295 var party = result['participants'][n] 296 var profile =party['profile']; 297 var penalty=result['penalties'][n]; 266 // FIXME this can't be with a MAP 267 const participants = result['participants']; 268 for (var pid in participants) { 269 var partyandprofile = result['participants'][pid]; 270 var profile =partyandprofile['profile']; 271 var penalty=result['penalties'][pid]; 272 if (penalty==undefined) penalty=0; 298 273 // make short name for readability 299 var partyname = party ['party']['partyref'];274 var partyname = partyandprofile['party']['partyref']; 300 275 partyname = partyname.split('/'); 301 276 partyname = partyname[partyname.length-1]; 302 addUtilityCell(row.insertCell(-1), agreedbid, partyname, profile,penalty); 277 278 // we set bid to agreedbid only if party accepted agreedbid. 279 var bid = {}; 280 if (pid in result['agreements'] && deepEqual(agreedbid, result['agreements'][pid]['issuevalues'] ) ) 281 bid = agreedbid; 282 addUtilityCell(row.insertCell(-1), bid, partyname, profile, penalty); 303 283 } 304 284 } … … 410 390 } 411 391 392 /************ util functions to compare dict objects **************/ 393 /** 394 @return true if object1, object2 are 'deep equal'. That means, 395 if they are dicts then we check that the keys and their values are equal, 396 recursively. 397 */ 398 function deepEqual(object1, object2) { 399 const keys1 = Object.keys(object1); 400 const keys2 = Object.keys(object2); 401 402 if (keys1.length !== keys2.length) { 403 return false; 404 } 405 406 for (const key of keys1) { 407 const val1 = object1[key]; 408 const val2 = object2[key]; 409 const areObjects = isObject(val1) && isObject(val2); 410 if ( 411 areObjects && !deepEqual(val1, val2) || !areObjects && val1 !== val2 412 ) { 413 return false; 414 } 415 } 416 417 return true; 418 } 419 420 function isObject(object) { 421 return object != null && typeof object === 'object'; 422 } 423 424 /** 425 @param list the list to add value to 426 @param value the value to add 427 @return list with the value added, but only if not already in list. 428 Uses deepEqual to check equality of list members 429 */ 430 function addSet(list, value) { 431 for (const v of list) { 432 if (deepEqual(v, value)) 433 return list; 434 } 435 return list.concat(value); 436 } 412 437 413 438 ]]>
Note:
See TracChangeset
for help on using the changeset viewer.