From 653a4067a3a0421ed762562c4aad74e143bfc449 Mon Sep 17 00:00:00 2001 From: cpicanco Date: Wed, 23 Nov 2016 21:57:50 -0300 Subject: [PATCH] choice system is done --- form_matrixgame.lfm | 40 +++++++++++++++++++++++++++++----------- form_matrixgame.pas | 28 +++++++++++++++++++++------- units/game_control.pas | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- units/game_experiment.pas | 52 +++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 183 insertions(+), 54 deletions(-) diff --git a/form_matrixgame.lfm b/form_matrixgame.lfm index 9ad2989..a2b3528 100644 --- a/form_matrixgame.lfm +++ b/form_matrixgame.lfm @@ -1,14 +1,14 @@ object FormMatrixGame: TFormMatrixGame - Left = 0 - Height = 560 - Top = 70 - Width = 1278 - HorzScrollBar.Page = 1278 + Left = -621 + Height = 565 + Top = 124 + Width = 1393 + HorzScrollBar.Page = 1393 VertScrollBar.Page = 542 AutoScroll = True Caption = 'FormMatrixGame' - ClientHeight = 550 - ClientWidth = 1278 + ClientHeight = 555 + ClientWidth = 1393 Font.Name = 'Monospace' OnActivate = FormActivate LCLVersion = '1.6.2.0' @@ -184,7 +184,7 @@ object FormMatrixGame: TFormMatrixGame AnchorSideBottom.Side = asrBottom Left = 0 Height = 17 - Top = 533 + Top = 538 Width = 1632 Anchors = [akLeft, akRight, akBottom] AutoSize = True @@ -275,15 +275,15 @@ object FormMatrixGame: TFormMatrixGame Caption = 'NA' ParentColor = False end - object LabelExpNxtPlayer: TLabel + object LabelExpTurn: TLabel Left = 10 Height = 15 Top = 95 Width = 128 - Caption = 'Prox. Jog.:' + Caption = 'Turno:' ParentColor = False end - object LabelExpCountNxtPlayer: TLabel + object LabelExpCountTurn: TLabel Left = 158 Height = 15 Top = 95 @@ -451,4 +451,22 @@ object FormMatrixGame: TFormMatrixGame left = 24 top = 360 end + object PopupNotifier: TPopupNotifier + Color = clTeal + Icon.Data = { + 07544269746D617000000000 + } + Text = 'Text' + Visible = False + OnClose = PopupNotifierClose + left = 112 + top = 360 + end + object Timer: TTimer + Enabled = False + Interval = 8000 + OnTimer = TimerTimer + left = 200 + top = 360 + end end diff --git a/form_matrixgame.pas b/form_matrixgame.pas index 03daa5d..ebbbf88 100644 --- a/form_matrixgame.pas +++ b/form_matrixgame.pas @@ -15,7 +15,7 @@ interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Grids, - StdCtrls, DBGrids, ExtCtrls + StdCtrls, DBGrids, ExtCtrls, PopupNotifier , game_zmq_actors , game_actors @@ -46,8 +46,8 @@ type LabelExpCountGeneration: TLabel; LabelExpCycle: TLabel; LabelExpCountCycle: TLabel; - LabelExpNxtPlayer: TLabel; - LabelExpCountNxtPlayer: TLabel; + LabelExpTurn: TLabel; + LabelExpCountTurn: TLabel; LabelExpInterlocks: TLabel; LabelExpCountInterlocks: TLabel; LabelIndCount: TLabel; @@ -62,7 +62,9 @@ type ChatPanel: TPanel; ChatSplitter: TSplitter; OpenDialog: TOpenDialog; + PopupNotifier: TPopupNotifier; StringGridMatrix: TStringGrid; + Timer: TTimer; procedure btnConfirmRowClick(Sender: TObject); procedure Button3Click(Sender: TObject); procedure ButtonExpCancelClick(Sender: TObject); @@ -70,9 +72,12 @@ type procedure ButtonExpStartClick(Sender: TObject); procedure ChatMemoSendKeyPress(Sender: TObject; var Key: char); procedure FormActivate(Sender: TObject); + procedure PopupNotifierClose(Sender: TObject; var CloseAction: TCloseAction + ); procedure StringGridMatrixClick(Sender: TObject); procedure StringGridMatrixDrawCell(Sender: TObject; aCol, aRow: integer; aRect: TRect; aState: TGridDrawState); + procedure TimerTimer(Sender: TObject); private FGameControl : TGameControl; FID: string; @@ -212,6 +217,12 @@ begin end; end; +procedure TFormMatrixGame.TimerTimer(Sender: TObject); +begin + PopupNotifier.Visible:=False; + Timer.Enabled := False; +end; + procedure TFormMatrixGame.SetGameActor(AValue: TGameActor); procedure SetZMQAdmin; @@ -223,7 +234,7 @@ procedure TFormMatrixGame.SetGameActor(AValue: TGameActor); procedure SetZMQPlayer; begin FGameControl := TGameControl.Create(TZMQPlayer.Create(Self,FID)); - StringGridMatrix.Enabled := True; + //StringGridMatrix.Enabled := True; end; procedure SetZMQWatcher; @@ -267,6 +278,12 @@ begin end; end; +procedure TFormMatrixGame.PopupNotifierClose(Sender: TObject; + var CloseAction: TCloseAction); +begin + // do nothing for now +end; + procedure TFormMatrixGame.StringGridMatrixClick(Sender: TObject); begin if goRowSelect in StringGridMatrix.Options then Exit; @@ -292,9 +309,6 @@ end; procedure TFormMatrixGame.btnConfirmRowClick(Sender: TObject); begin - StringGridMatrix.Enabled:= False; - btnConfirmRow.Enabled:=False; - btnConfirmRow.Caption:='OK'; FGameControl.SendMessage(K_CHOICE); end; diff --git a/units/game_control.pas b/units/game_control.pas index 82134e3..958dfab 100644 --- a/units/game_control.pas +++ b/units/game_control.pas @@ -43,13 +43,14 @@ type procedure SetMustDrawDotsClear(AValue: Boolean); procedure SetRowBase(AValue: integer); private - function CanStartExperiment : Boolean; + function ShouldStartExperiment : Boolean; procedure KickPlayer(AID:string); procedure NextTurn(Sender: TObject); procedure NextCycle(Sender: TObject); procedure NextLineage(Sender: TObject); procedure NextCondition(Sender: TObject); procedure EndExperiment(Sender: TObject); + procedure StartExperiment; public constructor Create(AOwner : TComponent);override; destructor Destroy; override; @@ -76,6 +77,7 @@ const K_REFUSED = '.Refused'; K_CHAT_M = '.ChatM'; K_CHOICE = '.Choice'; + K_START = '.Start'; K_LEFT = '.Left'; K_RESUME = '.Resume'; K_DATA_A = '.Data'; @@ -115,7 +117,7 @@ end; { TGameControl } -function TGameControl.CanStartExperiment: Boolean; +function TGameControl.ShouldStartExperiment: Boolean; begin Result := FExperiment.PlayersCount = FExperiment.Condition[FExperiment.CurrentCondition].Turn.Value; end; @@ -127,21 +129,29 @@ end; procedure TGameControl.NextTurn(Sender: TObject); begin + // update admin view + FormMatrixGame.LabelExpCountTurn.Caption:=IntToStr(FExperiment.Condition[FExperiment.CurrentCondition].Turn.Count); + // inform players + end; procedure TGameControl.NextCycle(Sender: TObject); begin // prompt question to all players + FormMatrixGame.LabelExpCountCycle.Caption:=IntToStr(FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Count); end; procedure TGameControl.NextLineage(Sender: TObject); begin - + // pause, kick older player, wait for new player, resume + FormMatrixGame.LabelExpCountGeneration.Caption:=IntToStr(FExperiment.Condition[FExperiment.CurrentCondition].Cycles.Generation); end; procedure TGameControl.NextCondition(Sender: TObject); begin + FormMatrixGame.LabelExpCountCondition.Caption:= FExperiment.Condition[FExperiment.CurrentCondition].ConditionName; + // append OnStart data //FExperiment.Condition[FExperiment.CurrentCondition].Points.OnStart.A; //FExperiment.Condition[FExperiment.CurrentCondition].Points.OnStart.B; @@ -155,10 +165,23 @@ begin end; +procedure TGameControl.StartExperiment; +begin + // all players arrived, lets begin + FExperiment.State:=xsRunning; + + // wait some time, we just sent a message earlier + Sleep(5); + + // enable matrix grid for the first player + FZMQActor.SendMessage([K_START]); +end; + procedure TGameControl.Start; begin // basic data/csv setup // wait for players + end; procedure TGameControl.Pause; @@ -303,14 +326,6 @@ begin FRowBase:=AValue; end; -procedure TGameControl.StartTurn; -begin - FormMatrixGame.btnConfirmRow.Enabled:=True; - FormMatrixGame.StringGridMatrix.Options := FormMatrixGame.StringGridMatrix.Options-[goRowSelect]; - FormMatrixGame.btnConfirmRow.Caption:='Confirmar'; - FormMatrixGame.btnConfirmRow.Visible := False; -end; - constructor TGameControl.Create(AOwner: TComponent); begin FZMQActor := TZMQActor(AOwner); @@ -333,12 +348,18 @@ begin MustDrawDotsClear:=False; FExperiment := TExperiment.Create(FZMQActor.Owner); + FExperiment.State:=xsWaiting; FExperiment.OnEndTurn := @NextTurn; FExperiment.OnEndCycle := @NextCycle; FExperiment.OnEndGeneration:=@NextLineage; FExperiment.OnEndCondition:= @NextCondition; FExperiment.OnEndExperiment:= @EndExperiment; + NextTurn(Self); + NextCycle(Self); + NextLineage(Self); + NextCondition(Self); + SendRequest(K_LOGIN); end; @@ -453,10 +474,10 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); gaPlayer: begin P := FExperiment.PlayerFromString[AMessage[1]]; + FExperiment.AppendPlayer(P); if Self.ID = P.ID then begin - FExperiment.AppendPlayer(P); - CreatePlayerBox(P, True); + CreatePlayerBox(P, True) end else CreatePlayerBox(P,False); @@ -465,27 +486,76 @@ procedure TGameControl.ReceiveMessage(AMessage: TStringList); end; + procedure EnableMatrix(ATurn:integer); + begin + if FExperiment.PlayerFromID[Self.ID].Turn = ATurn then + begin + FormMatrixGame.StringGridMatrix.Enabled:=True; + FormMatrixGame.StringGridMatrix.Options := FormMatrixGame.StringGridMatrix.Options-[goRowSelect]; + FormMatrixGame.btnConfirmRow.Enabled:=True; + FormMatrixGame.btnConfirmRow.Caption:='Confirmar'; + FormMatrixGame.btnConfirmRow.Visible := False; + end; + end; + procedure ReceiveChoice; + var P : TPlayer; begin - with GetPlayerBox(AMessage[1]) do + P := FExperiment.PlayerFromID[AMessage[1]]; + + // add last responses to player box + with GetPlayerBox(P.ID) do begin - LabelLastRowCount.Caption := Format('%-*.*d', [1,2,StrToInt(AMessage[2])]); + LabelLastRowCount.Caption := AMessage[2]; PanelLastColor.Color := GetRowColorFromString(AMessage[3]); - FormMatrixGame.Caption:=''; + PanelLastColor.Caption:=''; end; case FActor of gaPlayer:begin - + if Self.ID = P.ID then + begin + FormMatrixGame.StringGridMatrix.Enabled:= False; + FormMatrixGame.btnConfirmRow.Enabled:=False; + FormMatrixGame.btnConfirmRow.Caption:='OK'; + end + else + EnableMatrix(P.Turn+1); end; gaAdmin:begin - // if last choice in cycle then end cycle FExperiment.NextTurn; end; end; end; + procedure NotifyPlayers; + var PopUpPos : TPoint; + begin + case FActor of + gaPlayer: + begin + PopUpPos.X := FormMatrixGame.StringGridMatrix.Left+FormMatrixGame.StringGridMatrix.Width; + PopUpPos.Y := FormMatrixGame.StringGridMatrix.Top; + PopUpPos := FormMatrixGame.StringGridMatrix.ClientToScreen(PopUpPos); + if FExperiment.PlayerFromID[Self.ID].Turn = 0 then + begin + PopUpPos.X := FormMatrixGame.StringGridMatrix.Left+FormMatrixGame.StringGridMatrix.Width; + PopUpPos.Y := FormMatrixGame.StringGridMatrix.Top; + EnableMatrix(0); + FormMatrixGame.PopupNotifier.Text:='É sua vez! Clique sobre uma linha da matrix e confirme sua escolha.'; + FormMatrixGame.PopupNotifier.ShowAtPos(PopUpPos.X,PopUpPos.Y); + end + else + begin + FormMatrixGame.PopupNotifier.Text:='Começou! Aguarde sua vez.'; + FormMatrixGame.PopupNotifier.ShowAtPos(PopUpPos.X,PopUpPos.Y); + end; + FormMatrixGame.Timer.Enabled:=True; + end; + end; + end; + procedure ReceiveChat; begin FormMatrixGame.ChatMemoRecv.Lines.Append(('['+AMessage[1]+']: ')+AMessage[2]); @@ -551,6 +621,7 @@ begin if MHas(K_CHAT_M) then ReceiveChat; if MHas(K_CHOICE) then ReceiveChoice; if MHas(K_KICK) then SayGoodBye; + if MHas(K_START) then NotifyPlayers; end; // Here FActor is garanted to be a TZMQAdmin @@ -585,10 +656,9 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); end else begin - // if not generate and save p data + // if not then generate and save p data i := FExperiment.AppendPlayer; P.Nicname := GenResourceName(i); - P.Turn := FExperiment.NextTurn; P.Points.A:=0; P.Points.B:=0; P.Status:=gpsPlaying; @@ -596,8 +666,8 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); P.Choice.Current.Row:=grNone; P.Choice.Last.Color:=gcNone; P.Choice.Last.Row:=grNone; - // turns by entrance order - P.Turn := FExperiment.PlayersCount; + // turns by entrance order or by random order + P.Turn := FExperiment.NextTurn; FExperiment.Player[i] := P; end; @@ -631,7 +701,7 @@ procedure TGameControl.ReceiveRequest(var ARequest: TStringList); FZMQActor.SendMessage([K_ARRIVED,PS]); // start Experiment if allowed - if CanStartExperiment then + if ShouldStartExperiment then StartExperiment; end @@ -671,6 +741,7 @@ procedure TGameControl.ReceiveReply(AReply: TStringList); for i:= 3 to AReply.Count -2 do begin P := FExperiment.PlayerFromString[AReply[i]]; + FExperiment.AppendPlayer(P); CreatePlayerBox(P, False); end; diff --git a/units/game_experiment.pas b/units/game_experiment.pas index 4ddccda..0826b61 100644 --- a/units/game_experiment.pas +++ b/units/game_experiment.pas @@ -40,6 +40,7 @@ type FSendChatHistoryForNewPlayers: Boolean; FShowChat: Boolean; FState: TExperimentState; + FTurnsRandom : TStringList; function GetCondition(I : Integer): TCondition; function GetConditionsCount: integer; function GetContingency(ACondition, I : integer): TContingency; @@ -146,12 +147,14 @@ end; function TExperiment.GetNextTurn: integer; // used during player arriving begin - Result := FConditions[CurrentCondition].Turn.Count; + if FConditions[CurrentCondition].Turn.Random then + Result := StrToInt(FTurnsRandom.Names[FConditions[CurrentCondition].Turn.Count]) + else + Result := FConditions[CurrentCondition].Turn.Count; + if Assigned(FOnEndTurn) then FOnEndTurn(Self); + if FConditions[CurrentCondition].Turn.Count < FConditions[CurrentCondition].Turn.Value then - begin - Inc(FConditions[CurrentCondition].Turn.Count); - if Assigned(FOnEndTurn) then FOnEndTurn(Self); - end + Inc(FConditions[CurrentCondition].Turn.Count) else begin FConditions[CurrentCondition].Turn.Count := 0; @@ -174,8 +177,11 @@ begin else begin FConditions[CurrentCondition].Cycles.Count := 0; - if Assigned(FOnEndGeneration) then FOnEndGeneration(Self); - NextCondition; + if State = xsRunning then + begin + if Assigned(FOnEndGeneration) then FOnEndGeneration(Self); + NextCondition; + end; end; end; @@ -186,7 +192,7 @@ var procedure EndCondition; begin - Inc(CurrentCondition); + Inc(FCurrentCondition); if Assigned(FOnEndCondition) then FOnEndCondition(Self); end; @@ -197,7 +203,7 @@ begin FConditions[CurrentCondition].Cycles.Generation) + FConditions[CurrentCondition].Cycles.Count; // interlockings in last x cycles - LInterlocks := InterlockingsIn(FConditions[CurrentCondition].EndCriterium.LastCycles); + LInterlocks := InterlockingsIn[FConditions[CurrentCondition].EndCriterium.LastCycles]; case FConditions[CurrentCondition].EndCriterium.Value of gecWhichComeFirst: begin @@ -260,8 +266,8 @@ var begin case AStatus of gpsWaiting: Result := '0'; - gpsPlayed: Result := '1'; - gpsPlaying: Result := '2'; + gpsPlaying: Result := '1'; + gpsPlayed: Result := '2'; end; end; @@ -308,6 +314,7 @@ begin , GetStatusString(P.Status) , GetChoiceString(P.Choice.Current) , GetChoiceString(P.Choice.Last) + , IntToStr(P.Turn) ]); for i := 0 to Length(M)-1 do Result += M[i] + '|'; @@ -360,8 +367,8 @@ function TExperiment.GetPlayerFromString(s: UTF8string): TPlayer; begin case S of '0': Result := gpsWaiting; - '1': Result := gpsPlayed; - '2': Result := gpsPlaying; + '1': Result := gpsPlaying; + '2': Result := gpsPlayed; end; end; begin @@ -379,6 +386,7 @@ begin Result.Status := GetStatusFromString(ExtractDelimited(4,s,['|'])); Result.Choice.Current := GetChoiceFromString(ExtractDelimited(5,s,['|'])); Result.Choice.Last := GetChoiceFromString(ExtractDelimited(6,s,['|'])); + Result.Turn:=StrToInt(ExtractDelimited(7,s,['|'])); end; function TExperiment.GetPlayerIndexFromID(AID: UTF8string): integer; @@ -511,13 +519,31 @@ begin end; constructor TExperiment.Create(AFilename: string;AOwner:TComponent); +var c , + i, + r : integer; begin inherited Create(AOwner); + FTurnsRandom := TStringList.Create; LoadExperimentFromFile(Self,AFilename); + if Condition[CurrentCondition].Turn.Random then + begin + for i:= 0 to Condition[CurrentCondition].Turn.Value-1 do + FTurnsRandom.Add(IntToStr(i)); + + c := FTurnsRandom.Count - 1; + for i := 0 to c do + begin + r := Random(c); + while r = i do r := Random(c); + FTurnsRandom.Exchange(r,i); + end; + end; end; destructor TExperiment.Destroy; begin + FTurnsRandom.Free; inherited Destroy; end; -- libgit2 0.21.2