virtualcommons-svn Mailing List for Virtual Commons Experiment Software (Page 27)
Status: Beta
Brought to you by:
alllee
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(21) |
Aug
(31) |
Sep
(6) |
Oct
(15) |
Nov
(2) |
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(4) |
Feb
(6) |
Mar
(12) |
Apr
(52) |
May
(14) |
Jun
(19) |
Jul
(81) |
Aug
(115) |
Sep
(36) |
Oct
(88) |
Nov
(46) |
Dec
(58) |
2010 |
Jan
(52) |
Feb
(55) |
Mar
(48) |
Apr
(15) |
May
(5) |
Jun
(38) |
Jul
(27) |
Aug
(24) |
Sep
(28) |
Oct
(1) |
Nov
(2) |
Dec
(29) |
2011 |
Jan
(87) |
Feb
(39) |
Mar
(63) |
Apr
(42) |
May
(26) |
Jun
(53) |
Jul
(23) |
Aug
(43) |
Sep
(37) |
Oct
(25) |
Nov
(4) |
Dec
(7) |
2012 |
Jan
(73) |
Feb
(79) |
Mar
(62) |
Apr
(28) |
May
(12) |
Jun
(2) |
Jul
(9) |
Aug
(1) |
Sep
(8) |
Oct
|
Nov
(3) |
Dec
(3) |
2013 |
Jan
(8) |
Feb
(16) |
Mar
(38) |
Apr
(74) |
May
(62) |
Jun
(15) |
Jul
(49) |
Aug
(19) |
Sep
(9) |
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(25) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Bitbucket <com...@bi...> - 2011-09-22 00:02:13
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/cba7af59d290/ changeset: cba7af59d290 user: alllee date: 2011-09-22 02:02:05 summary: fixing ui glitches on windows due to improper repaint. fixes issue 14 TODO: clipping plane from field of vision is overlapping the rest of the interface when it's not supposed to. affected #: 2 files (-1 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Wed Sep 21 16:30:54 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Wed Sep 21 17:02:05 2011 -0700 @@ -141,7 +141,7 @@ timeLeftLabel.setText(getTimeLeftLabelText(roundTimeLeft)); // FIXME: subjectView.repaint() causes graphical glitches here // only when we transition from 3D -> 2D experiment. Find out why. - subjectView.repaint(); + getPanel().repaint(); } }); } @@ -153,16 +153,22 @@ * @param event */ public void init() { - RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); - if (roundConfiguration.isFirstRound()) { - setInstructions(roundConfiguration.getWelcomeInstructions()); - } - // don't display next round time, instead wait for the - // facilitator signal. - timeLeftLabel.setText("Waiting for facilitator's signal."); - informationLabel.setText("Waiting for facilitator's signal."); - // add the next round instructions to the existing debriefing text set by the previous - // EndRoundEvent. + final RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (roundConfiguration.isFirstRound()) { + setInstructions(roundConfiguration.getWelcomeInstructions()); + } + // don't display next round time, instead wait for the + // facilitator signal. + timeLeftLabel.setText("Waiting for facilitator's signal."); + informationLabel.setText("Waiting for facilitator's signal."); + // add the next round instructions to the existing debriefing text set by the previous + // EndRoundEvent. + } + }); + + } private void setQuestionColors(List<String> questionNumbers, String color) { --- a/src/main/resources/web/client.jnlp Wed Sep 21 16:30:54 2011 -0700 +++ b/src/main/resources/web/client.jnlp Wed Sep 21 17:02:05 2011 -0700 @@ -12,8 +12,10 @@ <j2se version="1.6+"/><jar href="client.jar"/><jar href='@FRAMEWORK_JAR@'/> + <!-- <property name="sun.java2d.noddraw" value="true"/><extension name="jogl" href="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp"/> + --></resources><application-desc main-class="@MAIN_CLASS@"/></jnlp> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-21 23:31:05
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/1808124f273b/ changeset: 1808124f273b user: alllee date: 2011-09-22 01:30:54 summary: setting up configuration for bratislava pretest, copied changes over to the asu pretest config as well. changed trust-game configuration parameter to post-round-trust-game to more accurately reflect what will happen if the parameter is set to true. affected #: 17 files (-1 bytes) --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Wed Sep 21 16:30:54 2011 -0700 @@ -522,7 +522,7 @@ } public boolean isTrustGameEnabled() { - return getBooleanProperty("trust-game", true); + return getBooleanProperty("post-round-trust-game", false); } public boolean isInRoundChatEnabled() { --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Wed Sep 21 16:30:54 2011 -0700 @@ -12,6 +12,8 @@ <entry key='subjects-field-of-vision'>true</entry><entry key='in-round-chat-enabled'>true</entry> +<entry key='post-round-trust-game'>true</entry> + <entry key="quiz">true</entry><entry key="q1">C</entry><entry key="q2">B</entry> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round1.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round1.xml Wed Sep 21 16:30:54 2011 -0700 @@ -10,7 +10,8 @@ <entry key='always-explicit'>true</entry><entry key='max-cell-occupancy'>1</entry> -<entry key='in-round-chat-enabled'>true</entry> +<entry key='tokens-field-of-vision'>true</entry> +<entry key='subjects-field-of-vision'>true</entry><entry key="instructions"><![CDATA[ @@ -63,7 +64,7 @@ </p><p> You will see other participants labeled as "1", "2","3", "4", or "5" in the chat -box. You can send a chat message by typing into the textfield and pressing the +window. You can send a chat message by typing into the textfield and pressing the enter key. </p> ]]> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round2.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round2.xml Wed Sep 21 16:30:54 2011 -0700 @@ -14,10 +14,8 @@ <entry key='tokens-field-of-vision'>true</entry><entry key='subjects-field-of-vision'>true</entry> - <entry key='always-explicit'>true</entry><entry key='max-cell-occupancy'>1</entry> -<entry key='in-round-chat-enabled'>true</entry><entry key="instructions"><![CDATA[ @@ -32,23 +30,4 @@ </p> ]]></entry> -<entry key="chat-instructions"> -<![CDATA[ -<p> -You can chat with the other participants in your group during this round. -You may communicate about any aspect of the experiment that you would like to -discuss with other participants with whom you have been matched. You may not promise -them side-payments after the experiment is completed or threaten them with any -consequence after the experiment is finished. We are monitoring the chat traffic -while you chat. If we see that somebody reveals his or her identity, we have to stop -the experiment and remove the whole group from which this person is a member out of -this room. -</p> -<p> -You will see other participants labeled as "1", "2","3", "4", or "5" in the chat -box. You can send a chat message by typing into the textfield and pressing the -enter key. -</p> -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round3.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round3.xml Wed Sep 21 16:30:54 2011 -0700 @@ -17,9 +17,8 @@ <!-- resource regrowth parameters --><entry key="initial-distribution">.25</entry> +<entry key='post-round-trust-game'>true</entry> -<entry key='resource-generator'>mobile</entry> -<entry key='in-round-chat-enabled'>true</entry><entry key="instructions"><![CDATA[ @@ -34,23 +33,4 @@ </p> ]]></entry> -<entry key="chat-instructions"> -<![CDATA[ -<p> -You can chat with the other participants in your group during this round. -You may communicate about any aspect of the experiment that you would like to -discuss with other participants with whom you have been matched. You may not promise -them side-payments after the experiment is completed or threaten them with any -consequence after the experiment is finished. We are monitoring the chat traffic -while you chat. If we see that somebody reveals his or her identity, we have to stop -the experiment and remove the whole group from which this person is a member out of -this room. -</p> -<p> -You will see other participants labeled as "1", "2","3", "4", or "5" in the chat -box. You can send a chat message by typing into the textfield and pressing the -enter key. -</p> -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round4.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round4.xml Wed Sep 21 16:30:54 2011 -0700 @@ -16,59 +16,20 @@ <entry key='max-cell-occupancy'>1</entry><entry key='in-round-chat-enabled'>true</entry> - -<!-- enable sanctioning --> -<entry key="sanction-type">real-time</entry> -<entry key="sanction-cost">1</entry> -<entry key="sanction-multiplier">2</entry> - -<entry key='resource-generator'>top-bottom-patchy</entry> - - <entry key="initial-distribution">.25</entry> -<!-- enable quiz --> -<entry key='quiz'>true</entry> -<entry key='q1'>B</entry> -<entry key='q2'>C</entry> -<entry key='q3'>B</entry> -<entry key='q4'>B</entry> - <entry key="instructions"><![CDATA[ <h3>Round 4 Instructions</h3><hr><p> -Round 4 is the same as the previous two rounds with two exceptions. + Round 4 is the same as the previous rounds with one exception. You will be able + to communicate with the other participants in your group <b>during</b> the + round. To communicate, hit the enter key, type uour message, and then hit the + enter key again. You must hit the enter key before every message you type, + otherwise control will return to the game screen where you can use the arrow + keys to move around. </p> -<p> -The resource dynamics have changed. One section of the resource has a high growth -rate, and another section has a low growth rate. -</p> -<p> -During the next round you will have the option to reduce the earnings of another -participant at a cost to your own earnings. -</p> -<ul> -<li>If you press the numeric key 1-5 corresponding to another participant, you -will reduce the number of tokens they have collected in this round by two -tokens. This will also reduce your own token amount by one token. The decision -whether or when to use this option is up to you. -<li>When you reduce the number of tokens of another participant, they will -receive a message stating that you have reduced their tokens. Likewise, if -another participant reduces your number of tokens, you will also receive a -message. These messages will be displayed on the bottom of your screen. -<li>If your tokens are being reduced or you are reducing another participant's -tokens, you will receive some visual cues. When you are sanctioned your yellow dot will turn red briefly with a blue background. The participant sanctioning you will turn purple with a white background. -<li>You may sanction other participants as long as there are -tokens remaining on the screen and while both you and the other participant -have a positive number of tokens collected during the round. <b>Each time</b> -you press the numeric key corresponding to another participant your token -amount is reduced by <b>one</b>, and their token amount is reduced by -<b>two</b>. <b>Note:</b> You can only remove tokens from a participant that is -visible to you. -</ul> -<p><p> The length of this round is four minutes. @@ -99,50 +60,4 @@ </p> ]]></entry> -<entry key="quiz-instructions"> -<![CDATA[ -<p>Before the next round begins you must complete the quiz below. You can -only continue when you have answered all questions correctly. If an error is -made you will need to answer the questions again. -</p> - -<form> -<span class='q1'>Q1. Each time I press the numeric keys between 1-5 my tokens will be reduced -by:</span><br> -<input type="radio" name="q1" value="A">A. 0 tokens<br> -<input type="radio" name="q1" value="B">B. 1 token<br> -<input type="radio" name="q1" value="C">C. 2 tokens<br> -<input type="radio" name="q1" value="D">D. 4 tokens<br> -<br><br> - -<span class='q2'>Q2. Each time I press the numeric keys between 1-5 the number of tokens of the -corresponding participant is reduced by:</span><br> -<input type="radio" name="q2" value="A">A. 0 tokens<br> -<input type="radio" name="q2" value="B">B. 1 token<br> -<input type="radio" name="q2" value="C">C. 2 tokens<br> -<input type="radio" name="q2" value="D">D. 4 tokens<br> -<br><br> - -<span class='q3'>Q3. The background of your yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"> turns blue. What does this represent?</span><br> -<input type="radio" name="q3" value="A">A. You collected a token<br> -<input type="radio" name="q3" value="B">B. Another participant is subtracting two -tokens from you<br> -<input type="radio" name="q3" value="C">C. You are subtracting two tokens from another -participant<br> -<input type="radio" name="q3" value="D">D. You are moving too fast<br> -<br><br> - -<span class='q4'>Q4. Every time I press the numeric keys between 1-5:</span><br> -<input type="radio" name="q4" value="A">A. Two tokens are subtracted from my tokens -collected this round<br> -<input type="radio" name="q4" value="B">B. One token is subtracted from my tokens -collected this round<br> -<input type="radio" name="q4" value="C">C. The background of my yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"> turns blue -momentarily<br> -<input type="radio" name="q4" value="D">D. My yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"> is paused for two seconds<br> - -<input type="submit" name="submit" value="Submit"> -</form> -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round5.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round5.xml Wed Sep 21 16:30:54 2011 -0700 @@ -12,18 +12,10 @@ <entry key='tokens-field-of-vision'>true</entry><entry key='subjects-field-of-vision'>true</entry> -<!-- enable sanctioning --> -<entry key="sanction-type">real-time</entry> -<entry key="sanction-cost">1</entry> -<entry key="sanction-multiplier">2</entry> - <entry key="initial-distribution">.25</entry> -<entry key='resource-generator'>top-bottom-patchy</entry><entry key='always-explicit'>true</entry><entry key='max-cell-occupancy'>1</entry> - -<!-- before this round begins, we have a chat session --><entry key="in-round-chat-enabled">true</entry><entry key="instructions"> @@ -60,13 +52,4 @@ </p> ]]></entry> - -<entry key='private-chat-instructions'> -<![CDATA[ -You may send private messages to a specific participant by clicking on the -appropriately labeled button (1, 2, 3, 4, or 5) before typing your message in -the chat box and sending it. By default you are communicating with all -members of your group. -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round6.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round6.xml Wed Sep 21 16:30:54 2011 -0700 @@ -10,19 +10,14 @@ <entry key='tokens-field-of-vision'>true</entry><entry key='subjects-field-of-vision'>true</entry> -<!-- enable sanctioning --> -<entry key="sanction-type">real-time</entry> -<entry key="sanction-cost">1</entry> -<entry key="sanction-multiplier">2</entry><entry key="initial-distribution">.25</entry> -<entry key='resource-generator'>top-bottom-patchy</entry><!-- in round chat enabled --><entry key="in-round-chat-enabled">true</entry> - <entry key='always-explicit'>true</entry><entry key='max-cell-occupancy'>1</entry> +<entry key='post-round-trust-game'>true</entry><entry key="instructions"> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Wed Sep 21 12:13:03 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Wed Sep 21 16:30:54 2011 -0700 @@ -151,4 +151,26 @@ </p> ]]></entry> + +<entry key="chat-instructions"> +<![CDATA[ +<p> +You can chat with the other participants in your group during this round. +You may discuss any aspect of the experiment with the other participants in your group with two exceptions: +<ol> + <li>You <b>may not promise side-payments after the experiment is completed or threaten anyone with any consequence after the experiment is finished</b>.</li> + <li>You <b>may not reveal your actual identity</b></li> +</ol> +We are monitoring the chat traffic while you chat. If we detect any violation of the +rules we will have to stop the the experiment and remove the group where the offense +occurred from the room. +</p> +<p> +You will see other participants labeled as "1", "2","3", "4", or "5" in the chat +box. You can send a chat message by typing into the textfield and pressing the +enter key. +</p> +]]> +</entry> + </properties> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-21 19:13:15
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/77cecbdf3f88/ changeset: 77cecbdf3f88 user: alllee date: 2011-09-21 21:13:03 summary: adding logic to display updated total income, including quiz answer rewards and trust game earnings. fixing ant clean target to remove ant cache and maven cache so that the proper csidex jar will be downloaded affected #: 4 files (-1 bytes) --- a/build.xml Fri Sep 16 15:32:44 2011 -0700 +++ b/build.xml Wed Sep 21 12:13:03 2011 -0700 @@ -190,6 +190,9 @@ </target><!-- Clean up build by deleting build directories --><target name="clean"> + <echo message="Removing ${user.home}/.ant/cache" /> + <delete dir='${user.home}/.ant/cache' /> + <delete dir='${user.home}/.m2/repository/edu/asu/commons' /><delete dir="${build.dir}"/><delete dir="${test.build.dir}"/><delete dir="${lib.dir}"/> --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Fri Sep 16 15:32:44 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Wed Sep 21 12:13:03 2011 -0700 @@ -333,10 +333,6 @@ return getProperty(questionNumber + "-explanation"); } - public double getQuizCorrectAnswerReward() { - return getDoubleProperty("quiz-correct-answer-reward", 0.50d); - } - /** * Possible values, freeze, fine? * @@ -626,4 +622,9 @@ return getProperty("trust-game-instructions"); } + public double getQuizCorrectAnswerReward() { + String key = "quiz-correct-answer-reward"; + return getDoubleProperty(key, getParentConfiguration().getDoubleProperty(key)); + } + } --- a/src/main/java/edu/asu/commons/foraging/conf/ServerConfiguration.java Fri Sep 16 15:32:44 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/ServerConfiguration.java Wed Sep 21 12:13:03 2011 -0700 @@ -66,6 +66,10 @@ public double getShowUpPayment() { return assistant.getDoubleProperty("show-up-payment", 5.0d); } + + public double getQuizCorrectAnswerReward() { + return assistant.getDoubleProperty("quiz-correct-answer-reward", 0.50d); + } public String getWelcomeInstructions() { return assistant.getStringProperty("welcome-instructions", "Please wait quietly and do not open or close any programs on this computer."); @@ -79,6 +83,8 @@ return assistant.getProperty("field-of-vision-instructions", "Your view of the resource will be limited in this round. The area visible to you will be shaded."); } + + } --- a/src/main/java/edu/asu/commons/foraging/facilitator/FacilitatorWindow.java Fri Sep 16 15:32:44 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/facilitator/FacilitatorWindow.java Wed Sep 21 12:13:03 2011 -0700 @@ -24,6 +24,7 @@ import javax.swing.ScrollPaneConstants; import edu.asu.commons.foraging.conf.RoundConfiguration; +import edu.asu.commons.foraging.conf.ServerConfiguration; import edu.asu.commons.foraging.event.FacilitatorEndRoundEvent; import edu.asu.commons.foraging.event.FacilitatorSanctionUpdateEvent; import edu.asu.commons.foraging.model.ClientData; @@ -326,8 +327,6 @@ TreeSet<Identifier> orderedSet = new TreeSet<Identifier>(clientDataMap.keySet()); for (Identifier clientId : orderedSet) { ClientData data = clientDataMap.get(clientId); - // FIXME: hack... inject the configuration into the client data so that getIncome() will return something appropriate. - // should just refactor getIncome or remove it from ClientData entirely. builder.append(String.format( "<tr><td>%s</td>" + "<td align='center'>%d</td>" + @@ -336,7 +335,7 @@ clientId.toString(), data.getCurrentTokens(), getIncome(data.getCurrentTokens()), - data.getTotalIncome() + facilitator.getServerConfiguration().getShowUpPayment())); + getTotalIncome(data))); } builder.append("</tbody></table><hr>"); if (event.isLastRound()) { @@ -349,12 +348,16 @@ stopRoundMenuItem.setEnabled(false); } + private double getTotalIncome(ClientData data) { + ServerConfiguration serverConfiguration = facilitator.getServerConfiguration(); + double quizEarnings = data.getCorrectQuizAnswers() * serverConfiguration.getQuizCorrectAnswerReward(); + double trustGameEarnings = data.getTrustGameEarnings(); + double totalIncome = data.getTotalIncome() + serverConfiguration.getShowUpPayment() + quizEarnings + trustGameEarnings; + return totalIncome; + } + private double getIncome(float numTokens) { RoundConfiguration configuration = facilitator.getCurrentRoundConfiguration(); - if (configuration == null) { - // FIXME: last minute hack. - return 0.02f * numTokens; - } if (configuration.isPracticeRound()) { return 0.0f; } @@ -396,8 +399,6 @@ TreeSet<Identifier> orderedSet = new TreeSet<Identifier>(clientDataMap.keySet()); for (Identifier clientId : orderedSet) { ClientData data = clientDataMap.get(clientId); - // FIXME: hack... inject the configuration into the client data so that getIncome() will return something appropriate. - // should just refactor getIncome or remove it from ClientData entirely. buffer.append(String.format( "<tr><td>%s</td>" + "<td align='center'>%d</td>" + Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-16 22:32:57
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/bd412fb965c7/ changeset: bd412fb965c7 user: alllee date: 2011-09-17 00:32:44 summary: setting chat handles on the server side, cleaning up the configuration instructions, and working on some ui improvements for the foraging client. fixes issue 15 fixes issue 11 affected #: 3 files (-1 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Fri Sep 16 15:19:05 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Fri Sep 16 15:32:44 2011 -0700 @@ -168,6 +168,7 @@ public void handle(RoundStartedEvent event) { System.err.println("client starting round: " + dataModel.is2dExperiment()); dataModel.initialize(event.getGroupDataModel()); + setId(event.getId()); getGameWindow().startRound(); if (dataModel.is2dExperiment()) { messageQueue.start(); --- a/src/main/java/edu/asu/commons/foraging/model/ServerDataModel.java Fri Sep 16 15:19:05 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/model/ServerDataModel.java Fri Sep 16 15:32:44 2011 -0700 @@ -159,7 +159,7 @@ public synchronized void addClientToGroup(ClientData clientData, GroupDataModel group) { group.addClient(clientData); clientsToGroups.put(clientData.getId(), group); - clientData.getId().setChatHandle(CHAT_HANDLES[group.size()]); + clientData.getId().setChatHandle(CHAT_HANDLES[group.size() - 1]); channel.handle(new AddClientEvent(clientData, group, clientData.getPosition())); } --- a/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Fri Sep 16 15:19:05 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Fri Sep 16 15:32:44 2011 -0700 @@ -95,13 +95,13 @@ private Identifier facilitatorId; - // FIXME: use java.util.concurrent constructs instead? CountDownLatch / CyclicBarrier? + // FIXME: use java.util.concurrent constructs instead? CountDownLatch / CyclicBarrier? private final Object roundSignal = new Object(); private final Object quizSignal = new Object(); private final Object postRoundSanctioningSignal = new Object(); private final Object agentDesignSignal = new Object(); - // FIXME: these latches don't quite do what we want. We need a way to reset them at each round. - // private CountDownLatch postRoundSanctionLatch; + // FIXME: these latches don't quite do what we want. We need a way to reset them at each round. + // private CountDownLatch postRoundSanctionLatch; private StateMachine stateMachine = new ForagingStateMachine(); @@ -110,7 +110,7 @@ private volatile int numberOfSubmittedQuizzes; private volatile int numberOfCompletedSanctions; private volatile int numberOfCompletedAgentDesigns; - + private int monitorRotationInterval; private Duration currentRoundDuration; @@ -118,7 +118,6 @@ private volatile boolean experimentStarted; - // FIXME: add the ability to reconfigure an already instantiated server public ForagingServer() { this(new ServerConfiguration()); @@ -131,8 +130,7 @@ Handler logHandler = new FileHandler(configuration.getLogFileDestination(), true); logHandler.setFormatter(new SimpleFormatter()); logger.addHandler(logHandler); - } - catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); logger.severe("Unable to log to file : " + configuration.getLogFileDestination()); } @@ -142,7 +140,7 @@ public void processReplInput(String input, BufferedReader reader) { if (input.equals("clients")) { System.out.println("Connected Clients: " + clients.size()); - for (Identifier id: clients.keySet()) { + for (Identifier id : clients.keySet()) { getLogger().info("\t" + id); } } @@ -169,20 +167,17 @@ try { String path = reader.readLine(); boolean converted = ForagingSaveFileConverter.convert(path); - if (! converted) { + if (!converted) { System.out.println("Unable to convert from path: " + path); } - } - catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); - } - catch (RuntimeException e) { + } catch (RuntimeException e) { e.printStackTrace(); } } } - @Override protected StateMachine getStateMachine() { return stateMachine; @@ -192,9 +187,9 @@ return getConfiguration().getCurrentParameters(); } - enum ServerState { WAITING, ROUND_IN_PROGRESS }; - - + enum ServerState { + WAITING, ROUND_IN_PROGRESS + }; private class ForagingStateMachine implements StateMachine { private Command roundProcessor; @@ -202,29 +197,34 @@ private ResourceDispenser resourceDispenser; private ServerState serverState; private final Duration secondTick = Duration.create(1000L); + /** * Initializes the state machine before the experiment ever begins. */ public void initialize() { serverState = ServerState.WAITING; - serverDataModel = new ServerDataModel( getEventChannel() ); + serverDataModel = new ServerDataModel(getEventChannel()); // these two seem to be paired up frequently. serverDataModel.setRoundConfiguration(getCurrentRoundConfiguration()); initializeRoundProcessor(); - resourceDispenser = new ResourceDispenser( serverDataModel ); + resourceDispenser = new ResourceDispenser(serverDataModel); initializeClientHandlers(); initializeFacilitatorHandlers(); } private void initializeRoundProcessor() { if (serverDataModel.getRoundConfiguration().is2dExperiment()) { - roundProcessor = new Command() { - public void execute() { processRound2d(); } + roundProcessor = new Command() { + public void execute() { + processRound2d(); + } }; } else { roundProcessor = new Command() { - public void execute() { processRound3d(); } + public void execute() { + processRound3d(); + } }; } } @@ -253,15 +253,15 @@ transmit(new ClientMessageEvent(event.getId(), "The experiment has already started, we cannot add you at this time.")); return; } - // String t = event.getId().toString(); - // StringBuilder t1 = new StringBuilder(t); - // t1.append(clientIdCount); + // String t = event.getId().toString(); + // StringBuilder t1 = new StringBuilder(t); + // t1.append(clientIdCount); Identifier newClientIdentifier = event.getId(); - // Identifier newClientIdentifier = (Identifier)t1.toString(); + // Identifier newClientIdentifier = (Identifier)t1.toString(); - System.out.println("New Client ID : "+newClientIdentifier); + System.out.println("New Client ID : " + newClientIdentifier); - synchronized (clients) { + synchronized (clients) { clients.put(newClientIdentifier, new ClientData(newClientIdentifier)); } // send welcome instructions and experiment configuration @@ -280,7 +280,7 @@ addEventProcessor(new EventTypeProcessor<ChatRequest>(ChatRequest.class) { public void handle(final ChatRequest request) { RoundConfiguration configuration = getCurrentRoundConfiguration(); - if (! configuration.isChatEnabled()) { + if (!configuration.isChatEnabled()) { logger.warning("configuration doesn't allow for chat but received " + request); return; } @@ -313,7 +313,7 @@ public void handle(PostRoundSanctionRequest event) { System.out.println("Received post round sanction request"); clients.get(event.getId()).getGroupDataModel().handleSanctionRequest(event); - // postRoundSanctionLatch.countDown(); + // postRoundSanctionLatch.countDown(); numberOfCompletedSanctions++; if (numberOfCompletedSanctions == clients.size()) { // send an updated debriefing to everyone again. @@ -321,7 +321,7 @@ clientData.applyPostRoundSanctioning(); } boolean lastRound = getConfiguration().isLastRound(); - for (ClientData clientData: clients.values()) { + for (ClientData clientData : clients.values()) { PostRoundSanctionUpdateEvent updateEvent = new PostRoundSanctionUpdateEvent(clientData, getCurrentRoundConfiguration(), lastRound); transmit(updateEvent); } @@ -350,16 +350,16 @@ } }); - addEventProcessor(new EventTypeProcessor<ClientMovementRequest>(ClientMovementRequest.class) { public void handle(ClientMovementRequest event) { - if (serverState == ServerState.WAITING) return; + if (serverState == ServerState.WAITING) + return; Identifier id = event.getId(); Direction direction = event.getDirection(); serverDataModel.moveClient(id, direction); } }); - addEventProcessor(new EventTypeProcessor<ExplicitCollectionModeRequest>(ExplicitCollectionModeRequest.class){ + addEventProcessor(new EventTypeProcessor<ExplicitCollectionModeRequest>(ExplicitCollectionModeRequest.class) { public void handleInExperimentThread(ExplicitCollectionModeRequest event) { clients.get(event.getId()).setExplicitCollectionMode(event.isExplicitCollectionMode()); } @@ -393,7 +393,8 @@ }); addEventProcessor(new EventTypeProcessor<ClientPoseUpdate>(ClientPoseUpdate.class) { public void handleInExperimentThread(ClientPoseUpdate event) { - if (serverState == ServerState.WAITING) return; + if (serverState == ServerState.WAITING) + return; ClientData client = clients.get(event.getId()); client.setPosition(event.getPosition()); client.setHeading(event.getHeading()); @@ -404,26 +405,30 @@ // FIXME: turn into lockResource/unlockResource? addEventProcessor(new EventTypeProcessor<LockResourceRequest>(LockResourceRequest.class) { public void handleInExperimentThread(LockResourceRequest event) { - if (serverState == ServerState.WAITING) return; + if (serverState == ServerState.WAITING) + return; boolean successfullyLocked = serverDataModel.lockResource(event); transmit(new LockResourceEvent(event.getId(), event.getResource(), successfullyLocked)); } }); addEventProcessor(new EventTypeProcessor<UnlockResourceRequest>(UnlockResourceRequest.class) { public void handleInExperimentThread(UnlockResourceRequest event) { - if (serverState == ServerState.WAITING) return; + if (serverState == ServerState.WAITING) + return; serverDataModel.unlockResource(event); } }); addEventProcessor(new EventTypeProcessor<HarvestResourceRequest>(HarvestResourceRequest.class) { public void handleInExperimentThread(HarvestResourceRequest event) { - if (serverState == ServerState.WAITING) return; + if (serverState == ServerState.WAITING) + return; serverDataModel.harvestResource(event); } }); addEventProcessor(new EventTypeProcessor<HarvestFruitRequest>(HarvestFruitRequest.class) { public void handleInExperimentThread(HarvestFruitRequest event) { - if (serverState == ServerState.WAITING) return; + if (serverState == ServerState.WAITING) + return; serverDataModel.harvestFruits(event); } }); @@ -432,134 +437,138 @@ private void handleEnforcementSanctionRequest(RealTimeSanctionRequest request) { ClientData sourceClient = clients.get(request.getSource()); ClientData targetClient = clients.get(request.getTarget()); - + GroupDataModel group = sourceClient.getGroupDataModel(); - if (! group.equals(targetClient.getGroupDataModel())) { - logger.severe("source client and target client groups are different: " + sourceClient + targetClient); - return; + if (!group.equals(targetClient.getGroupDataModel())) { + logger.severe("source client and target client groups are different: " + sourceClient + targetClient); + return; } EnforcementMechanism enforcementMechanism = group.getActiveEnforcementMechanism(); switch (enforcementMechanism) { - case EVERYONE_CAN_SANCTION: - handleRealTimeSanctionRequest(request); - break; - case RANDOM_MONITOR: - case ROTATING_MONITOR: - if (sourceClient.isMonitor()) { - // monitor can always sanction regardless of if they have enough tokens. - if (targetClient.getCurrentTokens() == 0) { - // nothing to take, so sanctioning has no effect. + case EVERYONE_CAN_SANCTION: + handleRealTimeSanctionRequest(request); + break; + case RANDOM_MONITOR: + case ROTATING_MONITOR: + if (sourceClient.isMonitor()) { + // monitor can always sanction regardless of if they have enough tokens. + if (targetClient.getCurrentTokens() == 0) { + // nothing to take, so sanctioning has no effect. + transmit(new ClientMessageEvent(sourceClient.getId(), + String.format("Ignoring token reduction request: # %d does not have any tokens to reduce.", + targetClient.getAssignedNumber()))); + return; + } + // monitors don't get any sanction costs. + targetClient.sanctionPenalty(); + // add sanction request to the target client so they can figure out who just sanctioned them + sourceClient.getLatestSanctions().add(request); + targetClient.getLatestSanctions().add(request); transmit(new ClientMessageEvent(sourceClient.getId(), - String.format("Ignoring token reduction request: # %d does not have any tokens to reduce.", targetClient.getAssignedNumber()))); - return; + String.format("Subtracting %d tokens from # %d at the cost of 0 to yourself.", + getCurrentRoundConfiguration().getSanctionPenalty(), + targetClient.getAssignedNumber()))); + transmit(new ClientMessageEvent(targetClient.getId(), + String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration() + .getSanctionPenalty()))); } - // monitors don't get any sanction costs. - targetClient.sanctionPenalty(); - // add sanction request to the target client so they can figure out who just sanctioned them - sourceClient.getLatestSanctions().add(request); - targetClient.getLatestSanctions().add(request); - transmit(new ClientMessageEvent(sourceClient.getId(), - String.format("Subtracting %d tokens from # %d at the cost of 0 to yourself." , - getCurrentRoundConfiguration().getSanctionPenalty(), - targetClient.getAssignedNumber()))); - transmit(new ClientMessageEvent(targetClient.getId(), - String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration().getSanctionPenalty()))); - } - break; - case NONE: - default: - logger.severe("tried to sanction with EnforcementMechanism.NONE"); + break; + case NONE: + default: + logger.severe("tried to sanction with EnforcementMechanism.NONE"); } // TODO: reimplement -// -// -// int srcEnforcementType = sourceClient.getEnforcementData().getResultIndex(); -// int tgtEnforcementType = targetClient.getEnforcementData().getResultIndex(); -// -// if(srcEnforcementType == tgtEnforcementType) { -// System.out.println("This condition should be always true"); -// switch(srcEnforcementType) { -// /* -// * No sanctioning just harvest -// */ case NO_SANCTIONS: -// System.out.println("This code should never be reached"); -// -// break; -// -// /* -// * Harvest and sanction -// * Reduce other by 2 but also own by 1 -// */ -// case HARVEST_WITH_SANCTION: -// sourceClient.sanctionCost(); -// targetClient.monitorSanctionPenalty(1); -// // add sanction request to the target client so they can figure out who just sanctioned them -// targetClient.getLatestSanctions().add(request); -// transmit(new ClientMessageEvent(sourceClient.getId(), -// String.format("Subtracting %d tokens from # %d at the cost of %d to yourself." , -// getCurrentRoundConfiguration().getSanctionPenalty(1), -// targetClient.getAssignedNumber(), -// getCurrentRoundConfiguration().getSanctionCost()))); -// transmit(new ClientMessageEvent(targetClient.getId(), -// String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration().getSanctionPenalty(1)))); -// break; -// -// -// /* -// * One participant is a moniter who sanctions but cannot harvest -// * Moniter can give penalty by subtract 1 from sanctionee -// * Nothing taken from Moniter but receives 25% tokens from each -// */ case RANDOM_SANCTIONER: -// //sourceClient.sanctionCost(); -// targetClient.monitorSanctionPenalty(0); -// // add sanction request to the target client so they can figure out who just sanctioned them -// targetClient.getLatestSanctions().add(request); -// transmit(new ClientMessageEvent(sourceClient.getId(), -// String.format("Subtracting %d tokens from # %d at the cost of 0 to yourself." , -// getCurrentRoundConfiguration().getSanctionPenalty(0), -// targetClient.getAssignedNumber()))); -// transmit(new ClientMessageEvent(targetClient.getId(), -// String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration().getSanctionPenalty(0)))); -// break; -// -// /* -// * Harvest and sanction for 48 secs in sequence -// * One participant is a moniter who sanctions but cannot harvest -// * Moniter can give penalty by subtract 1 from sanctionee -// * Nothing taken from Moniter but receives 25% tokens from each -// */ case CIRCULAR_MONITERING: -// //sourceClient.sanctionCost(); -// targetClient.monitorSanctionPenalty(0); -// // add sanction request to the target client so they can figure out who just sanctioned them -// targetClient.getLatestSanctions().add(request); -// transmit(new ClientMessageEvent(sourceClient.getId(), -// String.format("Subtracting %d tokens from # %d at the cost of 0 to yourself." , -// getCurrentRoundConfiguration().getSanctionPenalty(), -// targetClient.getAssignedNumber()))); -// transmit(new ClientMessageEvent(targetClient.getId(), -// String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration().getSanctionPenalty()))); -// break; -// } -// } + // + // + // int srcEnforcementType = sourceClient.getEnforcementData().getResultIndex(); + // int tgtEnforcementType = targetClient.getEnforcementData().getResultIndex(); + // + // if(srcEnforcementType == tgtEnforcementType) { + // System.out.println("This condition should be always true"); + // switch(srcEnforcementType) { + // /* + // * No sanctioning just harvest + // */ case NO_SANCTIONS: + // System.out.println("This code should never be reached"); + // + // break; + // + // /* + // * Harvest and sanction + // * Reduce other by 2 but also own by 1 + // */ + // case HARVEST_WITH_SANCTION: + // sourceClient.sanctionCost(); + // targetClient.monitorSanctionPenalty(1); + // // add sanction request to the target client so they can figure out who just sanctioned them + // targetClient.getLatestSanctions().add(request); + // transmit(new ClientMessageEvent(sourceClient.getId(), + // String.format("Subtracting %d tokens from # %d at the cost of %d to yourself." , + // getCurrentRoundConfiguration().getSanctionPenalty(1), + // targetClient.getAssignedNumber(), + // getCurrentRoundConfiguration().getSanctionCost()))); + // transmit(new ClientMessageEvent(targetClient.getId(), + // String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration().getSanctionPenalty(1)))); + // break; + // + // + // /* + // * One participant is a moniter who sanctions but cannot harvest + // * Moniter can give penalty by subtract 1 from sanctionee + // * Nothing taken from Moniter but receives 25% tokens from each + // */ case RANDOM_SANCTIONER: + // //sourceClient.sanctionCost(); + // targetClient.monitorSanctionPenalty(0); + // // add sanction request to the target client so they can figure out who just sanctioned them + // targetClient.getLatestSanctions().add(request); + // transmit(new ClientMessageEvent(sourceClient.getId(), + // String.format("Subtracting %d tokens from # %d at the cost of 0 to yourself." , + // getCurrentRoundConfiguration().getSanctionPenalty(0), + // targetClient.getAssignedNumber()))); + // transmit(new ClientMessageEvent(targetClient.getId(), + // String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration().getSanctionPenalty(0)))); + // break; + // + // /* + // * Harvest and sanction for 48 secs in sequence + // * One participant is a moniter who sanctions but cannot harvest + // * Moniter can give penalty by subtract 1 from sanctionee + // * Nothing taken from Moniter but receives 25% tokens from each + // */ case CIRCULAR_MONITERING: + // //sourceClient.sanctionCost(); + // targetClient.monitorSanctionPenalty(0); + // // add sanction request to the target client so they can figure out who just sanctioned them + // targetClient.getLatestSanctions().add(request); + // transmit(new ClientMessageEvent(sourceClient.getId(), + // String.format("Subtracting %d tokens from # %d at the cost of 0 to yourself." , + // getCurrentRoundConfiguration().getSanctionPenalty(), + // targetClient.getAssignedNumber()))); + // transmit(new ClientMessageEvent(targetClient.getId(), + // String.format("# %d subtracted %d tokens from you.", sourceClient.getAssignedNumber(), getCurrentRoundConfiguration().getSanctionPenalty()))); + // break; + // } + // } } - + private void handleRealTimeSanctionRequest(RealTimeSanctionRequest request) { ClientData sourceClient = clients.get(request.getSource()); ClientData targetClient = clients.get(request.getTarget()); // validate request - //FIXME:Added a new test condition to check for the simplified version of sanctioning - boolean invalidSanctionRequest = sourceClient.getCurrentTokens() == 0 || targetClient.getCurrentTokens() == 0 || sourceClient.getGroupDataModel().isResourceDistributionEmpty() || (sourceClient.getGroupDataModel().getActiveSanctionMechanism()== SanctionMechanism.NONE); - if ( invalidSanctionRequest ) { + // FIXME:Added a new test condition to check for the simplified version of sanctioning + boolean invalidSanctionRequest = sourceClient.getCurrentTokens() == 0 || targetClient.getCurrentTokens() == 0 + || sourceClient.getGroupDataModel().isResourceDistributionEmpty() + || (sourceClient.getGroupDataModel().getActiveSanctionMechanism() == SanctionMechanism.NONE); + if (invalidSanctionRequest) { // ignore the sanction request, send a message to the sanctioner. logger.warning("Ignoring token reduction request, sending new client error message event to : " + sourceClient.getId()); - if (sourceClient.getGroupDataModel().getActiveSanctionMechanism()== SanctionMechanism.NONE) { - transmit(new ClientMessageEvent(sourceClient.getId(), + if (sourceClient.getGroupDataModel().getActiveSanctionMechanism() == SanctionMechanism.NONE) { + transmit(new ClientMessageEvent(sourceClient.getId(), String.format("Ignoring token reduction request: Sanctioning not allowed in this round", targetClient.getAssignedNumber()))); } else { - transmit(new ClientMessageEvent(sourceClient.getId(), - String.format("Ignoring token reduction request: # %d does not have any tokens to reduce.", targetClient.getAssignedNumber()))); + transmit(new ClientMessageEvent(sourceClient.getId(), + String.format("Ignoring token reduction request: # %d does not have any tokens to reduce.", targetClient.getAssignedNumber()))); } return; } @@ -571,7 +580,7 @@ // the sanction cost should always be set since the client should prevent any sanction requests from being emitted // if the user doesn't have enough tokens to issue the request. sanctionAppliedEvent.setSanctionCost(sanctionCost); - // the sanction penalty may be in the range [1, RoundConfiguration.getSanctionPenalty()] - + // the sanction penalty may be in the range [1, RoundConfiguration.getSanctionPenalty()] - // if target has less than the actual sanction penalty they just get their tokens reduced to 0. sanctionAppliedEvent.setSanctionPenalty(subtractedTokens); sanctionAppliedEvent.setTarget(targetClient.getId()); @@ -580,15 +589,15 @@ sourceClient.getLatestSanctions().add(request); targetClient.getLatestSanctions().add(request); logger.info("target client " + targetClient.getId() + " has sanctions: " + targetClient.getLatestSanctions()); - transmit(new ClientMessageEvent(sourceClient.getId(), - String.format("Subtracting %d tokens from # %d at the cost of %d to yourself." , - subtractedTokens, - targetClient.getAssignedNumber(), - sanctionCost))); + transmit(new ClientMessageEvent(sourceClient.getId(), + String.format("Subtracting %d tokens from # %d at the cost of %d to yourself.", + subtractedTokens, + targetClient.getAssignedNumber(), + sanctionCost))); transmit(new ClientMessageEvent(targetClient.getId(), - String.format("# %d subtracted %d tokens from you.", - sourceClient.getAssignedNumber(), - subtractedTokens))); + String.format("# %d subtracted %d tokens from you.", + sourceClient.getAssignedNumber(), + subtractedTokens))); } private void initializeFacilitatorHandlers() { @@ -607,7 +616,7 @@ // FIXME: assign groups? if (event.getId().equals(facilitatorId)) { logger.info("Show Instructions request from facilitator - showing round instructions."); - for (Identifier id: clients.keySet()) { + for (Identifier id : clients.keySet()) { transmit(new ShowInstructionsRequest(id)); } } @@ -620,7 +629,7 @@ public void handle(ShowTrustGameRequest event) { if (event.getId().equals(facilitatorId)) { logger.info("Showing trust game."); - for (Identifier id: clients.keySet()) { + for (Identifier id : clients.keySet()) { transmit(new ShowTrustGameRequest(id)); } } @@ -634,7 +643,7 @@ if (event.getId().equals(facilitatorId)) { if (getCurrentRoundConfiguration().isFirstRound()) { // shuffle groups - // set up the Client Group relationships ONLY IF we are in the first round... + // set up the Client Group relationships ONLY IF we are in the first round... // kind of a hack. shuffleParticipants(); initializeResourceDispenser(); @@ -659,62 +668,62 @@ }); addEventProcessor(new EventTypeProcessor<TrustGameSubmissionRequest>(TrustGameSubmissionRequest.class) { int numberOfSubmissions = 0; + public void handle(TrustGameSubmissionRequest request) { if (getCurrentRoundConfiguration().isTrustGameEnabled()) { logger.info("trust game submission: " + request); // basic sanity check ClientData clientData = clients.get(request.getId()); clientData.setTrustGamePlayerOneAmountToKeep(request.getPlayerOneAmountToKeep()); - clientData.setTrustGamePlayerTwoAmountsToKeep(request.getPlayerTwoAmountsToKeep()); + clientData.setTrustGamePlayerTwoAmountsToKeep(request.getPlayerTwoAmountsToKeep()); persister.store(request); numberOfSubmissions++; } if (numberOfSubmissions >= clients.size()) { // once all clients have submitted their decisions, execute the trust game. - for (GroupDataModel group: serverDataModel.getGroups()) { + for (GroupDataModel group : serverDataModel.getGroups()) { LinkedList<ClientData> clientList = new LinkedList<ClientData>(group.getClientDataMap().values()); Collections.shuffle(clientList); // FIXME: arbitrary choice to save the first one to pair up with the last one as well. - ClientData first = clientList.getFirst(); - for (Iterator<ClientData> iter = clientList.iterator(); iter.hasNext(); ) { + ClientData first = clientList.getFirst(); + for (Iterator<ClientData> iter = clientList.iterator(); iter.hasNext();) { ClientData playerOne = iter.next(); ClientData playerTwo = first; if (iter.hasNext()) { - playerTwo = iter.next(); + playerTwo = iter.next(); } logger.info(String.format("Pairing %s with %s for trust game", playerOne, playerTwo)); - serverDataModel.calculateTrustGame(playerOne, playerTwo); - } + serverDataModel.calculateTrustGame(playerOne, playerTwo); + } } - numberOfSubmissions = 0; - } - } - }); + numberOfSubmissions = 0; + } + } + }); addEventProcessor(new EventTypeProcessor<BeginChatRoundRequest>(BeginChatRoundRequest.class) { public void handle(BeginChatRoundRequest request) { if (getCurrentRoundConfiguration().isChatEnabled()) { - + // FIXME: need to handle properly corner case where chat is enabled before the first round + // at that point the clients haven't been added to any groups yet. + // probably the best way to handle this is to have the clients added + // to groups when the show instructions request is handled. if (getCurrentRoundConfiguration().isFirstRound()) { shuffleParticipants(); initializeResourceDispenser(); } - // FIXME: need to handle properly corner case where chat is enabled before the first round - // at that point the clients haven't been added to any groups yet. - // probably the best way to handle this is to have the clients added - // to groups when the show instructions request is handled. - for (Map.Entry<Identifier, ClientData> entry: clients.entrySet()) { + for (Map.Entry<Identifier, ClientData> entry : clients.entrySet()) { Identifier id = entry.getKey(); ClientData clientData = entry.getValue(); // FIXME: hacky, get rid of this. if (clientData.getGroupDataModel() == null) { - // we haven't added this client to the server data model yet. Add them now.. - // FIXME: will this cause problems if we invoke shuffleParticipants() later? I.e., + // we haven't added this client to the server data model yet. Add them now.. + // FIXME: will this cause problems if we invoke shuffleParticipants() later? I.e., // the clients get added to the server data model for the purposes of the chat - // and then when they start the actual round they get reshuffled? Need to - // rethink clearly/carefully how clients and when clients get added to the server + // and then when they start the actual round they get reshuffled? Need to + // rethink clearly/carefully how clients and when clients get added to the server // data model...! serverDataModel.addClient(clientData); } @@ -727,7 +736,7 @@ } }); // FIXME: handle reconfiguration requests from facilitator - } + } private void relayChatRequest(ChatRequest request) { Identifier source = request.getSource(); @@ -739,10 +748,10 @@ // check for field of vision RoundConfiguration currentConfiguration = getCurrentRoundConfiguration(); if (currentConfiguration.isFieldOfVisionEnabled()) { - // FIXME: replace with clientData.getFieldOfVision? + // FIXME: replace with clientData.getFieldOfVision? Circle circle = new Circle(clientData.getPosition(), currentConfiguration.getViewSubjectsRadius()); - sendChatEvent(request, clientData.getGroupDataModel().getClientIdentifiersWithin(circle)); + sendChatEvent(request, clientData.getGroupDataModel().getClientIdentifiersWithin(circle)); } else { sendChatEvent(request, clientData.getGroupDataModel().getClientIdentifiers()); @@ -750,12 +759,12 @@ } else { getLogger().info(String.format("%s sending [%s] to target [%s]", request.getSource(), request, request.getTarget())); - ChatEvent chatEvent = new ChatEvent(request.getTarget(), request.toString(), request.getSource()); + ChatEvent chatEvent = new ChatEvent(request.getTarget(), request.toString(), request.getSource()); transmit(chatEvent); } persister.store(request); } - + private void sendChatEvent(ChatRequest request, Collection<Identifier> identifiers) { for (Identifier targetId : identifiers) { ChatEvent chatEvent = new ChatEvent(targetId, request.toString(), request.getSource(), true); @@ -763,54 +772,54 @@ } } - // FIXME: remove Dispatcher reference if it's unused. + // FIXME: remove Dispatcher reference if it's unused. public void execute(Dispatcher dispatcher) { switch (serverState) { - case ROUND_IN_PROGRESS: - // process incoming information - if (currentRoundDuration.hasExpired()) { - // perform token adjustment if needed. - for (GroupDataModel group: serverDataModel.getGroups()) { - if (group.getActiveEnforcementMechanism().hasMonitor()) { - group.applyMonitorTax(); + case ROUND_IN_PROGRESS: + // process incoming information + if (currentRoundDuration.hasExpired()) { + // perform token adjustment if needed. + for (GroupDataModel group : serverDataModel.getGroups()) { + if (group.getActiveEnforcementMechanism().hasMonitor()) { + group.applyMonitorTax(); + } } + stopRound(); + break; } - stopRound(); + + roundProcessor.execute(); + // Thread.yield(); + Utils.sleep(SERVER_SLEEP_INTERVAL); break; - } - - roundProcessor.execute(); -// Thread.yield(); - Utils.sleep(SERVER_SLEEP_INTERVAL); - break; - case WAITING: - // initialize persister first so we store all relevant events. - // persister MUST be initialized early so that we store pre-round events like QuizResponseEvent, ChatEvent, and the various Ranking requests. - initializeRound(); - + case WAITING: + // initialize persister first so we store all relevant events. + // persister MUST be initialized early so that we store pre-round events like QuizResponseEvent, ChatEvent, and the various Ranking + // requests. + initializeRound(); - getLogger().info("Round is initialized: now waiting for facilitator signal to start next round."); - if (getCurrentRoundConfiguration().isQuizEnabled()) { - getLogger().info("Waiting for all quizzes to be submitted."); - Utils.waitOn(quizSignal); - } - // then wait for the signal from the facilitator to actually start the round (a chat session might occur or a voting session). - Utils.waitOn(roundSignal); - // actually start the round once we receive the facilitator signal. - startRound(); - break; - default: - throw new RuntimeException("Should never get here."); + getLogger().info("Round is initialized: now waiting for facilitator signal to start next round."); + if (getCurrentRoundConfiguration().isQuizEnabled()) { + getLogger().info("Waiting for all quizzes to be submitted."); + Utils.waitOn(quizSignal); + } + // then wait for the signal from the facilitator to actually start the round (a chat session might occur or a voting session). + Utils.waitOn(roundSignal); + // actually start the round once we receive the facilitator signal. + startRound(); + break; + default: + throw new RuntimeException("Should never get here."); } } private void processRound3d() { boolean secondHasPassed = secondTick.hasExpired(); if (secondHasPassed) { - int secondsPerYear = getConfiguration().getCurrentParameters().getResourceAgingSecondsPerYear(); - for (GroupDataModel group: serverDataModel.getGroups()) { + int secondsPerYear = getConfiguration().getCurrentParameters().getResourceAgingSecondsPerYear(); + for (GroupDataModel group : serverDataModel.getGroups()) { // update resource age - if (secondTick.getStartCount() % secondsPerYear == 0) { + if (secondTick.getStartCount() % secondsPerYear == 0) { resourceDispenser.updateResourceAge(group); } // renew resources @@ -820,38 +829,38 @@ } // send new information to each client long timeLeft = currentRoundDuration.getTimeLeft(); - for (ClientData data: clients.values()) { + for (ClientData data : clients.values()) { transmit(new SynchronizeClientEvent(data, timeLeft)); } serverDataModel.clearDiffLists(); } - + private void processRound2d() { boolean secondHasPassed = secondTick.hasExpired(); if (secondHasPassed) { - // handle rotating monitors. - if (getCurrentRoundConfiguration().isRotatingMonitorEnabled() - && currentRoundDuration.getElapsedTimeInSeconds() % monitorRotationInterval == 0) - { - for (GroupDataModel group: serverDataModel.getGroups()) { - boolean rotated = group.rotateMonitorIfNecessary(); - if (rotated) { - // send new roles to all clients - // FIXME: this is inefficient, we could synchronize twice. - for (ClientData clientData : group.getClientDataMap().values()) { - transmit(new SynchronizeClientEvent(clientData, currentRoundDuration.getTimeLeft())); - } - } - - } - } + // handle rotating monitors. + if (getCurrentRoundConfiguration().isRotatingMonitorEnabled() + && currentRoundDuration.getElapsedTimeInSeconds() % monitorRotationInterval == 0) + { + for (GroupDataModel group : serverDataModel.getGroups()) { + boolean rotated = group.rotateMonitorIfNecessary(); + if (rotated) { + // send new roles to all clients + // FIXME: this is inefficient, we could synchronize twice. + for (ClientData clientData : group.getClientDataMap().values()) { + transmit(new SynchronizeClientEvent(clientData, currentRoundDuration.getTimeLeft())); + } + } + + } + } resourceDispenser.generateResources(); secondTick.restart(); } - for (GroupDataModel group: serverDataModel.getGroups()) { - for (ClientData clientData: group.getClientDataMap().values()) { + for (GroupDataModel group : serverDataModel.getGroups()) { + for (ClientData clientData : group.getClientDataMap().values()) { // ask each client if it wants to grab a token, wherever it is. - clientData.collectToken(); + clientData.collectToken(); } } @@ -879,21 +888,21 @@ private boolean shouldSynchronize(int assignedNumber) { long startCount = secondTick.getStartCount(); - return (startCount < 3) || ((startCount % SYNCHRONIZATION_FREQUENCY) == (assignedNumber * 10)); + return (startCount < 3) || ((startCount % SYNCHRONIZATION_FREQUENCY) == (assignedNumber * 10)); } private void stopRound() { serverState = ServerState.WAITING; // FIXME: not needed, persister.persist() automatically adds this. -// persister.store(new RoundEndedMarkerEvent()); + // persister.store(new RoundEndedMarkerEvent()); sendEndRoundEvents(); if (getCurrentRoundConfiguration().isPostRoundSanctioningEnabled()) { // stop most of the round but don't persist/cleanup yet. // block until we receive all postround sanctioning events. - // FIXME: use new java.util.concurrent constructs? CountDownLatch or CyclicBarrier? - // postRoundSanctionLatch = new CountDownLatch(clients.size()); - // try { postRoundSanctionLatch.await(); } - // catch (InterruptedException ignored) {} + // FIXME: use new java.util.concurrent constructs? CountDownLatch or CyclicBarrier? + // postRoundSanctionLatch = new CountDownLatch(clients.size()); + // try { postRoundSanctionLatch.await(); } + // catch (InterruptedException ignored) {} Utils.waitOn(postRoundSanctioningSignal); } persistRound(); @@ -913,7 +922,7 @@ for (Map.Entry<Identifier, ClientData> clientDataEntry : clients.entrySet()) { Identifier id = clientDataEntry.getKey(); ClientData clientData = clientDataEntry.getValue(); - transmit( new EndRoundEvent(id, clientData, lastRound) ); + transmit(new EndRoundEvent(id, clientData, lastRound)); } } @@ -923,7 +932,7 @@ private void cleanupRound() { serverDataModel.cleanupRound(); - for (ClientData clientData: clients.values()) { + for (ClientData clientData : clients.values()) { clientData.reset(); } } @@ -938,7 +947,7 @@ RoundConfiguration nextRoundConfiguration = getConfiguration().nextRound(); serverDataModel.setRoundConfiguration(nextRoundConfiguration); initializeRoundProcessor(); - // reset the group linkages + // reset the group linkages if (shouldShuffleParticipants(currentRoundConfiguration, nextRoundConfiguration)) { shuffleParticipants(); } @@ -947,7 +956,7 @@ } logger.info("Advancing to round # " + getConfiguration().getCurrentRoundNumber()); // send the next round configuration to each client - for (Identifier id: clients.keySet()) { + for (Identifier id : clients.keySet()) { transmit(new SetConfigurationEvent<RoundConfiguration>(id, nextRoundConfiguration)); } transmit(new SetConfigurationEvent<RoundConfiguration>(facilitatorId, nextRoundConfiguration)); @@ -957,10 +966,10 @@ // when do we _have_ to shuffle participants? // 1. when randomize-groups is set for the next round // 2. when we move from a private property round to a open access round - // 3. in general, when the clients per group in the current round is different from the + // 3. in general, when the clients per group in the current round is different from the // clients per group in the next round (FIXME: is this too broad or can #2 just be a special case of this?) return nextRoundConfiguration.shouldRandomizeGroup() - || (currentRoundConfiguration.getClientsPerGroup() != nextRoundConfiguration.getClientsPerGroup()); + || (currentRoundConfiguration.getClientsPerGroup() != nextRoundConfiguration.getClientsPerGroup()); } private void shuffleParticipants() { @@ -975,10 +984,10 @@ } private void initializeClientPositions() { - // reinitialize all client positions. We don't have to do this if we are randomizing the group - // because client positions get initialized when they are added to the group + // reinitialize all client positions. We don't have to do this if we are randomizing the group + // because client positions get initialized when they are added to the group // (during the randomization process). - for (ClientData clientData: clients.values()) { + for (ClientData clientData : clients.values()) { clientData.initializePosition(); } } @@ -987,9 +996,9 @@ persister.initialize(getCurrentRoundConfiguration()); initializeResourceDispenser(); } - + private void initializeResourceDispenser() { - // set up the resource dispenser, generates the initial resource distributions for the + // set up the resource dispenser, generates the initial resource distributions for the // groups, must be done after creating the client group relationships. resourceDispenser.initialize(); } @@ -1009,7 +1018,7 @@ monitorRotationInterval = Math.max(Duration.toSeconds(currentRoundDuration.getTimeLeft()) / roundConfiguration.getClientsPerGroup(), 1); logger.info("monitor rotation interval: " + monitorRotationInterval); } - currentRoundDuration.start(); + currentRoundDuration.start(); transmit(new FacilitatorUpdateEvent(facilitatorId, serverDataModel, currentRoundDuration.getTimeLeft())); secondTick.start(); serverState = ServerState.ROUND_IN_PROGRESS; @@ -1017,8 +1026,8 @@ } /** - * Main entry point. Configuration options: - * + * Main entry point. Configuration options: + * * conf.dir, e.g -Dconf.dir=path/to/configuration * */ Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-16 22:19:16
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/1a2c34842d48/ changeset: 1a2c34842d48 user: alllee date: 2011-09-17 00:19:05 summary: pushing more markup into the config files instead.. really need some way to templatize some of this data affected #: 2 files (-1 bytes) --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Fri Sep 16 15:13:25 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Fri Sep 16 15:19:05 2011 -0700 @@ -575,7 +575,6 @@ } // and add the quiz instructions if the quiz is enabled. if (isQuizEnabled()) { - instructionsBuilder.append("<h1>Quiz</h1>").append("<hr>"); instructionsBuilder.append(getQuizInstructions()); } return instructionsBuilder; --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Fri Sep 16 15:13:25 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Fri Sep 16 15:19:05 2011 -0700 @@ -18,7 +18,7 @@ <entry key='instructions'><![CDATA[ -<h3>Practice Round Instructions</h3> +<h2>Practice Round Instructions</h2><hr><p> You will now have four minutes to practice with the experimental environment. The @@ -38,9 +38,12 @@ <entry key="quiz-instructions"><![CDATA[ +<h2>Quiz</h2> +<hr><p> -Before we begin the practice round please answer the following questions. +Before we begin the practice round please answer the following questions. You will earn $0.50 for each correct answer. </p> +<br><br><form><span class='q1'>Q1. Which one of the following statements is incorrect?</span><br><input type="radio" name="q1" value="A">A. Your decisions of where to collect tokens affects the regeneration of tokens.<br> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-16 22:13:36
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/cb2bfd179dae/ changeset: cb2bfd179dae user: alllee date: 2011-09-17 00:13:25 summary: setting chat handles on participants affected #: 2 files (-1 bytes) --- a/src/main/java/edu/asu/commons/foraging/model/ServerDataModel.java Fri Sep 16 15:09:25 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/model/ServerDataModel.java Fri Sep 16 15:13:25 2011 -0700 @@ -58,6 +58,8 @@ private transient FractalTerrain terrain; private transient boolean dirty = false; + + private final static String[] CHAT_HANDLES = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S" }; // Maps client Identifiers to the GroupDataModel that the client belongs to @@ -157,6 +159,7 @@ public synchronized void addClientToGroup(ClientData clientData, GroupDataModel group) { group.addClient(clientData); clientsToGroups.put(clientData.getId(), group); + clientData.getId().setChatHandle(CHAT_HANDLES[group.size()]); channel.handle(new AddClientEvent(clientData, group, clientData.getPosition())); } --- a/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Fri Sep 16 15:09:25 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Fri Sep 16 15:13:25 2011 -0700 @@ -708,6 +708,7 @@ for (Map.Entry<Identifier, ClientData> entry: clients.entrySet()) { Identifier id = entry.getKey(); ClientData clientData = entry.getValue(); + // FIXME: hacky, get rid of this. if (clientData.getGroupDataModel() == null) { // we haven't added this client to the server data model yet. Add them now.. // FIXME: will this cause problems if we invoke shuffleParticipants() later? I.e., Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-16 22:09:39
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/316c0b0609f8/ changeset: 316c0b0609f8 user: alllee date: 2011-09-17 00:09:25 summary: updating instructions and adding checkerboard image from Mady affected #: 3 files (-1 bytes) --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 15 17:26:57 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Fri Sep 16 15:09:25 2011 -0700 @@ -32,9 +32,7 @@ press the <b>R</b> key you will reset the resource to its initial distribution, randomly filling half of the cells. </p> -<p><b>Please do not communicate with any other participant.</b></p> -<p>If you have any questions please raise your hand. <b>Do you have any -questions so far?</b></p> +<p>If you have any questions please raise your hand. <b>Do you have any questions so far?</b></p> ]]></entry> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 15 17:26:57 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Fri Sep 16 15:09:25 2011 -0700 @@ -43,7 +43,7 @@ Welcome to the experiment. The experiment will begin shortly after everyone has been assigned a station. <br><br> -Please <b>wait quietly</b> and <b>do not close this window or open any other applications</b>. +Please <b>wait quietly</b> and <b>do not close this window, open any other applications, or communicate with any of the other participants</b>. </p> ]]></entry> @@ -52,22 +52,31 @@ <![CDATA[ <h1>General Instructions</h1><p> -Welcome. You have already earned 5 dollars by showing up at this experiment. You can -earn more, up to a maximum of about 40 dollars, by participating in this experiment, which -will take about an hour to an hour and a half. The amount of money you earn depends -on your decisions as well as the decisions of other people in this room during the -six rounds of the experiment. + <b>Welcome</b>. You have already earned 5 dollars just for showing up at this experiment. </p><p> +You can earn more, up to a maximum of about 40 dollars, by participating in this +experiment, which will take about an hour to an hour and a half. The amount of money +you earn depends on your decisions AND the decisions of other people in this room +over the course of the experiment. +</p> +<h2>How to participate</h2> +<hr> +<p> You will appear on the screen as a yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"></img>. -You can move by pressing the four arrow keys on your keyboard. You can move up, -down, left, or right. You have to press a key for each and every move of your -yellow dot. In this experiment you can collect green diamond shaped tokens -<img src="@CODEBASE_URL@/images/gem-token.gif"></img> and earn two cents for each collected token. -To collect a token, move your yellow dot over a green token and <b>press the space -bar</b>. Simply moving your avatar over a token does NOT collect that token. +You can move by pressing the four arrow keys on your keyboard. +</p> +<p> + You can move up, down, left, or right. You have to press a key for each and + every move of your yellow dot. In this experiment you can collect green diamond + shaped tokens <img src="@CODEBASE_URL@/images/gem-token.gif"></img> and earn two + cents for each collected token. To collect a token, move your yellow dot over a + green token and <b>press the space bar</b>. Simply moving your avatar over a + token does NOT collect that token. </p> +<h2>Tokens</h2> +<hr><p> The tokens that you collect have the potential to regenerate. After you have collected a green token, a new token can re-appear on that empty cell. The rate at @@ -79,7 +88,6 @@ than the middle cell in Image 2. When all neighboring cells are empty, there is <b>no chance for regeneration</b>. </p> - <table width="100%"><tr><td align="center"><b>Image 1</b></td> @@ -105,7 +113,7 @@ diagram shown below, where half of the cells are empty and arranged in a way that maximizes regrowth. <br> -<img src="@CODEBASE_URL@/images/optimal-strategy.jpg" alt="Checkerboard Resource"></img> +<img src="@CODEBASE_URL@/images/foraging-checkerboard.png" alt="Checkerboard Resource"></img></p> ]]></entry> @@ -115,24 +123,20 @@ <h1>Trust Game Instructions</h1><hr><p> - You will now play a mini-game where you will be matched with a random person in - your group. In this game there are two roles, Player 1 and Player 2. Your job - is to design strategies for both Player 1 and Player 2 roles. When you are - randomly paired with another member of your group you may be selected as Player - 1 <b>or</b> Player 2. The results of your strategies will be shown to you at - the <b>end of the experiment</b>. + You will now participate in an exercise where you will be matched with a random + person in your group. In this game there are two roles, Player 1 and Player 2. + Your job is to design strategies for both Player 1 and Player 2 roles. When you + are randomly paired with another member of your group you may be selected as + Player 1 <b>or</b> Player 2. The results of your strategies will be shown to + you at the <b>end of the experiment</b>. </p> -<h2>Game Mechanics</h2> +<h2>How to participate</h2><hr> -<p> -The game works as follows: -</p><ol> - <li>Player 1 first receives an endowment of one dollar and has to decide <b>how much to keep</b> and <b>how much to send to Player 2</b>. - <li>The amount Player 1 decides to send to Player 2 is tripled by - the system and then given to Player 2. Player 2 then has to decide <b>how - much to keep</b> and <b>how much to send back to Player 1</b>. + <li>Player 1 will first receive an endowment of one dollar and has to decide <b>how much to keep</b>. The remaining amount is <b>sent to Player 2</b>. + <li>The amount Player 1 sends to Player 2 is tripled by the system and then + given to Player 2. Player 2 must then decide <b>how much to keep</b> and <b>how much to send back to Player 1</b>. </ol><p> For example, if Player 1 sends 0 cents to Player 2, Player 1 earns 1 dollar and Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-16 00:27:19
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/613caccb3865/ changeset: 613caccb3865 user: alllee date: 2011-09-16 02:26:57 summary: removing unicode characters from comments affected #: 1 file (-1 bytes) --- a/src/main/java/edu/asu/commons/foraging/util/QuickTimeOutputStream.java Thu Sep 08 17:51:36 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/util/QuickTimeOutputStream.java Thu Sep 15 17:26:57 2011 -0700 @@ -33,6 +33,8 @@ import javax.imageio.stream.MemoryCacheImageOutputStream; /** + * FIXME: switch to upgraded versions: http://www.randelshofer.ch/multishow/ + * * This class supports writing of images as frames into the video track of * a QuickTime movie file. * <p> @@ -780,7 +782,7 @@ d.writeFixed16D16(0); // matrix[7] d.writeFixed2D30(1f); // matrix[8] // The matrix structure associated with this movie. A matrix shows how - // to map points from one coordinate space into another. See “Matrices” + // to map points from one coordinate space into another. See Matrices // for a discussion of how display matrices are used in QuickTime: // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap4/chapter_5_section_4.html#//apple_ref/doc/uid/TP40000939-CH206-18737 @@ -978,7 +980,7 @@ d.writeShort(0); // language; // A 16-bit integer that specifies the language code for this media. - // See “Language Code Values” for valid language codes: + // See "Language Code Values" for valid language codes: // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap4/chapter_5_section_2.html#//apple_ref/doc/uid/TP40000939-CH206-27005 d.writeShort(0); // quality @@ -1068,7 +1070,7 @@ // A 16-bit integer that specifies the transfer mode. The transfer mode // specifies which Boolean operation QuickDraw should perform when // drawing or transferring an image from one location to another. - // See “Graphics Modes” for a list of graphics modes supported by + // See Graphics Modes for a list of graphics modes supported by // QuickTime: // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap4/chapter_5_section_5.html#//apple_ref/doc/uid/TP40000939-CH206-18741 @@ -1206,7 +1208,7 @@ // description varies, depending on the media type. For example, in the // case of video media, the sample descriptions are image description // structures. The sample description information for each media type is - // explained in “Media Data Atom Types”: + // explained in Media Data Atom Types: // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_1.html#//apple_ref/doc/uid/TP40000939-CH205-SW1 leaf = new DataAtom("stsd"); stblAtom.add(leaf); @@ -1538,8 +1540,8 @@ d.writeInt(1); // sample description // The identification number associated with the sample description for - // the sample. For details on sample description atoms, see “Sample - // Description Atoms.”: + // the sample. For details on sample description atoms, see Sample + // Description Atoms.: // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap2/chapter_3_section_5.html#//apple_ref/doc/uid/TP40000939-CH204-25691 /* sample size atom -------- */ Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-09 00:50:44
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/b62a4c6e49b1/ changeset: b62a4c6e49b1 user: alllee date: 2011-09-09 02:51:36 summary: cleaning up ChatPanel implementation and working on some UI improvements for consistency and clarity. affected #: 9 files (9.7 KB) --- a/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java Thu Sep 08 17:51:36 2011 -0700 @@ -2,21 +2,10 @@ import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; @@ -28,23 +17,16 @@ import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.text.StyledDocument; -import javax.swing.text.html.HTMLEditorKit; import edu.asu.commons.event.ChatEvent; import edu.asu.commons.event.ChatRequest; import edu.asu.commons.event.EventTypeProcessor; import edu.asu.commons.net.Identifier; - - - /** * $Id: ChatPanel.java 516 2010-05-10 23:31:53Z alllee $ * - * Chat panel used to communicate with other players. - * - * FIXME: randomize handle mappings (e.g., A -> 3, B -> 1, C -> 4, D -> 2 ...) so that it's - * not linear. + * Chat panel used to communicate with other players. * * @author alllee * @version $Revision: 516 $ @@ -53,55 +35,118 @@ public class ChatPanel extends JPanel { private ForagingClient client; - - private boolean inRoundChat = false; + + private JScrollPane messageScrollPane; + + private JTextPane messageWindow; + + private List<Identifier> participants; + + private TextEntryPanel textEntryPanel; + + private JEditorPane chatInstructionsPane; public ChatPanel(ForagingClient client) { this.client = client; - this.clientId = client.getId(); client.getEventChannel().add(this, new EventTypeProcessor<ChatEvent>(ChatEvent.class) { public void handle(final ChatEvent chatEvent) { - displayMessage(getChatHandle(chatEvent.getSource()) -// FIXME: either "all" or "you". -// + " -> " + getChatHandle(chatEvent.getTarget()) - ,chatEvent.toString()); + displayMessage(chatEvent.getSource(), chatEvent.toString()); } }); + initGuiComponents(); } + + private void addStylesToMessageWindow() { + StyledDocument styledDocument = messageWindow.getStyledDocument(); + Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle( + StyleContext.DEFAULT_STYLE); + StyleConstants.setFontFamily(defaultStyle, "Helvetica"); + StyleConstants.setBold(styledDocument.addStyle("bold", defaultStyle), + true); + StyleConstants.setItalic(styledDocument + .addStyle("italic", defaultStyle), true); + } + + private void initGuiComponents() { + setLayout(new BorderLayout(3, 3)); + setName("Chat panel"); + messageWindow = new JTextPane(); + messageWindow.setEditable(false); + messageWindow.setBackground(Color.WHITE); + messageScrollPane = new JScrollPane(messageWindow); + addStylesToMessageWindow(); + + textEntryPanel = new TextEntryPanel(client); + // orient the components in true lazyman fashion. + +// chatInstructionsPane = new JEditorPane(); +// chatInstructionsPane.setContentType("text/html"); +// chatInstructionsPane.setEditorKit(new HTMLEditorKit()); +// chatInstructionsPane.setEditable(false); +// chatInstructionsPane.setBackground(Color.WHITE); +// JScrollPane chatInstructionsScrollPane = new JScrollPane(chatInstructionsPane); +// chatInstructionsPane.setText(client.getCurrentRoundConfiguration().getChatInstructions()); +// add(chatInstructionsScrollPane, BorderLayout.NORTH); + + add(textEntryPanel, BorderLayout.NORTH); + add(messageScrollPane, BorderLayout.CENTER); + } + + public void setTextFieldFocus() { + textEntryPanel.setChatFieldFocus(); + } + + public TextEntryPanel getTextEntryPanel() { + return textEntryPanel; + } + + public JScrollPane getMessageScrollPane() { + return messageScrollPane; + } + + public void clear() { + participants.clear(); + } + + private void displayMessage(Identifier identifier, String message) { + StyledDocument document = messageWindow.getStyledDocument(); + try { + String source = identifier.getChatHandle() + " : "; + document.insertString(0, source, document.getStyle("bold")); + document.insertString(source.length(), message + "\n", null); + messageWindow.setCaretPosition(0); + } catch (BadLocationException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public void initialize() { + this.participants = client.getDataModel().getAllClientIdentifiers(); + } + private class TextEntryPanel extends JPanel { - private JLabel targetHandleLabel; + + private static final long serialVersionUID = -4846486696999203769L; private Identifier targetIdentifier = Identifier.ALL; private JTextField chatField; - public TextEntryPanel() { - super(); + public TextEntryPanel(ForagingClient client) { setLayout(new BorderLayout(3, 3)); chatField = new JTextField(); chatField.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent event) { - // System.err.println("event keycode is: " + - // event.getKeyCode()); - // System.err.println("vk_enter: " + KeyEvent.VK_ENTER); if (event.getKeyCode() == KeyEvent.VK_ENTER) { sendMessage(); } } }); - JPanel targetHandlePanel = new JPanel(); - targetHandlePanel.setLayout(new BoxLayout(targetHandlePanel, BoxLayout.LINE_AXIS)); - targetHandleLabel = new JLabel("everyone"); - targetHandleLabel.setFont(new Font("Arial", Font.BOLD, 14)); - targetHandleLabel.setForeground(new Color(0x0000dd)); - targetHandlePanel.add(new JLabel(" Chatting with: ")); - targetHandlePanel.add(targetHandleLabel); - - add(targetHandlePanel, BorderLayout.NORTH); + add(new JLabel("In round chat"), BorderLayout.NORTH); add(chatField, BorderLayout.CENTER); - setChatFieldFocus(); } - private void setChatFieldFocus() { + void setChatFieldFocus() { chatField.requestFocusInWindow(); } @@ -111,9 +156,10 @@ if (message == null || "".equals(message) || targetIdentifier == null) { return; } - client.transmit(new ChatRequest(clientId, message, targetIdentifier)); - if (inRoundChat) { - client.getGameWindow().getPanel().requestFocusInWindow(); + client.transmit(new ChatRequest(client.getId(), message, targetIdentifier)); + // special case for in round chat + if (client.getCurrentRoundConfiguration().isInRoundChatEnabled()) { + client.getGameWindow().requestFocusInWindow(); } else { chatField.requestFocusInWindow(); @@ -121,185 +167,6 @@ chatField.setText(""); } - private void setTargetHandle(Identifier targetIdentifier) { - this.targetIdentifier = targetIdentifier; - if (targetIdentifier == Identifier.ALL) { - targetHandleLabel.setText("everyone"); - } else { - targetHandleLabel.setText(getChatHandle(targetIdentifier)); - } - setChatFieldFocus(); - } - } - - private final static String HANDLE_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - private String[] HANDLES; - - private Identifier clientId; - - private JScrollPane messageScrollPane; - - private JTextPane messageWindow; - - // used by the participant to select which participant to send a message to. - private JPanel participantButtonPanel; - - private List<Identifier> participants; - - private TextEntryPanel textEntryPanel; - - private JEditorPane chatInstructionsPane; - - private void addStylesToMessageWindow() { - StyledDocument styledDocument = messageWindow.getStyledDocument(); - // and why not have something like... StyleContext.getDefaultStyle() to - // replace this junk - Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle( - StyleContext.DEFAULT_STYLE); - // Style regularStyle = styledDocument.addStyle("regular", - // defaultStyle); - StyleConstants.setFontFamily(defaultStyle, "Helvetica"); - StyleConstants.setBold(styledDocument.addStyle("bold", defaultStyle), - true); - StyleConstants.setItalic(styledDocument - .addStyle("italic", defaultStyle), true); - } - - private String getChatHandle(Identifier source) { - if (source.equals(Identifier.ALL)) { - return "all"; - } - else { - String chatHandle = HANDLES[participants.indexOf(source)]; - if (source.equals(clientId)) { - return chatHandle.concat(" (you)"); - } - return chatHandle; - } - } - - private void initGuiComponents() { - setLayout(new BorderLayout(3, 3)); - setName("Chat panel"); - messageWindow = new JTextPane(); - messageWindow.setEditable(false); - messageWindow.setBackground(Color.WHITE); - messageScrollPane = new JScrollPane(messageWindow); - addStylesToMessageWindow(); - - // set up the participant panel - participantButtonPanel = new JPanel(); - // participantButtonPanel.setLayout(new - // BoxLayout(participantButtonPanel, - // BoxLayout.PAGE_AXIS)); - participantButtonPanel.setLayout(new GridLayout(0, 1)); - participantButtonPanel.setBackground(Color.GRAY); - // JLabel selfLabel = new JLabel(getChatHandle(clientId)); - // selfLabel.setForeground(Color.ORANGE); - // selfLabel.setBackground(Color.ORANGE); - // selfLabel.setAlignmentX(Component.CENTER_ALIGNMENT); - JButton selfButton = new JButton(getChatHandle(clientId)); - selfButton.setEnabled(false); - selfButton.setAlignmentX(Component.CENTER_ALIGNMENT); - participantButtonPanel.add(selfButton); - participantButtonPanel.add(Box.createRigidArea(new Dimension(0, 15))); - for (final Identifier targetId: participants) { - if (targetId.equals(clientId)) { - continue; - } - JButton button = new JButton(getChatHandle(targetId)); - button.setAlignmentX(JButton.CENTER_ALIGNMENT); - button.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - // change stuff in the messageEntryPanel - textEntryPanel.setTargetHandle(targetId); - } - }); - participantButtonPanel.add(button); - } - // special case to send a message to everyone - JButton sendAllButton = new JButton(" all "); - sendAllButton.setAlignmentX(Component.CENTER_ALIGNMENT); - sendAllButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - textEntryPanel.setTargetHandle(Identifier.ALL); - } - }); - participantButtonPanel.add(sendAllButton); - - textEntryPanel = new TextEntryPanel(); - // orient the components in true lazyman fashion. - - chatInstructionsPane = new JEditorPane(); - chatInstructionsPane.setContentType("text/html"); - chatInstructionsPane.setEditorKit(new HTMLEditorKit()); - chatInstructionsPane.setEditable(false); - chatInstructionsPane.setBackground(Color.WHITE); - JScrollPane chatInstructionsScrollPane = new JScrollPane(chatInstructionsPane); - chatInstructionsPane.setText(client.getCurrentRoundConfiguration().getChatInstructions()); - -// add(chatInstructionsScrollPane, BorderLayout.NORTH); - add(new JLabel("In round chat"), BorderLayout.NORTH); - add(messageScrollPane, BorderLayout.CENTER); - add(textEntryPanel, BorderLayout.SOUTH); - textEntryPanel.setChatFieldFocus(); - } - - public void setTextFieldFocus() { - textEntryPanel.setChatFieldFocus(); - } - - public TextEntryPanel getTextEntryPanel() { - return textEntryPanel; - } - - public JScrollPane getMessageScrollPane() { - return messageScrollPane; - } - - public void clear() { - participants.clear(); - } - - private void displayMessage(String chatHandle, String message) { - // String chatHandle = getChatHandle(source); - StyledDocument document = messageWindow.getStyledDocument(); - try { - document.insertString(document.getLength(), chatHandle + " : ", - document.getStyle("bold")); - document.insertString(document.getLength(), message + "\n", null); - messageWindow.setCaretPosition(document.getLength()); - } catch (BadLocationException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public void initialize(boolean inRoundChat) { - this.inRoundChat = inRoundChat; - if (HANDLES != null) { - displayMessage("System message", " --- Round ended --- "); - return; - } - this.participants = client.getDataModel().getAllClientIdentifiers(); - HANDLES = new String[participants.size()]; - List<String> handles = new ArrayList<String>(); - if (client.getDataModel().getRoundConfiguration().isChatAnonymized()) { - for (int i = HANDLES.length; --i >= 0;) { - handles.add(HANDLE_STRING.charAt(i) + ""); - } - Collections.shuffle(handles); - for (int i = 0; i < HANDLES.length; i++) { - HANDLES[i] = handles.get(i); - } - } - else { - for (int i = 0; i < HANDLES.length; i++) { - HANDLES[i] = client.getDataModel().getAssignedNumber(participants.get(i)) + ""; - } - } - initGuiComponents(); } } --- a/src/main/java/edu/asu/commons/foraging/client/EmbeddedChatPanel.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/EmbeddedChatPanel.java Thu Sep 08 17:51:36 2011 -0700 @@ -147,6 +147,7 @@ + getChatHandle(chatEvent.getTarget()), chatEvent.toString()); } }); + initGuiComponents(); } public void stop() { @@ -192,60 +193,7 @@ messageScrollPane.setMaximumSize(messageWindowSize); addStylesToMessageWindow(); - // set up the participant panel -// participantButtonPanel = new JPanel(); -// // participantButtonPanel.setLayout(new -// // BoxLayout(participantButtonPanel, -// // BoxLayout.PAGE_AXIS)); -// participantButtonPanel.setLayout(new GridLayout(0, 1)); -// participantButtonPanel.setBackground(Color.GRAY); -// // JLabel selfLabel = new JLabel(getChatHandle(clientId)); -// // selfLabel.setForeground(Color.ORANGE); -// // selfLabel.setBackground(Color.ORANGE); -// // selfLabel.setAlignmentX(Component.CENTER_ALIGNMENT); -// JButton selfButton = new JButton(getChatHandle(clientId)); -// selfButton.setEnabled(false); -// selfButton.setAlignmentX(Component.CENTER_ALIGNMENT); -// participantButtonPanel.add(selfButton); -// participantButtonPanel.add(Box.createRigidArea(new Dimension(0, 15))); -// for (int i = 0; i < HANDLES.length; i++) { -// final Identifier targetId = participants.get(i); -// if (targetId.equals(clientId)) { -// continue; -// } -// String handle = HANDLES[i]; -// JButton button = new JButton(handle); -// button.setAlignmentX(Component.CENTER_ALIGNMENT); -// button.addActionListener(new ActionListener() { -// public void actionPerformed(ActionEvent e) { -// // change stuff in the messageEntryPanel -// textEntryPanel.setTargetHandle(targetId); -// } -// }); -// participantButtonPanel.add(button); -// } -// // special case to send a message to everyone -// JButton sendAllButton = new JButton(" all "); -// sendAllButton.setAlignmentX(Component.CENTER_ALIGNMENT); -// sendAllButton.addActionListener(new ActionListener() { -// public void actionPerformed(ActionEvent e) { -// textEntryPanel.setTargetHandle(Identifier.ALL); -// } -// }); -// participantButtonPanel.add(sendAllButton); - textEntryPanel = new TextEntryPanel(); - // orient the components in true lazyman fashion. - -// chatInstructionsPane = new JEditorPane(); -// chatInstructionsPane.setContentType("text/html"); -// chatInstructionsPane.setEditorKit(new HTMLEditorKit()); -// chatInstructionsPane.setEditable(false); -// JScrollPane chatInstructionsScrollPane = new JScrollPane(chatInstructionsPane); -// chatInstructionsPane.setText(CHAT_INSTRUCTIONS); - - -// add(chatInstructionsScrollPane, BorderLayout.NORTH); add(messageScrollPane, BorderLayout.CENTER); add(textEntryPanel, BorderLayout.SOUTH); } @@ -285,6 +233,5 @@ for (int i = HANDLES.length; --i >= 0;) { HANDLES[i] = " " + HANDLE_STRING.charAt(i) + " "; } - initGuiComponents(); } } --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow.java Thu Sep 08 17:51:36 2011 -0700 @@ -21,5 +21,6 @@ public void showInstructions(); public void showTrustGame(); public JPanel getPanel(); + public void requestFocusInWindow(); } --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 08 17:51:36 2011 -0700 @@ -341,7 +341,7 @@ htmlPane.setEditable(false); htmlPane.setDoubleBuffered(true); htmlPane.setBackground(Color.WHITE); - htmlPane.setFont(new Font("sansserif", Font.PLAIN, 12)); + htmlPane.setFont(new Font("Trebuchet MS", Font.PLAIN, 15)); return htmlPane; } @@ -389,7 +389,7 @@ messagePanel.add(new JLabel("Messages"), BorderLayout.NORTH); messageTextPane = new JTextPane(); messageTextPane.setEditable(false); - messageTextPane.setFont(new Font("arial", Font.BOLD, 12)); + messageTextPane.setFont(new Font("Trebuchet MS", Font.BOLD, 15)); messageTextPane.setBackground(Color.WHITE); addStyles(messageTextPane.getStyledDocument()); messageScrollPane = new JScrollPane(messageTextPane); @@ -577,7 +577,7 @@ update(configuration.getRoundDuration().getTimeLeft()); if (configuration.isInRoundChatEnabled()) { ChatPanel chatPanel = getChatPanel(); - chatPanel.initialize(true); + chatPanel.initialize(); Dimension chatPanelSize = new Dimension(250, getPanel().getSize().height); chatPanel.setPreferredSize(chatPanelSize); // FIXME: switch to different layout manager @@ -802,7 +802,7 @@ SwingUtilities.invokeLater(new Runnable() { public void run() { ChatPanel chatPanel = getChatPanel(); - chatPanel.initialize(false); + chatPanel.initialize(); showPanel(CHAT_PANEL_NAME); startChatTimer(); } @@ -817,4 +817,10 @@ public JPanel getPanel() { return mainPanel; } + + @Override + public void requestFocusInWindow() { + getPanel().requestFocusInWindow(); + + } } --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow3D.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow3D.java Thu Sep 08 17:51:36 2011 -0700 @@ -240,4 +240,9 @@ public String getChatHandle(Identifier id) { return chatPanel.getChatHandle(id); } + + @Override + public void requestFocusInWindow() { + getPanel().requestFocusInWindow(); + } } --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Thu Sep 08 17:51:36 2011 -0700 @@ -566,11 +566,16 @@ public StringBuilder buildInstructions(StringBuilder instructionsBuilder) { if (isFirstRound()) { instructionsBuilder.append(getGeneralInstructions()); + instructionsBuilder.append(getInstructions()); } - instructionsBuilder.append(getInstructions()); - addAllSpecialInstructions(instructionsBuilder); + else { + // FIXME: dirty hack, need to fix after we paginate things + instructionsBuilder.append(getInstructions()); + addAllSpecialInstructions(instructionsBuilder); + } // and add the quiz instructions if the quiz is enabled. if (isQuizEnabled()) { + instructionsBuilder.append("<h1>Quiz</h1>").append("<hr>"); instructionsBuilder.append(getQuizInstructions()); } return instructionsBuilder; --- a/src/main/java/edu/asu/commons/foraging/conf/ServerConfiguration.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/ServerConfiguration.java Thu Sep 08 17:51:36 2011 -0700 @@ -77,7 +77,7 @@ public String getFieldOfVisionInstructions() { return assistant.getProperty("field-of-vision-instructions", - "Your vision is limited in this experiment. The area that is visible to you will be shaded."); + "Your view of the resource will be limited in this round. The area visible to you will be shaded."); } --- a/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 08 17:51:36 2011 -0700 @@ -234,9 +234,6 @@ @Override public void handle(SocketIdentifierUpdateRequest request) { SocketIdentifier socketId = request.getSocketIdentifier(); - //getLogger().info("socket id from client: " + socketId); - //getLogger().info("station number from client: " + socketId.getStationNumber()); - //getLogger().info("station number from event: " + request.getStationNumber()); ClientData clientData = clients.get(socketId); if (clientData == null) { getLogger().warning("No client data available for socket: " + socketId); --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 01 15:16:10 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 08 17:51:36 2011 -0700 @@ -37,9 +37,12 @@ <entry key="welcome-instructions"><![CDATA[ -<h3>Welcome to the experiment. The experiment will begin shortly after everyone has been -assigned a station.</h3> +<h1>Welcome</h1> +<hr><p> +Welcome to the experiment. The experiment will begin shortly after everyone has been +assigned a station. +<br><br> Please <b>wait quietly</b> and <b>do not close this window or open any other applications</b>. </p> ]]> @@ -47,7 +50,7 @@ <entry key="general-instructions"><![CDATA[ -<h3>General Instructions</h3> +<h1>General Instructions</h1><p> Welcome. You have already earned 5 dollars by showing up at this experiment. You can earn more, up to a maximum of about 40 dollars, by participating in this experiment, which @@ -56,7 +59,7 @@ six rounds of the experiment. </p><p> - You will appear on the screen as a yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"></img>. +You will appear on the screen as a yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"></img>. You can move by pressing the four arrow keys on your keyboard. You can move up, down, left, or right. You have to press a key for each and every move of your yellow dot. In this experiment you can collect green diamond shaped tokens @@ -92,7 +95,8 @@ </tr></table> -<h3>Best Strategy</h3> +<h2>Best Strategy</h2> +<hr><p> The chance that a token will regenerate on an empty cell increases as there are more tokens surrounding it. Therefore, you want to have as many tokens around an @@ -108,7 +112,8 @@ <entry key='trust-game-instructions'><![CDATA[ -<h3>Trust Game Instructions</h3> +<h1>Trust Game Instructions</h1> +<hr><p> You will now play a mini-game where you will be matched with a random person in your group. In this game there are two roles, Player 1 and Player 2. Your job @@ -118,7 +123,8 @@ the <b>end of the experiment</b>. </p> -<h3>Game Mechanics</h3> +<h2>Game Mechanics</h2> +<hr><p> The game works as follows: </p> @@ -141,24 +147,4 @@ </p> ]]></entry> -<entry key='in-round-chat-instructions'> - <![CDATA[ -<p> -You can chat with all other <b>visible</b> participants in your group <b>during this round</b>. -You may communicate about any aspect of the experiment that you would like to -discuss with other participants with whom you have been matched. You may not promise -them side-payments after the experiment is completed or threaten them with any -consequence after the experiment is finished. We are monitoring the chat traffic -while you chat. If we see that somebody reveals his or her identity, we have to stop -the experiment and remove the whole group from which this person is a member out of -this room. -</p> -<p> -You will see other participants labeled as "1", "2","3", "4", or "5" in the chat -box. You can send a chat message by hitting the enter key, typing into the -textfield and then pressing the enter key again. You must hit the enter key before -you enter each message. -</p> - ]]> -</entry></properties> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 22:15:39
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/d9f711904913/ changeset: d9f711904913 user: alllee date: 2011-09-02 00:16:10 summary: showing trust game log for each round for testing, move back in production affected #: 1 file (131 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 15:12:18 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 15:16:10 2011 -0700 @@ -650,11 +650,13 @@ double showUpPayment = dataModel.getRoundConfiguration().getParentConfiguration().getShowUpPayment(); instructionsBuilder.append(String.format("Your <b>total income</b> so far (including a $%3.2f bonus for showing up) is : $%3.2f<hr>", showUpPayment, dataModel.getTotalIncome() + showUpPayment + quizReward)); - + for (String trustGameLog : event.getTrustGameLog()) { + instructionsBuilder.append(trustGameLog); + } if (event.isLastRound()) { - for (String trustGameLog : event.getTrustGameLog()) { - instructionsBuilder.append(trustGameLog); - } +// for (String trustGameLog : event.getTrustGameLog()) { +// instructionsBuilder.append(trustGameLog); +// } instructionsBuilder.append(client.getDataModel().getRoundConfiguration().getLastRoundDebriefing()); timeLeftLabel.setText("The experiment is now over."); } Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 22:11:47
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/b7adfb571813/ changeset: b7adfb571813 user: alllee date: 2011-09-02 00:12:18 summary: updated in round chat instructions affected #: 1 file (954 bytes) --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 01 15:08:09 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 01 15:12:18 2011 -0700 @@ -141,4 +141,24 @@ </p> ]]></entry> +<entry key='in-round-chat-instructions'> + <![CDATA[ +<p> +You can chat with all other <b>visible</b> participants in your group <b>during this round</b>. +You may communicate about any aspect of the experiment that you would like to +discuss with other participants with whom you have been matched. You may not promise +them side-payments after the experiment is completed or threaten them with any +consequence after the experiment is finished. We are monitoring the chat traffic +while you chat. If we see that somebody reveals his or her identity, we have to stop +the experiment and remove the whole group from which this person is a member out of +this room. +</p> +<p> +You will see other participants labeled as "1", "2","3", "4", or "5" in the chat +box. You can send a chat message by hitting the enter key, typing into the +textfield and then pressing the enter key again. You must hit the enter key before +you enter each message. +</p> + ]]> +</entry></properties> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 22:07:38
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/23c293b91ca1/ changeset: 23c293b91ca1 user: alllee date: 2011-09-02 00:08:09 summary: fixing a minor bug in the practice round, forgot to break after hitting return affected #: 1 file (35 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:57:23 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 15:08:09 2011 -0700 @@ -503,6 +503,7 @@ if (dataModel.getRoundConfiguration().isInRoundChatEnabled()) { getChatPanel().setTextFieldFocus(); } + break; case KeyEvent.VK_R: if (canResetTokenDistribution()) { event = new ResetTokenDistributionRequest(client.getId()); Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 21:56:53
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/be6bbd54380e/ changeset: be6bbd54380e user: alllee date: 2011-09-01 23:57:23 summary: updated configuration for pretest affected #: 7 files (11.3 KB) --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 01 14:53:56 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 01 14:57:23 2011 -0700 @@ -10,6 +10,7 @@ <entry key='tokens-field-of-vision'>true</entry><entry key='subjects-field-of-vision'>true</entry> +<entry key='in-round-chat-enabled'>true</entry><entry key="quiz">true</entry><entry key="q1">C</entry> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round1.xml Thu Sep 01 14:53:56 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round1.xml Thu Sep 01 14:57:23 2011 -0700 @@ -68,44 +68,4 @@ </p> ]]></entry> -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to chose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. -We ask you to fill in the tables for player 1 as well as for player 2, and we will -drawn whether you are player 1 or 2 after you have made the decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round2.xml Thu Sep 01 14:53:56 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round2.xml Thu Sep 01 14:57:23 2011 -0700 @@ -51,44 +51,4 @@ </p> ]]></entry> -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to chose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. -We ask you to fill in the tables for player 1 as well as for player 2, and we will -drawn whether you are player 1 or 2 after you have made the decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round3.xml Thu Sep 01 14:53:56 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round3.xml Thu Sep 01 14:57:23 2011 -0700 @@ -53,44 +53,4 @@ </p> ]]></entry> -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to chose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. -We ask you to fill in the tables for player 1 as well as for player 2, and we will -drawn whether you are player 1 or 2 after you have made the decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round4.xml Thu Sep 01 14:53:56 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round4.xml Thu Sep 01 14:57:23 2011 -0700 @@ -145,84 +145,4 @@ </form> ]]></entry> -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to chose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. -We ask you to fill in the tables for player 1 as well as for player 2, and we will -drawn whether you are player 1 or 2 after you have made the decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry> -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to chose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. -We ask you to fill in the tables for player 1 as well as for player 2, and we will -drawn whether you are player 1 or 2 after you have made the decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round5.xml Thu Sep 01 14:53:56 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round5.xml Thu Sep 01 14:57:23 2011 -0700 @@ -16,9 +16,6 @@ <entry key="sanction-type">real-time</entry><entry key="sanction-cost">1</entry><entry key="sanction-multiplier">2</entry> -<!-- before this round begins, we have a chat session --> -<entry key="chat-enabled">true</entry> - <entry key="initial-distribution">.25</entry><entry key='resource-generator'>top-bottom-patchy</entry> @@ -27,7 +24,7 @@ <entry key='max-cell-occupancy'>1</entry><!-- before this round begins, we have a chat session --> -<entry key="chat-enabled">true</entry> +<entry key="in-round-chat-enabled">true</entry><entry key="instructions"><![CDATA[ @@ -72,45 +69,4 @@ members of your group. ]]></entry> -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to chose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. -We ask you to fill in the tables for player 1 as well as for player 2, and we will -drawn whether you are player 1 or 2 after you have made the decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry> - </properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round6.xml Thu Sep 01 14:53:56 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round6.xml Thu Sep 01 14:57:23 2011 -0700 @@ -17,15 +17,13 @@ <entry key="initial-distribution">.25</entry><entry key='resource-generator'>top-bottom-patchy</entry> -<!-- before this round begins, we have a chat session --> -<entry key="chat-enabled">true</entry> +<!-- in round chat enabled --> +<entry key="in-round-chat-enabled">true</entry><entry key='always-explicit'>true</entry><entry key='max-cell-occupancy'>1</entry> -<!-- before this round begins, we have a chat session --> -<entry key="chat-enabled">true</entry><entry key="instructions"><![CDATA[ @@ -81,44 +79,4 @@ ]]></entry> -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to chose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. -We ask you to fill in the tables for player 1 as well as for player 2, and we will -drawn whether you are player 1 or 2 after you have made the decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry></properties> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 21:53:27
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/fa6d63ba8ae8/ changeset: fa6d63ba8ae8 user: alllee date: 2011-09-01 23:53:56 summary: updating focus after chat and adding private property chat affected #: 4 files (208 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java Thu Sep 01 14:37:13 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java Thu Sep 01 14:53:56 2011 -0700 @@ -113,7 +113,7 @@ } client.transmit(new ChatRequest(clientId, message, targetIdentifier)); if (inRoundChat) { - getParent().requestFocusInWindow(); + client.getGameWindow().getPanel().requestFocusInWindow(); } else { chatField.requestFocusInWindow(); --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:37:13 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:53:56 2011 -0700 @@ -202,6 +202,7 @@ setQuestionColors(incorrectAnswers, "red"); if (incorrectAnswers.isEmpty()) { builder.append(configuration.getInstructions()); + configuration.addAllSpecialInstructions(builder); // notify the server and also notify the participant. builder.append("<br><b>Congratulations!</b> You have answered all questions correctly."); setInstructions(builder.toString()); --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Thu Sep 01 14:37:13 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Thu Sep 01 14:53:56 2011 -0700 @@ -14,16 +14,16 @@ /** * $Id: RoundConfiguration.java 534 2011-05-08 02:02:39Z alllee $ * - * At some point this should be persistent database objects in a key-value store..? + * At some point this should be persistent database objects in a key-value store..? * * Something like: * - * Parameter name, value, type, instructions + * Parameter name, value, type, instructions * * need to deal with i18n at some point as well.. * * - * + * * @author <a href='mailto:All...@as...'>Allen Lee</a> * @version $Rev: 534 $ */ @@ -36,38 +36,39 @@ public final static int DEFAULT_ROUND_TIME = 5 * 60; private static final int DEFAULT_SANCTION_FLASH_DURATION = 3; - + private static final double DEFAULT_DOLLARS_PER_TOKEN = .02d; private static final double DEFAULT_TOKEN_MOVEMENT_PROBABILITY = 0.2d; - + private static final double DEFAULT_TOKEN_BIRTH_PROBABILITY = 0.01d; public double getTrustGamePayoffIncrement() { return getDoubleProperty("trust-game-payoff", 0.25d); } - + public enum SanctionType { REAL_TIME, POST_ROUND, NONE; public static SanctionType find(String name) { try { return valueOf(name.toUpperCase().replaceAll("-", "_")); - } - catch (Exception exception) { + } catch (Exception exception) { return NONE; } } } - + private final static Map<String, ExperimentType> experimentTypeMap = new HashMap<String, ExperimentType>(3); public enum ExperimentType { TWO_DIMENSIONAL("2d"), ABSTRACT("abstract"), FORESTRY("forestry"); private final String name; + private ExperimentType(String name) { this.name = name; experimentTypeMap.put(name, this); } + public static ExperimentType find(String name) { ExperimentType experimentType = experimentTypeMap.get(name); if (experimentType == null) { @@ -75,17 +76,18 @@ } return experimentType; } + public String toString() { return name; } } - + public enum SanctionAction { FINE() { public void applySanctionCost(ClientData clientData) { // perform sanction cost logic here for fines } - + public void applySanctionPenalty(ClientData clientData) { // perform sanction penalty logic here for fines } @@ -94,37 +96,39 @@ public void applySanctionCost(ClientData clientData) { // perform sanction cost logic here for freezing } - + public void applySanctionPenalty(ClientData clientData) { // perform sanction penalty logic here for freezing } }; - + // FIXME: do these need to be here to be able to invoke these methods on SanctionAction? - public void applySanctionCost(ClientData clientData) { } - - public void applySanctionPenalty(ClientData clientData) { } - + public void applySanctionCost(ClientData clientData) { + } + + public void applySanctionPenalty(ClientData clientData) { + } + public boolean isFine() { return this == FINE; } - + public boolean isFreeze() { return this == FREEZE; } } - + public RoundConfiguration() { super(); } - + public RoundConfiguration(String resource) { super(resource); } public boolean shouldRandomizeGroup() { - return ( isPracticeRound() && isPrivateProperty() ) - || getBooleanProperty("randomize-group", false); + return (isPracticeRound() && isPrivateProperty()) + || getBooleanProperty("randomize-group", false); } /** @@ -136,30 +140,30 @@ public int getSanctionFlashDuration() { return getIntProperty("sanction-flash-duration", DEFAULT_SANCTION_FLASH_DURATION); } - + public double getTokenBirthProbability() { return getDoubleProperty("token-birth-probability", DEFAULT_TOKEN_BIRTH_PROBABILITY); } - + public double getTokenMovementProbability() { return getDoubleProperty("token-movement-probability", DEFAULT_TOKEN_MOVEMENT_PROBABILITY); } - + public boolean isTokensFieldOfVisionEnabled() { return getBooleanProperty("tokens-field-of-vision", false); } - + public boolean isSubjectsFieldOfVisionEnabled() { return getBooleanProperty("subjects-field-of-vision", false); } - + public int getViewSubjectsRadius() { if (isSubjectsFieldOfVisionEnabled()) { return getIntProperty("view-subjects-radius", 6); } throw new UnsupportedOperationException("subject field of vision is not enabled."); } - + public double getViewTokensRadius() { if (isTokensFieldOfVisionEnabled()) { return getDoubleProperty("view-tokens-radius", 6.0d); @@ -168,16 +172,17 @@ } /** - * Returns a double between [0, 1] used as a scaling factor modifying the probability - * that a token grows in a neighboring cell. + * Returns a double between [0, 1] used as a scaling factor modifying the probability + * that a token grows in a neighboring cell. + * * @return */ public double getRegrowthRate() { return getDoubleProperty("regrowth-rate", DEFAULT_REGROWTH_RATE); } - + public int getInitialNumberOfTokens() { - return getIntProperty("starting-tokens", + return getIntProperty("starting-tokens", (int) (getInitialDistribution() * getResourceWidth() * getResourceDepth())); } @@ -211,37 +216,39 @@ } return getIntProperty("clients-per-group", Integer.MAX_VALUE); } - + /** - * Returns an int specifying how many tokens the sanctioner must pay to + * Returns an int specifying how many tokens the sanctioner must pay to * penalize another player. + * * @return */ public int getSanctionCost() { return getIntProperty("sanction-cost", 1); } - + /** - * Returns an int specifying how much we should scale the tokens used to sanction another + * Returns an int specifying how much we should scale the tokens used to sanction another * player (for a bonus or penalty). + * * @return */ public int getSanctionMultiplier() { return getIntProperty("sanction-multiplier", 2); } - + public int getSanctionPenalty() { return getSanctionCost() * getSanctionMultiplier(); } - + public SanctionType getSanctionType() { return SanctionType.find(getProperty("sanction-type", "none")); } - + public boolean isPostRoundSanctioningEnabled() { return getSanctionType().equals(SanctionType.POST_ROUND); } - + public boolean isRealTimeSanctioningEnabled() { return getSanctionType().equals(SanctionType.REAL_TIME); } @@ -249,19 +256,19 @@ public boolean isSanctioningEnabled() { return isRealTimeSanctioningEnabled() || isPostRoundSanctioningEnabled(); } - + public boolean shouldCheckOccupancy() { return getMaximumOccupancyPerCell() < getClientsPerGroup(); } - + public int getMaximumOccupancyPerCell() { return getIntProperty("max-cell-occupancy", getClientsPerGroup()); } - + public boolean isChatAnonymized() { return getBooleanProperty("anonymous-chat", false); } - + public double getDollarsPerToken() { return getDoubleProperty("dollars-per-token", DEFAULT_DOLLARS_PER_TOKEN); } @@ -272,40 +279,42 @@ public String getInstructions() { return getProperty("instructions", "<b>No instructions available for this round.</b>"); } - + public boolean shouldDisplayGroupTokens() { return getBooleanProperty("display-group-tokens"); } - + public boolean isQuizEnabled() { return getBooleanProperty("quiz"); } - public String getChatInstructions() { return getProperty("chat-instructions"); } - + public String getRegulationInstructions() { - return getProperty("regulation-instructions"); + return getProperty("regulation-instructions"); } - + public String getVotingInstructions() { - return getProperty("voting-instructions", "You may rank the options below from 1 to 5, where 1 is the most favorable and 5 is the least favorable. When you rank a given option it will be sorted automatically."); + return getProperty( + "voting-instructions", + "You may rank the options below from 1 to 5, where 1 is the most favorable and 5 is the least favorable. When you rank a given option it will be sorted automatically."); } - + public String getLastRoundDebriefing() { return getProperty("last-round-debriefing"); } - + /** * FIXME: quiz instructions and quiz enabled should be tightly coupled.. + * * @return */ public String getQuizInstructions() { return getProperty("quiz-instructions"); } - + public Map<String, String> getQuizAnswers() { Properties properties = getProperties(); if (isQuizEnabled()) { @@ -319,83 +328,84 @@ } return Collections.emptyMap(); } - + public String getQuizExplanation(String questionNumber) { return getProperty(questionNumber + "-explanation"); } - + public double getQuizCorrectAnswerReward() { return getDoubleProperty("quiz-correct-answer-reward", 0.50d); } /** * Possible values, freeze, fine? + * * @return */ public SanctionAction getSanctionAction() { return SanctionAction.valueOf(getProperty("sanction-action", "FINE")); } - + public int getNumberOfSanctionOpportunities() { return getIntProperty("sanction-opportunities", 30); } - + public int getChatDuration() { return getIntProperty("chat-duration", 240); } - + public int getSanctionVotingDuration() { return getIntProperty("sanction-voting-duration", 30); } - + public int getRegulationSubmissionDuration() { return getIntProperty("regulation-submission-duration", 60); } - + public int getRegulationDisplayDuration() { return getIntProperty("regulation-display-duration", 30); } - + public int getRegulationVotingDuration() { return getIntProperty("regulation-voting-duration", 60); } - + public int getEnforcementVotingDuration() { return getIntProperty("enforcement-voting-duration", 60); } - + public int getEnforcementDisplayDuration() { return getIntProperty("enforcement-display-duration", 30); } - + public String getSanctionInstructions() { - return getProperty("sanction-instructions","<h2>Voting instructions</h2>" + - "<ul> " + - "<li> You must make a choice within the next 30 seconds. " + - "<li>The votes of all participants in your group will determine the outcome." + - "</ul>"); + return getProperty("sanction-instructions", "<h2>Voting instructions</h2>" + + "<ul> " + + "<li> You must make a choice within the next 30 seconds. " + + "<li>The votes of all participants in your group will determine the outcome." + + "</ul>"); } - + public boolean isAlwaysInExplicitCollectionMode() { return getBooleanProperty("always-explicit", true); } - + public boolean isExplicitCollectionEnabled() { return getBooleanProperty("explicit-collection", true); } public double getTopRegrowthScalingFactor() { - return getDoubleProperty("top-rate", 0.02); + return getDoubleProperty("top-rate", 0.02); } - + public double getBottomRegrowthScalingFactor() { return getDoubleProperty("bottom-rate", 0.01); } - + public double getTopInitialResourceDistribution() { return getDoubleProperty("top-initial-distribution", 0.50); } - + public double getBottomInitialResourceDistribution() { return getDoubleProperty("bottom-initial-distribution", 0.25); } @@ -403,11 +413,11 @@ public String getResourceGeneratorType() { return getProperty("resource-generator", "density-dependent"); } - + public int getWorldWidth() { return getResourceWidth() * getResourceWorldScale(); } - + public int getWorldDepth() { return getResourceDepth() * getResourceWorldScale(); } @@ -415,54 +425,54 @@ public int getResourceWorldScale() { return getIntProperty("resource-scale", 32); } - - //Should always return true for 3d experiments + + // Should always return true for 3d experiments public boolean isChatEnabled() { - return ! isPrivateProperty() && (getBooleanProperty("chat-enabled") || isInRoundChatEnabled()); + return getBooleanProperty("chat-enabled") || isInRoundChatEnabled(); } - + public int getMaximumResourceAge() { return getIntProperty("maximum-resource-age", 10); } - + public int getChattingRadius() { return getIntProperty("chat-radius", 50); } - + public int getResourceAgingSecondsPerYear() { return getIntProperty("seconds-per-year", 10); } - + public Point3D getTopLeftCornerCoordinate() { float zExtend = getWorldWidth() / 2.0f; float xExtend = getWorldDepth() / 2.0f; return new Point3D(-xExtend, 0, -zExtend); } - + public int ageToTokens(int resourceAge) { switch (resourceAge) { - case 0: - return 0; - case 1: - return 1; - case 2: - return 2; - case 3: - return 6; - case 4: - return 9; - case 5: - return 15; - case 6: - return 20; - case 7: - return 23; - case 8: - default: - return 25; + case 0: + return 0; + case 1: + return 1; + case 2: + return 2; + case 3: + return 6; + case 4: + return 9; + case 5: + return 15; + case 6: + return 20; + case 7: + return 23; + case 8: + default: + return 25; } } - + public int getTokensPerFruits() { return getIntProperty("tokens-per-fruits", 4); } @@ -470,9 +480,9 @@ public int getFruitHarvestDelay() { return getIntProperty("fruit-harvest-delay", 20); } - + public ExperimentType getExperimentType() { - return ExperimentType.find( getStringProperty("experiment-type", "2d") ); + return ExperimentType.find(getStringProperty("experiment-type", "2d")); } public boolean is2dExperiment() { @@ -480,66 +490,66 @@ } public boolean is3dExperiment() { - return ! is2dExperiment(); + return !is2dExperiment(); } - + public String getWelcomeInstructions() { return getParentConfiguration().getWelcomeInstructions(); } - + public String getGeneralInstructions() { return getParentConfiguration().getGeneralInstructions(); } - + public String getFieldOfVisionInstructions() { return getParentConfiguration().getFieldOfVisionInstructions(); } - + public EnforcementMechanism[] getEnforcementMechanisms() { return EnforcementMechanism.values(); } - + public boolean isRotatingMonitorEnabled() { - return getBooleanProperty("rotating-monitor-enabled", false); + return getBooleanProperty("rotating-monitor-enabled", false); } - + public boolean isVotingAndRegulationEnabled() { return getBooleanProperty("voting-and-regulation-enabled", false); } - + public boolean isFieldOfVisionEnabled() { return isTokensFieldOfVisionEnabled() || isSubjectsFieldOfVisionEnabled(); } - + public boolean isCensoredChat() { return getBooleanProperty("censored-chat-enabled", false); } - + public boolean isTrustGameEnabled() { return getBooleanProperty("trust-game", true); } - + public boolean isInRoundChatEnabled() { return getBooleanProperty("in-round-chat-enabled", false); } - + public String getCensoredChatInstructions() { - return getProperty("censored-chat-instructions", + return getProperty("censored-chat-instructions", "Your messages must be approved before they will be relayed to the rest of your group."); } - + public int getNumberOfChatsPerSecond() { return getIntProperty("chats-per-second", 5); } - + public int getDelayBetweenChats() { return getIntProperty("delay-between-chats", 0); } - + public StringBuilder getCurrentRoundInstructions() { return buildInstructions(new StringBuilder()); } - + /** * The preferred method of building instructions within the foraging experiment. * @@ -547,7 +557,7 @@ * to this {@link #RoundConfiguration()}. * * For example, if the field of vision is enabled, will append the field of vision instructions, - * if censored chat is enabled, then it will aadd the censored chat instructions, if the + * if censored chat is enabled, then it will aadd the censored chat instructions, if the * chat is enabled, will append the chat instructions. * * @param instructionsBuilder @@ -558,44 +568,48 @@ instructionsBuilder.append(getGeneralInstructions()); } instructionsBuilder.append(getInstructions()); - if (isFieldOfVisionEnabled()) { - addSpecialInstructions(instructionsBuilder,getFieldOfVisionInstructions()); - } - if (isCensoredChat()) { - addSpecialInstructions(instructionsBuilder,getCensoredChatInstructions()); - } - else if (isInRoundChatEnabled()) { - addSpecialInstructions(instructionsBuilder,getInRoundChatInstructions()); - } - else if (isChatEnabled()) { - // FIXME: hard-coded, need to make instructions template-able, perhaps - // via FreeMarker or Velocity. - addSpecialInstructions(instructionsBuilder, - "Before the beginning of this round you will be able to chat with the other members of your group for " + getChatDuration() + " seconds."); - } - String resourceGeneratorType = getResourceGeneratorType(); - if (resourceGeneratorType.equals("mobile")) { - addSpecialInstructions(instructionsBuilder,getMobileResourceInstructions()); - } - else if (resourceGeneratorType.equals("top-bottom-patchy")) { - addSpecialInstructions(instructionsBuilder,getPatchyResourceInstructions()); - } - + addAllSpecialInstructions(instructionsBuilder); // and add the quiz instructions if the quiz is enabled. if (isQuizEnabled()) { instructionsBuilder.append(getQuizInstructions()); } return instructionsBuilder; } - + + public StringBuilder addAllSpecialInstructions(StringBuilder builder) { + if (isFieldOfVisionEnabled()) { + addSpecialInstructions(builder, getFieldOfVisionInstructions()); + } + if (isCensoredChat()) { + addSpecialInstructions(builder, getCensoredChatInstructions()); + } + else if (isInRoundChatEnabled()) { + addSpecialInstructions(builder, getInRoundChatInstructions()); + } + else if (isChatEnabled()) { + // FIXME: hard-coded, need to make instructions template-able, perhaps + // via FreeMarker or Velocity. + addSpecialInstructions(builder, + "Before the beginning of this round you will be able to chat with the other members of your group for " + getChatDuration() + " seconds."); + } + String resourceGeneratorType = getResourceGeneratorType(); + if (resourceGeneratorType.equals("mobile")) { + addSpecialInstructions(builder, getMobileResourceInstructions()); + } + else if (resourceGeneratorType.equals("top-bottom-patchy")) { + addSpecialInstructions(builder, getPatchyResourceInstructions()); + } + return builder; + } + private void addSpecialInstructions(StringBuilder builder, String instructions) { builder.append("<p>").append(instructions).append("</p>"); } - + private String getMobileResourceInstructions() { return getProperty("mobile-resource-instructions", "<p>The resource can move around in a semblance of free will / agency.</p>"); } - + private String getPatchyResourceInstructions() { return getProperty("patch-resource-instructiosn", "<p>The resource is not uniformly distributed. There are patches of high growth and low growth.</p>"); } --- a/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 01 14:37:13 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 01 14:53:56 2011 -0700 @@ -298,7 +298,7 @@ addEventProcessor(new EventTypeProcessor<QuizResponseEvent>(QuizResponseEvent.class) { public void handle(final QuizResponseEvent event) { - logger.debug("Received quiz response: " + event); + logger.info("Received quiz response: " + event); numberOfSubmittedQuizzes++; transmit(new QuizCompletedEvent(facilitatorId)); ClientData clientData = clients.get(event.getId()); @@ -685,6 +685,7 @@ if (iter.hasNext()) { playerTwo = iter.next(); } + logger.info(String.format("Pairing %s with %s for trust game", playerOne, playerTwo)); serverDataModel.calculateTrustGame(playerOne, playerTwo); } Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 21:36:43
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/5b4a1cadfd82/ changeset: 5b4a1cadfd82 user: alllee date: 2011-09-01 23:37:13 summary: minor cleanup to facilitator, fixes issue 10 and fixing an off-by-one bug in getNumberOfCorrectAnswers affected #: 5 files (709 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java Thu Sep 01 14:21:01 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/ChatPanel.java Thu Sep 01 14:37:13 2011 -0700 @@ -54,6 +54,8 @@ private ForagingClient client; + private boolean inRoundChat = false; + public ChatPanel(ForagingClient client) { this.client = client; this.clientId = client.getId(); @@ -86,12 +88,6 @@ } } }); - final JButton sendButton = new JButton("Send"); - sendButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - sendMessage(); - } - }); JPanel targetHandlePanel = new JPanel(); targetHandlePanel.setLayout(new BoxLayout(targetHandlePanel, BoxLayout.LINE_AXIS)); targetHandleLabel = new JLabel("everyone"); @@ -102,7 +98,6 @@ add(targetHandlePanel, BorderLayout.NORTH); add(chatField, BorderLayout.CENTER); -// add(sendButton, BorderLayout.SOUTH); setChatFieldFocus(); } @@ -116,8 +111,13 @@ if (message == null || "".equals(message) || targetIdentifier == null) { return; } - client.transmit(new ChatRequest(clientId, message, targetIdentifier)); - chatField.requestFocusInWindow(); + client.transmit(new ChatRequest(clientId, message, targetIdentifier)); + if (inRoundChat) { + getParent().requestFocusInWindow(); + } + else { + chatField.requestFocusInWindow(); + } chatField.setText(""); } @@ -276,7 +276,8 @@ } } - public void initialize() { + public void initialize(boolean inRoundChat) { + this.inRoundChat = inRoundChat; if (HANDLES != null) { displayMessage("System message", " --- Round ended --- "); return; --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:21:01 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:37:13 2011 -0700 @@ -575,7 +575,7 @@ update(configuration.getRoundDuration().getTimeLeft()); if (configuration.isInRoundChatEnabled()) { ChatPanel chatPanel = getChatPanel(); - chatPanel.initialize(); + chatPanel.initialize(true); Dimension chatPanelSize = new Dimension(250, getPanel().getSize().height); chatPanel.setPreferredSize(chatPanelSize); // FIXME: switch to different layout manager @@ -641,13 +641,13 @@ "<ul>" + "<li>Tokens collected: %d</li>" + "<li>Income: $%3.2f</li>" + - "<li>Quiz questions answered correctly: %d (%3.2f)</li>" + + "<li>Quiz questions answered correctly: %d (adds $%3.2f to your total)</li>" + "</ul>", event.getCurrentTokens(), getIncome(event.getCurrentTokens()), correctQuizAnswers, quizReward) ); double showUpPayment = dataModel.getRoundConfiguration().getParentConfiguration().getShowUpPayment(); instructionsBuilder.append(String.format("Your <b>total income</b> so far (including a $%3.2f bonus for showing up) is : $%3.2f<hr>", - showUpPayment, dataModel.getTotalIncome() + showUpPayment)); + showUpPayment, dataModel.getTotalIncome() + showUpPayment + quizReward)); if (event.isLastRound()) { for (String trustGameLog : event.getTrustGameLog()) { @@ -798,7 +798,7 @@ SwingUtilities.invokeLater(new Runnable() { public void run() { ChatPanel chatPanel = getChatPanel(); - chatPanel.initialize(); + chatPanel.initialize(false); showPanel(CHAT_PANEL_NAME); startChatTimer(); } --- a/src/main/java/edu/asu/commons/foraging/event/QuizResponseEvent.java Thu Sep 01 14:21:01 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/event/QuizResponseEvent.java Thu Sep 01 14:37:13 2011 -0700 @@ -44,7 +44,8 @@ } public int getNumberOfCorrectAnswers() { - int correctAnswers = responses.size() - incorrectAnswers.size(); + // FIXME: kludgy - responses is always off by one as it also contains the input submit button. + int correctAnswers = (responses.size() - 1) - incorrectAnswers.size(); if (correctAnswers < 0) { // FIXME: replace with proper logging? System.err.println("Somehow the number of responses was less than the number of incorrect answers: " --- a/src/main/java/edu/asu/commons/foraging/facilitator/FacilitatorWindow.java Thu Sep 01 14:21:01 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/facilitator/FacilitatorWindow.java Thu Sep 01 14:37:13 2011 -0700 @@ -59,10 +59,6 @@ private int viewSpacing = 50; - private JMenuItem startExperimentMenuItem; - - private JMenuItem stopExperimentMenuItem; - private JMenuItem showInstructionsMenuItem; private JMenuItem startRoundMenuItem; @@ -113,8 +109,6 @@ showInstructionsMenuItem.setEnabled(false); startRoundMenuItem.setEnabled(false); stopRoundMenuItem.setEnabled(true); - startExperimentMenuItem.setEnabled(false); - stopExperimentMenuItem.setEnabled(true); // initViewPanel(); // repaint(); } @@ -305,8 +299,6 @@ } public void updateMenuItems() { - startExperimentMenuItem.setEnabled(true); - stopExperimentMenuItem.setEnabled(false); startRoundMenuItem.setEnabled(false); showInstructionsMenuItem.setEnabled(false); } @@ -387,8 +379,6 @@ loadExperimentMenuItem.setEnabled(true); //Disable all other menus - startExperimentMenuItem.setEnabled(false); - stopExperimentMenuItem.setEnabled(false); startRoundMenuItem.setEnabled(false); stopRoundMenuItem.setEnabled(false); } --- a/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 01 14:21:01 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 01 14:37:13 2011 -0700 @@ -298,6 +298,7 @@ addEventProcessor(new EventTypeProcessor<QuizResponseEvent>(QuizResponseEvent.class) { public void handle(final QuizResponseEvent event) { + logger.debug("Received quiz response: " + event); numberOfSubmittedQuizzes++; transmit(new QuizCompletedEvent(facilitatorId)); ClientData clientData = clients.get(event.getId()); Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 21:20:30
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/32a91b64094d/ changeset: 32a91b64094d user: alllee date: 2011-09-01 23:21:01 summary: fixes issue 6 by changing the instructions JScrollPane ScrollMode to BACKINGSTORE_SCROLL_MODE instead of the default BLIT_SCROLL_MODE affected #: 2 files (1.5 KB) --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:12:16 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:21:01 2011 -0700 @@ -30,6 +30,7 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextPane; +import javax.swing.JViewport; import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.text.Style; @@ -326,7 +327,7 @@ } private void setInstructions(String s) { - System.err.println("Setting instructions to " + s); +// System.err.println("Setting instructions to " + s); instructionsEditorPane.setText(s); instructionsEditorPane.repaint(); getPanel().repaint(); @@ -355,6 +356,7 @@ instructionsEditorPane = createInstructionsEditorPane(); instructionsScrollPane = new JScrollPane(instructionsEditorPane); instructionsScrollPane.setDoubleBuffered(true); + instructionsScrollPane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE); instructionsScrollPane.setName(INSTRUCTIONS_PANEL_NAME); add(instructionsScrollPane); --- a/src/main/java/edu/asu/commons/foraging/facilitator/FacilitatorWindow.java Thu Sep 01 14:12:16 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/facilitator/FacilitatorWindow.java Thu Sep 01 14:21:01 2011 -0700 @@ -120,36 +120,9 @@ } private JMenuBar createMenu() { - JMenu menu = new JMenu("Experiment"); menuBar = new JMenuBar(); - - menu.setMnemonic(KeyEvent.VK_E); - - startExperimentMenuItem = new JMenuItem("Start"); - startExperimentMenuItem.setMnemonic(KeyEvent.VK_S); - startExperimentMenuItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - facilitator.sendBeginExperimentRequest(); - } - }); - menu.add(startExperimentMenuItem); - - stopExperimentMenuItem = new JMenuItem("Stop"); - stopExperimentMenuItem.setMnemonic(KeyEvent.VK_O); - stopExperimentMenuItem.setEnabled(false); - stopExperimentMenuItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - throw new UnsupportedOperationException("FIXME: Cannot stop experiments right now"); -// facilitator.sendStopExperimentRequest(); - //loadConfigurationMenu.setEnabled(true); -// displayInstructions(); - } - }); - menu.add(stopExperimentMenuItem); - menuBar.add(menu); - //Round menu - menu = new JMenu("Round"); + JMenu menu = new JMenu("Round"); menu.setMnemonic(KeyEvent.VK_R); startChatMenuItem = new JMenuItem("Start chat"); @@ -208,19 +181,10 @@ menuItem.setMnemonic(KeyEvent.VK_L); menuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - new ConfigurationDialog(facilitator, (facilitator - .isExperimentRunning() || facilitator.isReplaying())); + new ConfigurationDialog(facilitator, (facilitator.isExperimentRunning() || facilitator.isReplaying())); } }); menu.add(menuItem); - - /* JMenuItem treatment = new JMenuItem("Treatment"); - treatmnet.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - new - } - })*/ - menuBar.add(menu); return menuBar; Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 21:11:47
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/d9f7b7155ba2/ changeset: d9f7b7155ba2 user: alllee date: 2011-09-01 23:12:16 summary: adding quiz payments to debriefing affected #: 2 files (642 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:05:21 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:12:16 2011 -0700 @@ -1,6 +1,5 @@ package edu.asu.commons.foraging.client; - import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; @@ -56,9 +55,6 @@ import edu.asu.commons.util.Duration; import edu.asu.commons.util.HtmlEditorPane; - - - /** * $Id: GameWindow2D.java 529 2010-08-17 00:08:01Z alllee $ * @@ -71,7 +67,7 @@ public class GameWindow2D implements GameWindow { private final ClientDataModel dataModel; - + private final static String INSTRUCTIONS_PANEL_NAME = "Foraging instructions panel"; private final static String GAME_PANEL_NAME = "Game panel"; private final static String TRUST_GAME_PANEL_NAME = "Trust game panel"; @@ -79,14 +75,14 @@ private final static String CHAT_PANEL_NAME = "Chat panel"; protected static final String POST_ROUND_SANCTIONING_PANEL_NAME = null; - + private String currentCardPanel = INSTRUCTIONS_PANEL_NAME; - -// private Component currentCenterComponent; - + + // private Component currentCenterComponent; + private JPanel mainPanel; - - // instructions components. + + // instructions components. private JScrollPane instructionsScrollPane; private HtmlEditorPane instructionsEditorPane; @@ -111,7 +107,7 @@ private SubjectView subjectView; - public Timer timer; + public Timer timer; private final StringBuilder instructionsBuilder = new StringBuilder(); @@ -124,18 +120,18 @@ public GameWindow2D(ForagingClient client, Dimension size) { this.client = client; this.dataModel = client.getDataModel(); - // FIXME: set the actual screen size dimensions after this JPanel has been initialized... + // FIXME: set the actual screen size dimensions after this JPanel has been initialized... this.channel = client.getEventChannel(); // feed subject view the available screen size so that // it can adjust appropriately when given a board size -// int width = (int) Math.min(Math.floor(size.getWidth()), Math.floor(size.getHeight() * 0.85)); + // int width = (int) Math.min(Math.floor(size.getWidth()), Math.floor(size.getHeight() * 0.85)); initGuiComponents(size); } /** * Instead of invoking specific update methods we invoke just a single - * method, update() after we're done changing state. + * method, update() after we're done changing state. */ public void update(final long roundTimeLeft) { SwingUtilities.invokeLater(new Runnable() { @@ -143,15 +139,16 @@ informationLabel.setText(getInformationLabelText()); timeLeftLabel.setText(getTimeLeftLabelText(roundTimeLeft)); // FIXME: subjectView.repaint() causes graphical glitches here - // only when we transition from 3D -> 2D experiment. Find out why. + // only when we transition from 3D -> 2D experiment. Find out why. subjectView.repaint(); } }); } - /** - * In certain cases, init() _can_ be called before endRound() is finished. Need to lock + /** + * In certain cases, init() _can_ be called before endRound() is finished. Need to lock * access! + * * @param event */ public void init() { @@ -167,7 +164,6 @@ // EndRoundEvent. } - private void setQuestionColors(List<String> questionNumbers, String color) { HTMLEditorKit editorKit = (HTMLEditorKit) instructionsEditorPane.getEditorKit(); StyleSheet styleSheet = editorKit.getStyleSheet(); @@ -190,7 +186,7 @@ for (Map.Entry<String, String> entry : quizAnswers.entrySet()) { String questionNumber = entry.getKey(); String expectedAnswer = entry.getValue(); - if (expectedAnswer.equals(actualAnswers.getProperty(questionNumber)) ) { + if (expectedAnswer.equals(actualAnswers.getProperty(questionNumber))) { correctAnswers.add(questionNumber); } else { @@ -198,7 +194,7 @@ incorrectAnswers.add(questionNumber); } } - + client.transmit(new QuizResponseEvent(client.getId(), actualAnswers, incorrectAnswers)); StringBuilder builder = new StringBuilder(); setQuestionColors(correctAnswers, "black"); @@ -220,24 +216,24 @@ HTMLEditorKit editorKit = (HTMLEditorKit) instructionsEditorPane.getEditorKit(); StyleSheet styleSheet = editorKit.getStyleSheet(); StringBuilder correctString = new StringBuilder(); - if (! correctAnswers.isEmpty()) { + if (!correctAnswers.isEmpty()) { correctString.append("<h3>Correctly answered questions</h3><ul>"); // FIXME: extract style modifications to method for (String correctQuestionNumber : correctAnswers) { String styleString = String.format(".%s { color: black; }", correctQuestionNumber); styleSheet.addRule(styleString); - correctString.append(String.format("<li>Your answer [ %s ] was correct for question %s.", - actualAnswers.get(correctQuestionNumber), - correctQuestionNumber)); + correctString.append(String.format("<li>Your answer [ %s ] was correct for question %s.", + actualAnswers.get(correctQuestionNumber), + correctQuestionNumber)); } correctString.append("</ul>"); } - + correctString.append("<h3>Incorrectly answered questions</h3><ul>"); for (String incorrectQuestionNumber : incorrectAnswers) { String styleString = String.format(".%s { color: red; }", incorrectQuestionNumber); styleSheet.addRule(styleString); - correctString.append(String.format("<li>Your answer [ %s ] was incorrect for question %s. The correct answer was [ %s ]. %s", + correctString.append(String.format("<li>Your answer [ %s ] was incorrect for question %s. The correct answer was [ %s ]. %s", actualAnswers.get(incorrectQuestionNumber), incorrectQuestionNumber, quizAnswers.get(incorrectQuestionNumber), @@ -251,7 +247,7 @@ } }; } - + /** * Invoked when a subject collected a token at Point p. * @@ -263,7 +259,7 @@ private void startChatTimer() { if (timer == null) { - final RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); + final RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); final Duration duration = Duration.create(roundConfiguration.getChatDuration()); timer = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent event) { @@ -273,7 +269,7 @@ timer = null; } else { - timeLeftLabel.setText( String.format("Chat will end in %d seconds.", duration.getTimeLeft() / 1000L) ); + timeLeftLabel.setText(String.format("Chat will end in %d seconds.", duration.getTimeLeft() / 1000L)); } } }); @@ -287,31 +283,31 @@ // XXX: use this method so that we get the proper ordering of client ids/assigned numbers.. Map<Identifier, ClientData> clientDataMap = dataModel.getClientDataMap(); Point clientPosition = dataModel.getCurrentPosition(); - - for (Identifier id: dataModel.getAllClientIdentifiers()) { + + for (Identifier id : dataModel.getAllClientIdentifiers()) { ClientData clientData = clientDataMap.get(id); String formatString = ""; if (id.equals(dataModel.getId())) { formatString = " [%d (you) : %d] "; - builder.append(String.format(formatString, clientData.getAssignedNumber(), clientData.getCurrentTokens())); + builder.append(String.format(formatString, clientData.getAssignedNumber(), clientData.getCurrentTokens())); } - else { - if(!dataModel.getRoundConfiguration().isFieldOfVisionEnabled()){ - formatString = " [%d : %d] "; - builder.append(String.format(formatString, clientData.getAssignedNumber(), clientData.getCurrentTokens())); - } - else { - double radius = dataModel.getRoundConfiguration().getViewSubjectsRadius(); - Circle fieldOfVision = new Circle(clientPosition, radius); - if(fieldOfVision.contains(clientData.getPosition())) { - formatString = " [%d : %d] "; - builder.append(String.format(formatString, clientData.getAssignedNumber(), clientData.getCurrentTokens())); - } - else { - formatString = " [%d : XX] "; - builder.append(String.format(formatString, clientData.getAssignedNumber())); - } - } + else { + if (!dataModel.getRoundConfiguration().isFieldOfVisionEnabled()) { + formatString = " [%d : %d] "; + builder.append(String.format(formatString, clientData.getAssignedNumber(), clientData.getCurrentTokens())); + } + else { + double radius = dataModel.getRoundConfiguration().getViewSubjectsRadius(); + Circle fieldOfVision = new Circle(clientPosition, radius); + if (fieldOfVision.contains(clientData.getPosition())) { + formatString = " [%d : %d] "; + builder.append(String.format(formatString, clientData.getAssignedNumber(), clientData.getCurrentTokens())); + } + else { + formatString = " [%d : XX] "; + builder.append(String.format(formatString, clientData.getAssignedNumber())); + } + } } } return builder.toString(); @@ -338,7 +334,7 @@ private HtmlEditorPane createInstructionsEditorPane() { // JEditorPane pane = new JEditorPane("text/html", - // "Costly Sanctioning Experiment"); + // "Costly Sanctioning Experiment"); final HtmlEditorPane htmlPane = new HtmlEditorPane(); htmlPane.setEditable(false); htmlPane.setDoubleBuffered(true); @@ -351,8 +347,8 @@ // FIXME: replace with CardLayout for easier switching between panels cardLayout = new CardLayout(); mainPanel = new JPanel(cardLayout); - - Dimension subjectViewSize = new Dimension((int) size.getWidth(), (int) (size.getHeight() * 0.85)); + + Dimension subjectViewSize = new Dimension((int) size.getWidth(), (int) (size.getHeight() * 0.85)); subjectView = new SubjectView(subjectViewSize, dataModel); // add instructions panel card @@ -375,7 +371,7 @@ // latencyLabel = new JLabel("Latency: 0"); informationLabel.setBackground(Color.YELLOW); informationLabel.setForeground(Color.BLUE); - + labelPanel = new JPanel(); labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.LINE_AXIS)); labelPanel.setBackground(Color.WHITE); @@ -386,7 +382,7 @@ // add message window. messagePanel = new JPanel(new BorderLayout()); - // messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); + // messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); messagePanel.add(new JLabel("Messages"), BorderLayout.NORTH); messageTextPane = new JTextPane(); messageTextPane.setEditable(false); @@ -394,16 +390,16 @@ messageTextPane.setBackground(Color.WHITE); addStyles(messageTextPane.getStyledDocument()); messageScrollPane = new JScrollPane(messageTextPane); -// Dimension scrollPaneSize = new Dimension(getPreferredSize().width, 50); -// messageScrollPane.setMinimumSize(scrollPaneSize); -// messageScrollPane.setPreferredSize(scrollPaneSize); -// messageScrollPane.setMaximumSize(scrollPaneSize); + // Dimension scrollPaneSize = new Dimension(getPreferredSize().width, 50); + // messageScrollPane.setMinimumSize(scrollPaneSize); + // messageScrollPane.setPreferredSize(scrollPaneSize); + // messageScrollPane.setMaximumSize(scrollPaneSize); messagePanel.add(messageScrollPane, BorderLayout.CENTER); gamePanel.add(messagePanel, BorderLayout.SOUTH); - + add(gamePanel); - - mainPanel.addKeyListener( createGameWindowKeyListener() ); + + mainPanel.addKeyListener(createGameWindowKeyListener()); mainPanel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { mainPanel.requestFocusInWindow(); @@ -426,12 +422,14 @@ } /** - * IMPORTANT: this method handles client keyboard inputs within the game. + * IMPORTANT: this method handles client keyboard inputs within the game. + * * @return */ private KeyAdapter createGameWindowKeyListener() { return new KeyAdapter() { private volatile boolean keyReleased; + // FIXME: the keyReleased/keyPressed stuff here only seems to work on Windows. // Linux keyboards generate pairs of keyPressed/keyReleased events in tandem even // when you are keeping the key down the whole time! @@ -439,6 +437,7 @@ public void keyReleased(KeyEvent keyEvent) { keyReleased = true; } + // FIXME: refactor this method if possible. @Override public void keyPressed(KeyEvent keyEvent) { @@ -451,78 +450,85 @@ // check to see if the key is something else. switch (keyCode) { // token request handling - case KeyEvent.VK_SPACE: - if(dataModel.isHarvestingAllowed()) { - event = new CollectTokenRequest(client.getId()); - } - else { - displayErrorMessage("You cannot harvest at this time."); - } - break; + case KeyEvent.VK_SPACE: + if (dataModel.isHarvestingAllowed()) { + event = new CollectTokenRequest(client.getId()); + } + else { + displayErrorMessage("You cannot harvest at this time."); + } + break; // real-time sanctioning keycode handling - case KeyEvent.VK_1: case KeyEvent.VK_2: case KeyEvent.VK_3: - case KeyEvent.VK_4: case KeyEvent.VK_5: case KeyEvent.VK_6: - case KeyEvent.VK_7: case KeyEvent.VK_8: case KeyEvent.VK_9: - if (! dataModel.isSanctioningAllowed()) { - // get rid of magic constants - displayErrorMessage("You may not reduce other participants tokens at this time."); - return; - } - if (client.canPerformRealTimeSanction()) { - //System.out.println("Can do sanctioning"); - int assignedNumber = keyChar - 48; - Identifier sanctionee = dataModel.getClientId(assignedNumber); - if (sanctionee == null || sanctionee.equals(dataModel.getId())) { - // don't allow self-flagellation :-). + case KeyEvent.VK_1: + case KeyEvent.VK_2: + case KeyEvent.VK_3: + case KeyEvent.VK_4: + case KeyEvent.VK_5: + case KeyEvent.VK_6: + case KeyEvent.VK_7: + case KeyEvent.VK_8: + case KeyEvent.VK_9: + if (!dataModel.isSanctioningAllowed()) { + // get rid of magic constants + displayErrorMessage("You may not reduce other participants tokens at this time."); return; } - // only allow sanctions for subjects within this subject's field of vision - Point subjectPosition = dataModel.getClientDataMap().get(sanctionee).getPoint(); - if (dataModel.getClientData().isSubjectInFieldOfVision(subjectPosition)) { - // System.out.println("sanctioning event sent"); - event = new RealTimeSanctionRequest(dataModel.getId(), sanctionee); - // below function must be used for enforcement type4 -// dataModel.sanction(dataModel.getId(), sanctionee); - } - else { - displayErrorMessage("The participant is out of range."); + if (client.canPerformRealTimeSanction()) { + // System.out.println("Can do sanctioning"); + int assignedNumber = keyChar - 48; + Identifier sanctionee = dataModel.getClientId(assignedNumber); + if (sanctionee == null || sanctionee.equals(dataModel.getId())) { + // don't allow self-flagellation :-). + return; + } + // only allow sanctions for subjects within this subject's field of vision + Point subjectPosition = dataModel.getClientDataMap().get(sanctionee).getPoint(); + if (dataModel.getClientData().isSubjectInFieldOfVision(subjectPosition)) { + // System.out.println("sanctioning event sent"); + event = new RealTimeSanctionRequest(dataModel.getId(), sanctionee); + // below function must be used for enforcement type4 + // dataModel.sanction(dataModel.getId(), sanctionee); + } + else { + displayErrorMessage("The participant is out of range."); + return; + } + } + break; + // reset token distribution request handling + case KeyEvent.VK_ENTER: + if (dataModel.getRoundConfiguration().isInRoundChatEnabled()) { + getChatPanel().setTextFieldFocus(); + } + case KeyEvent.VK_R: + if (canResetTokenDistribution()) { + event = new ResetTokenDistributionRequest(client.getId()); + } + else return; + break; + case KeyEvent.VK_M: + if (!dataModel.getRoundConfiguration().isAlwaysInExplicitCollectionMode()) { + dataModel.toggleExplicitCollectionMode(); } - } - break; - // reset token distribution request handling - case KeyEvent.VK_ENTER: - if (dataModel.getRoundConfiguration().isInRoundChatEnabled()) { - getChatPanel().setTextFieldFocus(); - } - case KeyEvent.VK_R: - if (canResetTokenDistribution()) { - event = new ResetTokenDistributionRequest(client.getId()); - } - else return; - break; - case KeyEvent.VK_M: - if (! dataModel.getRoundConfiguration().isAlwaysInExplicitCollectionMode()) { - dataModel.toggleExplicitCollectionMode(); - } - return; - default: - System.err.println("Invalid input:" + KeyEvent.getKeyText(keyCode)); + return; + default: + System.err.println("Invalid input:" + KeyEvent.getKeyText(keyCode)); } } else { event = new ClientMovementRequest(client.getId(), direction); // move the client directly, this may get overridden later by a client update. /* - if (dataModel.getRoundConfiguration().isAlwaysInExplicitCollectionMode()) { - Point newPosition = direction.apply(dataModel.getCurrentPosition()); - dataModel.getClientData().setPosition(newPosition); - subjectView.repaint(); - } + * if (dataModel.getRoundConfiguration().isAlwaysInExplicitCollectionMode()) { + * Point newPosition = direction.apply(dataModel.getCurrentPosition()); + * dataModel.getClientData().setPosition(newPosition); + * subjectView.repaint(); + * } */ } if (keyReleased) { - // FIXME: have client directly render these requests? Would + // FIXME: have client directly render these requests? Would // make the app more "responsive" and less tied to server latency. channel.handle(event); keyReleased = false; @@ -537,17 +543,17 @@ return configuration.isPracticeRound() && configuration.isPrivateProperty(); } -// public void addCenterComponent(Component newCenterComponent) { -// if (currentCenterComponent != null) { -// currentCenterComponent.setVisible(false); -// getPanel().remove(currentCenterComponent); -// getPanel().add(newCenterComponent, BorderLayout.CENTER); -// newCenterComponent.setVisible(true); -// } -// currentCenterComponent = newCenterComponent; -// getPanel().revalidate(); -// getPanel().repaint(); -// } + // public void addCenterComponent(Component newCenterComponent) { + // if (currentCenterComponent != null) { + // currentCenterComponent.setVisible(false); + // getPanel().remove(currentCenterComponent); + // getPanel().add(newCenterComponent, BorderLayout.CENTER); + // newCenterComponent.setVisible(true); + // } + // currentCenterComponent = newCenterComponent; + // getPanel().revalidate(); + // getPanel().repaint(); + // } public void startRound() { final RoundConfiguration configuration = dataModel.getRoundConfiguration(); @@ -578,27 +584,27 @@ }; SwingUtilities.invokeLater(runnable); } - + public void displayErrorMessage(String errorMessage) { - displayMessage(errorMessage, Color.RED); + displayMessage(errorMessage, Color.RED); } - + public void displayMessage(String message) { - displayMessage(message, Color.BLACK); + displayMessage(message, Color.BLACK); } public void displayMessage(String errorMessage, Color color) { - // String chatHandle = getChatHandle(source); -// messageTextPane.setForeground(color); -// StyledDocument document = messageTextPane.getStyledDocument(); -// try { -// document.insertString(document.getLength(), errorMessage + "\n", document.getStyle("bold")); -// messageTextPane.setCaretPosition(document.getLength()); -// } -// catch (BadLocationException e) { -// e.printStackTrace(); -// throw new RuntimeException(e); -// } + // String chatHandle = getChatHandle(source); + // messageTextPane.setForeground(color); + // StyledDocument document = messageTextPane.getStyledDocument(); + // try { + // document.insertString(document.getLength(), errorMessage + "\n", document.getStyle("bold")); + // messageTextPane.setCaretPosition(document.getLength()); + // } + // catch (BadLocationException e) { + // e.printStackTrace(); + // throw new RuntimeException(e); + // } } // FIXME: add to some common GUI package? @@ -616,7 +622,6 @@ .addStyle("italic", defaultStyle), true); } - private double getIncome(float numTokens) { if (dataModel.getRoundConfiguration().isPracticeRound()) { return 0.0f; @@ -626,23 +631,26 @@ private void addDebriefingText(EndRoundEvent event) { instructionsBuilder.delete(0, instructionsBuilder.length()); + // FIXME: should be round-specific? We're not resetting correct quiz answers either. + int correctQuizAnswers = event.getClientData().getCorrectQuizAnswers(); + double quizReward = correctQuizAnswers * dataModel.getRoundConfiguration().getQuizCorrectAnswerReward(); instructionsBuilder.append( String.format("<h3>Your stats in this round:</h3>" + "<ul>" + "<li>Tokens collected: %d</li>" + "<li>Income: $%3.2f</li>" + - "</ul>", - event.getCurrentTokens(), - getIncome(event.getCurrentTokens())) - ); - double showUpFee = dataModel.getRoundConfiguration().getParentConfiguration().getShowUpPayment(); + "<li>Quiz questions answered correctly: %d (%3.2f)</li>" + + "</ul>", + event.getCurrentTokens(), getIncome(event.getCurrentTokens()), correctQuizAnswers, quizReward) + ); + double showUpPayment = dataModel.getRoundConfiguration().getParentConfiguration().getShowUpPayment(); instructionsBuilder.append(String.format("Your <b>total income</b> so far (including a $%3.2f bonus for showing up) is : $%3.2f<hr>", - showUpFee, dataModel.getTotalIncome() + showUpFee)); - for (String trustGameLog: event.getTrustGameLog()) { - instructionsBuilder.append(trustGameLog); - } - + showUpPayment, dataModel.getTotalIncome() + showUpPayment)); + if (event.isLastRound()) { + for (String trustGameLog : event.getTrustGameLog()) { + instructionsBuilder.append(trustGameLog); + } instructionsBuilder.append(client.getDataModel().getRoundConfiguration().getLastRoundDebriefing()); timeLeftLabel.setText("The experiment is now over."); } @@ -657,7 +665,7 @@ instructionsBuilder.append( String.format("<h3>Your statistics from the last round have been updated as follows:</h3>" + "<ul>" + - "<li>Tokens collected last round: %d</li>" + + "<li>Tokens collected last round: %d</li>" + "<li>Tokens subtracted by other players: %d</li>" + "<li>Tokens used to subtract tokens from other players: %d</li>" + "<li>Net earned tokens in the last round: %d</li>" + @@ -668,7 +676,7 @@ clientData.getSanctionCosts(), clientData.getCurrentTokens(), getIncome(clientData.getCurrentTokens())) - ); + ); instructionsBuilder.append(String.format("Your <b>total income</b> so far is: $%3.2f<hr>", getIncome(clientData.getTotalTokens()))); if (event.isLastRound()) { @@ -698,15 +706,15 @@ JScrollPane scrollPane = new JScrollPane(trustGameInstructionsEditorPane); trustGameInstructionsEditorPane.setText(client.getCurrentRoundConfiguration().getTrustGameInstructions()); panel.add(scrollPane); - + TrustGamePanel trustGamePanel = new TrustGamePanel(client); -// trustGamePanel.setPreferredSize(new Dimension(300, 400)); + // trustGamePanel.setPreferredSize(new Dimension(300, 400)); JScrollPane trustGameScrollPane = new JScrollPane(trustGamePanel); panel.add(trustGameScrollPane); panel.setName(TRUST_GAME_PANEL_NAME); -// addCenterComponent(panel); -// panel.revalidate(); -// panel.repaint(); + // addCenterComponent(panel); + // panel.revalidate(); + // panel.repaint(); add(panel); showPanel(TRUST_GAME_PANEL_NAME); } @@ -729,10 +737,11 @@ } }); } + public void switchInstructionsPane() { showPanel(INSTRUCTIONS_PANEL_NAME); } - + private void showPanel(final String panelName) { this.currentCardPanel = panelName; JPanel panel = getPanel(); @@ -771,14 +780,14 @@ } // generate debriefing text from data culled from the Event addDebriefingText(event); -// messageTextPane.setText(""); + // messageTextPane.setText(""); } }; try { SwingUtilities.invokeAndWait(runnable); - } - catch (InterruptedException ignored) { ignored.printStackTrace(); } - catch (InvocationTargetException e) { + } catch (InterruptedException ignored) { + ignored.printStackTrace(); + } catch (InvocationTargetException e) { e.printStackTrace(); } } @@ -793,7 +802,7 @@ } }); } - + public void add(JComponent component) { getPanel().add(component, component.getName()); } --- a/src/main/java/edu/asu/commons/foraging/event/EndRoundEvent.java Thu Sep 01 14:05:21 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/event/EndRoundEvent.java Thu Sep 01 14:12:16 2011 -0700 @@ -59,6 +59,10 @@ public List<String> getTrustGameLog() { return clientData.getTrustGameLog(); } + + public ClientData getClientData() { + return clientData; + } public boolean isLastRound() { return lastRound; Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 21:04:53
|
2 new changesets in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/633247996b34/ changeset: 633247996b34 user: alllee date: 2011-09-01 21:33:33 summary: adding basic quiz explanations affected #: 1 file (334 bytes) --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 01 11:54:48 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 01 12:33:33 2011 -0700 @@ -62,4 +62,15 @@ </form> ]]></entry> +<entry key='q1-explanation'> + <![CDATA[ + Tokens can only grow when there are other tokens around them. They cannot + spontaneously generate from the middle of the screen. + ]]> +</entry> +<entry key='q2-explanation'> + <![CDATA[ + There are no neighboring tokens next to the tokens that appeared in B. + ]]> +</entry></properties> http://bitbucket.org/virtualcommons/foraging/changeset/cf995a1552fb/ changeset: cf995a1552fb user: alllee date: 2011-09-01 23:05:21 summary: tightening up Swing repainting code, there is still some corruption happening on the instructions scroll pane in Linux, but am moving on to other parts of the code now. affected #: 8 files (1.5 KB) --- a/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Thu Sep 01 14:05:21 2011 -0700 @@ -271,7 +271,11 @@ public void transmit(PostRoundSanctionRequest request) { if (state == ClientState.WAITING) { //System.out.println("Sending post round sanction request"); - gameWindow2D.switchInstructionsPane(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + gameWindow2D.switchInstructionsPane(); + } + }); super.transmit(request); } } --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Thu Sep 01 14:05:21 2011 -0700 @@ -211,8 +211,8 @@ } else { String currentInstructions = instructionsBuilder.toString(); - // remove submit button, this is expensive but ah well. - currentInstructions = currentInstructions.replaceAll("<input type=\"submit\".*>", ""); + // remove all inputs. + currentInstructions = currentInstructions.replaceAll("<input.*value=\"[\\w]+\">", ""); System.err.println("new instructions: " + currentInstructions); builder.append(currentInstructions); Collections.sort(incorrectAnswers); @@ -248,7 +248,6 @@ builder.append(correctString); setInstructions(builder.toString()); } - getPanel().repaint(); } }; } @@ -331,11 +330,10 @@ } private void setInstructions(String s) { + System.err.println("Setting instructions to " + s); instructionsEditorPane.setText(s); - instructionsEditorPane.setCaretPosition(0); -// instructionsScrollPane.repaint(); -// instructionsScrollPane.requestFocusInWindow(); -// repaint(); + instructionsEditorPane.repaint(); + getPanel().repaint(); } private HtmlEditorPane createInstructionsEditorPane() { @@ -343,6 +341,7 @@ // "Costly Sanctioning Experiment"); final HtmlEditorPane htmlPane = new HtmlEditorPane(); htmlPane.setEditable(false); + htmlPane.setDoubleBuffered(true); htmlPane.setBackground(Color.WHITE); htmlPane.setFont(new Font("sansserif", Font.PLAIN, 12)); return htmlPane; @@ -359,6 +358,7 @@ // add instructions panel card instructionsEditorPane = createInstructionsEditorPane(); instructionsScrollPane = new JScrollPane(instructionsEditorPane); + instructionsScrollPane.setDoubleBuffered(true); instructionsScrollPane.setName(INSTRUCTIONS_PANEL_NAME); add(instructionsScrollPane); @@ -418,6 +418,7 @@ Dimension screenSize = new Dimension(component.getWidth(), component.getHeight() - 50); subjectView.setScreenSize(screenSize); subjectView.setImageSizes(); + getPanel().revalidate(); showPanel(currentCardPanel); } }); @@ -712,17 +713,21 @@ } public void showInstructions() { - RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); + final RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); instructionsBuilder.delete(0, instructionsBuilder.length()); roundConfiguration.buildInstructions(instructionsBuilder); // and add the quiz instructions if the quiz is enabled. - if (roundConfiguration.isQuizEnabled()) { - instructionsEditorPane.setActionListener(null); - instructionsEditorPane.setActionListener(createQuizListener(roundConfiguration)); - } - - setInstructions(instructionsBuilder.toString()); - switchInstructionsPane(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (roundConfiguration.isQuizEnabled()) { + instructionsEditorPane.setActionListener(null); + instructionsEditorPane.setActionListener(createQuizListener(roundConfiguration)); + } + setInstructions(instructionsBuilder.toString()); + switchInstructionsPane(); + instructionsEditorPane.setCaretPosition(0); + } + }); } public void switchInstructionsPane() { showPanel(INSTRUCTIONS_PANEL_NAME); --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Thu Sep 01 14:05:21 2011 -0700 @@ -327,8 +327,6 @@ public double getQuizCorrectAnswerReward() { return getDoubleProperty("quiz-correct-answer-reward", 0.50d); } - - /** * Possible values, freeze, fine? @@ -561,25 +559,26 @@ } instructionsBuilder.append(getInstructions()); if (isFieldOfVisionEnabled()) { - instructionsBuilder.append(getFieldOfVisionInstructions()); + addSpecialInstructions(instructionsBuilder,getFieldOfVisionInstructions()); } if (isCensoredChat()) { - instructionsBuilder.append(getCensoredChatInstructions()); + addSpecialInstructions(instructionsBuilder,getCensoredChatInstructions()); } else if (isInRoundChatEnabled()) { - instructionsBuilder.append(getInRoundChatInstructions()); + addSpecialInstructions(instructionsBuilder,getInRoundChatInstructions()); } else if (isChatEnabled()) { // FIXME: hard-coded, need to make instructions template-able, perhaps // via FreeMarker or Velocity. - instructionsBuilder.append("Before the beginning of this round you will be able to chat with the other members of your group for ").append(getChatDuration()).append(" seconds."); + addSpecialInstructions(instructionsBuilder, + "Before the beginning of this round you will be able to chat with the other members of your group for " + getChatDuration() + " seconds."); } String resourceGeneratorType = getResourceGeneratorType(); if (resourceGeneratorType.equals("mobile")) { - instructionsBuilder.append(getMobileResourceInstructions()); + addSpecialInstructions(instructionsBuilder,getMobileResourceInstructions()); } else if (resourceGeneratorType.equals("top-bottom-patchy")) { - instructionsBuilder.append(getPatchyResourceInstructions()); + addSpecialInstructions(instructionsBuilder,getPatchyResourceInstructions()); } // and add the quiz instructions if the quiz is enabled. @@ -589,6 +588,10 @@ return instructionsBuilder; } + private void addSpecialInstructions(StringBuilder builder, String instructions) { + builder.append("<p>").append(instructions).append("</p>"); + } + private String getMobileResourceInstructions() { return getProperty("mobile-resource-instructions", "<p>The resource can move around in a semblance of free will / agency.</p>"); } --- a/src/main/java/edu/asu/commons/foraging/event/QuizResponseEvent.java Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/event/QuizResponseEvent.java Thu Sep 01 14:05:21 2011 -0700 @@ -12,7 +12,7 @@ * * A client's quiz responses for a given quiz page. * - * + * * @author <a href='mailto:All...@as...'>Allen Lee</a> * @version $Rev: 522 $ */ @@ -42,4 +42,15 @@ public String toString() { return String.format("%s, responses: %s, incorrect answers: %s", id, responses, incorrectAnswers); } + + public int getNumberOfCorrectAnswers() { + int correctAnswers = responses.size() - incorrectAnswers.size(); + if (correctAnswers < 0) { + // FIXME: replace with proper logging? + System.err.println("Somehow the number of responses was less than the number of incorrect answers: " + + responses + " -- " + incorrectAnswers); + return 0; + } + return correctAnswers; + } } --- a/src/main/java/edu/asu/commons/foraging/model/ClientData.java Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/model/ClientData.java Thu Sep 01 14:05:21 2011 -0700 @@ -69,7 +69,8 @@ private ArrayList<String> trustGameLog = new ArrayList<String>(); - private double trustGameEarnings = 0.0d; + private double trustGameEarnings = 0.0d; + private int correctQuizAnswers = 0; public void setTrustGamePlayerOneAmountToKeep(double trustGamePlayerOneAmountToKeep) { this.trustGamePlayerOneAmountToKeep = trustGamePlayerOneAmountToKeep; @@ -595,4 +596,13 @@ public List<String> getTrustGameLog() { return trustGameLog; } + + public int getCorrectQuizAnswers() { + return correctQuizAnswers; + } + + public void addCorrectQuizAnswers(int numberOfCorrectAnswers) { + correctQuizAnswers += numberOfCorrectAnswers; + } + } --- a/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Thu Sep 01 14:05:21 2011 -0700 @@ -299,14 +299,16 @@ addEventProcessor(new EventTypeProcessor<QuizResponseEvent>(QuizResponseEvent.class) { public void handle(final QuizResponseEvent event) { numberOfSubmittedQuizzes++; + transmit(new QuizCompletedEvent(facilitatorId)); + ClientData clientData = clients.get(event.getId()); + clientData.addCorrectQuizAnswers(event.getNumberOfCorrectAnswers()); if (numberOfSubmittedQuizzes >= clients.size()) { // we're done, notify the sleeping queue. logger.info("Received all quizzes, notifying quiz signal"); Utils.notify(quizSignal); numberOfSubmittedQuizzes = 0; } - // FIXME: pass in the id of the client completing the quiz? - transmit(new QuizCompletedEvent(facilitatorId)); + } }); addEventProcessor(new EventTypeProcessor<PostRoundSanctionRequest>(PostRoundSanctionRequest.class) { --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 01 14:05:21 2011 -0700 @@ -43,34 +43,31 @@ Before we begin the practice round please answer the following questions. </p><form> -<fieldset> -<span class='q1'>Q1. Which of the statements is <b><u>incorrect</u></b>?</span><br> -<input type="radio" name="q1" value="A"/>A. Your decisions of where to collect tokens affects the regeneration of tokens.<br> -<input type="radio" name="q1" value="B"/>B. When you have collected all tokens on the screen, no new tokens will appear.<br> -<input type="radio" name="q1" value="C"/>C. Tokens grow from the middle of the screen.<br> -<input type="radio" name="q1" value="D"/>D. In order to collect a token you need to press the space bar while your yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"> is on a cell with a token.<br> -</fieldset> - -<fieldset> -<span class='q2'>Q2. Which sequence of situations is <b><u>not possible</u></b>?</span><br> -<img src="@CODEBASE_URL@/images/question2.jpg"><br> +<span class='q1'>Q1. Which one of the following statements is incorrect?</span><br> +<input type="radio" name="q1" value="A">A. Your decisions of where to collect tokens affects the regeneration of tokens.<br> +<input type="radio" name="q1" value="B">B. When you have collected all tokens on the screen, no new tokens will appear.<br> +<input type="radio" name="q1" value="C">C. Tokens grow from the middle of the screen.<br> +<input type="radio" name="q1" value="D">D. In order to collect a token you need to press the space bar while your yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"></img> is on a cell with a token.<br> +<br><br> +<span class='q2'>Q2. Which sequence of situations is not possible?</span><br> +<img src="@CODEBASE_URL@/images/question2.jpg"></img><br><input type="radio" name="q2" value="A">A<br><input type="radio" name="q2" value="B">B<br><input type="radio" name="q2" value="C">C<br> -</fieldset> -<input type="submit" name="submit" value="Submit"> +<input type="submit" name="submit" value="Submit"><br></form> ]]></entry><entry key='q1-explanation'><![CDATA[ - Tokens can only grow when there are other tokens around them. They cannot - spontaneously generate from the middle of the screen. + Tokens only regenerate when there are other tokens present in their immediately + neighboring cells. They do not spontaneously generate from the middle of the + screen. ]]></entry><entry key='q2-explanation'><![CDATA[ - There are no neighboring tokens next to the tokens that appeared in B. + Tokens cannot regenerate on an empty screen as shown in sequence B. ]]></entry></properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 01 12:33:33 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 01 14:05:21 2011 -0700 @@ -56,11 +56,11 @@ six rounds of the experiment. </p><p> -You will appear on the screen as a yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif">. + You will appear on the screen as a yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"></img>. You can move by pressing the four arrow keys on your keyboard. You can move up, down, left, or right. You have to press a key for each and every move of your yellow dot. In this experiment you can collect green diamond shaped tokens -<img src="@CODEBASE_URL@/images/gem-token.gif"> and earn two cents for each collected token. +<img src="@CODEBASE_URL@/images/gem-token.gif"></img> and earn two cents for each collected token. To collect a token, move your yellow dot over a green token and <b>press the space bar</b>. Simply moving your avatar over a token does NOT collect that token. </p> @@ -75,6 +75,7 @@ The middle cell in Image 1 denoted with an X has a greater chance of regeneration than the middle cell in Image 2. When all neighboring cells are empty, there is <b>no chance for regeneration</b>. +</p><table width="100%"><tr> @@ -83,13 +84,14 @@ </tr><tr><td align="center"> -<img src="@CODEBASE_URL@/images/8neighbors.jpg" alt="image 1"> + <img src="@CODEBASE_URL@/images/8neighbors.jpg" alt="image 1"></img></td><td align="center"> -<img src="@CODEBASE_URL@/images/5neighbors.jpg" alt="image 2"> + <img src="@CODEBASE_URL@/images/5neighbors.jpg" alt="image 2"></img></td></tr></table> + <h3>Best Strategy</h3><p> The chance that a token will regenerate on an empty cell increases as there are @@ -98,7 +100,8 @@ regrowth. The optimal spatial pattern of tokens on the screen is the checkerboard diagram shown below, where half of the cells are empty and arranged in a way that maximizes regrowth. -<img src="@CODEBASE_URL@/images/optimal-strategy.jpg" alt="Checkerboard Resource"> +<br> +<img src="@CODEBASE_URL@/images/optimal-strategy.jpg" alt="Checkerboard Resource"></img></p> ]]></entry> @@ -116,25 +119,25 @@ </p><h3>Game Mechanics</h3> +<p> The game works as follows: +</p><ol><li>Player 1 first receives an endowment of one dollar and has to decide <b>how much to keep</b> and <b>how much to send to Player 2</b>. <li>The amount Player 1 decides to send to Player 2 is tripled by the system and then given to Player 2. Player 2 then has to decide <b>how much to keep</b> and <b>how much to send back to Player 1</b>. </ol> - +<p> For example, if Player 1 sends 0 cents to Player 2, Player 1 earns 1 dollar and Player 2 earns 0 cents. However, if Player 1 sends 1 dollar to Player 2, 3 dollars would be sent to Player 2. Player 2 then decides to return $1.75 back to Player 1. In this case, Player 1 earns $1.75, and Player 2 earns $1.25. - -<p> - To design your strategies, please fill in the following form by selecting the - <b>Amount to Keep</b> column. </p><p> - <b>Are there any questions?</b> +Please fill in the following form to design your strategies as Player 1 or Player 2. +<br> +<b>If you have any questions, please raise your hand. Are there any questions?</b></p> ]]></entry> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 18:54:18
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/a70b6d501f36/ changeset: a70b6d501f36 user: alllee date: 2011-09-01 20:54:48 summary: updated trust game instructions and adding quiz explanation and correct answer rewards affected #: 3 files (3.7 KB) --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Wed Aug 31 17:18:28 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Thu Sep 01 11:54:48 2011 -0700 @@ -280,14 +280,7 @@ public boolean isQuizEnabled() { return getBooleanProperty("quiz"); } - - /** - * FIXME: quiz instructions and quiz enabled should be tightly coupled.. - * @return - */ - public String getQuizInstructions() { - return getProperty("quiz-instructions"); - } + public String getChatInstructions() { return getProperty("chat-instructions"); @@ -305,6 +298,14 @@ return getProperty("last-round-debriefing"); } + /** + * FIXME: quiz instructions and quiz enabled should be tightly coupled.. + * @return + */ + public String getQuizInstructions() { + return getProperty("quiz-instructions"); + } + public Map<String, String> getQuizAnswers() { Properties properties = getProperties(); if (isQuizEnabled()) { @@ -322,6 +323,12 @@ public String getQuizExplanation(String questionNumber) { return getProperty(questionNumber + "-explanation"); } + + public double getQuizCorrectAnswerReward() { + return getDoubleProperty("quiz-correct-answer-reward", 0.50d); + } + + /** * Possible values, freeze, fine? --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Wed Aug 31 17:18:28 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/round0.xml Thu Sep 01 11:54:48 2011 -0700 @@ -20,10 +20,10 @@ <h3>Practice Round Instructions</h3><hr><p> -You will now have four minutes to practice with the experimental environment. -The decisions you make in this round will NOT influence your earnings. At the -At the beginning of the practice round half of the cells are occupied -with green tokens. The environment is a 13 x 13 grid of cells. +You will now have four minutes to practice with the experimental environment. The +decisions you make in this round will NOT influence your earnings. At the beginning +of the practice round half of the cells are occupied with green tokens. The +environment is a 13 x 13 grid of cells. </p><p> During this practice round, and <b>only during</b> this practice round, you are able @@ -31,7 +31,7 @@ press the <b>R</b> key you will reset the resource to its initial distribution, randomly filling half of the cells. </p> -<p><b> Please do not communicate with any other participant.</b></p> +<p><b>Please do not communicate with any other participant.</b></p><p>If you have any questions please raise your hand. <b>Do you have any questions so far?</b></p> ]]> @@ -42,67 +42,24 @@ <p> Before we begin the practice round please answer the following questions. </p> -<br><form> +<fieldset><span class='q1'>Q1. Which of the statements is <b><u>incorrect</u></b>?</span><br> -<input type="radio" name="q1" value="A">A. Your decisions of where to collect tokens affects the regeneration of tokens.<br> -<input type="radio" name="q1" value="B">B. When you have collected all tokens on the screen, no new tokens will appear.<br> -<input type="radio" name="q1" value="C">C. Tokens grow from the middle of the -screen.<br> -<input type="radio" name="q1" value="D">D. In order to collect a token you need -to press the space bar while your yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"> is on a cell with a token.<br> -<br><br> - +<input type="radio" name="q1" value="A"/>A. Your decisions of where to collect tokens affects the regeneration of tokens.<br> +<input type="radio" name="q1" value="B"/>B. When you have collected all tokens on the screen, no new tokens will appear.<br> +<input type="radio" name="q1" value="C"/>C. Tokens grow from the middle of the screen.<br> +<input type="radio" name="q1" value="D"/>D. In order to collect a token you need to press the space bar while your yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif"> is on a cell with a token.<br> +</fieldset> + +<fieldset><span class='q2'>Q2. Which sequence of situations is <b><u>not possible</u></b>?</span><br><img src="@CODEBASE_URL@/images/question2.jpg"><br><input type="radio" name="q2" value="A">A<br><input type="radio" name="q2" value="B">B<br><input type="radio" name="q2" value="C">C<br> -<br> +</fieldset><input type="submit" name="submit" value="Submit"></form> ]]></entry> - -<entry key='trust-game-instructions'> -<![CDATA[ -<h3>Task</h3> -<p> -You will be matched with another person in your group, but you will not know who -that person is. And that person will not know who you are. You make decisions for -the case you are drawn to be player 1 and the case you will be player 2. The -results of the decisions are given to you at the end of the whole experiment. -</p> - -<p> -The person drawn to be player 1 has the following decision to make. You will receive -an endowment of one dollar and decide how much to keep and how much to send to -another person in your group. -</p> - -<p> -The amount you send to the other person will be tripled and then given to the person -in your group with whom you have been matched. That person will decide how much to -keep and how much to send back to you. For example, if you send 0 extra credit -points to the other person, 0 extra credit points will be sent to the other person. -However, if you write 3 extra credit points on the form, 9 extra credit points will -be sent to the person. The other person would then decide how much to return to -you. -</p> - -<p> -Player 2 has the following decision to make. You have to choose for each of the 4 -possible cases how much to receive from player 1 how much to keep and how much to -send back to player 1. We ask you to fill in the tables for player 1 as well as for -player 2, and we will drawn whether you are player 1 or 2 after you have made the -decisions. -</p> - -<p> -Are there any questions? If you have a question, raise your hand and I will try to -answer it. -</p> -]]> -</entry> - </properties> --- a/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Wed Aug 31 17:18:28 2011 -0700 +++ b/src/main/resources/configuration/asu-experiments/fall-2011/pretest/server.xml Thu Sep 01 11:54:48 2011 -0700 @@ -50,32 +50,31 @@ <h3>General Instructions</h3><p> Welcome. You have already earned 5 dollars by showing up at this experiment. You can -earn more, up to a maximum of 40 dollars, by participating in this experiment, which +earn more, up to a maximum of about 40 dollars, by participating in this experiment, which will take about an hour to an hour and a half. The amount of money you earn depends on your decisions as well as the decisions of other people in this room during the six rounds of the experiment. </p><p> -You appear on the screen as a yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif">. -You move by pressing the four arrow keys on your keyboard. You can move up, down, -left, or right. You have to press a key for each and every move of your yellow dot. -In this experiment you can collect green diamond shaped tokens +You will appear on the screen as a yellow dot <img src="@CODEBASE_URL@/images/gem-self.gif">. +You can move by pressing the four arrow keys on your keyboard. You can move up, +down, left, or right. You have to press a key for each and every move of your +yellow dot. In this experiment you can collect green diamond shaped tokens <img src="@CODEBASE_URL@/images/gem-token.gif"> and earn two cents for each collected token. -To collect a token, move your yellow dot over a green token and press the <b>space -bar</b>. If you move over a token without pressing the <b>space bar</b> you do NOT -collect that token. +To collect a token, move your yellow dot over a green token and <b>press the space +bar</b>. Simply moving your avatar over a token does NOT collect that token. </p><p> The tokens that you collect have the potential to regenerate. After you have -collected a green token, a new token can re-appear on that empty cell. -However, the rate at which new tokens will appear depends on the number of -adjacent cells with tokens. The more tokens in the eight cells around -an empty cell, the faster a new token will appear on that empty cell. In other -words, <b>existing tokens can generate new tokens</b>. To illustrate this, please -refer to Image 1 and Image 2. The middle cell in Image 1 denoted with an X has -a greater chance of regeneration than the middle cell in Image 2. When all -neighboring cells are empty, there is <b>no chance for regeneration</b>. +collected a green token, a new token can re-appear on that empty cell. The rate at +which new tokens appear is dependent on the number of adjacent cells with tokens. +The more tokens in the eight cells that surround an empty cell, the faster a new +token will appear on that empty cell. In other words, <b>existing tokens can +generate new tokens</b>. To illustrate this, please refer to Image 1 and Image 2. +The middle cell in Image 1 denoted with an X has a greater chance of regeneration +than the middle cell in Image 2. When all neighboring cells are empty, there is +<b>no chance for regeneration</b>. <table width="100%"><tr> @@ -91,8 +90,52 @@ </td></tr></table> +<h3>Best Strategy</h3> +<p> +The chance that a token will regenerate on an empty cell increases as there are +more tokens surrounding it. Therefore, you want to have as many tokens around an +empty cell as possible. However, you also need empty cells to benefit from this +regrowth. The optimal spatial pattern of tokens on the screen is the checkerboard +diagram shown below, where half of the cells are empty and arranged in a way that +maximizes regrowth. +<img src="@CODEBASE_URL@/images/optimal-strategy.jpg" alt="Checkerboard Resource"> +</p> ]]></entry> +<entry key='trust-game-instructions'> +<![CDATA[ +<h3>Trust Game Instructions</h3> +<p> + You will now play a mini-game where you will be matched with a random person in + your group. In this game there are two roles, Player 1 and Player 2. Your job + is to design strategies for both Player 1 and Player 2 roles. When you are + randomly paired with another member of your group you may be selected as Player + 1 <b>or</b> Player 2. The results of your strategies will be shown to you at + the <b>end of the experiment</b>. +</p> +<h3>Game Mechanics</h3> +The game works as follows: +<ol> + <li>Player 1 first receives an endowment of one dollar and has to decide <b>how much to keep</b> and <b>how much to send to Player 2</b>. + <li>The amount Player 1 decides to send to Player 2 is tripled by + the system and then given to Player 2. Player 2 then has to decide <b>how + much to keep</b> and <b>how much to send back to Player 1</b>. +</ol> + +For example, if Player 1 sends 0 cents to Player 2, Player 1 earns 1 dollar and +Player 2 earns 0 cents. However, if Player 1 sends 1 dollar to Player 2, 3 dollars +would be sent to Player 2. Player 2 then decides to return $1.75 back to Player 1. +In this case, Player 1 earns $1.75, and Player 2 earns $1.25. + +<p> + To design your strategies, please fill in the following form by selecting the + <b>Amount to Keep</b> column. +</p> +<p> + <b>Are there any questions?</b> +</p> +]]> +</entry></properties> Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-09-01 00:18:02
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/14ff30b94f1e/ changeset: 14ff30b94f1e user: alllee date: 2011-09-01 02:18:28 summary: refactoring GameWindow2D to use CardLayout instead of switchCenterComponent. adding a patch that fixes issue 4 by automatically submitting the quiz response. TODO: figure out visual glitches when resizing instructions panel and incorporate configurable payments for quiz questions + correct answer explanation and trust game. affected #: 6 files (6.4 KB) --- a/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Tue Aug 30 22:53:48 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Wed Aug 31 17:18:28 2011 -0700 @@ -37,7 +37,6 @@ import edu.asu.commons.foraging.event.TrustGameSubmissionRequest; import edu.asu.commons.net.SocketIdentifier; import edu.asu.commons.util.Duration; -import edu.asu.commons.util.Utils; @@ -81,15 +80,15 @@ public ForagingClient(ServerConfiguration configuration, Dimension screenSize) { super(configuration); dataModel = new ClientDataModel(this); + clientPanel.setLayout(new BorderLayout()); if (configuration.shouldInitialize2D()) { gameWindow2D = new GameWindow2D(this, screenSize); + clientPanel.add(gameWindow2D.getPanel(), BorderLayout.CENTER); } else if (configuration.shouldInitialize3D()) { gameWindow3D = new GameWindow3D(this); + clientPanel.add(gameWindow3D.getPanel(), BorderLayout.CENTER); } - clientPanel.setLayout(new BorderLayout()); - clientPanel.add(configuration.getCurrentParameters().is2dExperiment() ? gameWindow2D : gameWindow3D.getPanel(), - BorderLayout.CENTER); } @@ -137,9 +136,8 @@ SwingUtilities.invokeLater(new Runnable() { public void run() { clientPanel.removeAll(); - clientPanel.invalidate(); if (dataModel.is2dExperiment()) { - clientPanel.add(gameWindow2D, BorderLayout.CENTER); + clientPanel.add(gameWindow2D.getPanel(), BorderLayout.CENTER); if (gameWindow3D != null) { gameWindow3D.dispose(); } @@ -147,7 +145,7 @@ else { clientPanel.add(gameWindow3D.getPanel(), BorderLayout.CENTER); } - clientPanel.validate(); + clientPanel.revalidate(); clientPanel.repaint(); getGameWindow().init(); } --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow.java Tue Aug 30 22:53:48 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow.java Wed Aug 31 17:18:28 2011 -0700 @@ -1,5 +1,7 @@ package edu.asu.commons.foraging.client; +import javax.swing.JPanel; + import edu.asu.commons.foraging.event.EndRoundEvent; /** @@ -17,7 +19,7 @@ public void init(); public void update(long millisecondsLeft); public void showInstructions(); - public void showTrustGame(); + public JPanel getPanel(); } --- a/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Tue Aug 30 22:53:48 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GameWindow2D.java Wed Aug 31 17:18:28 2011 -0700 @@ -25,6 +25,7 @@ import javax.swing.Box; import javax.swing.BoxLayout; +import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; @@ -46,7 +47,6 @@ import edu.asu.commons.foraging.event.CollectTokenRequest; import edu.asu.commons.foraging.event.EndRoundEvent; import edu.asu.commons.foraging.event.PostRoundSanctionUpdateEvent; -import edu.asu.commons.foraging.event.QuizCompletedEvent; import edu.asu.commons.foraging.event.QuizResponseEvent; import edu.asu.commons.foraging.event.RealTimeSanctionRequest; import edu.asu.commons.foraging.event.ResetTokenDistributionRequest; @@ -68,19 +68,26 @@ * @author <a href='mailto:All...@as...'>Allen Lee</a> * @version $Revision: 529 $ */ -public class GameWindow2D extends JPanel implements GameWindow { +public class GameWindow2D implements GameWindow { - private static final long serialVersionUID = -7733523846114902166L; + private final ClientDataModel dataModel; + + private final static String INSTRUCTIONS_PANEL_NAME = "Foraging instructions panel"; + private final static String GAME_PANEL_NAME = "Game panel"; + private final static String TRUST_GAME_PANEL_NAME = "Trust game panel"; + // standalone chat panel + private final static String CHAT_PANEL_NAME = "Chat panel"; - // the data model - private final ClientDataModel dataModel; - - // instructions components. - - private Component currentCenterComponent; - + protected static final String POST_ROUND_SANCTIONING_PANEL_NAME = null; + + private String currentCardPanel = INSTRUCTIONS_PANEL_NAME; + +// private Component currentCenterComponent; + + private JPanel mainPanel; + + // instructions components. private JScrollPane instructionsScrollPane; - private HtmlEditorPane instructionsEditorPane; private JPanel messagePanel; @@ -98,7 +105,7 @@ private JLabel timeLeftLabel; - private JPanel subjectWindow; + private JPanel gamePanel; private ForagingClient client; @@ -110,7 +117,6 @@ private EventChannel channel; - // FIXME: replace switchXXXPanel with CardLayout switching. private CardLayout cardLayout; // private EnergyLevel energyLevel; @@ -123,9 +129,8 @@ // feed subject view the available screen size so that // it can adjust appropriately when given a board size // int width = (int) Math.min(Math.floor(size.getWidth()), Math.floor(size.getHeight() * 0.85)); - Dimension subjectViewSize = new Dimension((int) size.getWidth(), (int) (size.getHeight() * 0.85)); - subjectView = new SubjectView(subjectViewSize, dataModel); - initGuiComponents(); + + initGuiComponents(size); } /** @@ -175,43 +180,43 @@ private ActionListener createQuizListener(final RoundConfiguration configuration) { return new ActionListener() { public void actionPerformed(ActionEvent e) { - // System.err.println("In action performed with event: " + e); HtmlEditorPane.FormActionEvent formEvent = (HtmlEditorPane.FormActionEvent) e; Properties actualAnswers = formEvent.getData(); - // actualAnswers.list(System.err); List<String> incorrectAnswers = new ArrayList<String>(); List<String> correctAnswers = new ArrayList<String>(); // iterate through expected answers - for (Map.Entry<String, String> entry : configuration.getQuizAnswers().entrySet()) { + Map<String, String> quizAnswers = configuration.getQuizAnswers(); + for (Map.Entry<String, String> entry : quizAnswers.entrySet()) { String questionNumber = entry.getKey(); String expectedAnswer = entry.getValue(); - System.out.println(expectedAnswer); - if (! expectedAnswer.equals(actualAnswers.getProperty(questionNumber)) ) { + if (expectedAnswer.equals(actualAnswers.getProperty(questionNumber)) ) { + correctAnswers.add(questionNumber); + } + else { // flag the incorrect response incorrectAnswers.add(questionNumber); } - else { - correctAnswers.add(questionNumber); - } } client.transmit(new QuizResponseEvent(client.getId(), actualAnswers, incorrectAnswers)); - + StringBuilder builder = new StringBuilder(); + setQuestionColors(correctAnswers, "black"); + setQuestionColors(incorrectAnswers, "red"); if (incorrectAnswers.isEmpty()) { + builder.append(configuration.getInstructions()); // notify the server and also notify the participant. - StringBuilder builder = new StringBuilder(configuration.getInstructions()); builder.append("<br><b>Congratulations!</b> You have answered all questions correctly."); setInstructions(builder.toString()); - client.transmit(new QuizCompletedEvent(client.getId())); - setQuestionColors(correctAnswers, "black"); } else { - // FIXME: highlight the incorrect answers? + String currentInstructions = instructionsBuilder.toString(); + // remove submit button, this is expensive but ah well. + currentInstructions = currentInstructions.replaceAll("<input type=\"submit\".*>", ""); + System.err.println("new instructions: " + currentInstructions); + builder.append(currentInstructions); Collections.sort(incorrectAnswers); Collections.sort(correctAnswers); - StringBuilder builder = new StringBuilder().append(instructionsBuilder); - HTMLEditorKit editorKit = (HTMLEditorKit) instructionsEditorPane.getEditorKit(); StyleSheet styleSheet = editorKit.getStyleSheet(); StringBuilder correctString = new StringBuilder(); @@ -232,14 +237,18 @@ for (String incorrectQuestionNumber : incorrectAnswers) { String styleString = String.format(".%s { color: red; }", incorrectQuestionNumber); styleSheet.addRule(styleString); - correctString.append(String.format("<li>Your answer [ %s ] was incorrect for question %s.", + correctString.append(String.format("<li>Your answer [ %s ] was incorrect for question %s. The correct answer was [ %s ]. %s", actualAnswers.get(incorrectQuestionNumber), - incorrectQuestionNumber)); + incorrectQuestionNumber, + quizAnswers.get(incorrectQuestionNumber), + configuration.getQuizExplanation(incorrectQuestionNumber) + )); } correctString.append("</ul>"); builder.append(correctString); setInstructions(builder.toString()); } + getPanel().repaint(); } }; } @@ -253,79 +262,6 @@ subjectView.collectToken(position); } -// private void startEnforcementVotingTimer() { -// if (timer == null) { -// //FIXME: Need to fetch this value from the round4.xml -// duration = Duration.create(dataModel.getRoundConfiguration().getEnforcementVotingDuration()); -// timer = new Timer(1000, new ActionListener() { -// public void actionPerformed(ActionEvent event) { -// if (duration.hasExpired()) { -// timeLeftLabel.setText("Voting is now disabled."); -// timer.stop(); -// timer = null; -// getEnforcementPanel().sendEnforcementVotes(); -// displayVotingWaitMessage(); -// } -// else { -// timeLeftLabel.setText( String.format("Voting period will end in %d seconds.", duration.getTimeLeft() / 1000L) ); -// } -// } -// }); -// timer.start(); -// } -// } - - -// private void startRegulationVotingTimer() { -// -// if (timer == null) { -// duration = Duration.create(dataModel.getRoundConfiguration().getRegulationVotingDuration()); -// -// timer = new Timer(1000, new ActionListener() { -// public void actionPerformed(ActionEvent event) { -// if (duration.hasExpired()) { -// timeLeftLabel.setText("Voting is now disabled. Next round begins shortly."); -// -// //new code -// //Need to add the enforcementVotingPane over here -// //instead of the instructionsScrollPane -// timer.stop(); -// timer = null; -// //remove(sanctioningPanel); -// //getSanctioningPanel().stopTimer(); -// getRegulationPanel().sendRegulationVotes(); -// displayVotingWaitMessage(); -// } -// else { -// timeLeftLabel.setText( String.format("Voting period will end in %d seconds.", duration.getTimeLeft() / 1000L) ); -// } -// } -// }); -// timer.start(); -// } -// } -// -// private void startSanctionVotingTimer() { -// if (timer == null) { -// duration = Duration.create(dataModel.getRoundConfiguration().getSanctionVotingDuration()); -// timer = new Timer(1000, new ActionListener() { -// public void actionPerformed(ActionEvent event) { -// if (duration.hasExpired()) { -// timeLeftLabel.setText("Voting is now disabled. Next round begins shortly."); -// timer.stop(); -// timer = null; -// sendSanctionDecisionVotes(); -// displayVotingWaitMessage(); -// } -// else { -// timeLeftLabel.setText( String.format("Voting period will now end in %d seconds.", duration.getTimeLeft() / 1000L) ); -// } -// } -// }); -// timer.start(); -// } -// } - private void startChatTimer() { if (timer == null) { final RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); @@ -336,9 +272,6 @@ timeLeftLabel.setText("Chat is now disabled."); timer.stop(); timer = null; -// if (roundConfiguration.isVotingAndRegulationEnabled()) { -// initializeSanctionDecisionPanel(); -// } } else { timeLeftLabel.setText( String.format("Chat will end in %d seconds.", duration.getTimeLeft() / 1000L) ); @@ -354,10 +287,6 @@ StringBuilder builder = new StringBuilder("Tokens collected:"); // XXX: use this method so that we get the proper ordering of client ids/assigned numbers.. Map<Identifier, ClientData> clientDataMap = dataModel.getClientDataMap(); - - // To display the token artifacts only if the player lies in the - // field of vision - Point clientPosition = dataModel.getCurrentPosition(); for (Identifier id: dataModel.getAllClientIdentifiers()) { @@ -404,8 +333,8 @@ private void setInstructions(String s) { instructionsEditorPane.setText(s); instructionsEditorPane.setCaretPosition(0); - instructionsScrollPane.repaint(); - instructionsScrollPane.requestFocusInWindow(); +// instructionsScrollPane.repaint(); +// instructionsScrollPane.requestFocusInWindow(); // repaint(); } @@ -413,80 +342,83 @@ // JEditorPane pane = new JEditorPane("text/html", // "Costly Sanctioning Experiment"); final HtmlEditorPane htmlPane = new HtmlEditorPane(); - htmlPane.setPreferredSize(new Dimension(400, 400)); htmlPane.setEditable(false); htmlPane.setBackground(Color.WHITE); htmlPane.setFont(new Font("sansserif", Font.PLAIN, 12)); return htmlPane; } - private void initGuiComponents() { + private void initGuiComponents(Dimension size) { // FIXME: replace with CardLayout for easier switching between panels - // cardLayout = new CardLayout(); + cardLayout = new CardLayout(); + mainPanel = new JPanel(cardLayout); + + Dimension subjectViewSize = new Dimension((int) size.getWidth(), (int) (size.getHeight() * 0.85)); + subjectView = new SubjectView(subjectViewSize, dataModel); - setLayout(new BorderLayout(4, 4)); + // add instructions panel card instructionsEditorPane = createInstructionsEditorPane(); instructionsScrollPane = new JScrollPane(instructionsEditorPane); - add(instructionsScrollPane, BorderLayout.CENTER); - currentCenterComponent = instructionsScrollPane; - subjectWindow = new JPanel(new BorderLayout()); - subjectWindow.setBackground(Color.WHITE); - subjectWindow.setForeground(Color.BLACK); - subjectWindow.add(subjectView, BorderLayout.CENTER); - setBackground(Color.WHITE); - // replace with progress bar. + instructionsScrollPane.setName(INSTRUCTIONS_PANEL_NAME); + add(instructionsScrollPane); + + // add game panel card + // FIXME: use a more flexible LayoutManager so that in-round chat isn't so fubared. + gamePanel = new JPanel(new BorderLayout()); + gamePanel.setBackground(Color.WHITE); + gamePanel.setName(GAME_PANEL_NAME); + gamePanel.add(subjectView, BorderLayout.CENTER); + // add labels to game panel + // FIXME: replace with progress bar. timeLeftLabel = new JLabel("Connecting ..."); informationLabel = new JLabel("Tokens collected: 0 "); // latencyLabel = new JLabel("Latency: 0"); informationLabel.setBackground(Color.YELLOW); informationLabel.setForeground(Color.BLUE); - + labelPanel = new JPanel(); labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.LINE_AXIS)); labelPanel.setBackground(Color.WHITE); labelPanel.add(timeLeftLabel); labelPanel.add(Box.createHorizontalGlue()); labelPanel.add(informationLabel); - add(labelPanel, BorderLayout.NORTH); + gamePanel.add(labelPanel, BorderLayout.NORTH); -// // add message window. -// messagePanel = new JPanel(new BorderLayout()); -// // messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); -// messagePanel.add(new JLabel("Messages"), BorderLayout.NORTH); -// messageTextPane = new JTextPane(); -// messageTextPane.setEditable(false); -// messageTextPane.setFont(new Font("arial", Font.BOLD, 12)); -// messageTextPane.setBackground(Color.WHITE); -// -// -// addStyles(messageTextPane.getStyledDocument()); -// messageScrollPane = new JScrollPane(messageTextPane); + // add message window. + messagePanel = new JPanel(new BorderLayout()); + // messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.Y_AXIS)); + messagePanel.add(new JLabel("Messages"), BorderLayout.NORTH); + messageTextPane = new JTextPane(); + messageTextPane.setEditable(false); + messageTextPane.setFont(new Font("arial", Font.BOLD, 12)); + messageTextPane.setBackground(Color.WHITE); + addStyles(messageTextPane.getStyledDocument()); + messageScrollPane = new JScrollPane(messageTextPane); // Dimension scrollPaneSize = new Dimension(getPreferredSize().width, 50); // messageScrollPane.setMinimumSize(scrollPaneSize); // messageScrollPane.setPreferredSize(scrollPaneSize); // messageScrollPane.setMaximumSize(scrollPaneSize); -// messagePanel.add(messageScrollPane, BorderLayout.CENTER); -// add(messagePanel, BorderLayout.SOUTH); + messagePanel.add(messageScrollPane, BorderLayout.CENTER); + gamePanel.add(messagePanel, BorderLayout.SOUTH); - addKeyListener( createGameWindowKeyListener() ); - addMouseListener(new MouseAdapter() { + add(gamePanel); + + mainPanel.addKeyListener( createGameWindowKeyListener() ); + mainPanel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { - requestFocusInWindow(); + mainPanel.requestFocusInWindow(); } }); // resize listener - addComponentListener(new ComponentAdapter() { + mainPanel.addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent event) { Component component = event.getComponent(); - // offset by 35 to allow for message box - int subjectViewHeight = component.getHeight() - 35; - Dimension size = new Dimension(component.getWidth(), subjectViewHeight); - subjectView.setScreenSize(size); + // offset by 35 pixels to allow for message box + Dimension screenSize = new Dimension(component.getWidth(), component.getHeight() - 50); + subjectView.setScreenSize(screenSize); subjectView.setImageSizes(); - GameWindow2D.this.revalidate(); - currentCenterComponent.repaint(); -// GameWindow2D.this.repaint(); + showPanel(currentCardPanel); } }); // add component listeners, chat panel, and sanctioning window IF chat/sanctioning are enabled, and after the end of the round... @@ -604,17 +536,17 @@ return configuration.isPracticeRound() && configuration.isPrivateProperty(); } - public void addCenterComponent(Component newCenterComponent) { - if (currentCenterComponent != null) { - currentCenterComponent.setVisible(false); - remove(currentCenterComponent); - add(newCenterComponent, BorderLayout.CENTER); - newCenterComponent.setVisible(true); - } - currentCenterComponent = newCenterComponent; - revalidate(); - repaint(); - } +// public void addCenterComponent(Component newCenterComponent) { +// if (currentCenterComponent != null) { +// currentCenterComponent.setVisible(false); +// getPanel().remove(currentCenterComponent); +// getPanel().add(newCenterComponent, BorderLayout.CENTER); +// newCenterComponent.setVisible(true); +// } +// currentCenterComponent = newCenterComponent; +// getPanel().revalidate(); +// getPanel().repaint(); +// } public void startRound() { final RoundConfiguration configuration = dataModel.getRoundConfiguration(); @@ -635,14 +567,12 @@ if (configuration.isInRoundChatEnabled()) { ChatPanel chatPanel = getChatPanel(); chatPanel.initialize(); - Dimension chatPanelSize = new Dimension(250, getSize().height); + Dimension chatPanelSize = new Dimension(250, getPanel().getSize().height); chatPanel.setPreferredSize(chatPanelSize); - add(chatPanel, BorderLayout.EAST); + // FIXME: switch to different layout manager + gamePanel.add(chatPanel, BorderLayout.EAST); } -// add(messagePanel, BorderLayout.SOUTH); - addCenterComponent(subjectWindow); - - requestFocusInWindow(); + showPanel(GAME_PANEL_NAME); } }; SwingUtilities.invokeLater(runnable); @@ -758,7 +688,7 @@ RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); if (roundConfiguration.isTrustGameEnabled()) { JPanel panel = new JPanel(); - panel.setLayout(new BorderLayout()); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); JEditorPane trustGameInstructionsEditorPane = new JEditorPane(); trustGameInstructionsEditorPane.setContentType("text/html"); trustGameInstructionsEditorPane.setEditorKit(new HTMLEditorKit()); @@ -766,32 +696,25 @@ trustGameInstructionsEditorPane.setBackground(Color.WHITE); JScrollPane scrollPane = new JScrollPane(trustGameInstructionsEditorPane); trustGameInstructionsEditorPane.setText(client.getCurrentRoundConfiguration().getTrustGameInstructions()); - panel.add(scrollPane, BorderLayout.NORTH); + panel.add(scrollPane); TrustGamePanel trustGamePanel = new TrustGamePanel(client); - trustGamePanel.setPreferredSize(new Dimension(300, 400)); - panel.add(trustGamePanel, BorderLayout.CENTER); - addCenterComponent(panel); - panel.revalidate(); - panel.repaint(); +// trustGamePanel.setPreferredSize(new Dimension(300, 400)); + JScrollPane trustGameScrollPane = new JScrollPane(trustGamePanel); + panel.add(trustGameScrollPane); + panel.setName(TRUST_GAME_PANEL_NAME); +// addCenterComponent(panel); +// panel.revalidate(); +// panel.repaint(); + add(panel); + showPanel(TRUST_GAME_PANEL_NAME); } } public void showInstructions() { RoundConfiguration roundConfiguration = dataModel.getRoundConfiguration(); instructionsBuilder.delete(0, instructionsBuilder.length()); - roundConfiguration.buildInstructions(instructionsBuilder); - -// if (roundConfiguration.isFirstRound()) { -// instructionsBuilder.append(roundConfiguration.getGeneralInstructions()); -// } -// if (roundConfiguration.isFieldOfVisionEnabled()) { -// instructionsBuilder.append(roundConfiguration.getFieldOfVisionInstructions()); -// } -// instructionsBuilder.append(roundConfiguration.getInstructions()); -// - // and add the quiz instructions if the quiz is enabled. if (roundConfiguration.isQuizEnabled()) { instructionsEditorPane.setActionListener(null); @@ -802,64 +725,21 @@ switchInstructionsPane(); } public void switchInstructionsPane() { -// instructionsEditorPane.setText("<b>Please wait while we compute your new token totals.</b>"); - addCenterComponent(instructionsScrollPane); - revalidate(); - repaint(); - } - - public void displayActiveEnforcementMechanism() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - String activeRegulation = dataModel.getActiveRegulation().getText(); - if (activeRegulation == null || activeRegulation.trim().isEmpty()) { - activeRegulation = "No regulation specified."; - } - instructionsBuilder.append("<hr/><h2>Active regulation</h2><hr/><p>").append(activeRegulation).append("</p>"); - instructionsBuilder.append("<hr/><h2>Active enforcement mechanism</h2><hr/><p>").append(dataModel.getActiveEnforcementMechanism().getDescription()).append("</p>"); - setInstructions(instructionsBuilder.toString()); - addCenterComponent(instructionsScrollPane); - } - }); + showPanel(INSTRUCTIONS_PANEL_NAME); } - public void displaySanctionMechanism() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - instructionsBuilder.delete(0, instructionsBuilder.length()); - instructionsBuilder.append("<h2>Your group voted for the following enforcement mechanism: </h2><hr/><p>").append(dataModel.getActiveSanctionMechanism().getDescription()).append("</p>"); -// instructionsBuilder.append("<hr/><h2>Active enforcement mechanism</h2><hr/><p>").append(dataModel.getActiveEnforcementMechanism().getDescription()).append("</p>"); - setInstructions(instructionsBuilder.toString()); - addCenterComponent(instructionsScrollPane); - } - }); + private void showPanel(final String panelName) { + this.currentCardPanel = panelName; + JPanel panel = getPanel(); + cardLayout.show(panel, panelName); + panel.repaint(); } - private void displayVotingWaitMessage() { - setInstructions("<h3>Please wait while we finish collecting information from all the participants.</h3>"); - addCenterComponent(instructionsScrollPane); - } - -// public void displayActiveRegulation() { -// SwingUtilities.invokeLater(new Runnable() { -// public void run() { -// String activeRegulation = dataModel.getActiveRegulation().getText(); -// if (activeRegulation == null || activeRegulation.trim().isEmpty()) { -// activeRegulation = "No regulation specified."; -// } -// setInstructions( -// "<h3>The following regulation received the most votes:</h3><p>" + activeRegulation + "</p>"); -// addCenterComponent(instructionsScrollPane); -// startRegulationDisplayTimer(); -// } -// }); -// } - public void updateDebriefing(final PostRoundSanctionUpdateEvent event) { Runnable runnable = new Runnable() { public void run() { postSanctionDebriefingText(event); - addCenterComponent(instructionsScrollPane); + switchInstructionsPane(); } }; SwingUtilities.invokeLater(runnable); @@ -871,14 +751,17 @@ if (dataModel.getRoundConfiguration().isPostRoundSanctioningEnabled()) { // add sanctioning text and slap the PostRoundSanctioningPanel in PostRoundSanctioningPanel panel = new PostRoundSanctioningPanel(event, dataModel.getRoundConfiguration(), client); - addCenterComponent(panel); + panel.setName(POST_ROUND_SANCTIONING_PANEL_NAME); + add(panel); + showPanel(POST_ROUND_SANCTIONING_PANEL_NAME); } else { instructionsEditorPane.setText("Waiting for updated round totals from the server..."); - addCenterComponent(instructionsScrollPane); + switchInstructionsPane(); } if (chatPanel != null) { - remove(chatPanel); + // FIXME: figure out what to do here. + getPanel().remove(chatPanel); chatPanel = null; } // generate debriefing text from data culled from the Event @@ -900,10 +783,18 @@ public void run() { ChatPanel chatPanel = getChatPanel(); chatPanel.initialize(); -// remove( messagePanel ); - addCenterComponent( chatPanel ); + showPanel(CHAT_PANEL_NAME); startChatTimer(); } }); } + + public void add(JComponent component) { + getPanel().add(component, component.getName()); + } + + @Override + public JPanel getPanel() { + return mainPanel; + } } --- a/src/main/java/edu/asu/commons/foraging/client/SubjectView.java Tue Aug 30 22:53:48 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/SubjectView.java Wed Aug 31 17:18:28 2011 -0700 @@ -152,7 +152,6 @@ int verticalCharacterSpacing = (int) ( (dh - characterHeight) / 2); Point currentPosition = dataModel.getCurrentPosition(); if (subjectFieldOfVision) { - System.err.println("field of vision is set"); // paint a transparent circle centered on the current position of the subject. int radius = viewSubjectsRadius; viewSubjectsField.setCenter(currentPosition); @@ -172,7 +171,6 @@ for (Map.Entry<Identifier, ClientData> entry : positions.entrySet()) { Identifier id = entry.getKey(); Point subjectLocation = entry.getValue().getPosition(); - System.err.println("view subjects field: " + viewSubjectsField); // optimized conditional if (viewSubjectsField == null || id.equals(dataModel.getId()) || viewSubjectsField.contains(subjectLocation)) { // only draw if: --- a/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Tue Aug 30 22:53:48 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/conf/RoundConfiguration.java Wed Aug 31 17:18:28 2011 -0700 @@ -319,7 +319,9 @@ return Collections.emptyMap(); } - + public String getQuizExplanation(String questionNumber) { + return getProperty(questionNumber + "-explanation"); + } /** * Possible values, freeze, fine? @@ -552,55 +554,48 @@ } instructionsBuilder.append(getInstructions()); if (isFieldOfVisionEnabled()) { - // create note type box, test to see how - // JEditorPaneS render CSS divs or fieldsets..? - instructionsBuilder.append("<hr><b>"); - instructionsBuilder.append(getFieldOfVisionInstructions()).append("</b>"); + instructionsBuilder.append(getFieldOfVisionInstructions()); } if (isCensoredChat()) { - instructionsBuilder.append("<hr><b>"); - instructionsBuilder.append(getCensoredChatInstructions()).append("</b>"); + instructionsBuilder.append(getCensoredChatInstructions()); } else if (isInRoundChatEnabled()) { - instructionsBuilder.append("<hr><b>"); - instructionsBuilder.append(getInRoundChatInstructions()).append("</b>"); + instructionsBuilder.append(getInRoundChatInstructions()); } else if (isChatEnabled()) { - instructionsBuilder.append("<hr><b>"); // FIXME: hard-coded, need to make instructions template-able, perhaps // via FreeMarker or Velocity. - instructionsBuilder.append("Before the beginning of this round you will be able to chat with the other members of your group for ").append(getChatDuration()).append(" seconds.</b>"); + instructionsBuilder.append("Before the beginning of this round you will be able to chat with the other members of your group for ").append(getChatDuration()).append(" seconds."); } String resourceGeneratorType = getResourceGeneratorType(); if (resourceGeneratorType.equals("mobile")) { - instructionsBuilder.append("<hr>").append(getMobileResourceInstructions()); + instructionsBuilder.append(getMobileResourceInstructions()); } else if (resourceGeneratorType.equals("top-bottom-patchy")) { - instructionsBuilder.append("<hr>").append(getPatchyResourceInstructions()); + instructionsBuilder.append(getPatchyResourceInstructions()); } // and add the quiz instructions if the quiz is enabled. if (isQuizEnabled()) { - instructionsBuilder.append("<hr><b>"); - instructionsBuilder.append(getQuizInstructions()).append("</b>"); + instructionsBuilder.append(getQuizInstructions()); } return instructionsBuilder; } private String getMobileResourceInstructions() { - return getProperty("mobile-resource-instructions", "The resource can move around in a semblance of free will / agency."); + return getProperty("mobile-resource-instructions", "<p>The resource can move around in a semblance of free will / agency.</p>"); } private String getPatchyResourceInstructions() { - return getProperty("patch-resource-instructiosn", "The resource is not uniformly distributed. There are patches of high growth and low growth."); + return getProperty("patch-resource-instructiosn", "<p>The resource is not uniformly distributed. There are patches of high growth and low growth.</p>"); } private String getInRoundChatInstructions() { - return getProperty("in-round-chat-instructions", "You can chat during this round with all players visible on the screen."); + return getProperty("in-round-chat-instructions", "<p>You can chat during this round with all players visible on the screen.</p>"); } public String getTrustGameInstructions() { - return getProperty("trust-game-instructions", "You will be randomly matched with another person in your group."); + return getProperty("trust-game-instructions"); } } --- a/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Tue Aug 30 22:53:48 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/server/ForagingServer.java Wed Aug 31 17:18:28 2011 -0700 @@ -3,8 +3,11 @@ import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.FileHandler; @@ -72,9 +75,6 @@ import edu.asu.commons.net.event.DisconnectionRequest; import edu.asu.commons.util.Duration; import edu.asu.commons.util.Utils; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; /** * $Id: ForagingServer.java 529 2010-08-17 00:08:01Z alllee $ @@ -107,7 +107,7 @@ private ForagingPersister persister; - private volatile int numberOfCompletedQuizzes; + private volatile int numberOfSubmittedQuizzes; private volatile int numberOfCompletedSanctions; private volatile int numberOfCompletedAgentDesigns; @@ -298,21 +298,12 @@ addEventProcessor(new EventTypeProcessor<QuizResponseEvent>(QuizResponseEvent.class) { public void handle(final QuizResponseEvent event) { - // XXX: can get rid of this event processor once we verify that the persister is storing it properly - logger.info("Received quiz response: " + event); - } - }); - - addEventProcessor(new EventTypeProcessor<QuizCompletedEvent>(QuizCompletedEvent.class) { - public void handle(QuizCompletedEvent event) { - numberOfCompletedQuizzes++; - // System.err.println("XXX: queued clients; " + queuedClients); - //System.err.println("XXX: number of completed quizzes; " + numberOfCompletedQuizzes); - if (numberOfCompletedQuizzes == clients.size()) { + numberOfSubmittedQuizzes++; + if (numberOfSubmittedQuizzes >= clients.size()) { // we're done, notify the sleeping queue. logger.info("Received all quizzes, notifying quiz signal"); Utils.notify(quizSignal); - numberOfCompletedQuizzes = 0; + numberOfSubmittedQuizzes = 0; } // FIXME: pass in the id of the client completing the quiz? transmit(new QuizCompletedEvent(facilitatorId)); @@ -651,7 +642,7 @@ logger.info("Begin round request from facilitator - starting round."); experimentStarted = true; Utils.notify(roundSignal); - System.out.println("Signalled the round start"); + System.out.println("Notified round signal"); } else { logger.warning("Ignoring begin round request from id: " + event.getId()); Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-08-31 05:53:24
|
1 new changeset in foraging: http://bitbucket.org/virtualcommons/foraging/changeset/dcf0eb05d1f0/ changeset: dcf0eb05d1f0 user: alllee date: 2011-08-31 07:53:48 summary: changing setSizes to setPreferredSize / pack affected #: 2 files (63 bytes) --- a/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Mon Aug 22 18:57:38 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/ForagingClient.java Tue Aug 30 22:53:48 2011 -0700 @@ -411,16 +411,16 @@ e.printStackTrace(); System.err.println("Couldn't set native look and feel: "+ e); } - Dimension defaultDimension = new Dimension(600, 600); + Dimension defaultDimension = new Dimension(1024, 768); JFrame frame = new JFrame(); ForagingClient client = new ForagingClient(new ServerConfiguration(), defaultDimension); client.connect(); frame.setTitle("Client Window: " + client.getId()); - frame.setSize(defaultDimension); frame.add(client.clientPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setPreferredSize(defaultDimension); frame.setVisible(true); - + frame.pack(); } }; SwingUtilities.invokeLater(createGuiRunnable); --- a/src/main/java/edu/asu/commons/foraging/client/GridView.java Mon Aug 22 18:57:38 2011 -0700 +++ b/src/main/java/edu/asu/commons/foraging/client/GridView.java Tue Aug 30 22:53:48 2011 -0700 @@ -86,7 +86,7 @@ fontSize = (int)(0.85 * dh); font = new Font("sansserif", Font.BOLD, fontSize); // make sure we've got enough room - setSize(availableWidth, availableHeight); + setPreferredSize(new Dimension(availableWidth, availableHeight)); //FIXME: reduce code duplication // get scaled instances of the originals Repository URL: https://bitbucket.org/virtualcommons/foraging/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-08-30 22:04:16
|
2 new changesets in vcweb: http://bitbucket.org/virtualcommons/vcweb/changeset/e3ecfdd9c740/ changeset: e3ecfdd9c740 user: alllee date: 2011-08-31 00:02:26 summary: adding retrieve_all parameter to group activity json view affected #: 2 files (172 bytes) --- a/vcweb/lighterprints/models.py Mon Aug 22 16:24:16 2011 -0700 +++ b/vcweb/lighterprints/models.py Tue Aug 30 15:02:26 2011 -0700 @@ -90,6 +90,7 @@ return ActivityAvailability.objects.select_related(depth=1).filter(Q(**available_time_slot) | Q(**available_all_day)) def is_activity_available(activity, participant_group_relationship, **kwargs): + # FIXME: make sure that the activity level is appropriate for this PGR # how often can a participant participate in an activity? # whenever it falls within the ActivityAvailability schedule and if the participant # hasn't already performed this activity during this cycle. --- a/vcweb/lighterprints/views.py Mon Aug 22 16:24:16 2011 -0700 +++ b/vcweb/lighterprints/views.py Tue Aug 30 15:02:26 2011 -0700 @@ -129,7 +129,7 @@ return HttpResponseBadRequest(dumps({'response': "Could not perform activity"}), content_type='text/javascript') -def get_group_activity_json(participant_group_relationship, number_of_activities=5): +def get_group_activity_json(participant_group_relationship, number_of_activities=5, retrieve_all=True): group = participant_group_relationship.group chat_messages = [] for chat_message in ChatMessage.objects.filter(participant_group_relationship__group=group).order_by('-date_created'): @@ -140,6 +140,8 @@ }) group_activity = [] performed_activities = ParticipantRoundDataValue.objects.filter(participant_group_relationship__group=group, submitted=True, parameter=get_activity_performed_parameter()).order_by('-date_created') + if retrieve_all: + number_of_activities = len(performed_activities) for activity_prdv in performed_activities[:number_of_activities]: # FIXME: change this to activity name if we decide to use names instead of # pks http://bitbucket.org/virtualcommons/vcweb/changeset/187bc2b10ffb/ changeset: 187bc2b10ffb user: alllee date: 2011-08-31 00:04:02 summary: urk, forgot to fetch/merge before committing affected #: 2 files (172 bytes) --- a/vcweb/lighterprints/models.py Tue Aug 30 15:00:20 2011 -0700 +++ b/vcweb/lighterprints/models.py Tue Aug 30 15:04:02 2011 -0700 @@ -90,6 +90,7 @@ return ActivityAvailability.objects.select_related(depth=1).filter(Q(**available_time_slot) | Q(**available_all_day)) def is_activity_available(activity, participant_group_relationship, **kwargs): + # FIXME: make sure that the activity level is appropriate for this PGR # how often can a participant participate in an activity? # whenever it falls within the ActivityAvailability schedule and if the participant # hasn't already performed this activity during this cycle. --- a/vcweb/lighterprints/views.py Tue Aug 30 15:00:20 2011 -0700 +++ b/vcweb/lighterprints/views.py Tue Aug 30 15:04:02 2011 -0700 @@ -129,7 +129,7 @@ return HttpResponseBadRequest(dumps({'response': "Could not perform activity"}), content_type='text/javascript') -def get_group_activity_json(participant_group_relationship, number_of_activities=5): +def get_group_activity_json(participant_group_relationship, number_of_activities=5, retrieve_all=True): group = participant_group_relationship.group chat_messages = [] for chat_message in ChatMessage.objects.filter(participant_group_relationship__group=group).order_by('-date_created'): @@ -140,6 +140,8 @@ }) group_activity = [] performed_activities = ParticipantRoundDataValue.objects.filter(participant_group_relationship__group=group, submitted=True, parameter=get_activity_performed_parameter()).order_by('-date_created') + if retrieve_all: + number_of_activities = len(performed_activities) for activity_prdv in performed_activities[:number_of_activities]: # FIXME: change this to activity name if we decide to use names instead of # pks Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <com...@bi...> - 2011-08-30 22:00:01
|
1 new changeset in vcweb: http://bitbucket.org/virtualcommons/vcweb/changeset/f874f11bf8ee/ changeset: f874f11bf8ee user: alllee date: 2011-08-31 00:00:20 summary: applying never_cache cache-control http headers to json calls affected #: 2 files (105 bytes) --- a/vcweb/lighterprints/urls.py Mon Aug 22 16:24:16 2011 -0700 +++ b/vcweb/lighterprints/urls.py Tue Aug 30 15:00:20 2011 -0700 @@ -1,4 +1,5 @@ from django.conf.urls.defaults import url, patterns +from django.views.decorators.cache import never_cache from vcweb.lighterprints.views import (ActivityDetailView, ActivityListView, MobileView, post_chat_message, perform_activity, DiscussionBoardView, login, @@ -7,10 +8,10 @@ urlpatterns = patterns('vcweb.lighterprints.views', url(r'^mobile$', MobileView.as_view(), name='mobile'), url(r'^(?P<experiment_id>\d+)/configure$', 'configure', name='configure'), - url(r'^activity/list/?$', ActivityListView.as_view()), - url(r'^activity/(?P<activity_id>\d+)$', ActivityDetailView.as_view()), + url(r'^activity/list/?$', never_cache(ActivityListView.as_view())), + url(r'^activity/(?P<activity_id>\d+)$', never_cache(ActivityDetailView.as_view())), url(r'^discussion/(?P<experiment_id>\d+)/(?P<participant_id>\d+)', DiscussionBoardView.as_view()), - url(r'^api/group-activity/(?P<participant_group_id>\d+)', group_activity), + url(r'^api/group-activity/(?P<participant_group_id>\d+)', never_cache(group_activity)), url(r'^api/do-activity$', perform_activity), url(r'^api/post-chat', post_chat_message), url(r'^api/login', login), --- a/vcweb/lighterprints/views.py Mon Aug 22 16:24:16 2011 -0700 +++ b/vcweb/lighterprints/views.py Tue Aug 30 15:00:20 2011 -0700 @@ -8,7 +8,7 @@ from django.views.generic.list import BaseListView, MultipleObjectTemplateResponseMixin from vcweb.core.forms import LoginForm -from vcweb.core.models import (ChatMessage, Experiment, ParticipantGroupRelationship, ParticipantRoundDataValue) +from vcweb.core.models import (ChatMessage, ParticipantGroupRelationship, ParticipantRoundDataValue) from vcweb.core.views import JSONResponseMixin, dumps, set_authentication_token from vcweb.core.validate_jsonp import is_valid_jsonp_callback_value # FIXME: move ChatForm to core? Repository URL: https://bitbucket.org/virtualcommons/vcweb/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. |
From: Bitbucket <iss...@bi...> - 2011-08-29 18:36:33
|
--- you can reply above this line --- New issue 31: work out custom information availability https://bitbucket.org/virtualcommons/vcweb/issue/31/work-out-custom-information-availability A Lee / alllee on Mon, 29 Aug 2011 20:36:27 +0200: Description: Concurrent groups will probably have different information sets available to them. Need to: # figure out what logic goes server-side and what goes client-side # if possible, push everything to server-side, makes it simpler # identify what client-side visualizations need to be created Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |
From: Bitbucket <iss...@bi...> - 2011-08-26 19:18:11
|
--- you can reply above this line --- New issue 30: level isn't being used in is_activity_available https://bitbucket.org/virtualcommons/vcweb/issue/30/level-isnt-being-used-in A Lee / alllee on Fri, 26 Aug 2011 21:18:05 +0200: Description: Responsible: alllee -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. |