小编Sve*_*sli的帖子

DelCon中是否有一个事件在ActiveControl发生变化时触发?

每当ActiveControl变化时我都想运行一个小程序.我怎样才能做到这一点?我想过有一个计时器可以在一定的时间间隔内检查主动控制,并在它发生变化时触发我的程序,但是有更优雅的解决方案吗?

delphi controls

11
推荐指数
1
解决办法
1367
查看次数

排序7个整数数组的最快方法是什么?

这是分析扑克几率的程序的一部分,特别是德州扑克.我有一个我很满意的程序,但它需要一些小的优化才能完美.

我使用这种类型(当然还有其他类型):

  type
    T7Cards = array[0..6] of integer;
Run Code Online (Sandbox Code Playgroud)

在决定如何对其进行排序时,此数组有两件事可能很重要:

  1. 每个项目都是0到51之间的值.没有其他值可以.
  2. 没有重复.决不.

有了这些信息,对这个数组进行排序的绝对最快的方法是什么?我使用Delphi,所以pascal代码将是最好的,但我可以读取C和伪,虽然有点慢:-)

目前我使用quicksort,但有趣的是,这几乎不比bubblesort快!可能因为项目数量很少.排序几乎占该方法总运行时间的50%.

编辑:

Mason Wheeler问为什么有必要进行优化.一个原因是该方法将被称为2118760次.

基本的扑克信息:所有玩家都获得两张牌(口袋),然后五张牌被发给牌桌(第一张牌被称为翻牌圈,第三张被称为翻牌圈,第二张牌是转牌圈,最后一张牌是河牌圈.每位玩家选择五张牌卡来弥补他们的手)

如果口袋里有两张牌,P1和P2,我将使用以下循环来生成所有可能的组合:

for C1 := 0 to 51-4 do
  if (C1<>P1) and (C1<>P2) then
     for C2 := C1+1 to 51-3 do
       if (C2<>P1) and (C2<>P2) then
         for C3 := C2+1 to 51-2 do
           if (C3<>P1) and (C3<>P2) then
             for C4 := C3+1 to 51-1 do
               if (C4<>P1) and (C4<>P2) then
                 for C5 := C4+1 to 51 do
                   if (C5<>P1) and (C5<>P2) then …
Run Code Online (Sandbox Code Playgroud)

delphi sorting algorithm pascal

10
推荐指数
3
解决办法
3090
查看次数

打开后如何关闭模态表格?

从我的应用程序中我想打开一个对话框,在某些情况下应该立即关闭(在短消息之后).

我试过这个:

procedure TForm2.FormActivate(Sender: TObject);
begin
  if SomeCondition then
  begin
    ShowMessage('You can''t use this dialog right now.');
    close;
    modalresult := mrCancel;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

但对话框保持打开状态.我也尝试将代码放在OnShow事件中,但结果是一样的.

为什么这不起作用?

delphi dialog

10
推荐指数
3
解决办法
2万
查看次数

为TList和TStringList添加稳定排序的简便方法

我使用TList/TObjectList和TStringList(带有关联对象)来执行大量任务,既可以是原样,也可以作为更复杂结构的基础.虽然排序功能通常足够好,但我有时需要进行稳定排序,两个列表都使用快速排序.

为TList和/或TStringList实现稳定排序的最简单方法是什么?我是否必须编写自己的排序例程,还是可以通过TStringListSortCompare/TListSortCompare使用一些聪明的技巧来完成?

delphi sorting list stable-sort

10
推荐指数
1
解决办法
1513
查看次数

如何在TMetaFileCanvas上透明地绘制PNG

我需要在MetaFileCanvas上透明地绘制PNG.当我绘制到位图(我在屏幕上显示时使用)时这很好用,但是对于打印我需要一个MetaFile.我怎样才能做到这一点?

这是一些演示此问题的代码.将附加的PNG放在某处并更新代码中的路径.

procedure TForm1.Test;
var
  vPNG : TPNGImage;

  vBMP : TBitmap;
  vMeta : TMetafile;
  vMetaCanvas : TMetafileCanvas;
  LDC : HDC;
