Commit a1b6309a11f729e97e4031b5468f794029636ded

Authored by Carlos Picanco
1 parent fe645aa2
Exists in master

implement next condition and experiment end

form_chooseactor.pas
@@ -126,9 +126,10 @@ begin @@ -126,9 +126,10 @@ begin
126 WordWrap := True; 126 WordWrap := True;
127 Parent:=Self; 127 Parent:=Self;
128 Font.Size := 30; 128 Font.Size := 30;
  129 + OnClick := @ShowResumeButton;
129 case FStyle of 130 case FStyle of
130 - '.Left': OnClick := @ShowResumeButton;  
131 - '.EndX': OnClick := @ExitApplication; 131 + '.Left': btnPlayerResume.Caption := 'Entrar';
  132 + '.EndX': btnPlayerResume.Caption := 'Sair';
132 end; 133 end;
133 end; 134 end;
134 end; 135 end;
units/game_control.pas
@@ -56,11 +56,14 @@ type @@ -56,11 +56,14 @@ type
56 procedure ShowConsequenceMessage(AID,S:string;ForGroup:Boolean); 56 procedure ShowConsequenceMessage(AID,S:string;ForGroup:Boolean);
57 procedure DisableConfirmationButton; 57 procedure DisableConfirmationButton;
58 procedure CleanMatrix(AEnabled : Boolean); 58 procedure CleanMatrix(AEnabled : Boolean);
  59 + procedure NextConditionSetup(S : string);
59 procedure EnablePlayerMatrix(AID:UTF8string; ATurn:integer; AEnabled:Boolean); 60 procedure EnablePlayerMatrix(AID:UTF8string; ATurn:integer; AEnabled:Boolean);
60 private 61 private
  62 + function IsLastCondition : Boolean;
61 function ShouldStartExperiment: Boolean; 63 function ShouldStartExperiment: Boolean;
62 function ShouldEndCycle : Boolean; 64 function ShouldEndCycle : Boolean;
63 - function ShouldEndGeneration : Boolean; 65 + function ShouldEndCondition : Boolean;
  66 + //function ShouldEndGeneration : Boolean;
64 function ShouldAskQuestion : Boolean; 67 function ShouldAskQuestion : Boolean;
65 procedure NextTurn(Sender: TObject); 68 procedure NextTurn(Sender: TObject);
66 procedure NextCycle(Sender: TObject); 69 procedure NextCycle(Sender: TObject);
@@ -105,6 +108,7 @@ const @@ -105,6 +108,7 @@ const
105 K_QMESSAGE = '.QMessage'; 108 K_QMESSAGE = '.QMessage';
106 K_MOVQUEUE = '.Queue'; 109 K_MOVQUEUE = '.Queue';
107 K_END = '.EndX'; 110 K_END = '.EndX';
  111 + K_NXTCND = '.NextCond';
108 112
109 // 113 //
110 K_STATUS = '.Status'; 114 K_STATUS = '.Status';
@@ -158,16 +162,31 @@ begin @@ -158,16 +162,31 @@ begin
158 Result := FExperiment.Condition[FExperiment.CurrentCondition].Turn.Count = FExperiment.Condition[FExperiment.CurrentCondition].Turn.Value-1; 162 Result := FExperiment.Condition[FExperiment.CurrentCondition].Turn.Count = FExperiment.Condition[FExperiment.CurrentCondition].Turn.Value-1;
159 end; 163 end;
160 164
161 -function TGameControl.ShouldEndGeneration: Boolean; 165 +function TGameControl.IsLastCondition: Boolean;
162 begin 166 begin
163 - Result := FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Count = FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Value-1; 167 + Result := FExperiment.CurrentCondition = FExperiment.ConditionsCount-1;
164 end; 168 end;
165 169
  170 +function TGameControl.ShouldEndCondition: Boolean;
  171 +begin
  172 + Result := FExperiment.ShouldEndCondition;
  173 +end;
  174 +
  175 +//function TGameControl.ShouldEndGeneration: Boolean;
  176 +//begin
  177 +// Result := FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Count = FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Value-1;
  178 +//end;
  179 +
166 function TGameControl.ShouldAskQuestion: Boolean; 180 function TGameControl.ShouldAskQuestion: Boolean;
167 begin 181 begin
168 Result := Assigned(FExperiment.Condition[FExperiment.CurrentCondition].Prompt) and FExperiment.Condition[FExperiment.CurrentCondition].Contingencies[3].Fired; 182 Result := Assigned(FExperiment.Condition[FExperiment.CurrentCondition].Prompt) and FExperiment.Condition[FExperiment.CurrentCondition].Contingencies[3].Fired;
169 end; 183 end;
170 184
  185 +procedure TGameControl.EndExperiment(Sender: TObject);
  186 +begin
  187 + ShowPopUp('O Experimento terminou.');
  188 +end;
  189 +
171 procedure TGameControl.NextTurn(Sender: TObject); 190 procedure TGameControl.NextTurn(Sender: TObject);
172 begin 191 begin
173 // update admin view 192 // update admin view
@@ -194,11 +213,7 @@ begin @@ -194,11 +213,7 @@ begin
194 FormMatrixGame.LabelExpCountCondition.Caption:= FExperiment.Condition[FExperiment.CurrentCondition].ConditionName; 213 FormMatrixGame.LabelExpCountCondition.Caption:= FExperiment.Condition[FExperiment.CurrentCondition].ConditionName;
195 214
196 // append OnStart data 215 // append OnStart data
197 - //FExperiment.Condition[FExperiment.CurrentCondition].Points.OnStart.A;  
198 - //FExperiment.Condition[FExperiment.CurrentCondition].Points.OnStart.B;  
199 - //FExperiment.Condition[FExperiment.CurrentCondition].Points.OnStart.G;  
200 -  
201 - // append which player 216 + NextConditionSetup(FExperiment.CurrentConditionAsString);
202 end; 217 end;
203 218
204 procedure TGameControl.Interlocking(Sender: TObject); 219 procedure TGameControl.Interlocking(Sender: TObject);
@@ -223,11 +238,6 @@ begin @@ -223,11 +238,6 @@ begin
223 {$ENDIF} 238 {$ENDIF}
224 end; 239 end;
225 240
226 -procedure TGameControl.EndExperiment(Sender: TObject);  
227 -begin  
228 - FZMQActor.SendMessage([K_END]);  
229 -end;  
230 -  
231 procedure TGameControl.StartExperiment; 241 procedure TGameControl.StartExperiment;
232 begin 242 begin
233 // all players arrived, lets begin 243 // all players arrived, lets begin
@@ -532,6 +542,62 @@ begin @@ -532,6 +542,62 @@ begin
532 FormMatrixGame.btnConfirmRow.Visible := False; 542 FormMatrixGame.btnConfirmRow.Visible := False;
533 end; 543 end;
534 544
  545 +procedure TGameControl.NextConditionSetup(S: string);
  546 +var
  547 + A, B, G : integer;
  548 + P : TPlayer;
  549 + PB : TPlayerBox;
  550 +begin
  551 + if FExperiment.ABPoints then
  552 + begin
  553 + A := StrToInt(ExtractDelimited(1,S,['|']));
  554 + B := StrToInt(ExtractDelimited(2,S,['|']));
  555 + G := StrToInt(ExtractDelimited(3,S,['|']));
  556 +
  557 + G += StrToInt(FormMatrixGame.LabelGroupCount.Caption);
  558 + FormMatrixGame.LabelGroupCount.Caption := IntToStr(G);
  559 + case FActor of
  560 + gaPlayer:
  561 + begin
  562 + A += StrToInt(FormMatrixGame.LabelIndACount.Caption);
  563 + B += StrToInt(FormMatrixGame.LabelIndBCount.Caption);
  564 +
  565 + FormMatrixGame.LabelIndACount.Caption := IntToStr(A);
  566 + FormMatrixGame.LabelIndBCount.Caption := IntToStr(B);
  567 + end;
  568 + gaAdmin:
  569 + for P in FExperiment.Players do
  570 + begin
  571 + PB := GetPlayerBox(P.ID);
  572 + A += StrToInt(PB.LabelPointsCount.Caption) + B;
  573 + PB.LabelPointsCount.Caption := IntToStr(A);
  574 + end;
  575 + end;
  576 + end
  577 + else
  578 + begin
  579 + A := StrToInt(ExtractDelimited(1,S,['|']));
  580 + G := StrToInt(ExtractDelimited(2,S,['|']));
  581 + G += StrToInt(FormMatrixGame.LabelGroupCount.Caption);
  582 + FormMatrixGame.LabelGroupCount.Caption := IntToStr(G);
  583 + case FActor of
  584 + gaPlayer:
  585 + begin
  586 + A += StrToInt(FormMatrixGame.LabelIndACount.Caption);
  587 + FormMatrixGame.LabelIndCount.Caption := IntToStr(A);
  588 + end;
  589 +
  590 + gaAdmin:
  591 + for P in FExperiment.Players do
  592 + begin
  593 + PB := GetPlayerBox(P.ID);
  594 + A += StrToInt(PB.LabelPointsCount.Caption) + B;
  595 + PB.LabelPointsCount.Caption := IntToStr(A);
  596 + end;
  597 + end;
  598 + end;
  599 +end;
  600 +
