diff --git a/applications/fpchess/chessmodules.pas b/applications/fpchess/chessmodules.pas new file mode 100644 index 000000000..757b289f3 --- /dev/null +++ b/applications/fpchess/chessmodules.pas @@ -0,0 +1,75 @@ +unit chessmodules; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + Controls; + +type + TChessModuleKind = (cmkSinglePlayer, cmkInternet, cmkAI); + + TChessModule = class + public + Kind: TChessModuleKind; + Description: string; + procedure CreateUserInterface(); virtual; abstract; + procedure ShowUserInterface(AParent: TWinControl); virtual; abstract; + procedure HideUserInterface(); virtual; abstract; + procedure FreeUserInterface(); virtual; abstract; + end; + +var + gSelectedModuleIndex: Integer; + +procedure RegisterChessModule(AModule: TChessModule); +procedure PopulateChessModulesList(AList: TStrings); +function GetChessModule(AIndex: Integer): TChessModule; +function GetChessModuleCount(): Integer; + +implementation + +var + gChessModules: TList; + +procedure RegisterChessModule(AModule: TChessModule); +begin + if AModule = nil then raise Exception.Create('[RegisterChessModule] Attempted to register a nil module'); + gChessModules.Add(AModule); + AModule.CreateUserInterface(); +end; + +procedure PopulateChessModulesList(AList: TStrings); +var + i: Integer; + lModule: TChessModule; +begin + AList.Clear; + for i := 0 to gChessModules.Count - 1 do + begin + lModule := TChessModule(gChessModules.Items[i]); + if lModule <> nil then + AList.Add(lModule.Description); + end; +end; + +function GetChessModule(AIndex: Integer): TChessModule; +begin + if AIndex < 0 then Exit(nil); + Result := TChessModule(gChessModules.Items[AIndex]); +end; + +function GetChessModuleCount: Integer; +begin + Result := gChessModules.Count; +end; + +initialization + gChessModules := TList.Create; + gSelectedModuleIndex := -1; +finalization + gChessModules.Free; +end. + diff --git a/applications/fpchess/fpchess.lpi b/applications/fpchess/fpchess.lpi index 0ab0d752a..1544180cb 100644 --- a/applications/fpchess/fpchess.lpi +++ b/applications/fpchess/fpchess.lpi @@ -60,22 +60,15 @@ - + - - + - - - - - - - + - + @@ -131,6 +124,16 @@ + + + + + + + + + + diff --git a/applications/fpchess/fpchess.lpr b/applications/fpchess/fpchess.lpr index bb6e9c140..00bf5c574 100644 --- a/applications/fpchess/fpchess.lpr +++ b/applications/fpchess/fpchess.lpr @@ -7,8 +7,11 @@ uses cthreads, {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset - Forms, laz_synapse, mainform, chessdrawer, chessgame, chessconfig, - chesstcputils, IDelphiChess_Intf, wst_synapse; + Forms, lnetbase, mainform, chessdrawer, chessgame, chessconfig, + chesstcputils, chessmodules, mod_singleplayer + {$ifdef FPCHESS_WEBSERVICES} + ,IDelphiChess_Intf + {$endif}; //{$R *.res} diff --git a/applications/fpchess/mainform.lfm b/applications/fpchess/mainform.lfm index 420a21f4c..7e6dd4e6c 100644 --- a/applications/fpchess/mainform.lfm +++ b/applications/fpchess/mainform.lfm @@ -1,7 +1,7 @@ object formChess: TformChess - Left = 181 + Left = 216 Height = 433 - Top = 209 + Top = 164 Width = 360 ActiveControl = notebookMain Caption = 'FP Chess 0.1' @@ -14,7 +14,7 @@ object formChess: TformChess Height = 433 Top = 0 Width = 360 - PageIndex = 3 + PageIndex = 0 Align = alClient TabOrder = 0 TabStop = True @@ -35,7 +35,7 @@ object formChess: TformChess end object Label2: TLabel Left = 8 - Height = 30 + Height = 40 Top = 40 Width = 352 AutoSize = False @@ -46,7 +46,7 @@ object formChess: TformChess object Label6: TLabel Left = 28 Height = 17 - Top = 104 + Top = 128 Width = 52 Caption = 'Start as:' ParentColor = False @@ -54,43 +54,23 @@ object formChess: TformChess object Label7: TLabel Left = 80 Height = 17 - Top = 163 + Top = 175 Width = 150 Caption = 'minutes for each player' ParentColor = False end - object btnSinglePlayer: TBitBtn - Left = 24 - Height = 30 - Top = 200 - Width = 304 - Caption = 'Play Against the Computer' - Enabled = False - OnClick = HandleMainScreenButton - TabOrder = 0 - end - object btnDirectComm: TBitBtn - Left = 24 - Height = 30 - Top = 280 - Width = 304 - Caption = 'Play with a friend through a direct connection' - Enabled = False - OnClick = HandleMainScreenButton - TabOrder = 1 - end object BitBtn3: TBitBtn Left = 24 Height = 30 - Top = 360 + Top = 392 Width = 304 Caption = 'Quit' - TabOrder = 2 + TabOrder = 0 end object editPlayerName: TLabeledEdit Left = 88 Height = 22 - Top = 72 + Top = 104 Width = 120 EditLabel.AnchorSideLeft.Control = editPlayerName EditLabel.AnchorSideTop.Control = editPlayerName @@ -99,17 +79,17 @@ object formChess: TformChess EditLabel.AnchorSideBottom.Control = editPlayerName EditLabel.Left = 6 EditLabel.Height = 17 - EditLabel.Top = 75 + EditLabel.Top = 107 EditLabel.Width = 79 EditLabel.Caption = 'Player Name' EditLabel.ParentColor = False LabelPosition = lpLeft - TabOrder = 3 + TabOrder = 1 end object comboStartColor: TComboBox Left = 88 Height = 21 - Top = 104 + Top = 128 Width = 120 ItemHeight = 0 ItemIndex = 0 @@ -117,113 +97,124 @@ object formChess: TformChess 'White' 'Black' ) - TabOrder = 4 + TabOrder = 2 Text = 'White' end object checkTimer: TCheckBox Left = 24 Height = 18 - Top = 136 + Top = 152 Width = 212 Caption = 'Set a time limit for each Player' Checked = True State = cbChecked - TabOrder = 5 + TabOrder = 3 end object spinPlayerTime: TSpinEdit Left = 21 Height = 16 - Top = 160 + Top = 176 Width = 50 - TabOrder = 6 + TabOrder = 4 Value = 30 end - object btnHotSeat: TBitBtn - Left = 24 - Height = 30 - Top = 240 - Width = 304 - Caption = 'Play with a friend in the same Computer' - OnClick = HandleMainScreenButton - TabOrder = 7 - end - object btnAI: TBitBtn - Left = 24 - Height = 30 - Top = 320 - Width = 304 - Caption = 'Play against the Computer' - OnClick = HandleMainScreenButton - TabOrder = 8 - end - end - object pageConfigConnection: TPage - ClientWidth = 1424 - ClientHeight = 1620 - object Label3: TLabel - Left = 0 - Height = 32 - Top = 8 - Width = 240 - Alignment = taCenter - AutoSize = False - Caption = 'Direct Connection' - Font.Height = -19 - ParentColor = False - ParentFont = False - end - object editRemoteID: TLabeledEdit - Left = 112 + object comboGameMode: TComboBox + Left = 8 Height = 21 - Top = 72 - Width = 120 - EditLabel.AnchorSideLeft.Control = editRemoteID - EditLabel.AnchorSideTop.Control = editRemoteID - EditLabel.AnchorSideTop.Side = asrCenter - EditLabel.AnchorSideRight.Control = editRemoteID - EditLabel.AnchorSideBottom.Control = editRemoteID - EditLabel.Left = 31 - EditLabel.Height = 14 - EditLabel.Top = 75 - EditLabel.Width = 78 - EditLabel.Caption = 'Your friend''s IP:' - EditLabel.ParentColor = False - LabelPosition = lpLeft - TabOrder = 0 + Top = 74 + Width = 338 + ItemHeight = 0 + OnSelect = comboGameModeSelect + TabOrder = 5 + Text = 'comboGameMode' + end + object panelModules: TPanel + Left = 8 + Height = 161 + Top = 224 + Width = 344 + BevelOuter = bvNone + TabOrder = 6 end object editLocalIP: TLabeledEdit - Left = 112 - Height = 21 - Top = 104 + Left = 120 + Height = 22 + Top = 200 Width = 120 EditLabel.AnchorSideLeft.Control = editLocalIP EditLabel.AnchorSideTop.Control = editLocalIP EditLabel.AnchorSideTop.Side = asrCenter EditLabel.AnchorSideRight.Control = editLocalIP EditLabel.AnchorSideBottom.Control = editLocalIP - EditLabel.Left = 27 - EditLabel.Height = 14 - EditLabel.Top = 107 - EditLabel.Width = 82 + EditLabel.Left = 12 + EditLabel.Height = 17 + EditLabel.Top = 203 + EditLabel.Width = 105 EditLabel.Caption = 'Your IP Address:' EditLabel.ParentColor = False LabelPosition = lpLeft ReadOnly = True - TabOrder = 1 + TabOrder = 7 + end + end + object pageConfigureGame: TPage + ClientWidth = 1440 + ClientHeight = 1732 + object Label3: TLabel + AnchorSideRight.Control = pageConfigureGame + AnchorSideRight.Side = asrBottom + Left = 0 + Height = 32 + Top = 8 + Width = 360 + Alignment = taCenter + Anchors = [akTop, akLeft, akRight] + AutoSize = False + Caption = 'Configure Game' + Font.Height = -19 + ParentColor = False + ParentFont = False + end + object editRemoteID: TLabeledEdit + Left = 112 + Height = 22 + Top = 104 + Width = 120 + EditLabel.AnchorSideLeft.Control = editRemoteID + EditLabel.AnchorSideTop.Control = editRemoteID + EditLabel.AnchorSideTop.Side = asrCenter + EditLabel.AnchorSideRight.Control = editRemoteID + EditLabel.AnchorSideBottom.Control = editRemoteID + EditLabel.Left = 8 + EditLabel.Height = 17 + EditLabel.Top = 107 + EditLabel.Width = 101 + EditLabel.Caption = 'Your friend''s IP:' + EditLabel.ParentColor = False + LabelPosition = lpLeft + TabOrder = 0 end object btnConnect: TBitBtn - Left = 8 + Left = 49 Height = 30 - Top = 184 + Top = 264 Width = 224 Caption = 'Connect' OnClick = btnConnectClick - TabOrder = 2 + TabOrder = 1 + end + object Label10: TLabel + Left = 8 + Height = 17 + Top = 48 + Width = 170 + Caption = 'Please choose how to play:' + ParentColor = False end end object pageConnecting: TPage - ClientWidth = 1424 - ClientHeight = 1620 + ClientWidth = 11520 + ClientHeight = 13856 object Label4: TLabel Left = 0 Height = 32 @@ -245,8 +236,8 @@ object formChess: TformChess end end object pageGame: TPage - ClientWidth = 360 - ClientHeight = 433 + ClientWidth = 11520 + ClientHeight = 13856 object Label5: TLabel Left = 0 Height = 32 @@ -277,8 +268,8 @@ object formChess: TformChess end end object pageWebservice: TPage - ClientWidth = 1424 - ClientHeight = 1620 + ClientWidth = 11520 + ClientHeight = 13856 object Label8: TLabel Left = 0 Height = 32 @@ -301,10 +292,10 @@ object formChess: TformChess EditLabel.AnchorSideTop.Side = asrCenter EditLabel.AnchorSideRight.Control = editPlayerName EditLabel.AnchorSideBottom.Control = editPlayerName - EditLabel.Left = 6 - EditLabel.Height = 15 + EditLabel.Left = -1062 + EditLabel.Height = 17 EditLabel.Top = 75 - EditLabel.Width = 75 + EditLabel.Width = 79 EditLabel.Caption = 'Player Name' EditLabel.ParentColor = False LabelPosition = lpLeft diff --git a/applications/fpchess/mainform.pas b/applications/fpchess/mainform.pas index 3fc0b01db..4bf60f5f0 100644 --- a/applications/fpchess/mainform.pas +++ b/applications/fpchess/mainform.pas @@ -7,10 +7,9 @@ interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, ComCtrls, StdCtrls, Buttons, Spin, - // - IDelphiChess_Intf, - // - chessdrawer, chessgame, chessconfig, chesstcputils; + // fpchess + chessdrawer, chessgame, chessconfig, chesstcputils, + chessmodules; type @@ -29,16 +28,15 @@ type TformChess = class(TForm) btnConnect: TBitBtn; - btnAI: TBitBtn; - btnSinglePlayer: TBitBtn; - btnDirectComm: TBitBtn; BitBtn3: TBitBtn; - btnHotSeat: TBitBtn; btnPlayAgainstAI: TButton; checkTimer: TCheckBox; + comboGameMode: TComboBox; comboStartColor: TComboBox; + editLocalIP: TLabeledEdit; editWebserviceURL: TLabeledEdit; Label1: TLabel; + Label10: TLabel; labelTime: TLabel; Label2: TLabel; Label3: TLabel; @@ -51,12 +49,12 @@ type editWebServiceAI: TLabeledEdit; labelPos: TLabel; editRemoteID: TLabeledEdit; - editLocalIP: TLabeledEdit; editPlayerName: TLabeledEdit; pageStart: TPage; - pageConfigConnection: TPage; + pageConfigureGame: TPage; notebookMain: TNotebook; pageConnecting: TPage; + panelModules: TPanel; ProgressBar1: TProgressBar; pageGame: TPage; spinPlayerTime: TSpinEdit; @@ -64,13 +62,13 @@ type pageWebservice: TPage; procedure btnConnectClick(Sender: TObject); procedure btnPlayAgainstAIClick(Sender: TObject); + procedure comboGameModeSelect(Sender: TObject); procedure FormCreate(Sender: TObject); - procedure HandleMainScreenButton(Sender: TObject); - procedure pageBeforeShow(Sender: TObject; ANewPage: TPage; ANewIndex: Integer); procedure timerChessTimerTimer(Sender: TObject); private { private declarations } function FormatTime(ATimeInMiliseconds: Integer): string; + procedure UpdateChessModulesUI(ANewIndex: Integer); public { public declarations } procedure UpdateCaptions; @@ -87,37 +85,13 @@ implementation const INT_PAGE_START = 0; - INT_PAGE_CONFIGCONNECTION = 1; + INT_PAGE_CONFIGUREGAME = 1; INT_PAGE_CONNECTING = 2; INT_PAGE_GAME = 3; INT_PAGE_AI = 4; { TformChess } -procedure TformChess.HandleMainScreenButton(Sender: TObject); -begin - if Sender = btnSinglePlayer then - begin - notebookMain.PageIndex := INT_PAGE_GAME; - InitializeGameModel(); - end - else if Sender = btnHotSeat then - begin - notebookMain.PageIndex := INT_PAGE_GAME; - InitializeGameModel(); - end - else if Sender = btnDirectComm then notebookMain.PageIndex := INT_PAGE_CONFIGCONNECTION - else if Sender = btnAI then notebookMain.PageIndex := INT_PAGE_AI; -end; - -procedure TformChess.pageBeforeShow(Sender: TObject; ANewPage: TPage; ANewIndex: Integer); -begin - if ANewIndex = INT_PAGE_CONFIGCONNECTION then - begin - editLocalIP.Text := ChessGetLocalIP(); - end; -end; - procedure TformChess.timerChessTimerTimer(Sender: TObject); begin vChessGame.UpdateTimes(); @@ -149,6 +123,17 @@ begin Result := Result + IntToStr(lTimePart); end; +procedure TformChess.UpdateChessModulesUI(ANewIndex: Integer); +var + lModule: TChessModule; +begin + if ANewIndex = gSelectedModuleIndex then Exit; + + lModule := GetChessModule(gSelectedModuleIndex); + if lModule <> nil then lModule.FreeUserInterface(); + GetChessModule(ANewIndex).ShowUserInterface(panelModules); +end; + procedure TformChess.UpdateCaptions; var lStr: string; @@ -185,6 +170,16 @@ begin // Loading of resources vChessDrawer.LoadImages(); + + // Prepare the modules view + InitializeGameModel(); + editLocalIP.Text := ChessGetLocalIP(); + PopulateChessModulesList(comboGameMode.Items); + if GetChessModuleCount() >= 1 then + begin + comboGameMode.ItemIndex := 0; + UpdateChessModulesUI(0); + end; end; procedure TformChess.btnConnectClick(Sender: TObject); @@ -199,8 +194,14 @@ begin notebookMain.PageIndex := INT_PAGE_GAME; - if comboStartColor.ItemIndex = 0 then - GetNextMoveFromBorlandWS(); +// if comboStartColor.ItemIndex = 0 then +// GetNextMoveFromBorlandWS(); +end; + +procedure TformChess.comboGameModeSelect(Sender: TObject); +begin + UpdateChessModulesUI(comboGameMode.ItemIndex); + gSelectedModuleIndex := comboGameMode.ItemIndex; end; { TFormDrawerDelegate } diff --git a/applications/fpchess/mod_singleplayer.pas b/applications/fpchess/mod_singleplayer.pas new file mode 100644 index 000000000..9cbaa231b --- /dev/null +++ b/applications/fpchess/mod_singleplayer.pas @@ -0,0 +1,73 @@ +unit mod_singleplayer; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + StdCtrls, Forms, Controls, + chessmodules; + +type + + { TSinglePlayerChessModule } + + TSinglePlayerChessModule = class(TChessModule) + private + textSecondPlayerName: TStaticText; + editSecondPlayerName: TEdit; + public + SecondPlayerName: string; + constructor Create(); + procedure CreateUserInterface(); override; + procedure ShowUserInterface(AParent: TWinControl); override; + procedure HideUserInterface(); override; + procedure FreeUserInterface(); override; + end; + +implementation + +{ TSinglePlayerChessModule } + +constructor TSinglePlayerChessModule.Create; +begin + inherited Create; + + Description := 'Play against a friend in the same computer'; + Kind := cmkSinglePlayer; +end; + +procedure TSinglePlayerChessModule.CreateUserInterface; +begin + textSecondPlayerName := TStaticText.Create(nil); + textSecondPlayerName.SetBounds(20, 20, 180, 50); + textSecondPlayerName.Caption := 'Name of the second player'; + + editSecondPlayerName := TEdit.Create(nil); + editSecondPlayerName.SetBounds(200, 20, 150, 50); + editSecondPlayerName.Text := 'Second player'; +end; + +procedure TSinglePlayerChessModule.ShowUserInterface(AParent: TWinControl); +begin + textSecondPlayerName.Parent := AParent; + editSecondPlayerName.Parent := AParent; +end; + +procedure TSinglePlayerChessModule.HideUserInterface(); +begin + textSecondPlayerName.Parent := nil; + editSecondPlayerName.Parent := nil; +end; + +procedure TSinglePlayerChessModule.FreeUserInterface; +begin + textSecondPlayerName.Free; + editSecondPlayerName.Free; +end; + +initialization + RegisterChessModule(TSinglePlayerChessModule.Create); +end. +