begin
  vPNG := TPNGImage.Create;
  try
    vPNG.LoadFromFile('c:\temp\pic\pic.png'); 

    //1. Draw to bitmap. Draw stuff behind PNG to demonstrate transparency
    vBMP := TBitmap.Create;
    try
      vBMP.SetSize(vPNG.Width + 20,vPNG.Height + 20);
      vBMP.Canvas.Pen.Color := clLime;
      vBMP.Canvas.Pen.Width := 5;
      vBMP.Canvas.MoveTo(0,0);
      vBMP.Canvas.LineTo(vBMP.Width,vBMP.Height);
      vBMP.Canvas.MoveTo(vBMP.Width,0);
      vBMP.Canvas.LineTo(0,vBMP.Height);
      vBMP.Canvas.Draw(10,10,vPNG);  //This is drawn correctly and transparently

      Canvas.Draw(10,10,vBMP); //Draw to demo form
    finally
      vBMP.Free;
    end;

    //2. Draw to metafile
    vMeta := TMetaFile.Create;
    try
      LDC …
Run Code Online (Sandbox Code Playgroud)

delphi png metafile

8
推荐指数
1
解决办法
2353
查看次数

我应该使用什么算法进行"遗传AI改善"

首先:这不是关于如何让节目连续播放的问题.去过也做过.

介绍性解释

我做了一个五行的游戏作为一个框架,试验基因改进AI(哎呀,这听起来非常自命不凡).与大多数回合制游戏一样,最佳动作是通过为每个可能的动作分配分数,然后以最高分数进行动作来决定.将分数分配给移动(正方形)的功能如下:

  1. 如果正方形已有令牌,则得分为0,因为在正方形中放置新令牌是非法的.

  2. 每个方格可以是多达20个不同获胜行的一部分(5个水平,5个垂直,10个对角线).平方的得分是这些行中每一行的得分之和.

  3. 连续得分取决于行中已有的友方和敌方令牌的数量.例子:

    • 有四个友方令牌的行应该有无限分数,因为如果你在那里放置一个令牌,你就赢了游戏.
    • 具有四个敌人令牌的行的得分应该非常高,因为如果你没有在那里放置一个令牌,则对手将在下一回合获胜.
    • 具有友方和敌方令牌的行将得0,因为此行永远不会成为获胜行的一部分.

鉴于此算法,我已经声明了一个名为TBrain的类型:

type
  TBrain = array[cFriendly..cEnemy , 0..4] of integer; 
Run Code Online (Sandbox Code Playgroud)

数组中的值表示具有N个友好令牌和0个敌人令牌的行的分数,或0个友好令牌和N个敌人令牌.如果连续有5个令牌,那么因为该行已满,所以没有得分.

实际上很容易确定数组中应该包含哪些值.Brain [0,4](四个友方代币)应该是"无限",让我们称之为1.000.000.vBrain [1,4]应该非常高,但不要太高,以至于大脑更愿意阻止几个敌人胜利而不是自我胜利

以下(不可能的)董事会:

  0123456789
 +----------
0|1...1...12
1|.1..1..1.2
2|..1.1.1..2
3|...111...2
4|1111.1111.
5|...111....
6|..1.1.1...
7|.1..1..1..
8|1...1...1.
Run Code Online (Sandbox Code Playgroud)

玩家2应该将他的令牌放入(9,4),赢得游戏,而不是(4,4),即使他会阻止玩家1的8个潜在获胜行.Ergo,vBrain [1,4]应该是(vBrain) [0,4]/8)-1.像这样工作,我们可以找到"大脑"的最佳值,但同样,这不是我感兴趣的.我想要一个算法来找到最佳值.

我已经实现了这个框架,因此它完全是确定性的.分数中没有添加随机值,如果几个方格具有相同的分数,则会选择左上角.

实际问题

这是介绍,现在到有趣的部分(对我来说,至少)

我有两个"大脑",vBrain1和vBrain2.我应该如何迭代地使这些变得更好?我想象这样的事情:

  1. 使用随机值初始化vBrain1和vBrain2.
  2. 模拟他们之间的游戏.
  3. 将赢家的值分配给输家,然后稍微改变其中一个.

这似乎不起作用.大脑并没有变得更聪明.为什么?

分数方法是否应该为结果添加一些小的随机值,以便同一个两个大脑之间的两场比赛会有所不同?每次迭代的值应该改变多少?应该如何初始化"大脑"?有恒定的价值?随机值?