535 procedure TGameControl.EnablePlayerMatrix(AID:UTF8string; ATurn:integer; AEnabled:Boolean); 601 procedure TGameControl.EnablePlayerMatrix(AID:UTF8string; ATurn:integer; AEnabled:Boolean);
536 begin 602 begin
537 if FExperiment.PlayerFromID[AID].Turn = ATurn then 603 if FExperiment.PlayerFromID[AID].Turn = ATurn then
@@ -571,6 +637,7 @@ begin @@ -571,6 +637,7 @@ begin
571 FExperiment.OnEndExperiment:= @EndExperiment; 637 FExperiment.OnEndExperiment:= @EndExperiment;
572 FExperiment.OnInterlocking:=@Interlocking; 638 FExperiment.OnInterlocking:=@Interlocking;
573 FExperiment.OnConsequence:=@Consequence; 639 FExperiment.OnConsequence:=@Consequence;
  640 + FExperiment.OnTargetInterlocking:=@TargetInterlocking;
574 641
575 SendRequest(K_LOGIN); // admin cannot send requests 642 SendRequest(K_LOGIN); // admin cannot send requests
576 end; 643 end;
@@ -703,7 +770,8 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); @@ -703,7 +770,8 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList);
703 , ' ' 770 , ' '
704 , GA_PLAYER+K_QUESTION 771 , GA_PLAYER+K_QUESTION
705 , AskQuestion(AMessage[1]) 772 , AskQuestion(AMessage[1])
706 - , AMessage[2] 773 + , AMessage[2] // generation
  774 + , AMessage[3] // conditions
707 ]); 775 ]);
708 end; 776 end;
709 777
@@ -780,8 +848,13 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); @@ -780,8 +848,13 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList);
780 end; 848 end;
781 849
782 procedure ReceiveChat; 850 procedure ReceiveChat;
  851 + var
  852 + ALn: string;
783 begin 853 begin
784 - FormMatrixGame.ChatMemoRecv.Lines.Append(('['+AMessage[1]+']: ')+AMessage[2]); 854 + ALn := '['+AMessage[1]+']: '+AMessage[2];
  855 + FormMatrixGame.ChatMemoRecv.Lines.Append(ALn);
  856 + if FActor = gaAdmin then
  857 + FExperiment.WriteChatLn(ALn);
785 end; 858 end;
786 859
787 procedure MovePlayerQueue; 860 procedure MovePlayerQueue;
@@ -839,51 +912,7 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); @@ -839,51 +912,7 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList);
839 end; 912 end;
840 end; 913 end;
841 914
842 - procedure ResumeNextTurn;  
843 - begin  
844 - case FActor of  
845 - gaPlayer:begin  
846 - if AMessage[1] <> #32 then  
847 - SayGoodBye(AMessage[1])  
848 - else  
849 - EnablePlayerMatrix(Self.ID,0, True);  
850 -  
851 - end;  
852 - gaAdmin:begin  
853 - if AMessage[1] <> #32 then  
854 - begin  
855 - DeletePlayerBox(AMessage[1]); // old player  
856 - ShowPopUp(  
857 - 'O participante '+  
858 - FExperiment.PlayerFromID[AMessage[1]].Nicname+  
859 - ' saiu. Aguardando a entrada do próximo participante.'  
860 - );  
861 - end;  
862 - end;  
863 - end;  
864 - end;  
865 -  
866 - procedure QuestionMessages;  
867 - var  
868 - i : integer;  
869 - MID : string;  
870 - begin  
871 - if AMessage.Count > 1 then  
872 - begin  
873 - for i := 2 to AMessage.Count -1 do  
874 - begin  
875 - MID := ExtractDelimited(1,AMessage[i],['+']);  
876 - ShowConsequenceMessage(MID, ExtractDelimited(2,AMessage[i],['+']),MID = 'M');  
877 -  
878 - {$IFDEF DEBUG}  
879 - WriteLn('A Prompt consequence should have shown.');  
880 - {$ENDIF}  
881 - end;  
882 - end;  
883 - ResumeNextTurn;  
884 - end;  
885 -  
886 - procedure ShowPointsToPlayers; 915 + procedure EndExperimentMessage;
887 var Pts : string; 916 var Pts : string;
888 begin 917 begin
889 case FActor of 918 case FActor of
@@ -901,16 +930,74 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); @@ -901,16 +930,74 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList);
901 FormChooseActor.ShowPoints( 930 FormChooseActor.ShowPoints(
902 'A tarefa terminou, obrigado por sua participação! Você produziu ' + 931 'A tarefa terminou, obrigado por sua participação! Você produziu ' +
903 Pts + ' pontos e ' + 932 Pts + ' pontos e ' +
904 - FormMatrixGame.LabelGroupCount.Caption + 'itens escolares serão doados!');  
905 - FormChooseActor.Show;  
906 - end;  
907 - gaAdmin:  
908 - begin  
909 - Stop; 933 + FormMatrixGame.LabelGroupCount.Caption + 'itens escolares serão doados! Parabéns!');
  934 + FormChooseActor.ShowModal;
  935 + FormChooseActor.Free;
  936 + FormMatrixGame.Close;
910 end; 937 end;
  938 + gaAdmin:Stop;
911 end; 939 end;
912 end; 940 end;
913 941
  942 + procedure ResumeNextTurn;
  943 + begin
  944 + if AMessage[2] <> #27 then
  945 + begin
  946 + case FActor of
  947 + gaPlayer:
  948 + begin
  949 + if AMessage[1] <> #32 then
  950 + SayGoodBye(AMessage[1])
  951 + else
  952 + EnablePlayerMatrix(Self.ID,0, True);
  953 + end;
  954 +
  955 + gaAdmin:
  956 + begin
  957 + if AMessage[1] <> #32 then
  958 + begin
  959 + DeletePlayerBox(AMessage[1]); // old player
  960 + ShowPopUp(
  961 + 'O participante '+
  962 + FExperiment.PlayerFromID[AMessage[1]].Nicname+
  963 + ' saiu. Aguardando a entrada do próximo participante.'
  964 + );
  965 + end;
  966 + end;
  967 +
  968 + end;
  969 + if AMessage[2] <> #32 then
  970 + NextConditionSetup(AMessage[2]);
  971 + end
  972 + else EndExperimentMessage;
  973 + end;
  974 +
  975 + procedure QuestionMessages;
  976 + var
  977 + i : integer;
  978 + MID : string;
  979 + begin
  980 + if AMessage[2] <> #27 then
  981 + begin
  982 + if AMessage.Count > 1 then
  983 + begin
  984 + for i := 3 to AMessage.Count -1 do
  985 + begin
  986 + MID := ExtractDelimited(1,AMessage[i],['+']);
  987 + ShowConsequenceMessage(MID, ExtractDelimited(2,AMessage[i],['+']),MID = 'M');
  988 +
  989 + {$IFDEF DEBUG}
  990 + WriteLn('A Prompt consequence should have shown.');
  991 + {$ENDIF}
  992 + end;
  993 + end;
  994 + ResumeNextTurn;
  995 + if AMessage[2] <> #32 then
  996 + NextConditionSetup(AMessage[2]);
  997 + end
  998 + else EndExperimentMessage;
  999 + end;
  1000 +
