Commit f8cf50c5d02595fd30edfb78693c0d6a2ef26ac4
1 parent
4598d27c
Exists in
master
work end of experiment and player feedback on change generation
- also fix EndCriteria interlocks porcentage
Showing
12 changed files
with
1127 additions
and
65 deletions
Show diff stats
cultural_matrix.lpr
| ... | ... | @@ -31,10 +31,6 @@ uses |
| 31 | 31 | |
| 32 | 32 | |
| 33 | 33 | var |
| 34 | - {$IFDEF DEBUG} | |
| 35 | - I : integer; | |
| 36 | - {$ENDIF} | |
| 37 | - ID : TStringList; | |
| 38 | 34 | ApplicationPath, |
| 39 | 35 | F : string; |
| 40 | 36 | |
| ... | ... | @@ -71,6 +67,7 @@ const |
| 71 | 67 | {$ENDIF} |
| 72 | 68 | |
| 73 | 69 | function GetZMQNetworkID(var F:string):Boolean; |
| 70 | + var ID : TStringList; | |
| 74 | 71 | begin |
| 75 | 72 | Result := True; |
| 76 | 73 | ID := TStringList.Create; | ... | ... |
form_chooseactor.pas
| ... | ... | @@ -34,6 +34,8 @@ type |
| 34 | 34 | procedure btnPlayerResumeClick(Sender: TObject); |
| 35 | 35 | procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); |
| 36 | 36 | procedure FormCreate(Sender: TObject); |
| 37 | + procedure ExitApplication(Sender: TObject); | |
| 38 | + procedure ShowResumeButton(Sender: TObject); | |
| 37 | 39 | private |
| 38 | 40 | FGameActor: TGameActor; |
| 39 | 41 | FCanClose : Boolean; |
| ... | ... | @@ -41,8 +43,7 @@ type |
| 41 | 43 | procedure SetStyle(AValue: string); |
| 42 | 44 | { private declarations } |
| 43 | 45 | public |
| 44 | - procedure ShowPoints(A, B, G : string); | |
| 45 | - procedure ShowResumeButton; | |
| 46 | + procedure ShowPoints(M : string); | |
| 46 | 47 | property GameActor : TGameActor read FGameActor; |
| 47 | 48 | property Style : string read FStyle write SetStyle; |
| 48 | 49 | end; |
| ... | ... | @@ -86,26 +87,62 @@ begin |
| 86 | 87 | FCanClose := True; |
| 87 | 88 | end; |
| 88 | 89 | |
| 90 | +procedure TFormChooseActor.ExitApplication(Sender: TObject); | |
| 91 | +begin | |
| 92 | + Application.Terminate; | |
| 93 | +end; | |
| 94 | + | |
| 89 | 95 | procedure TFormChooseActor.SetStyle(AValue: string); |
| 90 | 96 | begin |
| 91 | 97 | if FStyle=AValue then Exit; |
| 98 | + FStyle:=AValue; | |
| 92 | 99 | case AValue of |
| 93 | 100 | '.Arrived': btnPlayerResume.Visible:=False; |
| 94 | - '.Left': btnPlayerResume.Visible:=True; | |
| 101 | + '.Left', '.EndX': | |
| 102 | + begin | |
| 103 | + btnPlayerResume.Visible:=False; | |
| 104 | + btnAdmin.Visible:= False; | |
| 105 | + btnPlayer.Visible:= False; | |
| 106 | + BorderStyle:=bsNone; | |
| 107 | + Position:=poDesigned; | |
| 108 | + FormStyle:=fsNormal; | |
| 109 | + WindowState:=wsFullScreen; | |
| 110 | + end; | |
| 95 | 111 | end; |
| 96 | - btnAdmin.Visible:= not btnPlayerResume.Visible; | |
| 97 | - btnPlayer.Visible:= not btnPlayerResume.Visible; | |
| 98 | - FStyle:=AValue; | |
| 99 | 112 | end; |
| 100 | 113 | |
| 101 | -procedure TFormChooseActor.ShowPoints(A, B, G: string); | |
| 114 | +procedure TFormChooseActor.ShowPoints(M: string); | |
| 115 | +var L : TLabel; | |
| 102 | 116 | begin |
| 103 | - | |
| 117 | + L := TLabel.Create(Self); | |
| 118 | + with L do | |
| 119 | + begin | |
| 120 | + Name := 'LabelGoodBye'; | |
| 121 | + Align:=alClient; | |
| 122 | + Caption:= M; | |
| 123 | + Alignment := taCenter; | |
| 124 | + Anchors := [akLeft,akRight]; | |
| 125 | + Layout := tlCenter; | |
| 126 | + WordWrap := True; | |
| 127 | + Parent:=Self; | |
| 128 | + Font.Size := 30; | |
| 129 | + case FStyle of | |
| 130 | + '.Left': OnClick := @ShowResumeButton; | |
| 131 | + '.EndX': OnClick := @ExitApplication; | |
| 132 | + end; | |
| 133 | + end; | |
| 104 | 134 | end; |
| 105 | 135 | |
| 106 | -procedure TFormChooseActor.ShowResumeButton; | |
| 136 | +procedure TFormChooseActor.ShowResumeButton(Sender: TObject); | |
| 137 | +var i : integer; | |
| 107 | 138 | begin |
| 108 | - | |
| 139 | + for i := 0 to ComponentCount-1 do | |
| 140 | + if Components[i].Name = 'LabelGoodBye' then | |
| 141 | + begin | |
| 142 | + TLabel(Components[i]).Visible:=False; | |
| 143 | + Break; | |
| 144 | + end; | |
| 145 | + btnPlayerResume.Visible:=True; | |
| 109 | 146 | end; |
| 110 | 147 | |
| 111 | 148 | end. | ... | ... |
| ... | ... | @@ -0,0 +1,782 @@ |
| 1 | +{ | |
| 2 | + Stimulus Control | |
| 3 | + Copyright (C) 2014-2016 Carlos Rafael Fernandes Picanço, Universidade Federal do Pará. | |
| 4 | + | |
| 5 | + The present file is distributed under the terms of the GNU General Public License (GPL v3.0). | |
| 6 | + | |
| 7 | + You should have received a copy of the GNU General Public License | |
| 8 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 9 | +} | |
| 10 | +unit game_experiment; | |
| 11 | + | |
| 12 | +{$mode objfpc}{$H+} | |
| 13 | + | |
| 14 | +interface | |
| 15 | + | |
| 16 | +uses | |
| 17 | + Classes, SysUtils | |
| 18 | + , game_actors | |
| 19 | + , regdata | |
| 20 | + ; | |
| 21 | + | |
| 22 | +type | |
| 23 | + | |
| 24 | + { TExperiment } | |
| 25 | + | |
| 26 | + TExperimentState = (xsWaiting,xsRunning,xsPaused,xsCanceled); | |
| 27 | + TConditions = array of TCondition; | |
| 28 | + | |
| 29 | + TExperiment = class(TComponent) | |
| 30 | + private | |
| 31 | + FExperimentAim, | |
| 32 | + FExperimentName, | |
| 33 | + FFilename, | |
| 34 | + FResearcher : string; | |
| 35 | + FGenPlayersAsNeeded : Boolean; | |
| 36 | + FResearcherCanChat: Boolean; | |
| 37 | + FResearcherCanPlay: Boolean; | |
| 38 | + FSendChatHistoryForNewPlayers: Boolean; | |
| 39 | + FShowChat: Boolean; | |
| 40 | + FMatrixType: TGameMatrixType; | |
| 41 | + private | |
| 42 | + FLastReportColNames : string; | |
| 43 | + FRegData : TRegData; | |
| 44 | + FPlayers : TPlayers; | |
| 45 | + FCurrentCondition : integer; | |
| 46 | + FConditions : TConditions; | |
| 47 | + FState: TExperimentState; | |
| 48 | + FTurnsRandom : TStringList; | |
| 49 | + function GetCondition(I : Integer): TCondition; | |
| 50 | + function GetConditionsCount: integer; | |
| 51 | + function GetContingenciesCount(C: integer): integer; | |
| 52 | + function GetContingency(ACondition, I : integer): TContingency; | |
| 53 | + function GetNextTurn: integer; | |
| 54 | + function GetNextTurnPlayerID: UTF8string; | |
| 55 | + function GetNextCycle:integer; | |
| 56 | + function GetNextCondition:integer; | |
| 57 | + function GetCurrentAbsoluteCycle : integer; | |
| 58 | + function GetPlayer(I : integer): TPlayer; overload; | |
| 59 | + function GetPlayer(AID : UTF8string): TPlayer; overload; | |
| 60 | + function AliasPlayerAsString(P: TPlayer): UTF8string; | |
| 61 | + function AliasPlayerFromString(s : UTF8string): TPlayer; | |
| 62 | + function GetPlayerIndexFromID(AID : UTF8string): integer; | |
| 63 | + function GetPlayerIsPlaying(AID : UTF8string): Boolean; | |
| 64 | + function GetPlayersCount: integer; | |
| 65 | + function GetInterlockingsIn(ALastCycles : integer):integer; | |
| 66 | + function GetConsequenceStringFromChoice(P:TPlayer): Utf8string; | |
| 67 | + function GetConsequenceStringFromChoices:UTF8String; | |
| 68 | + procedure CheckNeedForRandomTurns; | |
| 69 | + procedure SetCondition(I : Integer; AValue: TCondition); | |
| 70 | + procedure SetContingency(ACondition, I : integer; AValue: TContingency); | |
| 71 | + procedure SetMatrixType(AValue: TGameMatrixType); | |
| 72 | + procedure SetOnConsequence(AValue: TNotifyEvent); | |
| 73 | + procedure SetOnEndCondition(AValue: TNotifyEvent); | |
| 74 | + procedure SetOnEndCycle(AValue: TNotifyEvent); | |
| 75 | + procedure SetOnEndExperiment(AValue: TNotifyEvent); | |
| 76 | + procedure SetOnEndGeneration(AValue: TNotifyEvent); | |
| 77 | + procedure SetOnEndTurn(AValue: TNotifyEvent); | |
| 78 | + procedure SetOnInterlocking(AValue: TNotifyEvent); | |
| 79 | + procedure SetPlayer(I : integer; AValue: TPlayer); overload; | |
| 80 | + procedure SetPlayer(S : UTF8string ; AValue: TPlayer); overload; | |
| 81 | + procedure SetResearcherCanChat(AValue: Boolean); | |
| 82 | + procedure SetResearcherCanPlay(AValue: Boolean); | |
| 83 | + procedure SetSendChatHistoryForNewPlayers(AValue: Boolean); | |
| 84 | + procedure SetState(AValue: TExperimentState); | |
| 85 | + private | |
| 86 | + FChangeGeneration: string; | |
| 87 | + FOnConsequence: TNotifyEvent; | |
| 88 | + FOnInterlocking: TNotifyEvent; | |
| 89 | + FOnEndTurn: TNotifyEvent; | |
| 90 | + FOnEndCondition: TNotifyEvent; | |
| 91 | + FOnEndCycle: TNotifyEvent; | |
| 92 | + FOnEndExperiment: TNotifyEvent; | |
| 93 | + FOnEndGeneration: TNotifyEvent; | |
| 94 | + procedure Consequence(Sender : TObject); | |
| 95 | + function GetPlayerToKick: string; | |
| 96 | + procedure Interlocking(Sender : TObject); | |
| 97 | + procedure SetPlayersQueue(AValue: string); | |
| 98 | + procedure WriteReportHeader; | |
| 99 | + procedure WriteReportRowNames; | |
| 100 | + procedure WriteReportRow; | |
| 101 | + public | |
| 102 | + constructor Create(AOwner:TComponent);override; | |
| 103 | + constructor Create(AOwner:TComponent; AppPath:string);overload; | |
| 104 | + constructor Create(AOwner:TComponent; AFilename, AppPath:string); overload; | |
| 105 | + destructor Destroy; override; | |
| 106 | + function LoadFromFile(AFilename: string):Boolean; | |
| 107 | + function LoadFromGenerator:Boolean; | |
| 108 | + procedure SaveToFile(AFilename: string); overload; | |
| 109 | + procedure SaveToFile; overload; | |
| 110 | + procedure Clean; | |
| 111 | + procedure Play; | |
| 112 | + procedure WriteReportRowPrompt; | |
| 113 | + property ExperimentAim : string read FExperimentAim write FExperimentAim; | |
| 114 | + property ExperimentName : string read FExperimentName write FExperimentName; | |
| 115 | + property GenPlayersAsNeeded : Boolean read FGenPlayersAsNeeded write FGenPlayersAsNeeded; | |
| 116 | + property ResearcherCanPlay : Boolean read FResearcherCanPlay write SetResearcherCanPlay; | |
| 117 | + property ResearcherCanChat : Boolean read FResearcherCanChat write SetResearcherCanChat; | |
| 118 | + property Researcher : string read FResearcher write FResearcher; | |
| 119 | + property ShowChat : Boolean read FShowChat write FShowChat; | |
| 120 | + property SendChatHistoryForNewPlayers : Boolean read FSendChatHistoryForNewPlayers write SetSendChatHistoryForNewPlayers; | |
| 121 | + property MatrixType : TGameMatrixType read FMatrixType write SetMatrixType; | |
| 122 | + public | |
| 123 | + function AppendCondition : integer; overload; | |
| 124 | + function AppendCondition(ACondition : TCondition) : integer;overload; | |
| 125 | + function AppendContingency(ACondition : integer) : integer;overload; | |
| 126 | + function AppendContingency(ACondition : integer;AContingency : TContingency) : integer;overload; | |
| 127 | + function AppendPlayer : integer;overload; | |
| 128 | + function AppendPlayer(APlayer : TPlayer) : integer; overload; | |
| 129 | + property Condition[I : Integer]: TCondition read GetCondition write SetCondition; | |
| 130 | + property ConditionsCount : integer read GetConditionsCount; | |
| 131 | + property CurrentCondition : integer read FCurrentCondition write FCurrentCondition; | |
| 132 | + property Contingency[C, I : integer] : TContingency read GetContingency write SetContingency; | |
| 133 | + property ContingenciesCount[C:integer]:integer read GetContingenciesCount; | |
| 134 | + property Player[I : integer] : TPlayer read GetPlayer write SetPlayer; | |
| 135 | + property PlayerFromID[S : UTF8string ] : TPlayer read GetPlayer write SetPlayer; | |
| 136 | + property PlayersCount : integer read GetPlayersCount; | |
| 137 | + property PlayerIsPlaying[s : UTF8string] : Boolean read GetPlayerIsPlaying; | |
| 138 | + property PlayerIndexFromID[s : UTF8string]: integer read GetPlayerIndexFromID; | |
| 139 | + property PlayerAsString[P:TPlayer]: UTF8string read AliasPlayerAsString; | |
| 140 | + property PlayerFromString[s : UTF8string]: TPlayer read AliasPlayerFromString; | |
| 141 | + public | |
| 142 | + property InterlockingsIn[i:integer]:integer read GetInterlockingsIn; | |
| 143 | + property ConsequenceStringFromChoice[P:Tplayer]:UTF8String read GetConsequenceStringFromChoice; | |
| 144 | + property ConsequenceStringFromChoices: UTF8String read GetConsequenceStringFromChoices; | |
| 145 | + property NextTurnPlayerID : UTF8string read GetNextTurnPlayerID; | |
| 146 | + property NextTurn : integer read GetNextTurn; | |
| 147 | + property NextCycle : integer read GetNextCycle; | |
| 148 | + property NextCondition : integer read GetNextCondition; | |
| 149 | + property NextGeneration: string read GetPlayerToKick write SetPlayersQueue; | |
| 150 | + property State : TExperimentState read FState write SetState; | |
| 151 | + public | |
| 152 | + property OnEndTurn : TNotifyEvent read FOnEndTurn write SetOnEndTurn; | |
| 153 | + property OnEndCycle : TNotifyEvent read FOnEndCycle write SetOnEndCycle; | |
| 154 | + property OnEndGeneration : TNotifyEvent read FOnEndGeneration write SetOnEndGeneration; | |
| 155 | + property OnEndCondition : TNotifyEvent read FOnEndCondition write SetOnEndCondition; | |
| 156 | + property OnEndExperiment : TNotifyEvent read FOnEndExperiment write SetOnEndExperiment; | |
| 157 | + property OnConsequence : TNotifyEvent read FOnConsequence write SetOnConsequence; | |
| 158 | + property OnInterlocking : TNotifyEvent read FOnInterlocking write SetOnInterlocking; | |
| 159 | + end; | |
| 160 | + | |
| 161 | +resourcestring | |
| 162 | + WARN_CANNOT_SAVE = 'O experimento não pode ser salvo.'; | |
| 163 | + | |
| 164 | +implementation | |
| 165 | + | |
| 166 | +uses game_file_methods, game_resources, string_methods; | |
| 167 | + | |
| 168 | +{ TExperiment } | |
| 169 | + | |
| 170 | +function TExperiment.GetCondition(I : Integer): TCondition; | |
| 171 | +begin | |
| 172 | + Result := FConditions[I]; | |
| 173 | +end; | |
| 174 | + | |
| 175 | +function TExperiment.GetConditionsCount: integer; | |
| 176 | +begin | |
| 177 | + Result := Length(FConditions); | |
| 178 | +end; | |
| 179 | + | |
| 180 | +function TExperiment.GetContingenciesCount(C: integer): integer; | |
| 181 | +begin | |
| 182 | + Result := Length(FConditions[C].Contingencies); | |
| 183 | +end; | |
| 184 | + | |
| 185 | +function TExperiment.GetContingency(ACondition, I : integer): TContingency; | |
| 186 | +begin | |
| 187 | + Result := FConditions[ACondition].Contingencies[I]; | |
| 188 | +end; | |
| 189 | + | |
| 190 | +function TExperiment.GetNextTurn: integer; // used during player arriving | |
| 191 | +begin | |
| 192 | + if FConditions[CurrentCondition].Turn.Random then | |
| 193 | + Result := StrToInt(FTurnsRandom.Names[FConditions[CurrentCondition].Turn.Count]) | |
| 194 | + else | |
| 195 | + Result := FConditions[CurrentCondition].Turn.Count; | |
| 196 | + | |
| 197 | + if Assigned(FOnEndTurn) then FOnEndTurn(Self); | |
| 198 | + | |
| 199 | + if FConditions[CurrentCondition].Turn.Count < FConditions[CurrentCondition].Turn.Value-1 then | |
| 200 | + Inc(FConditions[CurrentCondition].Turn.Count) | |
| 201 | + else | |
| 202 | + begin | |
| 203 | + FConditions[CurrentCondition].Turn.Count := 0; | |
| 204 | + NextCycle; | |
| 205 | + end; | |
| 206 | +{$IFDEF DEBUG} | |
| 207 | + WriteLn('TExperiment.GetNextTurn:',Result); | |
| 208 | +{$ENDIF} | |
| 209 | +end; | |
| 210 | + | |
| 211 | +function TExperiment.GetNextTurnPlayerID: UTF8string; // used during cycles | |
| 212 | +begin | |
| 213 | + Result := Player[FConditions[CurrentCondition].Turn.Count].ID; | |
| 214 | +end; | |
| 215 | + | |
| 216 | +function TExperiment.GetNextCycle: integer; | |
| 217 | +begin | |
| 218 | + Result := FConditions[CurrentCondition].Cycles.Count; | |
| 219 | + WriteReportRow; | |
| 220 | + if Assigned(FOnEndCycle) then FOnEndCycle(Self); | |
| 221 | + | |
| 222 | + if FConditions[CurrentCondition].Cycles.Count < FConditions[CurrentCondition].Cycles.Value-1 then | |
| 223 | + Inc(FConditions[CurrentCondition].Cycles.Count) | |
| 224 | + else | |
| 225 | + begin | |
| 226 | + FConditions[CurrentCondition].Cycles.Count := 0; | |
| 227 | + if Assigned(FOnEndGeneration) then FOnEndGeneration(Self); | |
| 228 | + Inc(FConditions[CurrentCondition].Cycles.Generation); | |
| 229 | + NextCondition; | |
| 230 | + end; | |
| 231 | + {$IFDEF DEBUG} | |
| 232 | + WriteLn('TExperiment.GetNextCycle:',Result); | |
| 233 | + {$ENDIF} | |
| 234 | +end; | |
| 235 | + | |
| 236 | +function TExperiment.GetNextCondition: integer; | |
| 237 | +var | |
| 238 | + LInterlocks : integer; | |
| 239 | + | |
| 240 | + procedure EndCondition; | |
| 241 | + begin | |
| 242 | + if Assigned(FOnEndCondition) then FOnEndCondition(Self); | |
| 243 | + Inc(FCurrentCondition); | |
| 244 | + WriteReportRowNames; | |
| 245 | + end; | |
| 246 | + | |
| 247 | +begin | |
| 248 | + Result := CurrentCondition; | |
| 249 | + | |
| 250 | + // interlockings in the last x cycles | |
| 251 | + LInterlocks := InterlockingsIn[FConditions[CurrentCondition].EndCriterium.LastCycles]; | |
| 252 | + case FConditions[CurrentCondition].EndCriterium.Value of | |
| 253 | + gecWhichComeFirst: | |
| 254 | + begin | |
| 255 | + if (GetCurrentAbsoluteCycle = FConditions[CurrentCondition].EndCriterium.AbsoluteCycles) or | |
| 256 | + (LInterlocks = FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage) then | |
| 257 | + EndCondition; | |
| 258 | + | |
| 259 | + end; | |
| 260 | + gecAbsoluteCycles: | |
| 261 | + if GetCurrentAbsoluteCycle = FConditions[CurrentCondition].EndCriterium.AbsoluteCycles then | |
| 262 | + EndCondition; | |
| 263 | + | |
| 264 | + gecInterlockingPorcentage: | |
| 265 | + if LInterlocks = FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage then | |
| 266 | + EndCondition; | |
| 267 | + | |
| 268 | + end; | |
| 269 | + {$IFDEF DEBUG} | |
| 270 | + WriteLn('TExperiment.GetNextCondition:',Result); | |
| 271 | + {$ENDIF} | |
| 272 | +end; | |
| 273 | + | |
| 274 | +function TExperiment.GetCurrentAbsoluteCycle: integer; | |
| 275 | +var c:integer; | |
| 276 | +begin | |
| 277 | + c := CurrentCondition; | |
| 278 | + Result := (Condition[c].Cycles.Value*Condition[c].Cycles.Generation)+Condition[c].Cycles.Count; | |
| 279 | +end; | |
| 280 | + | |
| 281 | +function TExperiment.GetPlayer(I : integer): TPlayer; | |
| 282 | +begin | |
| 283 | + Result := FPlayers[i]; | |
| 284 | +end; | |
| 285 | + | |
| 286 | +function TExperiment.GetPlayer(AID: UTF8string): TPlayer; | |
| 287 | +var | |
| 288 | + i : integer; | |
| 289 | +begin | |
| 290 | + //Result.ID := ''; | |
| 291 | + if PlayersCount > 0 then | |
| 292 | + for i:= 0 to PlayersCount -1 do | |
| 293 | + if FPlayers[i].ID = AID then | |
| 294 | + begin | |
| 295 | + Result := FPlayers[i]; | |
| 296 | + Break; | |
| 297 | + end; | |
| 298 | +end; | |
| 299 | + | |
| 300 | +// fewer as possible data | |
| 301 | +function TExperiment.AliasPlayerAsString(P: TPlayer): UTF8string; | |
| 302 | +begin | |
| 303 | + Result:= GetPlayerAsString(P); | |
| 304 | +end; | |
| 305 | + | |
| 306 | +function TExperiment.AliasPlayerFromString(s: UTF8string): TPlayer; | |
| 307 | +begin | |
| 308 | + Result := GetPlayerFromString(S); | |
| 309 | +end; | |
| 310 | + | |
| 311 | +function TExperiment.GetPlayerIndexFromID(AID: UTF8string): integer; | |
| 312 | +var i : integer; | |
| 313 | +begin | |
| 314 | + Result := -1; | |
| 315 | + for i:= 0 to PlayersCount -1 do | |
| 316 | + if FPlayers[i].ID = AID then | |
| 317 | + begin | |
| 318 | + Result := i; | |
| 319 | + Break; | |
| 320 | + end; | |
| 321 | +end; | |
| 322 | + | |
| 323 | +function TExperiment.GetPlayerIsPlaying(AID: UTF8string): Boolean; | |
| 324 | +var i : integer; | |
| 325 | +begin | |
| 326 | + Result := PlayersCount > 0; | |
| 327 | + if Result then | |
| 328 | + for i := 0 to PlayersCount -1 do | |
| 329 | + if Player[i].ID = AID then | |
| 330 | + Exit; | |
| 331 | + Result:= False; | |
| 332 | +end; | |
| 333 | + | |
| 334 | + | |
| 335 | +function TExperiment.GetPlayersCount: integer; | |
| 336 | +begin | |
| 337 | + Result := Length(FPlayers); | |
| 338 | +end; | |
| 339 | + | |
| 340 | +function TExperiment.GetInterlockingsIn(ALastCycles: integer): integer; | |
| 341 | +var | |
| 342 | + S : TStringList; | |
| 343 | + LTargetMetaContingency : integer; | |
| 344 | +begin | |
| 345 | + S.LoadFromFile(FRegData.FileName); | |
| 346 | + | |
| 347 | +end; | |
| 348 | + | |
| 349 | +function TExperiment.GetConsequenceStringFromChoice(P: TPlayer): Utf8string; | |
| 350 | +var | |
| 351 | + i : integer; | |
| 352 | + c : integer; | |
| 353 | +begin | |
| 354 | + c := CurrentCondition; | |
| 355 | + PlayerFromID[P.ID] := P; | |
| 356 | + Result:= ''; | |
| 357 | + for i :=0 to ContingenciesCount[c] -1 do | |
| 358 | + if not Contingency[c,i].Meta then | |
| 359 | + if Contingency[c,i].ResponseMeetsCriteriaI(P.Choice.Row,P.Choice.Color) then | |
| 360 | + Result += Contingency[c,i].Consequence.AsString(P.ID); | |
| 361 | +end; | |
| 362 | + | |
| 363 | +function TExperiment.GetConsequenceStringFromChoices: UTF8String; | |
| 364 | +var | |
| 365 | + i : integer; | |
| 366 | + c : integer; | |
| 367 | +begin | |
| 368 | + c := CurrentCondition; | |
| 369 | + Result:= ''; | |
| 370 | + for i :=0 to ContingenciesCount[c] -1 do | |
| 371 | + if Contingency[c,i].Meta then | |
| 372 | + if Contingency[c,i].ResponseMeetsCriteriaG(FPlayers) then | |
| 373 | + Result += Contingency[c,i].Consequence.AsString(IntToStr(i)); | |
| 374 | +end; | |
| 375 | + | |
| 376 | +procedure TExperiment.CheckNeedForRandomTurns; | |
| 377 | +var c , | |
| 378 | + i, | |
| 379 | + r : integer; | |
| 380 | +begin | |
| 381 | + if Condition[CurrentCondition].Turn.Random then | |
| 382 | + begin | |
| 383 | + FTurnsRandom.Clear; | |
| 384 | + for i:= 0 to Condition[CurrentCondition].Turn.Value-1 do | |
| 385 | + FTurnsRandom.Add(IntToStr(i)); | |
| 386 | + | |
| 387 | + c := FTurnsRandom.Count - 1; | |
| 388 | + for i := 0 to c do | |
| 389 | + begin | |
| 390 | + r := Random(c); | |
| 391 | + while r = i do r := Random(c); | |
| 392 | + FTurnsRandom.Exchange(r,i); | |
| 393 | + end; | |
| 394 | + end; | |
| 395 | +end; | |
| 396 | + | |
| 397 | +procedure TExperiment.SetCondition(I : Integer; AValue: TCondition); | |
| 398 | +begin | |
| 399 | + FConditions[I] := AValue; | |
| 400 | +end; | |
| 401 | + | |
| 402 | +procedure TExperiment.SetContingency(ACondition, I : integer; AValue: TContingency); | |
| 403 | +begin | |
| 404 | + FConditions[ACondition].Contingencies[I] := AValue; | |
| 405 | + if FConditions[ACondition].Contingencies[I].Meta then | |
| 406 | + FConditions[ACondition].Contingencies[I].OnCriteria:=@Interlocking | |
| 407 | + else | |
| 408 | + FConditions[ACondition].Contingencies[I].OnCriteria:=@Consequence; | |
| 409 | +end; | |
| 410 | + | |
| 411 | +procedure TExperiment.SetMatrixType(AValue: TGameMatrixType); | |
| 412 | +begin | |
| 413 | + if FMatrixType=AValue then Exit; | |
| 414 | + FMatrixType:=AValue; | |
| 415 | +end; | |
| 416 | + | |
| 417 | +procedure TExperiment.SetOnConsequence(AValue: TNotifyEvent); | |
| 418 | +begin | |
| 419 | + if FOnConsequence=AValue then Exit; | |
| 420 | + FOnConsequence:=AValue; | |
| 421 | +end; | |
| 422 | + | |
| 423 | +procedure TExperiment.SetOnEndCondition(AValue: TNotifyEvent); | |
| 424 | +begin | |
| 425 | + if FOnEndCondition=AValue then Exit; | |
| 426 | + FOnEndCondition:=AValue; | |
| 427 | +end; | |
| 428 | + | |
| 429 | +procedure TExperiment.SetOnEndCycle(AValue: TNotifyEvent); | |
| 430 | +begin | |
| 431 | + if FOnEndCycle=AValue then Exit; | |
| 432 | + FOnEndCycle:=AValue; | |
| 433 | +end; | |
| 434 | + | |
| 435 | +procedure TExperiment.SetOnEndExperiment(AValue: TNotifyEvent); | |
| 436 | +begin | |
| 437 | + if FOnEndExperiment=AValue then Exit; | |
| 438 | + FOnEndExperiment:=AValue; | |
| 439 | +end; | |
| 440 | + | |
| 441 | +procedure TExperiment.SetOnEndGeneration(AValue: TNotifyEvent); | |
| 442 | +begin | |
| 443 | + if FOnEndGeneration=AValue then Exit; | |
| 444 | + FOnEndGeneration:=AValue; | |
| 445 | +end; | |
| 446 | + | |
| 447 | +procedure TExperiment.SetOnEndTurn(AValue: TNotifyEvent); | |
| 448 | +begin | |
| 449 | + if FOnEndTurn=AValue then Exit; | |
| 450 | + FOnEndTurn:=AValue; | |
| 451 | +end; | |
| 452 | + | |
| 453 | +procedure TExperiment.SetOnInterlocking(AValue: TNotifyEvent); | |
| 454 | +begin | |
| 455 | + if FOnInterlocking=AValue then Exit; | |
| 456 | + FOnInterlocking:=AValue; | |
| 457 | +end; | |
| 458 | + | |
| 459 | + | |
| 460 | +procedure TExperiment.SetPlayer(I : integer; AValue: TPlayer); | |
| 461 | +begin | |
| 462 | + FPlayers[I] := AValue; | |
| 463 | +end; | |
| 464 | + | |
| 465 | +procedure TExperiment.SetPlayer(S: UTF8string; AValue: TPlayer); | |
| 466 | +var i : integer; | |
| 467 | +begin | |
| 468 | + if PlayersCount > 0 then | |
| 469 | + for i:= 0 to PlayersCount -1 do | |
| 470 | + if FPlayers[i].ID = S then | |
| 471 | + begin | |
| 472 | + FPlayers[i] := AValue; | |
| 473 | + Exit; | |
| 474 | + end; | |
| 475 | + raise Exception.Create('TExperiment.SetPlayer: Could not set player.'); | |
| 476 | +end; | |
| 477 | + | |
| 478 | +procedure TExperiment.SetResearcherCanChat(AValue: Boolean); | |
| 479 | +begin | |
| 480 | + if FResearcherCanChat=AValue then Exit; | |
| 481 | + FResearcherCanChat:=AValue; | |
| 482 | +end; | |
| 483 | + | |
| 484 | +procedure TExperiment.SetResearcherCanPlay(AValue: Boolean); | |
| 485 | +begin | |
| 486 | + if FResearcherCanPlay=AValue then Exit; | |
| 487 | + FResearcherCanPlay:=AValue; | |
| 488 | +end; | |
| 489 | + | |
| 490 | +procedure TExperiment.SetSendChatHistoryForNewPlayers(AValue: Boolean); | |
| 491 | +begin | |
| 492 | + if FSendChatHistoryForNewPlayers=AValue then Exit; | |
| 493 | + FSendChatHistoryForNewPlayers:=AValue; | |
| 494 | +end; | |
| 495 | + | |
| 496 | +procedure TExperiment.SetState(AValue: TExperimentState); | |
| 497 | +begin | |
| 498 | + if FState=AValue then Exit; | |
| 499 | + FState:=AValue; | |
| 500 | +end; | |
| 501 | + | |
| 502 | +procedure TExperiment.Consequence(Sender: TObject); | |
| 503 | +begin | |
| 504 | + if Assigned(FOnConsequence) then FOnConsequence(Sender); | |
| 505 | +end; | |
| 506 | + | |
| 507 | +procedure TExperiment.Interlocking(Sender: TObject); | |
| 508 | +begin | |
| 509 | + if Assigned(FOnInterlocking) then FOnInterlocking(Sender); | |
| 510 | +end; | |
| 511 | + | |
| 512 | +procedure TExperiment.SetPlayersQueue(AValue: string); | |
| 513 | +var | |
| 514 | + i : integer; | |
| 515 | +begin | |
| 516 | + for i := 0 to PlayersCount-2 do | |
| 517 | + begin | |
| 518 | + FPlayers[i] := FPlayers[i+1]; | |
| 519 | + end; | |
| 520 | + FPlayers[High(FPlayers)] := PlayerFromString[AValue]; | |
| 521 | +end; | |
| 522 | + | |
| 523 | +function TExperiment.GetPlayerToKick: string; | |
| 524 | +var c : integer; | |
| 525 | +begin | |
| 526 | + c := CurrentCondition; | |
| 527 | + if Condition[c].Cycles.Count < Condition[c].Cycles.Value -1 then | |
| 528 | + Result := #32 | |
| 529 | + else | |
| 530 | + Result := FPlayers[0].ID; | |
| 531 | +end; | |
| 532 | + | |
| 533 | + | |
| 534 | +procedure TExperiment.WriteReportHeader; | |
| 535 | +var | |
| 536 | + LHeader : string; | |
| 537 | +begin | |
| 538 | + // header | |
| 539 | + LHeader := VAL_RESEARCHER+':' + #9 + FResearcher + #9 + LineEnding + | |
| 540 | + VAL_EXPERIMENT+':' + #9 + FExperimentName + #9 + LineEnding + | |
| 541 | + VAL_BEGIN_TIME+':' + #9 + DateTimeToStr(Date) + #9 + TimeToStr(Time) +#9+ LineEnding + #9 + LineEnding; | |
| 542 | + FRegData.SaveData(LHeader); | |
| 543 | + WriteReportRowNames; | |
| 544 | +end; | |
| 545 | + | |
| 546 | +procedure TExperiment.WriteReportRowNames; | |
| 547 | +var | |
| 548 | + c,j,i: integer; | |
| 549 | + LNames : string; | |
| 550 | +begin | |
| 551 | + c:= CurrentCondition; | |
| 552 | + | |
| 553 | + // column names, line 1 | |
| 554 | + LNames := 'Experimento'+#9+#9+#9; | |
| 555 | + for i:=0 to Condition[c].Turn.Value-1 do // player's response | |
| 556 | + begin | |
| 557 | + LNames += 'P'+IntToStr(i+1)+#9+#9; | |
| 558 | + for j:=0 to ContingenciesCount[c]-1 do | |
| 559 | + if not Contingency[c,j].Meta then | |
| 560 | + LNames += #9; | |
| 561 | + end; | |
| 562 | + | |
| 563 | + LNames += VAL_INTERLOCKING+'s'; | |
| 564 | + for i:=0 to ContingenciesCount[c]-1 do | |
| 565 | + if Contingency[c,i].Meta then | |
| 566 | + LNames += #9; | |
| 567 | + | |
| 568 | + if Assigned(Condition[c].Prompt) then | |
| 569 | + begin | |
| 570 | + LNames += 'Respostas à Pergunta'; | |
| 571 | + for i:=0 to Condition[c].Turn.Value-1 do | |
| 572 | + LNames += #9; | |
| 573 | + end; | |
| 574 | + LNames += LineEnding; | |
| 575 | + | |
| 576 | + // column names, line 2 | |
| 577 | + LNames += 'Condição'+#9+'Geração'+#9+'Ciclos'+#9; | |
| 578 | + for i:=0 to Condition[c].Turn.Value-1 do | |
| 579 | + begin | |
| 580 | + LNames += 'Linha'+#9+'Cor'+#9; | |
| 581 | + for j:=0 to ContingenciesCount[c]-1 do | |
| 582 | + if not Contingency[c,j].Meta then | |
| 583 | + LNames += Contingency[c,j].ContingencyName+#9; | |
| 584 | + end; | |
| 585 | + | |
| 586 | + for i:=0 to ContingenciesCount[c]-1 do | |
| 587 | + if Contingency[c,i].Meta then | |
| 588 | + LNames += Contingency[c,i].ContingencyName+#9; | |
| 589 | + | |
| 590 | + if Assigned(Condition[c].Prompt) then | |
| 591 | + for i:=0 to Condition[c].Turn.Value-1 do | |
| 592 | + LNames += 'R'+IntToStr(i+1)+#9; | |
| 593 | + | |
| 594 | + LNames += '|'+#9; | |
| 595 | + if FLastReportColNames <> LNames then | |
| 596 | + begin | |
| 597 | + FLastReportColNames := LNames; | |
| 598 | + FRegData.SaveData(LNames); | |
| 599 | + end; | |
| 600 | +end; | |
| 601 | + | |
| 602 | +procedure TExperiment.WriteReportRow; | |
| 603 | +var | |
| 604 | + c,j,i: integer; | |
| 605 | + LRow : string; | |
| 606 | +begin | |
| 607 | + c:= CurrentCondition; | |
| 608 | + | |
| 609 | + LRow := LineEnding + IntToStr(c+1)+#9+IntToStr(Condition[c].Cycles.Generation+1)+#9+IntToStr(GetCurrentAbsoluteCycle+1)+#9; | |
| 610 | + for i:=0 to Condition[c].Turn.Value-1 do | |
| 611 | + begin | |
| 612 | + LRow += GetRowString(FPlayers[i].Choice.Row)+#9+GetColorString(FPlayers[i].Choice.Color)+#9; | |
| 613 | + for j:=0 to ContingenciesCount[c]-1 do | |
| 614 | + if not Contingency[c,j].Meta then | |
| 615 | + if Contingency[c,j].ConsequenceFromPlayerID(FPlayers[i].ID) <> '' then | |
| 616 | + LRow += '1'+#9 | |
| 617 | + else | |
| 618 | + LRow += '0'+#9; | |
| 619 | + end; | |
| 620 | + | |
| 621 | + for i:=0 to ContingenciesCount[c]-1 do | |
| 622 | + if Contingency[c,i].Meta then | |
| 623 | + if Contingency[c,i].Fired then | |
| 624 | + LRow += '1'+#9 | |
| 625 | + else | |
| 626 | + LRow += '0'+#9; | |
| 627 | + | |
| 628 | + FRegData.SaveData(LRow); | |
| 629 | +end; | |
| 630 | + | |
| 631 | +procedure TExperiment.WriteReportRowPrompt; | |
| 632 | +var | |
| 633 | + c,i: integer; | |
| 634 | + LRow : string; | |
| 635 | +begin | |
| 636 | + c := CurrentCondition; | |
| 637 | + LRow := ''; | |
| 638 | + if Condition[c].Prompt.ResponsesCount = Condition[c].Turn.Value then | |
| 639 | + for i:=0 to Condition[c].Prompt.ResponsesCount-1 do | |
| 640 | + LRow += 'P'+IntToStr(PlayerIndexFromID[Delimited(1,Condition[c].Prompt.Response(i))]+1)+ | |
| 641 | + '|'+ | |
| 642 | + Delimited(2,Condition[c].Prompt.Response(i))+#9 | |
| 643 | + else | |
| 644 | + for i:=0 to Condition[c].Turn.Value-1 do | |
| 645 | + LRow += 'NA'+#9; | |
| 646 | + | |
| 647 | + FRegData.SaveData(LRow); | |
| 648 | +end; | |
| 649 | + | |
| 650 | +constructor TExperiment.Create(AOwner: TComponent); | |
| 651 | +begin | |
| 652 | + inherited Create(AOwner); | |
| 653 | + FTurnsRandom := TStringList.Create; | |
| 654 | + LoadExperimentFromResource(Self); | |
| 655 | + CheckNeedForRandomTurns; | |
| 656 | +end; | |
| 657 | + | |
| 658 | +constructor TExperiment.Create(AOwner: TComponent;AppPath:string); | |
| 659 | +begin | |
| 660 | + inherited Create(AOwner); | |
| 661 | + FTurnsRandom := TStringList.Create; | |
| 662 | + LoadExperimentFromResource(Self); | |
| 663 | + CheckNeedForRandomTurns; | |
| 664 | + FRegData := TRegData.Create(Self, AppPath+VAL_RESEARCHER+'es'+PathDelim+Researcher+PathDelim+ExperimentName+PathDelim+'000.dat'); | |
| 665 | + WriteReportHeader; | |
| 666 | +end; | |
| 667 | + | |
| 668 | +constructor TExperiment.Create(AOwner:TComponent;AFilename,AppPath:string); | |
| 669 | +begin | |
| 670 | + inherited Create(AOwner); | |
| 671 | + FTurnsRandom := TStringList.Create; | |
| 672 | + LoadExperimentFromFile(Self,AFilename); | |
| 673 | + CheckNeedForRandomTurns; | |
| 674 | +end; | |
| 675 | + | |
| 676 | +destructor TExperiment.Destroy; | |
| 677 | +begin | |
| 678 | + FTurnsRandom.Free; | |
| 679 | + inherited Destroy; | |
| 680 | +end; | |
| 681 | + | |
| 682 | +function TExperiment.LoadFromFile(AFilename: string): Boolean; | |
| 683 | +begin | |
| 684 | + Result := LoadExperimentFromFile(Self, AFilename); | |
| 685 | + if Result then | |
| 686 | + FFilename := AFilename; | |
| 687 | + CheckNeedForRandomTurns; | |
| 688 | +end; | |
| 689 | + | |
| 690 | +function TExperiment.LoadFromGenerator: Boolean; | |
| 691 | +begin | |
| 692 | + Result := LoadExperimentFromResource(Self); | |
| 693 | + if Result then | |
| 694 | + FFilename := GetCurrentDir + PathDelim + FResearcher + PathDelim; | |
| 695 | + CheckNeedForRandomTurns; | |
| 696 | +end; | |
| 697 | + | |
| 698 | +function TExperiment.AppendCondition: integer; | |
| 699 | +begin | |
| 700 | + SetLength(FConditions, Length(FConditions)+1); | |
| 701 | + Result := High(FConditions); | |
| 702 | +end; | |
| 703 | + | |
| 704 | +function TExperiment.AppendCondition(ACondition: TCondition): integer; | |
| 705 | +begin | |
| 706 | + SetLength(FConditions, Length(FConditions)+1); | |
| 707 | + Result := High(FConditions); | |
| 708 | + FConditions[Result] := ACondition; | |
| 709 | +end; | |
| 710 | + | |
| 711 | +function TExperiment.AppendContingency(ACondition: integer): integer; | |
| 712 | +begin | |
| 713 | + SetLength(FConditions[ACondition].Contingencies, Length(FConditions[ACondition].Contingencies)+1); | |
| 714 | + Result := High(FConditions[ACondition].Contingencies); | |
| 715 | +end; | |
| 716 | + | |
| 717 | +function TExperiment.AppendContingency(ACondition: integer; | |
| 718 | + AContingency: TContingency): integer; | |
| 719 | +begin | |
| 720 | + SetLength(FConditions[ACondition].Contingencies, Length(FConditions[ACondition].Contingencies)+1); | |
| 721 | + Result := High(FConditions[ACondition].Contingencies); | |
| 722 | + FConditions[ACondition].Contingencies[Result] := AContingency; | |
| 723 | +end; | |
| 724 | + | |
| 725 | +function TExperiment.AppendPlayer: integer; | |
| 726 | +begin | |
| 727 | + SetLength(FPlayers, Length(FPlayers)+1); | |
| 728 | + Result := High(FPlayers); | |
| 729 | +end; | |
| 730 | + | |
| 731 | +function TExperiment.AppendPlayer(APlayer: TPlayer): integer; | |
| 732 | +begin | |
| 733 | + SetLength(FPlayers, Length(FPlayers)+1); | |
| 734 | + Result := High(FPlayers); | |
| 735 | + FPlayers[Result] := APlayer; | |
| 736 | +end; | |
| 737 | + | |
| 738 | +procedure TExperiment.SaveToFile(AFilename: string); | |
| 739 | +begin | |
| 740 | + SaveExperimentToFile(Self,AFilename); | |
| 741 | +end; | |
| 742 | + | |
| 743 | +procedure TExperiment.SaveToFile; | |
| 744 | +begin | |
| 745 | + if FFilename <> '' then | |
| 746 | + SaveExperimentToFile(Self,FFilename) | |
| 747 | + else | |
| 748 | +{$IFDEF DEBUG} | |
| 749 | + WriteLn(WARN_CANNOT_SAVE) | |
| 750 | +{$ENDIF}; | |
| 751 | +end; | |
| 752 | + | |
| 753 | +procedure TExperiment.Clean; | |
| 754 | +var c,i : integer; | |
| 755 | +begin | |
| 756 | + for i := 0 to PlayersCount -1 do | |
| 757 | + begin | |
| 758 | + FPlayers[i].Choice.Row:=grNone; | |
| 759 | + FPlayers[i].Choice.Color:=gcNone; | |
| 760 | + end; | |
| 761 | + c := CurrentCondition; | |
| 762 | + for i := 0 to ContingenciesCount[c]-1 do | |
| 763 | + Contingency[c,i].Clean; | |
| 764 | + | |
| 765 | + Condition[c].Prompt.Clean; | |
| 766 | + | |
| 767 | + FRegData.CloseAndOpen; | |
| 768 | +end; | |
| 769 | + | |
| 770 | +procedure TExperiment.Play; | |
| 771 | +var i : integer; | |
| 772 | +begin | |
| 773 | + //for i := 0 to Condition[CurrentCondition].Turn.Value-1 do | |
| 774 | + // begin | |
| 775 | + // //TRegData.Save Header; | |
| 776 | + // end; | |
| 777 | + FState:=xsRunning; | |
| 778 | +end; | |
| 779 | + | |
| 780 | + | |
| 781 | +end. | |
| 782 | + | ... | ... |
| ... | ... | @@ -0,0 +1,124 @@ |
| 1 | +unit report_reader; | |
| 2 | + | |
| 3 | +{$mode objfpc}{$H+} | |
| 4 | + | |
| 5 | +interface | |
| 6 | + | |
| 7 | +uses | |
| 8 | + Classes, SysUtils; | |
| 9 | + | |
| 10 | +type | |
| 11 | + | |
| 12 | + TRowRange = record | |
| 13 | + Low, | |
| 14 | + High : integer; | |
| 15 | + end; | |
| 16 | + | |
| 17 | + { TReportReader } | |
| 18 | + | |
| 19 | + TReportReader = class | |
| 20 | + private | |
| 21 | + FLastRowsX : integer; | |
| 22 | + FRows : TStringList; | |
| 23 | + FCols : TStringList; | |
| 24 | + FRowRange: TRowRange; | |
| 25 | + FUseRange: Boolean; | |
| 26 | + function GetColumnOf(AName: string): TStringList; | |
| 27 | + procedure RangeAsLastXRows; | |
| 28 | + public | |
| 29 | + VRow : string; //helper | |
| 30 | + constructor Create; | |
| 31 | + destructor Destroy; override; | |
| 32 | + procedure Append(ARow : string); | |
| 33 | + procedure Extend(ARowExtention : string); | |
| 34 | + procedure Clean; | |
| 35 | + procedure SetXLastRows(X:integer); | |
| 36 | + property Range : TRowRange read FRowRange; | |
| 37 | + property UseRange : Boolean read FUseRange write FUseRange; | |
| 38 | + property ColumnOf[AName:string]:TStringList read GetColumnOf; | |
| 39 | + end; | |
| 40 | + | |
| 41 | +implementation | |
| 42 | + | |
| 43 | +uses strutils; | |
| 44 | + | |
| 45 | +{ TReportReader } | |
| 46 | + | |
| 47 | +function TReportReader.GetColumnOf(AName: string): TStringList; | |
| 48 | +var | |
| 49 | + c, | |
| 50 | + i : integer; | |
| 51 | + Row : string; | |
| 52 | +begin | |
| 53 | + Result := TStringList.Create; | |
| 54 | + c := FCols.IndexOf(AName); | |
| 55 | + if c > -1 then | |
| 56 | + if FUseRange and (FRowRange.Low <= FRowRange.High) and (FRowRange.Low > 0) then | |
| 57 | + for i := FRowRange.Low to FRowRange.High do | |
| 58 | + Result.Append(ExtractDelimited(c+1, FRows[i],[#9,#10])) | |
| 59 | + else | |
| 60 | + for Row in FRows do | |
| 61 | + Result.Append(ExtractDelimited(c+1, Row,[#9,#10])); | |
| 62 | +end; | |
| 63 | + | |
| 64 | +constructor TReportReader.Create; | |
| 65 | +begin | |
| 66 | + inherited Create; | |
| 67 | + FUseRange := False; | |
| 68 | + FRows := TStringList.Create; | |
| 69 | + FCols := TStringList.Create; | |
| 70 | + FCols.Delimiter := #9; | |
| 71 | + FCols.StrictDelimiter := True; | |
| 72 | +end; | |
| 73 | + | |
| 74 | +destructor TReportReader.Destroy; | |
| 75 | +begin | |
| 76 | + FRows.Free; | |
| 77 | + FCols.Free; | |
| 78 | + inherited Destroy; | |
| 79 | +end; | |
| 80 | + | |
| 81 | +procedure TReportReader.Append(ARow: string); | |
| 82 | +begin | |
| 83 | + if FCols.Count = 0 then | |
| 84 | + FCols.DelimitedText := ARow | |
| 85 | + else | |
| 86 | + begin | |
| 87 | + FRows.Append(ARow); | |
| 88 | + RangeAsLastXRows; | |
| 89 | + end; | |
| 90 | +end; | |
| 91 | + | |
| 92 | +procedure TReportReader.Extend(ARowExtention: string); | |
| 93 | +begin | |
| 94 | + FRows[FRows.Count-1] := FRows[FRows.Count-1] + ARowExtention; | |
| 95 | +end; | |
| 96 | + | |
| 97 | +procedure TReportReader.Clean; | |
| 98 | +begin | |
| 99 | + FCols.Clear; | |
| 100 | + FRows.Clear; | |
| 101 | +end; | |
| 102 | + | |
| 103 | +procedure TReportReader.SetXLastRows(X: integer); | |
| 104 | +begin | |
| 105 | + FLastRowsX:=X; | |
| 106 | + RangeAsLastXRows; | |
| 107 | +end; | |
| 108 | + | |
| 109 | +procedure TReportReader.RangeAsLastXRows; | |
| 110 | +begin | |
| 111 | + FRowRange.High := FRows.Count-1; | |
| 112 | + FRowRange.Low := FRows.Count-FLastRowsX; | |
| 113 | + {$IFDEF DEBUG} | |
| 114 | + if FRowRange.Low > FRowRange.High then | |
| 115 | + WriteLn('Warning: FRowRange.Low > FRowRange.High, range will not be used'); | |
| 116 | + | |
| 117 | + if FRowRange.Low < 0 then | |
| 118 | + WriteLn('Warning: FRowRange.Low < 0, range will not be used'); | |
| 119 | + {$ENDIF} | |
| 120 | +end; | |
| 121 | + | |
| 122 | + | |
| 123 | +end. | |
| 124 | + | ... | ... |
units/game_actors.pas
units/game_control.pas
| ... | ... | @@ -81,6 +81,7 @@ type |
| 81 | 81 | procedure Start; |
| 82 | 82 | procedure Pause; |
| 83 | 83 | procedure Resume; |
| 84 | + procedure Stop; | |
| 84 | 85 | property Experiment : TExperiment read FExperiment write FExperiment; |
| 85 | 86 | property ID : UTF8string read FID; |
| 86 | 87 | property RowBase : integer read FRowBase write SetRowBase; |
| ... | ... | @@ -90,28 +91,28 @@ type |
| 90 | 91 | |
| 91 | 92 | function GetRowColor(ARow : integer;ARowBase:integer) : TColor; |
| 92 | 93 | |
| 93 | -// TODO: PUT MESSAGES IN RESOURCE STRING | |
| 94 | +// TODO: PUT NORMAL STRING MESSAGES IN RESOURCESTRING INSTEAD | |
| 94 | 95 | |
| 95 | 96 | const |
| 96 | - K_FULLROOM = '.Full'; | |
| 97 | - K_PLAYING = '.Playing'; | |
| 98 | 97 | K_ARRIVED = '.Arrived'; |
| 99 | - K_REFUSED = '.Refused'; | |
| 100 | 98 | K_CHAT_M = '.ChatM'; |
| 101 | 99 | K_CHOICE = '.Choice'; |
| 102 | 100 | K_MESSAGE = '.Message'; |
| 103 | 101 | K_START = '.Start'; |
| 104 | 102 | K_RESUME = '.Resume'; |
| 105 | - K_DATA_A = '.Data'; | |
| 106 | 103 | K_LOGIN = '.Login'; |
| 107 | 104 | K_QUESTION = '.Question'; |
| 108 | 105 | K_QMESSAGE = '.QMessage'; |
| 109 | 106 | K_MOVQUEUE = '.Queue'; |
| 107 | + K_END = '.EndX'; | |
| 108 | + | |
| 110 | 109 | // |
| 111 | 110 | K_STATUS = '.Status'; |
| 112 | 111 | K_LEFT = '.Left'; |
| 113 | 112 | K_WAIT = '.Wait'; |
| 114 | - //K_RESPONSE = | |
| 113 | + K_FULLROOM = '.Full'; | |
| 114 | + K_PLAYING = '.Playing'; | |
| 115 | + K_REFUSED = '.Refused'; | |
| 115 | 116 | |
| 116 | 117 | implementation |
| 117 | 118 | |
| ... | ... | @@ -211,7 +212,7 @@ end; |
| 211 | 212 | |
| 212 | 213 | procedure TGameControl.EndExperiment(Sender: TObject); |
| 213 | 214 | begin |
| 214 | - | |
| 215 | + FZMQActor.SendMessage([K_END]); | |
| 215 | 216 | end; |
| 216 | 217 | |
| 217 | 218 | procedure TGameControl.StartExperiment; |
| ... | ... | @@ -224,23 +225,54 @@ begin |
| 224 | 225 | |
| 225 | 226 | // enable matrix grid for the first player |
| 226 | 227 | FZMQActor.SendMessage([K_START]); |
| 228 | + | |
| 229 | + // | |
| 230 | + Start; | |
| 227 | 231 | end; |
| 228 | 232 | |
| 229 | 233 | procedure TGameControl.Start; |
| 230 | 234 | begin |
| 231 | - // basic data/csv setup | |
| 232 | - // wait for players | |
| 235 | + // basic gui setup | |
| 236 | + | |
| 237 | + // points | |
| 238 | + FormMatrixGame.GBIndividualAB.Visible := FExperiment.ABPoints; | |
| 239 | + FormMatrixGame.GBIndividual.Visible:= not FormMatrixGame.GBIndividualAB.Visible; | |
| 240 | + | |
| 241 | + // turns | |
| 242 | + FormMatrixGame.LabelExpCountTurn.Caption:=IntToStr(FExperiment.Condition[FExperiment.CurrentCondition].Turn.Count+1); | |
| 243 | + | |
| 244 | + // cycle | |
| 245 | + FormMatrixGame.LabelExpCountCycle.Caption:=IntToStr(FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Count+1); | |
| 233 | 246 | |
| 247 | + // generation | |
| 248 | + FormMatrixGame.LabelExpCountGeneration.Caption:=IntToStr(FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Generation+1); | |
| 249 | + | |
| 250 | + // condition | |
| 251 | + FormMatrixGame.LabelExpCountCondition.Caption:= FExperiment.Condition[FExperiment.CurrentCondition].ConditionName; | |
| 252 | + | |
| 253 | + // interlocks | |
| 254 | + FormMatrixGame.LabelExpCountInterlocks.Caption:= IntToStr(FExperiment.Condition[FExperiment.CurrentCondition].Interlocks.Count+1); | |
| 255 | + | |
| 256 | + // wait for players | |
| 234 | 257 | end; |
| 235 | 258 | |
| 236 | 259 | procedure TGameControl.Pause; |
| 237 | 260 | begin |
| 261 | + // save to file | |
| 238 | 262 | |
| 263 | + // inform players | |
| 239 | 264 | end; |
| 240 | 265 | |
| 241 | 266 | procedure TGameControl.Resume; |
| 242 | 267 | begin |
| 268 | + // load from file | |
| 243 | 269 | |
| 270 | + // wait for players | |
| 271 | +end; | |
| 272 | + | |
| 273 | +procedure TGameControl.Stop; | |
| 274 | +begin | |
| 275 | + // cleaning | |
| 244 | 276 | end; |
| 245 | 277 | |
| 246 | 278 | function TGameControl.GetPlayerBox(AID: UTF8string): TPlayerBox; |
| ... | ... | @@ -486,8 +518,8 @@ end; |
| 486 | 518 | |
| 487 | 519 | constructor TGameControl.Create(AOwner: TComponent;AppPath:string); |
| 488 | 520 | begin |
| 521 | + inherited Create(AOwner); | |
| 489 | 522 | FZMQActor := TZMQActor(AOwner); |
| 490 | - inherited Create(FZMQActor.Owner); | |
| 491 | 523 | FID := FZMQActor.ID; |
| 492 | 524 | FZMQActor.OnMessageReceived:=@ReceiveMessage; |
| 493 | 525 | FZMQActor.OnRequestReceived:=@ReceiveRequest; |
| ... | ... | @@ -518,14 +550,7 @@ begin |
| 518 | 550 | FExperiment.OnInterlocking:=@Interlocking; |
| 519 | 551 | FExperiment.OnConsequence:=@Consequence; |
| 520 | 552 | |
| 521 | - //NextTurn(Self); | |
| 522 | - //NextCycle(Self); | |
| 523 | - //NextLineage(Self); | |
| 524 | - //NextCondition(Self); | |
| 525 | - //Interlocking(Self); | |
| 526 | - //Consequence(Self); | |
| 527 | - | |
| 528 | - SendRequest(K_LOGIN); | |
| 553 | + SendRequest(K_LOGIN); // admin cannot send requests | |
| 529 | 554 | end; |
| 530 | 555 | |
| 531 | 556 | destructor TGameControl.Destroy; |
| ... | ... | @@ -751,20 +776,33 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); |
| 751 | 776 | end; |
| 752 | 777 | |
| 753 | 778 | procedure SayGoodBye(AID:string); |
| 779 | + var Pts : string; | |
| 754 | 780 | begin |
| 755 | 781 | DeletePlayerBox(AID); // old player |
| 756 | 782 | case FActor of |
| 757 | 783 | gaPlayer:begin |
| 758 | 784 | if Self.ID = AID then |
| 759 | 785 | begin |
| 760 | - // TODO: SHOW EARNED POINTS TO PARTICIPANT | |
| 761 | - //FormMatrixGame.LabelIndA.Caption; | |
| 762 | - //FormMatrixGame.LabelIndB.Caption; | |
| 763 | - //FormMatrixGame.LabelIndG.Caption; | |
| 786 | + if FExperiment.ABPoints then | |
| 787 | + begin | |
| 788 | + Pts := IntToStr(StrToInt(FormMatrixGame.LabelIndACount.Caption)+StrToInt(FormMatrixGame.LabelIndBCount.Caption)); | |
| 789 | + FormMatrixGame.LabelIndACount.Caption := '0'; | |
| 790 | + FormMatrixGame.LabelIndBCount.Caption := '0'; | |
| 791 | + end | |
| 792 | + else | |
| 793 | + begin | |
| 794 | + Pts := FormMatrixGame.LabelIndCount.Caption; | |
| 795 | + FormMatrixGame.LabelIndCount.Caption := '0'; | |
| 796 | + end; | |
| 764 | 797 | |
| 765 | 798 | FormMatrixGame.Visible := False; |
| 766 | 799 | FormChooseActor := TFormChooseActor.Create(nil); |
| 767 | 800 | FormChooseActor.Style := K_LEFT; |
| 801 | + FormChooseActor.ShowPoints( | |
| 802 | + 'A tarefa terminou, obrigado por sua participação! Você produziu ' + | |
| 803 | + Pts + ' pontos e ' + | |
| 804 | + FormMatrixGame.LabelGroupCount.Caption + ' itens escolares serão doados!'); | |
| 805 | + | |
| 768 | 806 | if FormChooseActor.ShowModal = 1 then |
| 769 | 807 | begin |
| 770 | 808 | FZMQActor.Request([AID,' ',K_RESUME]); |
| ... | ... | @@ -774,22 +812,33 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); |
| 774 | 812 | FormChooseActor.Free; |
| 775 | 813 | end |
| 776 | 814 | else |
| 777 | - ShowPopUp('O jogador '+FExperiment.PlayerFromID[ID].Nicname+ ' saiu. Por favor, aguarde...'); | |
| 815 | + ShowPopUp(FExperiment.PlayerFromID[AID].Nicname+ ' saiu. Por favor, aguarde a chegada de alguém para ocupar o lugar.'); | |
| 778 | 816 | end; |
| 779 | - | |
| 780 | - gaAdmin:ShowPopUp( | |
| 781 | - 'O participante '+ | |
| 782 | - FExperiment.PlayerFromID[ID].Nicname+ | |
| 783 | - ' saiu. Aguardando a entrada do próximo participante.' | |
| 784 | - ); | |
| 785 | 817 | end; |
| 786 | 818 | end; |
| 819 | + | |
| 787 | 820 | procedure ResumeNextTurn; |
| 788 | 821 | begin |
| 789 | - if AMessage[1] <> #32 then | |
| 790 | - SayGoodBye(AMessage[1]) | |
| 791 | - else | |
| 792 | - EnablePlayerMatrix(Self.ID,0, True); | |
| 822 | + case FActor of | |
| 823 | + gaPlayer:begin | |
| 824 | + if AMessage[1] <> #32 then | |
| 825 | + SayGoodBye(AMessage[1]) | |
| 826 | + else | |
| 827 | + EnablePlayerMatrix(Self.ID,0, True); | |
| 828 | + | |
| 829 | + end; | |
| 830 | + gaAdmin:begin | |
| 831 | + if AMessage[1] <> #32 then | |
| 832 | + begin | |
| 833 | + DeletePlayerBox(AMessage[1]); // old player | |
| 834 | + ShowPopUp( | |
| 835 | + 'O participante '+ | |
| 836 | + FExperiment.PlayerFromID[AMessage[1]].Nicname+ | |
| 837 | + ' saiu. Aguardando a entrada do próximo participante.' | |
| 838 | + ); | |
| 839 | + end; | |
| 840 | + end; | |
| 841 | + end; | |
| 793 | 842 | end; |
| 794 | 843 | |
| 795 | 844 | procedure QuestionMessages; |
| ... | ... | @@ -816,6 +865,34 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); |
| 816 | 865 | ResumeNextTurn; |
| 817 | 866 | end; |
| 818 | 867 | |
| 868 | + procedure ShowPointsToPlayers; | |
| 869 | + var Pts : string; | |
| 870 | + begin | |
| 871 | + case FActor of | |
| 872 | + gaPlayer: | |
| 873 | + begin | |
| 874 | + CleanMatrix(False); | |
| 875 | + FormChooseActor := TFormChooseActor.Create(FormMatrixGame); | |
| 876 | + FormChooseActor.Style := K_END; | |
| 877 | + | |
| 878 | + if FExperiment.ABPoints then | |
| 879 | + Pts := IntToStr(StrToInt(FormMatrixGame.LabelIndACount.Caption)+StrToInt(FormMatrixGame.LabelIndBCount.Caption)) | |
| 880 | + else | |
| 881 | + Pts := FormMatrixGame.LabelIndCount.Caption; | |
| 882 | + | |
| 883 | + FormChooseActor.ShowPoints( | |
| 884 | + 'A tarefa terminou, obrigado por sua participação! Você produziu ' + | |
| 885 | + Pts + ' pontos e ' + | |
| 886 | + FormMatrixGame.LabelGroupCount.Caption + 'itens escolares serão doados!'); | |
| 887 | + FormChooseActor.Show; | |
| 888 | + end; | |
| 889 | + gaAdmin: | |
| 890 | + begin | |
| 891 | + Stop; | |
| 892 | + end; | |
| 893 | + end; | |
| 894 | + end; | |
| 895 | + | |
| 819 | 896 | begin |
| 820 | 897 | if MHas(K_ARRIVED) then ReceiveActor; |
| 821 | 898 | if MHas(K_CHAT_M) then ReceiveChat; |
| ... | ... | @@ -826,6 +903,7 @@ begin |
| 826 | 903 | if MHas(K_MOVQUEUE) then MovePlayerQueue; |
| 827 | 904 | if MHas(K_QMESSAGE) then QuestionMessages; |
| 828 | 905 | if MHas(K_RESUME) then ResumeNextTurn; |
| 906 | + if MHAs(K_END) then ShowPointsToPlayers; | |
| 829 | 907 | end; |
| 830 | 908 | |
| 831 | 909 | // Here FActor is garanted to be a TZMQAdmin |
| ... | ... | @@ -887,15 +965,18 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); |
| 887 | 965 | if FExperiment.Player[i].ID <> P.ID then |
| 888 | 966 | begin |
| 889 | 967 | TS := FExperiment.PlayerAsString[FEXperiment.Player[i]]; |
| 890 | - ARequest.Append(TS); // FROM 3 to COUNT-2 | |
| 968 | + ARequest.Append(TS); // FROM 3 to COUNT-3 | |
| 891 | 969 | end; |
| 892 | 970 | |
| 893 | 971 | // append chat data if allowed at the last position |
| 894 | 972 | if FExperiment.SendChatHistoryForNewPlayers then |
| 895 | - ARequest.Append(FormMatrixGame.ChatMemoRecv.Lines.Text) // LAST | |
| 973 | + ARequest.Append(FormMatrixGame.ChatMemoRecv.Lines.Text) // COUNT-2 | |
| 896 | 974 | else |
| 897 | 975 | ARequest.Append('[CHAT]'); // must append something to keep the message envelop standard |
| 898 | 976 | |
| 977 | + // append global configs. | |
| 978 | + ARequest.Append(BoolToStr(FExperiment.ABPoints)); // COUNT-1 | |
| 979 | + | |
| 899 | 980 | // inform all players about the new player, including itself |
| 900 | 981 | FZMQActor.SendMessage([K_ARRIVED,PS]); |
| 901 | 982 | |
| ... | ... | @@ -962,7 +1043,7 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); |
| 962 | 1043 | FExperiment.WriteReportRowPrompt; |
| 963 | 1044 | FExperiment.Clean; |
| 964 | 1045 | end; |
| 965 | - ARequest.Append(FExperiment.NextGeneration); // #32 no, else NextGeneration = PlayerToKick | |
| 1046 | + ARequest.Append(FExperiment.NextGeneration); // 9, #32 no, else NextGeneration = PlayerToKick | |
| 966 | 1047 | end; |
| 967 | 1048 | end; |
| 968 | 1049 | |
| ... | ... | @@ -1032,8 +1113,8 @@ begin |
| 1032 | 1113 | if MHas(K_QUESTION) then ValidateQuestionResponse; |
| 1033 | 1114 | end; |
| 1034 | 1115 | |
| 1035 | -// Here FActor is garanted to be a TZMQPlayer, reply by: | |
| 1036 | -// - sending private data to player player | |
| 1116 | +// Here FActor is garanted to be a TZMQPlayer, replying by: | |
| 1117 | +// - sending private data to player | |
| 1037 | 1118 | // - sending data from early history to income players |
| 1038 | 1119 | procedure TGameControl.ReceiveReply(AReply: TStringList); |
| 1039 | 1120 | function MHas(const C : UTF8string) : Boolean; |
| ... | ... | @@ -1048,7 +1129,7 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); |
| 1048 | 1129 | begin |
| 1049 | 1130 | if Self.ID = AReply[0] then |
| 1050 | 1131 | begin |
| 1051 | - for i:= 3 to AReply.Count -2 do | |
| 1132 | + for i:= 3 to AReply.Count -3 do | |
| 1052 | 1133 | begin |
| 1053 | 1134 | P := FExperiment.PlayerFromString[AReply[i]]; |
| 1054 | 1135 | FExperiment.AppendPlayer(P); |
| ... | ... | @@ -1057,7 +1138,11 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); |
| 1057 | 1138 | |
| 1058 | 1139 | // add chat |
| 1059 | 1140 | FormMatrixGame.ChatMemoRecv.Lines.Clear; |
| 1060 | - FormMatrixGame.ChatMemoRecv.Lines.Add(AReply[AReply.Count-1]); | |
| 1141 | + FormMatrixGame.ChatMemoRecv.Lines.Add(AReply[AReply.Count-2]); | |
| 1142 | + | |
| 1143 | + // set global configs | |
| 1144 | + FormMatrixGame.GBIndividualAB.Visible := StrToBool(AReply[AReply.Count-1]); | |
| 1145 | + FormMatrixGame.GBIndividual.Visible:= not FormMatrixGame.GBIndividualAB.Visible; | |
| 1061 | 1146 | end |
| 1062 | 1147 | else |
| 1063 | 1148 | begin | ... | ... |
units/game_experiment.pas
| ... | ... | @@ -68,6 +68,7 @@ type |
| 68 | 68 | function GetConsequenceStringFromChoice(P:TPlayer): Utf8string; |
| 69 | 69 | function GetConsequenceStringFromChoices:UTF8String; |
| 70 | 70 | procedure CheckNeedForRandomTurns; |
| 71 | + procedure EndExperiment; | |
| 71 | 72 | procedure SetCondition(I : Integer; AValue: TCondition); |
| 72 | 73 | procedure SetContingency(ACondition, I : integer; AValue: TContingency); |
| 73 | 74 | procedure SetMatrixType(AValue: TGameMatrixType); |
| ... | ... | @@ -85,6 +86,7 @@ type |
| 85 | 86 | procedure SetSendChatHistoryForNewPlayers(AValue: Boolean); |
| 86 | 87 | procedure SetState(AValue: TExperimentState); |
| 87 | 88 | private |
| 89 | + FABPoints: Boolean; | |
| 88 | 90 | FChangeGeneration: string; |
| 89 | 91 | FOnConsequence: TNotifyEvent; |
| 90 | 92 | FOnInterlocking: TNotifyEvent; |
| ... | ... | @@ -114,6 +116,7 @@ type |
| 114 | 116 | procedure WriteReportRowPrompt; |
| 115 | 117 | property ExperimentAim : string read FExperimentAim write FExperimentAim; |
| 116 | 118 | property ExperimentName : string read FExperimentName write FExperimentName; |
| 119 | + property ABPoints : Boolean read FABPoints write FABPoints; | |
| 117 | 120 | property GenPlayersAsNeeded : Boolean read FGenPlayersAsNeeded write FGenPlayersAsNeeded; |
| 118 | 121 | property ResearcherCanPlay : Boolean read FResearcherCanPlay write SetResearcherCanPlay; |
| 119 | 122 | property ResearcherCanChat : Boolean read FResearcherCanChat write SetResearcherCanChat; |
| ... | ... | @@ -243,6 +246,11 @@ var |
| 243 | 246 | begin |
| 244 | 247 | if Assigned(FOnEndCondition) then FOnEndCondition(Self); |
| 245 | 248 | Inc(FCurrentCondition); |
| 249 | + if FCurrentCondition = ConditionsCount-1 then | |
| 250 | + begin | |
| 251 | + EndExperiment; | |
| 252 | + Exit; | |
| 253 | + end; | |
| 246 | 254 | FReportReader.Clean; |
| 247 | 255 | FReportReader.SetXLastRows(Condition[CurrentCondition].EndCriterium.LastCycles); |
| 248 | 256 | WriteReportRowNames; |
| ... | ... | @@ -253,11 +261,11 @@ begin |
| 253 | 261 | |
| 254 | 262 | // interlockings in the last x cycles |
| 255 | 263 | LInterlocks := InterlockingsInLastCycles; |
| 256 | - case FConditions[CurrentCondition].EndCriterium.Value of | |
| 264 | + case FConditions[CurrentCondition].EndCriterium.Style of | |
| 257 | 265 | gecWhichComeFirst: |
| 258 | 266 | begin |
| 259 | 267 | if (GetCurrentAbsoluteCycle = FConditions[CurrentCondition].EndCriterium.AbsoluteCycles) or |
| 260 | - (LInterlocks = FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage) then | |
| 268 | + (LInterlocks >= FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage) then | |
| 261 | 269 | EndCondition; |
| 262 | 270 | |
| 263 | 271 | end; |
| ... | ... | @@ -266,7 +274,7 @@ begin |
| 266 | 274 | EndCondition; |
| 267 | 275 | |
| 268 | 276 | gecInterlockingPorcentage: |
| 269 | - if LInterlocks = FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage then | |
| 277 | + if LInterlocks >= FConditions[CurrentCondition].EndCriterium.InterlockingPorcentage then | |
| 270 | 278 | EndCondition; |
| 271 | 279 | |
| 272 | 280 | end; |
| ... | ... | @@ -424,6 +432,11 @@ begin |
| 424 | 432 | end; |
| 425 | 433 | end; |
| 426 | 434 | |
| 435 | +procedure TExperiment.EndExperiment; | |
| 436 | +begin | |
| 437 | + if Assigned(FOnEndExperiment) then FOnEndExperiment(Self); | |
| 438 | +end; | |
| 439 | + | |
| 427 | 440 | procedure TExperiment.SetCondition(I : Integer; AValue: TCondition); |
| 428 | 441 | begin |
| 429 | 442 | FConditions[I] := AValue; |
| ... | ... | @@ -628,7 +641,6 @@ begin |
| 628 | 641 | for i:=0 to Condition[c].Turn.Value-1 do |
| 629 | 642 | LNames += 'R'+IntToStr(i+1)+#9; |
| 630 | 643 | |
| 631 | - LNames += '|'+#9; | |
| 632 | 644 | if FLastReportColNames <> LNames then |
| 633 | 645 | begin |
| 634 | 646 | FLastReportColNames := LNames; |
| ... | ... | @@ -667,6 +679,7 @@ begin |
| 667 | 679 | LRow += '0'+#9; |
| 668 | 680 | |
| 669 | 681 | FRegData.SaveData(LRow); |
| 682 | + FReportReader.Append(LRow); | |
| 670 | 683 | end; |
| 671 | 684 | end; |
| 672 | 685 | |
| ... | ... | @@ -689,6 +702,7 @@ begin |
| 689 | 702 | LRow += 'NA'+#9; |
| 690 | 703 | |
| 691 | 704 | FRegData.SaveData(LRow); |
| 705 | + FReportReader.Extend(LRow); | |
| 692 | 706 | end; |
| 693 | 707 | end; |
| 694 | 708 | ... | ... |
units/game_file_methods.pas
| ... | ... | @@ -81,7 +81,7 @@ begin |
| 81 | 81 | GenPlayersAsNeeded:=True; |
| 82 | 82 | CurrentCondition := 0; |
| 83 | 83 | MatrixType:=[gmRows]; |
| 84 | - | |
| 84 | + ABPoints := True; | |
| 85 | 85 | //AppendPlayer(C_PLAYER_TEMPLATE); |
| 86 | 86 | //AppendPlayer(C_PLAYER_TEMPLATE); |
| 87 | 87 | |
| ... | ... | @@ -95,6 +95,11 @@ begin |
| 95 | 95 | Cycles.Count:=0; |
| 96 | 96 | Cycles.Value:=4; |
| 97 | 97 | Cycles.Generation:=0; |
| 98 | + EndCriterium.AbsoluteCycles := 20; | |
| 99 | + EndCriterium.InterlockingPorcentage := 80; | |
| 100 | + EndCriterium.LastCycles := 10; | |
| 101 | + EndCriterium.Style := gecWhichComeFirst; | |
| 102 | + | |
| 98 | 103 | SetLength(Contingencies, 4); |
| 99 | 104 | LConcequence := TConsequence.Create(AExperiment,1,[gscPoints, gscB, gscMessage,gscBroadcastMessage],['$NICNAME','queijo','queijos']); |
| 100 | 105 | Contingencies[0] := TContingency.Create(AExperiment,LConcequence,LCriteria1,False); | ... | ... |
units/game_resources.pas
units/game_zmq_actors.pas
units/report_reader.pas
| 1 | +{ | |
| 2 | + Stimulus Control | |
| 3 | + Copyright (C) 2014-2016 Carlos Rafael Fernandes Picanço, Universidade Federal do Pará. | |
| 4 | + | |
| 5 | + The present file is distributed under the terms of the GNU General Public License (GPL v3.0). | |
| 6 | + | |
| 7 | + You should have received a copy of the GNU General Public License | |
| 8 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 9 | +} | |
| 1 | 10 | unit report_reader; |
| 2 | 11 | |
| 3 | 12 | {$mode objfpc}{$H+} |
| ... | ... | @@ -26,9 +35,11 @@ type |
| 26 | 35 | function GetColumnOf(AName: string): TStringList; |
| 27 | 36 | procedure RangeAsLastXRows; |
| 28 | 37 | public |
| 38 | + VRow : string; //helper | |
| 29 | 39 | constructor Create; |
| 30 | 40 | destructor Destroy; override; |
| 31 | 41 | procedure Append(ARow : string); |
| 42 | + procedure Extend(ARowExtention : string); | |
| 32 | 43 | procedure Clean; |
| 33 | 44 | procedure SetXLastRows(X:integer); |
| 34 | 45 | property Range : TRowRange read FRowRange; |
| ... | ... | @@ -87,6 +98,11 @@ begin |
| 87 | 98 | end; |
| 88 | 99 | end; |
| 89 | 100 | |
| 101 | +procedure TReportReader.Extend(ARowExtention: string); | |
| 102 | +begin | |
| 103 | + FRows[FRows.Count-1] := FRows[FRows.Count-1] + ARowExtention; | |
| 104 | +end; | |
| 105 | + | |
| 90 | 106 | procedure TReportReader.Clean; |
| 91 | 107 | begin |
| 92 | 108 | FCols.Clear; | ... | ... |
units/string_methods.pas
| ... | ... | @@ -67,9 +67,9 @@ uses strutils; |
| 67 | 67 | function GetEndCriteriaFromString(S:string) : TEndConditionCriterium; |
| 68 | 68 | begin |
| 69 | 69 | case StrToIntDef(ExtractDelimited(1,S,[',']),2) of |
| 70 | - 0: Result.Value := gecAbsoluteCycles; | |
| 71 | - 1: Result.Value := gecInterlockingPorcentage; | |
| 72 | - 2: Result.Value := gecWhichComeFirst; | |
| 70 | + 0: Result.Style := gecAbsoluteCycles; | |
| 71 | + 1: Result.Style := gecInterlockingPorcentage; | |
| 72 | + 2: Result.Style := gecWhichComeFirst; | |
| 73 | 73 | end; |
| 74 | 74 | Result.AbsoluteCycles := StrToIntDef(ExtractDelimited(2,S,[',']), 20); |
| 75 | 75 | Result.InterlockingPorcentage := StrToIntDef(ExtractDelimited(3,S,[',']),10); |
| ... | ... | @@ -367,7 +367,7 @@ function GetEndCriteriaString(AEndCriterium: TEndConditionCriterium |
| 367 | 367 | ): string; |
| 368 | 368 | begin |
| 369 | 369 | // 2,20,10,10, |
| 370 | - case AEndCriterium.Value of | |
| 370 | + case AEndCriterium.Style of | |
| 371 | 371 | gecAbsoluteCycles: Result := '0'; |
| 372 | 372 | gecInterlockingPorcentage: Result := '1'; |
| 373 | 373 | gecWhichComeFirst: Result := '2'; | ... | ... |