此外,这与AI或遗传算法有什么关系吗?

PS:这个问题与五连胜无关.这只是我选择的东西,因为我可以宣布一个非常简单的"大脑"进行实验.

algorithm artificial-intelligence genetic-algorithm

7
推荐指数
2
解决办法
1238
查看次数

组件(类似于轨迹栏)输入一系列值

我需要一个组件来输入范围.我正在考虑一个带有两个标记的轨道栏.是否存在用于此目的的"原生Delphi"组件或可以轻松模拟它的组件?

delphi components trackbar

7
推荐指数
2
解决办法
8810
查看次数

如何确定方法所需的最低可见性?

作为大型重构项目的一部分,我需要确定不再使用的方法,或者可以降低可见性的方法.

请考虑以下代码:

program Project1;

type
  TMyClass = class(TObject)
  private
    function Method1 : integer;
  public
    function Method2 : integer;
    function Method3 : integer;
    function Method4 : integer;
  end;

var
  vMyObject : TMyClass;

function TMyClass.Method1: integer;
begin
  Result := Method2;
end;

function TMyClass.Method2: integer;
begin
  Result := 2;
end;

function TMyClass.Method3: integer;
begin
  Result := 3;
end;

function TMyClass.Method4: integer;
begin
  Result := 4;
end;

begin
  vMyObject := TMyClass.Create;
  try
    writeln(vMyObject.Method3);
  finally
    vMyObject.Free;
  end;
end.
Run Code Online (Sandbox Code Playgroud)

Delphi编译器发出警告"[DCC Hint] Project1.dpr(6):H2219私有符号'Method1'声明但从未使用过",这非常有用.但是我希望警告此代码还有其他问题:

  1. 方法4从未使用过,但我没有得到警告,因为它是公开的.
  2. Method2声明为public,但仅用于私有.

我可以使用任何工具来识别这些问题吗?

delphi refactoring

7
推荐指数
1
解决办法
246
查看次数

如何在Delphi的OLE自动化过程中使Word不可见

从我们的应用程序,我们使用OLE自动化来构建一个相当复杂的Word文档.我希望在制作文档时使Word不可见,因为有很多粘贴和插入需要相当长的时间.

我使用以下代码建立Word连接:

function ConnectToWord : TWordAutomationResult;
begin
  WordApp := TWordApplication.Create(nil);

  try
    WordApp.Connect;
    WordApp.Visible := false; 
  except on E: Exception do
    begin
      Result := waeErrorConnectingToWord;
      exit;
    end;
  end;
end;      
Run Code Online (Sandbox Code Playgroud)

我使用以下代码打开现有文档,然后由我的应用程序编辑.

function TWordAUtomation.OpenDocument(aFileName: string) : WordDocument;
var vFileName,
    vConfirmConversions,
    vReadOnly,
    vAddToRecentFiles,
    vPasswordDocument,
    vPasswordTemplate,
    vRevert,
    vWritePasswordDocument,
    vWritePasswordTemplate,
    vFormat,
    vEncoding,
    vVisible,
    vOpenConflictDocument,
    vOpenAndRepair,
    vWdDocumentDirection,
    vNoEncodingDialog  : OleVariant;
begin
  Result := nil;
  if not FileExists(aFileName) then exit;

  vFileName                := aFileName;
  vConfirmConversions      := True;
  vReadOnly                := False;
  vAddToRecentFiles        := False;
  vPasswordDocument        := EmptyParam;
  vPasswordTemplate        := EmptyParam; …
Run Code Online (Sandbox Code Playgroud)

delphi ole ms-word

6
推荐指数
1
解决办法
2794
查看次数

我可以在Delphi XE2中更改手表的顺序吗?

通常当我使用复杂的方法时,我会同时激活许多手表.如果我添加一个新手表,它将被放置在列表的底部.但有时候,我希望新手表旁边的其他手表,因为这两个变量有一些联系.我没有找到办法做到这一点,除了必须删除和重新插入手表.有没有更好的方法呢?

考虑到Delphi IDE历史悠久且令人印象深刻的历史,我觉得手表窗口一直被忽视.据我所知,它在Turbo Pascal中表现相同: - /

delphi debugging

6
推荐指数
1
解决办法
138
查看次数