914 begin 1001 begin
915 if MHas(K_ARRIVED) then ReceiveActor; 1002 if MHas(K_ARRIVED) then ReceiveActor;
916 if MHas(K_CHAT_M) then ReceiveChat; 1003 if MHas(K_CHAT_M) then ReceiveChat;
@@ -921,7 +1008,8 @@ begin @@ -921,7 +1008,8 @@ begin
921 if MHas(K_MOVQUEUE) then MovePlayerQueue; 1008 if MHas(K_MOVQUEUE) then MovePlayerQueue;
922 if MHas(K_QMESSAGE) then QuestionMessages; 1009 if MHas(K_QMESSAGE) then QuestionMessages;
923 if MHas(K_RESUME) then ResumeNextTurn; 1010 if MHas(K_RESUME) then ResumeNextTurn;
924 - if MHAs(K_END) then ShowPointsToPlayers; 1011 + if MHas(K_NXTCND) then NextConditionSetup(AMessage[1]);
  1012 + if MHAs(K_END) then EndExperimentMessage;
925 end; 1013 end;
926 1014
927 // Here FActor is garanted to be a TZMQAdmin 1015 // Here FActor is garanted to be a TZMQAdmin
@@ -983,17 +1071,20 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); @@ -983,17 +1071,20 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList);
983 if FExperiment.Player[i].ID <> P.ID then 1071 if FExperiment.Player[i].ID <> P.ID then
984 begin 1072 begin
985 TS := FExperiment.PlayerAsString[FEXperiment.Player[i]]; 1073 TS := FExperiment.PlayerAsString[FEXperiment.Player[i]];
986 - ARequest.Append(TS); // FROM 3 to COUNT-3 1074 + ARequest.Append(TS); // FROM 3 to COUNT-4
987 end; 1075 end;
988 1076
989 - // append chat data if allowed at the last position 1077 + // append chat data if allowed
990 if FExperiment.SendChatHistoryForNewPlayers then 1078 if FExperiment.SendChatHistoryForNewPlayers then
991 - ARequest.Append(FormMatrixGame.ChatMemoRecv.Lines.Text) // COUNT-2 1079 + ARequest.Append(FormMatrixGame.ChatMemoRecv.Lines.Text) // COUNT-3
992 else 1080 else
993 ARequest.Append('[CHAT]'); // must append something to keep the message envelop standard 1081 ARequest.Append('[CHAT]'); // must append something to keep the message envelop standard
994 1082
995 // append global configs. 1083 // append global configs.
996 - ARequest.Append(BoolToStr(FExperiment.ABPoints)); // COUNT-1 1084 + ARequest.Append(BoolToStr(FExperiment.ABPoints)); // COUNT-2
  1085 +
  1086 + // append condition global data
  1087 + ARequest.Append(FExperiment.CurrentConditionAsString);
997 1088
998 // inform all players about the new player, including itself 1089 // inform all players about the new player, including itself
999 FZMQActor.SendMessage([K_ARRIVED,PS]); 1090 FZMQActor.SendMessage([K_ARRIVED,PS]);
@@ -1019,7 +1110,9 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); @@ -1019,7 +1110,9 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList);
1019 LConsequences : string; 1110 LConsequences : string;
1020 P : TPlayer; 1111 P : TPlayer;
1021 S : string; 1112 S : string;
  1113 + LEndCondition,
1022 LEndCycle : Boolean; 1114 LEndCycle : Boolean;
  1115 + LEndGeneration: string;
1023 begin 1116 begin
1024 {$IFDEF DEBUG} 1117 {$IFDEF DEBUG}
1025 WriteLn('Count:',FExperiment.Condition[FExperiment.CurrentCondition].Turn.Count, '<', FExperiment.Condition[FExperiment.CurrentCondition].Turn.Value); 1118 WriteLn('Count:',FExperiment.Condition[FExperiment.CurrentCondition].Turn.Count, '<', FExperiment.Condition[FExperiment.CurrentCondition].Turn.Value);
@@ -1038,10 +1131,13 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); @@ -1038,10 +1131,13 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList);
1038 if Pos('$NICNAME',S) > 0 then 1131 if Pos('$NICNAME',S) > 0 then
1039 S := ReplaceStr(S,'$NICNAME',P.Nicname); 1132 S := ReplaceStr(S,'$NICNAME',P.Nicname);
1040 1133
1041 - // update turn 1134 + // "NextGeneration" and "ShouldEndCycle" methods must be called before Experiment.NextTurn
1042 LEndCycle := ShouldEndCycle; 1135 LEndCycle := ShouldEndCycle;
  1136 + LEndGeneration := FExperiment.NextGeneration;
1043 if LEndCycle then 1137 if LEndCycle then
1044 - LConsequences := FExperiment.ConsequenceStringFromChoices;// AsString generates the pts result; must be called before next cycle 1138 + LConsequences := FExperiment.ConsequenceStringFromChoices;
  1139 +
  1140 + // update turn
1045 P.Turn := FExperiment.NextTurn; 1141 P.Turn := FExperiment.NextTurn;
1046 FExperiment.Player[FExperiment.PlayerIndexFromID[P.ID]] := P; 1142 FExperiment.Player[FExperiment.PlayerIndexFromID[P.ID]] := P;
1047 1143
@@ -1061,7 +1157,22 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); @@ -1061,7 +1157,22 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList);
1061 FExperiment.WriteReportRowPrompt; 1157 FExperiment.WriteReportRowPrompt;
1062 FExperiment.Clean; 1158 FExperiment.Clean;
1063 end; 1159 end;
1064 - ARequest.Append(FExperiment.NextGeneration); // 9, #32 no, else NextGeneration = PlayerToKick 1160 +
  1161 + ARequest.Append(LEndGeneration); // 9, #32 resume, else NextGeneration = PlayerToKick AID
  1162 + LEndCondition := ShouldEndCondition;
  1163 + if IsLastCondition and LEndCondition then // 10
  1164 + // end experiment envelop
  1165 + ARequest.Append(#27)
  1166 + else
  1167 + if LEndCondition then
  1168 + begin
  1169 + FExperiment.NextCondition;
  1170 + // end condition envelop
  1171 + ARequest.Append(FExperiment.CurrentConditionAsString);
  1172 + end
  1173 + else
  1174 + // do nothing envelop
  1175 + ARequest.Append(#32);
1065 end; 1176 end;
1066 end; 1177 end;
1067 1178
@@ -1084,9 +1195,10 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); @@ -1084,9 +1195,10 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList);
1084 1195
1085 // generate messages 1196 // generate messages
1086 LPromptConsequences := FExperiment.Condition[FExperiment.CurrentCondition].Prompt.AsString; 1197 LPromptConsequences := FExperiment.Condition[FExperiment.CurrentCondition].Prompt.AsString;
1087 - SetLength(M, 2+LPromptConsequences.Count); 1198 + SetLength(M, 3+LPromptConsequences.Count);
1088 M[0] := K_QMESSAGE; 1199 M[0] := K_QMESSAGE;
1089 - M[1] := ARequest[4]; // generations 1200 + M[1] := ARequest[4]; // generation envelop
  1201 + M[2] := ARequest[5]; // conditions
