Skip to content

PGNDATABASE - An idea at a chess pgn database double-click to load games #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions Sources/Chess256.lpi
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<Version Value="12"/>
<General>
<Flags>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="Chess 256"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
Expand Down Expand Up @@ -53,7 +55,7 @@
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="63">
<Units Count="64">
<Unit0>
<Filename Value="Chess256.lpr"/>
<IsPartOfProject Value="True"/>
Expand Down Expand Up @@ -363,7 +365,7 @@
<IsPartOfProject Value="True"/>
<ComponentName Value="PseudoDockContainer"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<ResourceBaseClass Value="Frame"/>
</Unit58>
<Unit59>
<Filename Value="ImbalanceFrame.pas"/>
Expand All @@ -387,6 +389,14 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit62>
<Unit63>
<Filename Value="unitfrmpgndatabase.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="frmPGNDatabase"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="unitFrmPgnDatabase"/>
</Unit63>
</Units>
</ProjectOptions>
<CompilerOptions>
Expand Down
3 changes: 2 additions & 1 deletion Sources/Chess256.lpr
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
ImbalanceFrame,
ScaleDPI,
PersistentNotation,
LicenseInfo;
LicenseInfo, unitFrmPgnDatabase;

{$R *.res}

Expand All @@ -103,5 +103,6 @@
Application.CreateForm(TNewGameDialog, NewGameDialog);
Application.CreateForm(TTimerConfigureForm, TimerConfigureForm);
Application.CreateForm(TLicenseInfoFrom, LicenseInfoFrom);
Application.CreateForm(TfrmPGNDatabase, frmPGNDatabase);
Application.Run;
end.
61 changes: 38 additions & 23 deletions Sources/MainUnit.lfm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
object MainForm: TMainForm
Left = 402
Left = 3910
Height = 629
Top = 419
Top = -219
Width = 964
Caption = 'Chess 256'
ClientHeight = 629
Expand All @@ -12,8 +12,6 @@ object MainForm: TMainForm
OnResize = FormResize
OnShow = FormShow
Position = poScreenCenter
LCLVersion = '1.8.0.6'
Visible = False
object ToolBar: TToolBar
Left = 0
Height = 34
Expand Down Expand Up @@ -199,24 +197,24 @@ object MainForm: TMainForm
end
object GlobalPanel: TPanel
Left = 0
Height = 567
Height = 595
Top = 34
Width = 964
Align = alClient
BevelOuter = bvNone
ClientHeight = 567
ClientHeight = 595
ClientWidth = 964
Color = clWindow
ParentColor = False
TabOrder = 1
object Panel1: TPanel
Left = 565
Height = 567
Height = 595
Top = 0
Width = 399
Align = alRight
BevelOuter = bvNone
ClientHeight = 567
ClientHeight = 595
ClientWidth = 399
Color = clRed
ParentColor = False
Expand Down Expand Up @@ -246,7 +244,7 @@ object MainForm: TMainForm
end
object Panel2: TPanel
Left = 0
Height = 567
Height = 595
Top = 0
Width = 152
Align = alLeft
Expand All @@ -257,12 +255,12 @@ object MainForm: TMainForm
end
object Panel3: TPanel
Left = 157
Height = 567
Height = 595
Top = 0
Width = 403
Align = alClient
BevelOuter = bvNone
ClientHeight = 567
ClientHeight = 595
ClientWidth = 403
Color = clBlue
ParentColor = False
Expand All @@ -271,7 +269,7 @@ object MainForm: TMainForm
Cursor = crVSplit
Left = 0
Height = 5
Top = 460
Top = 488
Width = 403
Align = alBottom
MinSize = 1
Expand All @@ -281,7 +279,7 @@ object MainForm: TMainForm
object Panel4: TPanel
Left = 0
Height = 102
Top = 465
Top = 493
Width = 403
Align = alBottom
BevelOuter = bvNone
Expand All @@ -292,15 +290,15 @@ object MainForm: TMainForm
end
object Splitter2: TSplitter
Left = 152
Height = 567
Height = 595
Top = 0
Width = 5
MinSize = 1
ResizeStyle = rsPattern
end
object Splitter1: TSplitter
Left = 560
Height = 567
Height = 595
Top = 0
Width = 5
Align = alRight
Expand All @@ -313,21 +311,21 @@ object MainForm: TMainForm
object EngineHandleTimer: TTimer
Interval = 25
OnTimer = EngineHandleTimerTimer
left = 128
top = 64
Left = 128
Top = 64
end
object FontDialog: TFontDialog
Title = 'Select font...'
MinFontSize = 0
MaxFontSize = 0
PreviewText = '♙♘♗♖♕♔♟♞♝♜♛♚ABCDEFGH12345678'
left = 32
top = 64
Left = 32
Top = 64
end
object ActionList: TActionList
Images = GlyphKeeper.ImageList
left = 216
top = 64
Left = 216
Top = 64
object AboutAction: TAction
Caption = 'About'
ImageIndex = 20
Expand Down Expand Up @@ -372,10 +370,14 @@ object MainForm: TMainForm
OnExecute = ExitActionExecute
ShortCut = 32883
end
object actLoadPGNFile: TAction
Caption = 'Open PGN...'
OnExecute = actLoadPGNFileExecute
end
end
object MainMenu: TMainMenu
left = 288
top = 64
Left = 288
Top = 64
object MenuItem1: TMenuItem
Caption = 'Game'
object MenuItem6: TMenuItem
Expand All @@ -397,6 +399,12 @@ object MainForm: TMainForm
Action = ExitAction
end
end
object mniFile: TMenuItem
Caption = 'File'
object mniLoadPGN: TMenuItem
Action = actLoadPGNFile
end
end
object MenuItem3: TMenuItem
Caption = 'Edit'
object MenuItem46: TMenuItem
Expand Down Expand Up @@ -524,4 +532,11 @@ object MainForm: TMainForm
end
end
end
object dlgOpenPGN: TOpenDialog
Title = 'Open existing PGN file'
Filter = 'PGN (Portable Game Notation)|*.pgn'
Options = [ofFileMustExist, ofEnableSizing, ofViewDetail]
Left = 206
Top = 150
end
end
80 changes: 78 additions & 2 deletions Sources/MainUnit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface
ApplicationForms, Dialogs, SysUtils, NotationForms, ClockForms,
ChessRules, AnalysisForms, TextureContainers, ChessGame, GameStartDialogs,
ChessStrings, ActnList, Menus, ComCtrls, BoardForms, MoveVariantForms,
PseudoDockedForms, Classes;
PseudoDockedForms, Classes, RegExpr, unitFrmPgnDatabase;