1090 if LPromptConsequences.Count > 0 then 1202 if LPromptConsequences.Count > 0 then
1091 begin 1203 begin
1092 for i := 0 to LPromptConsequences.Count-1 do 1204 for i := 0 to LPromptConsequences.Count-1 do
@@ -1096,7 +1208,7 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); @@ -1096,7 +1208,7 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList);
1096 LPromptConsequences[i] := ReplaceStr(LPromptConsequences[i],'$NICNAME', P.Nicname); 1208 LPromptConsequences[i] := ReplaceStr(LPromptConsequences[i],'$NICNAME', P.Nicname);
1097 end; 1209 end;
1098 for i := 0 to LPromptConsequences.Count -1 do 1210 for i := 0 to LPromptConsequences.Count -1 do
1099 - M[i+2] := LPromptConsequences[i]; 1211 + M[i+3] := LPromptConsequences[i]; // messages envelop
1100 end 1212 end
1101 else; 1213 else;
1102 1214
@@ -1147,7 +1259,7 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); @@ -1147,7 +1259,7 @@ procedure TGameControl.ReceiveReply(AReply: TStringList);
1147 begin 1259 begin
1148 if Self.ID = AReply[0] then 1260 if Self.ID = AReply[0] then
1149 begin 1261 begin
1150 - for i:= 3 to AReply.Count -3 do 1262 + for i:= 3 to AReply.Count -4 do
1151 begin 1263 begin
1152 P := FExperiment.PlayerFromString[AReply[i]]; 1264 P := FExperiment.PlayerFromString[AReply[i]];
1153 FExperiment.AppendPlayer(P); 1265 FExperiment.AppendPlayer(P);
@@ -1156,11 +1268,15 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); @@ -1156,11 +1268,15 @@ procedure TGameControl.ReceiveReply(AReply: TStringList);
1156 1268
1157 // add chat 1269 // add chat
1158 FormMatrixGame.ChatMemoRecv.Lines.Clear; 1270 FormMatrixGame.ChatMemoRecv.Lines.Clear;
1159 - FormMatrixGame.ChatMemoRecv.Lines.Add(AReply[AReply.Count-2]); 1271 + FormMatrixGame.ChatMemoRecv.Lines.Add(AReply[AReply.Count-3]);
1160 1272
1161 // set global configs 1273 // set global configs
1162 - FormMatrixGame.GBIndividualAB.Visible := StrToBool(AReply[AReply.Count-1]); 1274 + FExperiment.ABPoints := StrToBool(AReply[AReply.Count-2]);
  1275 + FormMatrixGame.GBIndividualAB.Visible := FExperiment.ABPoints;
1163 FormMatrixGame.GBIndividual.Visible:= not FormMatrixGame.GBIndividualAB.Visible; 1276 FormMatrixGame.GBIndividual.Visible:= not FormMatrixGame.GBIndividualAB.Visible;
  1277 +
  1278 + // set condition specific configurations
  1279 + NextConditionSetup(AReply[AReply.Count-1])
1164 end 1280 end
1165 else 1281 else
1166 begin 1282 begin
@@ -1184,12 +1300,17 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); @@ -1184,12 +1300,17 @@ procedure TGameControl.ReceiveReply(AReply: TStringList);
1184 {$IFDEF DEBUG} 1300 {$IFDEF DEBUG}
1185 WriteLn('LCount:',LCount); 1301 WriteLn('LCount:',LCount);
1186 {$ENDIF} 1302 {$ENDIF}
  1303 +
  1304 + // inform other players about self.id choice
1187 FZMQActor.SendMessage([K_CHOICE,AReply[0],AReply[3],AReply[4],AReply[5]]); 1305 FZMQActor.SendMessage([K_CHOICE,AReply[0],AReply[3],AReply[4],AReply[5]]);
1188 1306
  1307 + // The Announcer sends a message, waits interval time until all messages have been sent and then destroys itself.
1189 LAnnouncer := TIntervalarAnnouncer.Create(nil); 1308 LAnnouncer := TIntervalarAnnouncer.Create(nil);
1190 LAnnouncer.OnStart := @FZMQActor.SendMessage; 1309 LAnnouncer.OnStart := @FZMQActor.SendMessage;
1191 - LAnnouncer.Interval := 2000; 1310 + LAnnouncer.Interval := 500;
1192 LCount := WordCount(AReply[6],['+']); 1311 LCount := WordCount(AReply[6],['+']);
  1312 +
  1313 + // individual consequences
1193 if LCount > 0 then 1314 if LCount > 0 then
1194 for i := 1 to LCount do 1315 for i := 1 to LCount do
1195 begin 1316 begin
@@ -1208,6 +1329,7 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); @@ -1208,6 +1329,7 @@ procedure TGameControl.ReceiveReply(AReply: TStringList);
1208 {$ENDIF} 1329 {$ENDIF}
1209 end; 1330 end;
1210 1331
  1332 + // group consequence
1211 if AReply.Count > 7 then 1333 if AReply.Count > 7 then
1212 begin 1334 begin
1213 LCount := WordCount(AReply[7],['+']); 1335 LCount := WordCount(AReply[7],['+']);
@@ -1223,12 +1345,21 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); @@ -1223,12 +1345,21 @@ procedure TGameControl.ReceiveReply(AReply: TStringList);
1223 {$ENDIF} 1345 {$ENDIF}
1224 end; 1346 end;
1225 1347
  1348 + // should ask question or just resume (going to the next turn)?
1226 if AReply[8] <> #32 then 1349 if AReply[8] <> #32 then
1227 //FZMQActor.SendMessage([K_QUESTION,AReply[8],AReply[9]]) 1350 //FZMQActor.SendMessage([K_QUESTION,AReply[8],AReply[9]])
1228 - LAnnouncer.Append([K_QUESTION,AReply[8],AReply[9]]) 1351 + LAnnouncer.Append([K_QUESTION,AReply[8],AReply[9],AReply[10]])
1229 else 1352 else
1230 //FZMQActor.SendMessage([K_RESUME,AReply[9]]); 1353 //FZMQActor.SendMessage([K_RESUME,AReply[9]]);
1231 - LAnnouncer.Append([K_RESUME,AReply[9]]); 1354 + LAnnouncer.Append([K_RESUME,AReply[9],AReply[10]]);
  1355 +
  1356 + // should end experiment or go to the next condition?
  1357 + if (AReply[10] = #27) and (AReply[8] = #32) then
  1358 + LAnnouncer.Append([K_END])
  1359 + else
  1360 + if (AReply[10] <> #32) then
  1361 + LAnnouncer.Append([K_NXTCND,AReply[10]])
  1362 +
1232 end; 1363 end;
1233 1364
1234 LAnnouncer.Reversed; 1365 LAnnouncer.Reversed;
units/game_experiment.pas
@@ -13,6 +13,10 @@ unit game_experiment; @@ -13,6 +13,10 @@ unit game_experiment;
13 13
14 interface 14 interface
15 15
  16 +
  17 + // TODO: REFACTORING. FILE METHODS MUST USE THE SAME METHODS FROM HERE WHEN LOADING CONDITONS, CONTINGENCIES AND SO ON. KEEP IT SIMPLE.
  18 +
  19 +
16 uses 20 uses
17 Classes, SysUtils 21 Classes, SysUtils
18 , game_actors 22 , game_actors
@@ -29,6 +33,8 @@ type @@ -29,6 +33,8 @@ type
29 33
30 TExperiment = class(TComponent) 34 TExperiment = class(TComponent)
31 private 35 private
  36 + FABPoints: Boolean;
  37 + //FChangeGeneration: string;
32 FExperimentAim, 38 FExperimentAim,
33 FExperimentName, 39 FExperimentName,
34 FFilename, 40 FFilename,
@@ -42,6 +48,7 @@ type @@ -42,6 +48,7 @@ type
42 private 48 private
43 FLastReportColNames : string; 49 FLastReportColNames : string;
44 FRegData : TRegData; 50 FRegData : TRegData;
  51 + FRegChat : TRegData;
45 FReportReader : TReportReader; 52 FReportReader : TReportReader;
46 FPlayers : TPlayers; 53 FPlayers : TPlayers;
47 FCurrentCondition : integer; 54 FCurrentCondition : integer;
@@ -57,10 +64,11 @@ type @@ -57,10 +64,11 @@ type
57 function GetNextCycle:integer; 64 function GetNextCycle:integer;
58 function GetNextCondition:integer; 65 function GetNextCondition:integer;
59 function GetCurrentAbsoluteCycle : integer; 66 function GetCurrentAbsoluteCycle : integer;
60 - function GetPlayer(I : integer): TPlayer; overload;  
61 - function GetPlayer(AID : UTF8string): TPlayer; overload;  
62 function AliasPlayerAsString(P: TPlayer): UTF8string; 67 function AliasPlayerAsString(P: TPlayer): UTF8string;
63 function AliasPlayerFromString(s : UTF8string): TPlayer; 68 function AliasPlayerFromString(s : UTF8string): TPlayer;
  69 + function GetPlayer(I : integer): TPlayer; overload;
  70 + function GetPlayer(AID : UTF8string): TPlayer; overload;
  71 + function GetPlayerToKick: string;
64 function GetPlayerIndexFromID(AID : UTF8string): integer; 72 function GetPlayerIndexFromID(AID : UTF8string): integer;
65 function GetPlayerIsPlaying(AID : UTF8string): Boolean; 73 function GetPlayerIsPlaying(AID : UTF8string): Boolean;
66 function GetPlayersCount: integer; 74 function GetPlayersCount: integer;
@@ -69,26 +77,22 @@ type @@ -69,26 +77,22 @@ type
69 function GetConsequenceStringFromChoices:UTF8String; 77 function GetConsequenceStringFromChoices:UTF8String;
70 procedure CheckNeedForRandomTurns; 78 procedure CheckNeedForRandomTurns;
71 procedure EndExperiment; 79 procedure EndExperiment;
  80 + procedure WriteReportHeader;
  81 + procedure WriteReportRowNames;
  82 + procedure WriteReportRow;
72 procedure SetCondition(I : Integer; AValue: TCondition); 83 procedure SetCondition(I : Integer; AValue: TCondition);
73 procedure SetContingency(ACondition, I : integer; AValue: TContingency); 84 procedure SetContingency(ACondition, I : integer; AValue: TContingency);
74 procedure SetMatrixType(AValue: TGameMatrixType); 85 procedure SetMatrixType(AValue: TGameMatrixType);
75 - procedure SetOnConsequence(AValue: TNotifyEvent);  
76 - procedure SetOnEndCondition(AValue: TNotifyEvent);  
77 - procedure SetOnEndCycle(AValue: TNotifyEvent);  
78 - procedure SetOnEndExperiment(AValue: TNotifyEvent);  
79 - procedure SetOnEndGeneration(AValue: TNotifyEvent);  
80 - procedure SetOnEndTurn(AValue: TNotifyEvent);  
81 - procedure SetOnInterlocking(AValue: TNotifyEvent);  
82 procedure SetPlayer(I : integer; AValue: TPlayer); overload; 86 procedure SetPlayer(I : integer; AValue: TPlayer); overload;
83 procedure SetPlayer(S : UTF8string ; AValue: TPlayer); overload; 87 procedure SetPlayer(S : UTF8string ; AValue: TPlayer); overload;
84 procedure SetResearcherCanChat(AValue: Boolean); 88 procedure SetResearcherCanChat(AValue: Boolean);
85 procedure SetResearcherCanPlay(AValue: Boolean); 89 procedure SetResearcherCanPlay(AValue: Boolean);
86 procedure SetSendChatHistoryForNewPlayers(AValue: Boolean); 90 procedure SetSendChatHistoryForNewPlayers(AValue: Boolean);
87 procedure SetState(AValue: TExperimentState); 91 procedure SetState(AValue: TExperimentState);
88 - procedure SetTargetInterlocking; 92 + procedure SetTargetInterlockingEvent;
  93 + procedure SetContingenciesEvents;
  94 + procedure SetPlayersQueue(AValue: string);
89 private 95 private
90 - FABPoints: Boolean;  
91 - FChangeGeneration: string;  
92 FOnConsequence: TNotifyEvent; 96 FOnConsequence: TNotifyEvent;
93 FOnInterlocking: TNotifyEvent; 97 FOnInterlocking: TNotifyEvent;
94 FOnEndTurn: TNotifyEvent; 98 FOnEndTurn: TNotifyEvent;
@@ -98,14 +102,17 @@ type @@ -98,14 +102,17 @@ type
98 FOnEndGeneration: TNotifyEvent; 102 FOnEndGeneration: TNotifyEvent;
99 FOnTargetInterlocking: TNotifyEvent; 103 FOnTargetInterlocking: TNotifyEvent;
100 procedure Consequence(Sender : TObject); 104 procedure Consequence(Sender : TObject);
101 - function GetPlayerToKick: string;  
102 procedure Interlocking(Sender : TObject); 105 procedure Interlocking(Sender : TObject);
  106 + procedure SetOnTargetInterlocking(AValue: TNotifyEvent);
103 procedure TargetInterlocking(Sender : TObject); 107 procedure TargetInterlocking(Sender : TObject);
104 - procedure SetPlayersQueue(AValue: string);  
105 - procedure WriteReportHeader;  
106 - procedure WriteReportRowNames;  
107 - procedure WriteReportRow;  
108 - public 108 + procedure SetOnConsequence(AValue: TNotifyEvent);
  109 + procedure SetOnEndCondition(AValue: TNotifyEvent);
  110 + procedure SetOnEndCycle(AValue: TNotifyEvent);
  111 + procedure SetOnEndExperiment(AValue: TNotifyEvent);
  112 + procedure SetOnEndGeneration(AValue: TNotifyEvent);
  113 + procedure SetOnEndTurn(AValue: TNotifyEvent);
  114 + procedure SetOnInterlocking(AValue: TNotifyEvent);
  115 + public // creation/ destruction
109 constructor Create(AOwner:TComponent);override; 116 constructor Create(AOwner:TComponent);override;
110 constructor Create(AOwner:TComponent; AppPath:string);overload; 117 constructor Create(AOwner:TComponent; AppPath:string);overload;
111 constructor Create(AOwner:TComponent; AFilename, AppPath:string); overload; 118 constructor Create(AOwner:TComponent; AFilename, AppPath:string); overload;
@@ -114,9 +121,7 @@ type @@ -114,9 +121,7 @@ type
114 function LoadFromGenerator:Boolean; 121 function LoadFromGenerator:Boolean;
115 procedure SaveToFile(AFilename: string); overload; 122 procedure SaveToFile(AFilename: string); overload;
116 procedure SaveToFile; overload; 123 procedure SaveToFile; overload;
117 - procedure Clean;  
118 - procedure Play;  
119 - procedure WriteReportRowPrompt; 124 + public // global configuration
120 property ExperimentAim : string read FExperimentAim write FExperimentAim; 125 property ExperimentAim : string read FExperimentAim write FExperimentAim;
121 property ExperimentName : string read FExperimentName write FExperimentName; 126 property ExperimentName : string read FExperimentName write FExperimentName;
122 property ABPoints : Boolean read FABPoints write FABPoints; 127 property ABPoints : Boolean read FABPoints write FABPoints;
@@ -127,7 +132,7 @@ type @@ -127,7 +132,7 @@ type
127 property ShowChat : Boolean read FShowChat write FShowChat; 132 property ShowChat : Boolean read FShowChat write FShowChat;
128 property SendChatHistoryForNewPlayers : Boolean read FSendChatHistoryForNewPlayers write SetSendChatHistoryForNewPlayers; 133 property SendChatHistoryForNewPlayers : Boolean read FSendChatHistoryForNewPlayers write SetSendChatHistoryForNewPlayers;
129 property MatrixType : TGameMatrixType read FMatrixType write SetMatrixType; 134 property MatrixType : TGameMatrixType read FMatrixType write SetMatrixType;
130 - public 135 + public // manipulation/ self awareness
131 function AppendCondition : integer; overload; 136 function AppendCondition : integer; overload;
132 function AppendCondition(ACondition : TCondition) : integer;overload; 137 function AppendCondition(ACondition : TCondition) : integer;overload;
133 function AppendContingency(ACondition : integer) : integer;overload; 138 function AppendContingency(ACondition : integer) : integer;overload;
@@ -140,15 +145,22 @@ type @@ -140,15 +145,22 @@ type
140 property Contingency[C, I : integer] : TContingency read GetContingency write SetContingency; 145 property Contingency[C, I : integer] : TContingency read GetContingency write SetContingency;
141 property ContingenciesCount[C:integer]:integer read GetContingenciesCount; 146 property ContingenciesCount[C:integer]:integer read GetContingenciesCount;
142 property Cycles : integer read GetCurrentAbsoluteCycle; 147 property Cycles : integer read GetCurrentAbsoluteCycle;
  148 + property InterlockingsInLastCycles:real read GetInterlockingPorcentageInLastCycles;
143 property Player[I : integer] : TPlayer read GetPlayer write SetPlayer; 149 property Player[I : integer] : TPlayer read GetPlayer write SetPlayer;
  150 + property Players : TPlayers read FPlayers;
144 property PlayerFromID[S : UTF8string ] : TPlayer read GetPlayer write SetPlayer; 151 property PlayerFromID[S : UTF8string ] : TPlayer read GetPlayer write SetPlayer;
145 property PlayersCount : integer read GetPlayersCount; 152 property PlayersCount : integer read GetPlayersCount;
146 property PlayerIsPlaying[s : UTF8string] : Boolean read GetPlayerIsPlaying; 153 property PlayerIsPlaying[s : UTF8string] : Boolean read GetPlayerIsPlaying;
147 property PlayerIndexFromID[s : UTF8string]: integer read GetPlayerIndexFromID; 154 property PlayerIndexFromID[s : UTF8string]: integer read GetPlayerIndexFromID;
148 property PlayerAsString[P:TPlayer]: UTF8string read AliasPlayerAsString; 155 property PlayerAsString[P:TPlayer]: UTF8string read AliasPlayerAsString;
149 property PlayerFromString[s : UTF8string]: TPlayer read AliasPlayerFromString; 156 property PlayerFromString[s : UTF8string]: TPlayer read AliasPlayerFromString;
150 - public  
151 - property InterlockingsInLastCycles:real read GetInterlockingPorcentageInLastCycles; 157 + public // standard control
  158 + function ShouldEndCondition:Boolean;
  159 + function CurrentConditionAsString:UTF8String;
  160 + procedure Clean;
  161 + procedure Play;
  162 + procedure WriteReportRowPrompt;
  163 + procedure WriteChatLn(ALn : string);
152 property ConsequenceStringFromChoice[P:Tplayer]:UTF8String read GetConsequenceStringFromChoice; 164 property ConsequenceStringFromChoice[P:Tplayer]:UTF8String read GetConsequenceStringFromChoice;
153 property ConsequenceStringFromChoices: UTF8String read GetConsequenceStringFromChoices; 165 property ConsequenceStringFromChoices: UTF8String read GetConsequenceStringFromChoices;
154 property NextTurnPlayerID : UTF8string read GetNextTurnPlayerID; 166 property NextTurnPlayerID : UTF8string read GetNextTurnPlayerID;
@@ -157,7 +169,7 @@ type @@ -157,7 +169,7 @@ type
157 property NextCondition : integer read GetNextCondition; 169 property NextCondition : integer read GetNextCondition;
158 property NextGeneration: string read GetPlayerToKick write SetPlayersQueue; 170 property NextGeneration: string read GetPlayerToKick write SetPlayersQueue;
159 property State : TExperimentState read FState write SetState; 171 property State : TExperimentState read FState write SetState;
160 - public 172 + public // events
161 property OnEndTurn : TNotifyEvent read FOnEndTurn write SetOnEndTurn; 173 property OnEndTurn : TNotifyEvent read FOnEndTurn write SetOnEndTurn;
162 property OnEndCycle : TNotifyEvent read FOnEndCycle write SetOnEndCycle; 174 property OnEndCycle : TNotifyEvent read FOnEndCycle write SetOnEndCycle;
163 property OnEndGeneration : TNotifyEvent read FOnEndGeneration write SetOnEndGeneration; 175 property OnEndGeneration : TNotifyEvent read FOnEndGeneration write SetOnEndGeneration;
@@ -165,7 +177,7 @@ type @@ -165,7 +177,7 @@ type
165 property OnEndExperiment : TNotifyEvent read FOnEndExperiment write SetOnEndExperiment; 177 property OnEndExperiment : TNotifyEvent read FOnEndExperiment write SetOnEndExperiment;
166 property OnConsequence : TNotifyEvent read FOnConsequence write SetOnConsequence; 178 property OnConsequence : TNotifyEvent read FOnConsequence write SetOnConsequence;
167 property OnInterlocking : TNotifyEvent read FOnInterlocking write SetOnInterlocking; 179 property OnInterlocking : TNotifyEvent read FOnInterlocking write SetOnInterlocking;
168 - property OnTargetInterlocking : TNotifyEvent read FOnTargetInterlocking write FOnTargetInterlocking; 180 + property OnTargetInterlocking : TNotifyEvent read FOnTargetInterlocking write SetOnTargetInterlocking;
169 end; 181 end;
170 182
171 resourcestring 183 resourcestring
@@ -236,7 +248,6 @@ begin @@ -236,7 +248,6 @@ begin
236 FConditions[CurrentCondition].Cycles.Count := 0; 248 FConditions[CurrentCondition].Cycles.Count := 0;
237 if Assigned(FOnEndGeneration) then FOnEndGeneration(Self); 249 if Assigned(FOnEndGeneration) then FOnEndGeneration(Self);
238 Inc(FConditions[CurrentCondition].Cycles.Generation); 250 Inc(FConditions[CurrentCondition].Cycles.Generation);
239 - NextCondition;  
240 end; 251 end;
241 {$IFDEF DEBUG} 252 {$IFDEF DEBUG}
242 WriteLn('TExperiment.GetNextCycle:',Result); 253 WriteLn('TExperiment.GetNextCycle:',Result);
@@ -244,45 +255,24 @@ begin @@ -244,45 +255,24 @@ begin
244 end; 255 end;
245 256
246 function TExperiment.GetNextCondition: integer; 257 function TExperiment.GetNextCondition: integer;
247 -var  
248 - LInterlocks : real;  
249 -  
250 - procedure EndCondition;  
251 - begin  
252 - if Assigned(FOnEndCondition) then FOnEndCondition(Self);  
253 - Inc(FCurrentCondition);  
254 - if FCurrentCondition = ConditionsCount then  
255 - begin  
256 - EndExperiment;  
257 - Exit;  
258 - end;  
259 - FReportReader.Clean;  
260 - FReportReader.SetXLastRows(Condition[CurrentCondition].EndCriterium.LastCycles);  
261 - WriteReportRowNames;  
262 - end;  
263 -  
264 begin 258 begin
265 Result := CurrentCondition; 259 Result := CurrentCondition;
  260 + if Assigned(FOnEndCondition) then FOnEndCondition(Self);
  261 + if FCurrentCondition < ConditionsCount-1 then
  262 + begin
  263 + Inc(FCurrentCondition);
  264 + SetTargetInterlockingEvent;
  265 + SetContingenciesEvents;
  266 + FReportReader.Clean;
  267 + FReportReader.SetXLastRows(Condition[CurrentCondition].EndCriterium.LastCycles);
  268 + WriteReportRowNames;
  269 + end
  270 + else
  271 + begin
  272 + EndExperiment;
  273 + State:=xsWaiting;
  274 + end;
266 275
267 - // interlockings in the last x cycles  
268 - LInterlocks := InterlockingsInLastCycles;  
269 - case FConditions[CurrentCondition].EndCriterium.Style of  
270 - gecWhichComeFirst:  
271 - begin  
272 - if (GetCurrentAbsoluteCycle = FConditions[CurrentCondition].EndCriterium.AbsoluteCycles-1) or  
273 - (LInterlocks >= FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage) then  
274 - EndCondition;  
275 -  
276 - end;  
277 - gecAbsoluteCycles:  
278 - if GetCurrentAbsoluteCycle = FConditions[CurrentCondition].EndCriterium.AbsoluteCycles-1 then  
279 - EndCondition;  
280 -  
281 - gecInterlockingPorcentage:  
282 - if LInterlocks >= FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage then  
283 - EndCondition;  
284 -  
285 - end;  
286 {$IFDEF DEBUG} 276 {$IFDEF DEBUG}
287 WriteLn('TExperiment.GetNextCondition:',Result); 277 WriteLn('TExperiment.GetNextCondition:',Result);
288 {$ENDIF} 278 {$ENDIF}
@@ -383,7 +373,7 @@ begin @@ -383,7 +373,7 @@ begin
383 if LContingencyResults.Count = Condition[c].EndCriterium.LastCycles then 373 if LContingencyResults.Count = Condition[c].EndCriterium.LastCycles then
384 begin 374 begin
385 375
386 - // count how many times interlocks in last X cycles 376 + // count how many interlocks in last X cycles
387 for LRow in LContingencyResults do 377 for LRow in LContingencyResults do
388 if LRow = '1' then Inc(i); 378 if LRow = '1' then Inc(i);
389 379
@@ -456,10 +446,6 @@ end; @@ -456,10 +446,6 @@ end;
456 procedure TExperiment.SetContingency(ACondition, I : integer; AValue: TContingency); 446 procedure TExperiment.SetContingency(ACondition, I : integer; AValue: TContingency);
457 begin 447 begin
458 FConditions[ACondition].Contingencies[I] := AValue; 448 FConditions[ACondition].Contingencies[I] := AValue;
459 - if FConditions[ACondition].Contingencies[I].Meta then  
460 - FConditions[ACondition].Contingencies[I].OnCriteria:=@Interlocking  
461 - else  
462 - FConditions[ACondition].Contingencies[I].OnCriteria:=@Consequence;  
463 end; 449 end;
464 450
465 procedure TExperiment.SetMatrixType(AValue: TGameMatrixType); 451 procedure TExperiment.SetMatrixType(AValue: TGameMatrixType);
@@ -553,10 +539,10 @@ begin @@ -553,10 +539,10 @@ begin
553 FState:=AValue; 539 FState:=AValue;
554 end; 540 end;
555 541
556 -procedure TExperiment.SetTargetInterlocking; 542 +procedure TExperiment.SetTargetInterlockingEvent;
557 var i : integer; 543 var i : integer;
558 begin 544 begin
559 - for i:= 0 to ContingenciesCount[CurrentCondition] do 545 + for i:= 0 to ContingenciesCount[CurrentCondition]-1 do
560 if Condition[CurrentCondition].Contingencies[i].Meta then 546 if Condition[CurrentCondition].Contingencies[i].Meta then
561 begin 547 begin
562 Condition[CurrentCondition].Contingencies[i].OnTargetCriteria:=@TargetInterlocking; 548 Condition[CurrentCondition].Contingencies[i].OnTargetCriteria:=@TargetInterlocking;
@@ -564,6 +550,17 @@ begin @@ -564,6 +550,17 @@ begin
564 end; 550 end;
565 end; 551 end;
566 552
  553 +procedure TExperiment.SetContingenciesEvents;
  554 +var
  555 + i: Integer;
  556 +begin
  557 + for i := 0 to ContingenciesCount[CurrentCondition]-1 do
  558 + if FConditions[CurrentCondition].Contingencies[I].Meta then
  559 + FConditions[CurrentCondition].Contingencies[I].OnCriteria:=@Interlocking
  560 + else
  561 + FConditions[CurrentCondition].Contingencies[I].OnCriteria:=@Consequence;
  562 +end;
  563 +
567 procedure TExperiment.Consequence(Sender: TObject); 564 procedure TExperiment.Consequence(Sender: TObject);
568 begin 565 begin
569 if Assigned(FOnConsequence) then FOnConsequence(Sender); 566 if Assigned(FOnConsequence) then FOnConsequence(Sender);
@@ -600,6 +597,12 @@ begin @@ -600,6 +597,12 @@ begin
600 if Assigned(FOnInterlocking) then FOnInterlocking(Sender); 597 if Assigned(FOnInterlocking) then FOnInterlocking(Sender);
601 end; 598 end;
602 599
  600 +procedure TExperiment.SetOnTargetInterlocking(AValue: TNotifyEvent);
  601 +begin
  602 + if FOnTargetInterlocking=AValue then Exit;
  603 + FOnTargetInterlocking:=AValue;
  604 +end;
  605 +
603 606
604 procedure TExperiment.WriteReportHeader; 607 procedure TExperiment.WriteReportHeader;
605 var 608 var
@@ -733,6 +736,12 @@ begin @@ -733,6 +736,12 @@ begin
733 end; 736 end;
734 end; 737 end;
735 738
  739 +procedure TExperiment.WriteChatLn(ALn: string);
  740 +begin
  741 + FRegChat.SaveData(ALn);
  742 + FRegChat.CloseAndOpen;
  743 +end;
  744 +
736 constructor TExperiment.Create(AOwner: TComponent); 745 constructor TExperiment.Create(AOwner: TComponent);
737 begin 746 begin
738 inherited Create(AOwner); 747 inherited Create(AOwner);
@@ -742,14 +751,16 @@ begin @@ -742,14 +751,16 @@ begin
742 end; 751 end;
743 752
744 constructor TExperiment.Create(AOwner: TComponent;AppPath:string); 753 constructor TExperiment.Create(AOwner: TComponent;AppPath:string);
745 -var i : integer; 754 +var LDataPath : string;
746 begin 755 begin
747 inherited Create(AOwner); 756 inherited Create(AOwner);
  757 + LDataPath := AppPath+VAL_RESEARCHER+'es'+PathDelim+Researcher+PathDelim+ExperimentName+PathDelim;
748 FTurnsRandom := TStringList.Create; 758 FTurnsRandom := TStringList.Create;
749 LoadExperimentFromResource(Self); 759 LoadExperimentFromResource(Self);
750 760
751 // TODO: Allow custom target interlocking. Now just taking the first meta, as usual in the lab. 761 // TODO: Allow custom target interlocking. Now just taking the first meta, as usual in the lab.
752 - SetTargetInterlocking; 762 + SetTargetInterlockingEvent;
  763 + SetContingenciesEvents;
753 764
754 CheckNeedForRandomTurns; 765 CheckNeedForRandomTurns;
755 766
@@ -757,7 +768,9 @@ begin @@ -757,7 +768,9 @@ begin
757 FReportReader.UseRange:=True; 768 FReportReader.UseRange:=True;
758 FReportReader.SetXLastRows(Condition[CurrentCondition].EndCriterium.LastCycles); 769 FReportReader.SetXLastRows(Condition[CurrentCondition].EndCriterium.LastCycles);
759 770
760 - FRegData := TRegData.Create(Self, AppPath+VAL_RESEARCHER+'es'+PathDelim+Researcher+PathDelim+ExperimentName+PathDelim+'000.dat'); 771 + FRegData := TRegData.Create(Self, LDataPath+'000.dat');
  772 + if ShowChat then
  773 + FRegChat := TRegData.Create(Self, LDataPath+'000.chat');
761 WriteReportHeader; 774 WriteReportHeader;
762 end; 775 end;
763 776
@@ -835,6 +848,53 @@ begin @@ -835,6 +848,53 @@ begin
835 FPlayers[Result] := APlayer; 848 FPlayers[Result] := APlayer;
836 end; 849 end;
837 850
  851 +function TExperiment.ShouldEndCondition: Boolean;
  852 +var
  853 + LInterlocks: Real;
  854 + LAbsCycles: Integer;
  855 +begin
  856 + Result := False;
  857 + // interlockings in the last x cycles
  858 + LInterlocks := InterlockingsInLastCycles;
  859 +
  860 + // absolute cycles count
  861 + LAbsCycles := GetCurrentAbsoluteCycle;
  862 + case FConditions[CurrentCondition].EndCriterium.Style of
  863 + gecWhichComeFirst:
  864 + begin
  865 + if (LAbsCycles = FConditions[CurrentCondition].EndCriterium.AbsoluteCycles) or
  866 + (LInterlocks >= FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage) then
  867 + Result := True;
  868 +
  869 + end;
  870 + gecAbsoluteCycles:
  871 + if LAbsCycles = FConditions[CurrentCondition].EndCriterium.AbsoluteCycles then
  872 + Result := True;
  873 +
  874 + gecInterlockingPorcentage:
  875 + if LInterlocks >= FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage then
  876 + Result := True;
  877 + end;
  878 +end;
  879 +
  880 +function TExperiment.CurrentConditionAsString: UTF8String;
  881 +begin
  882 + if ABPoints then
  883 + Result :=
  884 + IntToStr(Condition[CurrentCondition].Points.OnStart.A)+'|'+
  885 + IntToStr(Condition[CurrentCondition].Points.OnStart.B)+'|'+
  886 + IntToStr(Condition[CurrentCondition].Points.OnStart.G)
  887 + else
  888 + Result:=
  889 + IntToStr(Condition[CurrentCondition].Points.OnStart.A)+'|'+
  890 + IntToStr(Condition[CurrentCondition].Points.OnStart.G);
  891 +end;
  892 +
  893 +//procedure TExperiment.TargetInterlocking;
  894 +//begin
  895 +// SetTargetInterlocking;
  896 +//end;
  897 +
838 procedure TExperiment.SaveToFile(AFilename: string); 898 procedure TExperiment.SaveToFile(AFilename: string);
839 begin 899 begin
840 SaveExperimentToFile(Self,AFilename); 900 SaveExperimentToFile(Self,AFilename);
@@ -868,7 +928,6 @@ begin @@ -868,7 +928,6 @@ begin
868 end; 928 end;
869 929
870 procedure TExperiment.Play; 930 procedure TExperiment.Play;
871 -var i : integer;  
872 begin 931 begin
873 //for i := 0 to Condition[CurrentCondition].Turn.Value-1 do 932 //for i := 0 to Condition[CurrentCondition].Turn.Value-1 do
874 // begin 933 // begin
units/game_file_methods.pas
@@ -93,9 +93,9 @@ begin @@ -93,9 +93,9 @@ begin
93 Turn.Value:=2; 93 Turn.Value:=2;
94 Turn.Random:=False; 94 Turn.Random:=False;
95 Cycles.Count:=0; 95 Cycles.Count:=0;
96 - Cycles.Value:=4; 96 + Cycles.Value:=20;
97 Cycles.Generation:=0; 97 Cycles.Generation:=0;
98 - EndCriterium.AbsoluteCycles := 20; 98 + EndCriterium.AbsoluteCycles := 15;
99 EndCriterium.InterlockingPorcentage := 80; 99 EndCriterium.InterlockingPorcentage := 80;
100 EndCriterium.LastCycles := 10; 100 EndCriterium.LastCycles := 10;
101 EndCriterium.Style := gecWhichComeFirst; 101 EndCriterium.Style := gecWhichComeFirst;
@@ -113,7 +113,6 @@ begin @@ -113,7 +113,6 @@ begin
113 LConcequence := TConsequence.Create(AExperiment,-1,[gscPoints, gscG, gscMessage],['','item escolar','itens escolares']); 113 LConcequence := TConsequence.Create(AExperiment,-1,[gscPoints, gscG, gscMessage],['','item escolar','itens escolares']);
114 Contingencies[3] := TContingency.Create(AExperiment,LConcequence,LCriteria4,True); 114 Contingencies[3] := TContingency.Create(AExperiment,LConcequence,LCriteria4,True);
115 Contingencies[3].ContingencyName := 'MPUN -1G'; 115 Contingencies[3].ContingencyName := 'MPUN -1G';
116 -  
117 Prompt := TPrompt.Create( 116 Prompt := TPrompt.Create(
118 AExperiment 117 AExperiment
119 , [gsAll,gsYes,gsMetacontingency,gsContingency,gsRevertPoints,gsBasA] 118 , [gsAll,gsYes,gsMetacontingency,gsContingency,gsRevertPoints,gsBasA]
units/report_reader.pas
@@ -38,6 +38,7 @@ type @@ -38,6 +38,7 @@ type
38 VRow : string; //helper 38 VRow : string; //helper
39 constructor Create; 39 constructor Create;
40 destructor Destroy; override; 40 destructor Destroy; override;
  41 + function Dump : string;
41 procedure Append(ARow : string); 42 procedure Append(ARow : string);
42 procedure Extend(ARowExtention : string); 43 procedure Extend(ARowExtention : string);
43 procedure Clean; 44 procedure Clean;
@@ -64,10 +65,10 @@ begin @@ -64,10 +65,10 @@ begin
64 if c > -1 then 65 if c > -1 then
65 if FUseRange and (FRowRange.Low <= FRowRange.High) and (FRowRange.Low > 0) then 66 if FUseRange and (FRowRange.Low <= FRowRange.High) and (FRowRange.Low > 0) then
66 for i := FRowRange.Low to FRowRange.High do 67 for i := FRowRange.Low to FRowRange.High do
67 - Result.Append(ExtractDelimited(c+1, FRows[i],[#9,#10])) 68 + Result.Append(ExtractDelimited(c+2, FRows[i],[#9,#10]));
68 else 69 else
69 for Row in FRows do 70 for Row in FRows do
70 - Result.Append(ExtractDelimited(c+1, Row,[#9,#10])); 71 + Result.Append(ExtractDelimited(c+2, Row,[#9,#10]));
71 end; 72 end;
72 73
73 constructor TReportReader.Create; 74 constructor TReportReader.Create;
@@ -87,6 +88,11 @@ begin @@ -87,6 +88,11 @@ begin
87 inherited Destroy; 88 inherited Destroy;
88 end; 89 end;
89 90
  91 +function TReportReader.Dump: string;
  92 +begin
  93 + Result := FCols.Text+LineEnding+FRows.Text;
  94 +end;
  95 +
90 procedure TReportReader.Append(ARow: string); 96 procedure TReportReader.Append(ARow: string);
91 begin 97 begin
92 if FCols.Count = 0 then 98 if FCols.Count = 0 then