resourcestring
SResignConfirmation = 'Do you really want to resign?';
Expand All @@ -42,6 +42,7 @@ interface

TMainForm = class(TApplicationForm)
AboutAction: TAction;
actLoadPGNFile: TAction;
ExitAction: TAction;
MainMenu: TMainMenu;
MenuItem1: TMenuItem;
Expand Down Expand Up @@ -87,6 +88,9 @@ TMainForm = class(TApplicationForm)
MenuItem46: TMenuItem;
MenuItem47: TMenuItem;
MenuItem48: TMenuItem;
mniLoadPGN: TMenuItem;
mniFile: TMenuItem;
dlgOpenPGN: TOpenDialog;
Panel4: TPanel;
Splitter3: TSplitter;
ToolButton28: TToolButton;
Expand Down Expand Up @@ -143,6 +147,7 @@ TMainForm = class(TApplicationForm)
ToolButton8: TToolButton;
ToolButton9: TToolButton;
procedure AboutActionExecute(Sender: TObject);
procedure actLoadPGNFileExecute(Sender: TObject);
procedure ChangeLookActionExecute(Sender: TObject);
procedure ExitActionExecute(Sender: TObject);
procedure FontSelectActionExecute(Sender: TObject);
Expand All @@ -163,11 +168,11 @@ TMainForm = class(TApplicationForm)
procedure ChildFormHide(Sender: TObject);
private
Texture: TTextureContainer;
FGame: TChessGame;
protected
procedure AddWindow(AForm: TApplicationForm; APanel: TCustomPanel;
ASplitter: TSplitter; CanHide: boolean);
public
FGame: TChessGame;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a good idea to promote the field from private to public. Passing either a callback to change the current game or a reference to TChessGame into the new form is acceptable, though.

procedure CreateNewGame;
end;

Expand Down Expand Up @@ -203,6 +208,77 @@ procedure TMainForm.AboutActionExecute(Sender: TObject);
AboutBox.ShowModal;
end;

procedure TMainForm.actLoadPGNFileExecute(Sender: TObject);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. It is not a good idea to mix GUI creation and parsing in one function. Parsing should go to some other unit (like NotationLists.pas, ChessNotation.pas and the related things are done). GUI creation should go to the new form unit itself instead of creating everything in the main form.
  2. I don't think that splitting PGNs with regular expressions is reliable. While Chess256 parser currently assumes that there is only one PGN in the file, the splitter ideally should use this parser, without relying on regular expressions.

var
SList : TStringList;
i, R, j, row : Integer;
s, s2, pgntags, white, black : AnsiString;
RegexObj: TRegExpr;
begin
//load pgn file
RegexObj := TRegExpr.Create();
RegexObj.Expression := '((((\[.*?\])\s*)+)(1\..+?(0-1|1-0|1/2-1/2)))';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The game can be also unfinished and end with *. Also, it could be a good idea to handle some non-standard options for game ending. See https://github.com/alex65536/Chess256/blob/master/Sources/PGNParser.inc#L170-L183.

if dlgOpenPGN.Execute() then
begin
frmPGNDatabase.Show();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using () after function names is not required in Pascal, and is never used in Chess256.

frmPGNDatabase.gridPGNDatabase.Clear();
frmPGNDatabase.gridPGNDatabase.RowCount := 1 + frmPGNDatabase.gridPGNDatabase.FixedRows;
s := '';
s2 := '';
R := 1;
row := frmPGNDatabase.gridPGNDatabase.FixedRows;
SList := TStringList.Create();
SList.LoadFromFile(dlgOpenPGN.FileName);
for i := 0 to SList.Count-1 do
begin
s2 := SList[i];
s += s2 + #13#10;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never use #13#10. There is a LineEnding constant AFAIR.

if (s2.Contains(' 1-0') or s2.Contains(' 1/2-1/2') or s2.Contains(' 0-1')) and RegexObj.Exec(s) then
begin
pgntags := RegexObj.Match[2];
j := pgntags.IndexOf('[White "');
white := '';
if (j > 0) then
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if j > 0 then

Braces here are not required.

begin
white := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
end;
j := pgntags.IndexOf('[Black "');
black := '';
if (j > 0) then
begin
black := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
end;

frmPGNDatabase.gridPGNDatabase.RowCount := frmPGNDatabase.gridPGNDatabase.RowCount + 1;

frmPGNDatabase.gridPGNDatabase.Cells[0, row] := RegexObj.Match[2];
frmPGNDatabase.gridPGNDatabase.Cells[1, row] := white;
frmPGNDatabase.gridPGNDatabase.Cells[2, row] := black;
frmPGNDatabase.gridPGNDatabase.Cells[3, row] := RegexObj.Match[5];
Inc(row);
s := '';
R := R + 1;
end
end;
if (R-1 = 1) then
begin
frmPGNDatabase.Caption := FormatFloat('#,',R-1) + ' PGN Game';
end else
begin
frmPGNDatabase.Caption := FormatFloat('#,',R-1) + ' PGN Games';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For various UI messages, we use resourcestring and dedicated constants.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it could be a better idea to place the number of game on the status bar, not into the window title

end;

try
CreateNewGame();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR CreateNewGame will just create the new game with the current new game dialog settings. So, if you are not in the analysis mode now, then the following will happen:

  • the current game will be restarted (not in analysis mode)
  • in the game mode, all the attempts to replace the current notation will be disallowed

So, it's necessary to disallow using this in the analysis mode.

except
on E: Exception do
MessageDlg(E.Message, mtError, [mbOK], 0);
end;
SList.Free();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// create SList
try
  // do something
finally
  FreeAndNil(SList);
end;

end;
RegexObj.Free();
end;

procedure TMainForm.ChangeLookActionExecute(Sender: TObject);
var
WasTexture: TTextureContainer;
Expand Down
7 changes: 3 additions & 4 deletions Sources/PseudoDockedForms.lfm
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
object PseudoDockContainer: TPseudoDockContainer
Left = 284
Left = 0
Height = 200
Top = 84
Top = 0
Width = 218
ClientHeight = 200
ClientWidth = 218
LCLVersion = '1.8.0.6'
Visible = True
TabOrder = 0
object CaptionPanel: TPanel
Left = 0
Height = 14
Expand Down
Loading