Hi ,

I'm afraid I don't understand this part, to tell you the truth I "feel" like there has to be a way to be able to handle the "random" monster selection from within the class ..but I have no idea how.

For example I create monster... and it somehow check for available monsters to attack, but how would this newly created monster know if there are at all other monsters to attack, or how many monsters
are there (sorry for the confusion, I'm a bit confused myself to)

Right now it's really simple because everyone can attack everyone, but say if there would be groups of friendly units, and group of enemy units...I would have problems.

2. Replace mytargetID varaible with pointer to monster class. This way you allow yourself to easily get certain information from that monster (Position, Health, MosterType, etc.) by simply accesing property of that class (no need to search through a list of all monsters to find which has apropriate ID).


Also I've altered the code, seems I have to use strict private...otherwise private values are visible...and modifiable....outside of the class...from TForm for example....

So , private are all with F ,FArmor, FHealth, from within class on the OnHit procedure for example is it ok to use Health or FHealth ?

Code:
unit Unit1;

interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids, Math,
  Vcl.ExtCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    Memo1: TMemo;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  TMonster = class
    strict private  // othervise private is visible
      FName : string;
      FHealth : smallint;
      FArmor : smallint;
      FAttack : smallint;
      FTargetID : byte;
      FDead : boolean;
    published
      property Name : string
        read FName write FName;
      property Health : smallint
        read FHealth write FHealth;
      property Armor : smallint
        read FArmor write FArmor;
      property Attack : smallint
        read FAttack write FAttack;
      property TargetID : byte
        read FTargetID write FTargetID;
      property Dead : boolean
        read FDead write FDead;
    constructor Create (name : string ; health : byte ; armor : byte ; attack : byte);
    procedure OnHit( attack : byte );

  end;
var
  Form1: TForm1;
  Ogre : array of TMonster;

implementation
{$R *.dfm}
constructor TMonster.Create(name : string ; health: Byte ; armor : byte ; attack : byte);
begin
  FName := name;
  FHealth := health;
  FArmor := armor;
  FAttack :=attack;
  FDead := false; // by default alive
end;

procedure TMonster.OnHit(attack: Byte);
var damage : smallint;
begin
    damage := attack - armor; //Reduce damage by armor
    if damage > 0 then
      begin
        Health := Health - damage; //Reduce health
        if Health <= 0 then
          begin
            Dead := True;
            Health :=0;
          end;
      end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled:=true;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i : integer;
begin
  // we have 10 little ogre's
  SetLength(Ogre,10);
  // each of them has a name , and healtpoints , armor, attack
  Ogre[0] := TMonster.Create('William',100,1,1);
  Ogre[1] := TMonster.Create('William 2nd',120,1,1);
  Ogre[2] := TMonster.Create('Robert the Grumpy',145,2,3);
  Ogre[3] := TMonster.Create('Antal the SpaceOgre',150,4,3);
  Ogre[4] := TMonster.Create('Sebastian the Unstopable',160,1,4);
  Ogre[5] := TMonster.Create('Blorb the Blorb',99,5,6);
  Ogre[6] := TMonster.Create('Shrek',49,2,4);
  Ogre[7] := TMonster.Create('Devid the Serbian Ogre',180,4,6);
  Ogre[8] := TMonster.Create('Keen the Wise Ogre',167,6,9);
  Ogre[9] := TMonster.Create('Ogre the Ogre',98,6,11);
  StringGrid1.RowCount:=11;
  StringGrid1.Cells[0,0]:='Name';
  StringGrid1.Cells[1,0]:='Health';
  StringGrid1.Cells[2,0]:='Armor';
  StringGrid1.Cells[3,0]:='Attack';
  for I := 0 to 9 do
    begin
      StringGrid1.Cells[0,i+1]:=Ogre[i].name;
      StringGrid1.Cells[1,i+1]:=inttostr(Ogre[i].Health);
      StringGrid1.Cells[2,i+1]:=inttostr(Ogre[i].armor);
      StringGrid1.Cells[3,i+1]:=inttostr(Ogre[i].attack);
    end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var i,target: integer;
    AvailableTarget : array of integer;
begin
  randomize();
  Memo1.Lines.Clear;
  // fill array with alive monsters
  SetLength(AvailableTarget,0);
  for i := 0 to 9 do
    begin
      if Ogre[i].Dead = false then
        begin
          SetLength(AvailableTarget, length(AvailableTarget)+1);
          AvailableTarget[High(AvailableTarget)]:=i;
        end;
    end;

  for I := 0 to 9 do
    begin
      if Ogre[i].Dead = false then  // can only attack if alive
        begin
          target := AvailableTarget[random(length(AvailableTarget))]; // target is choosen from array of alive monsters
          if i <> target then  // will not attack self
            begin
              Ogre[i].TargetID:=target;
              Ogre[target].OnHit(Ogre[i].attack);
              Memo1.Lines.Add(Ogre[i].name+' attacks '+inttostr(Ogre[i].TargetID)+' '+Ogre[Ogre[i].TargetID].name);
            end;
        end;
    end;


  // update ogre stats
  for I := 0 to 9 do
    begin
      StringGrid1.Cells[0,i+1]:=Ogre[i].name;
      StringGrid1.Cells[1,i+1]:=inttostr(Ogre[i].Health);
      StringGrid1.Cells[2,i+1]:=inttostr(Ogre[i].armor);
      StringGrid1.Cells[3,i+1]:=inttostr(Ogre[i].attack);
    end;
  // if only one target is available , means we have a winner, everyone else is dead
  if length(AvailableTarget) = 1 then
    begin
      Timer1.Enabled:=false;
      for i := 0 to 9 do
        begin
          if Ogre[i].Dead = false then
            Memo1.Lines.Add('The Winner is : '+ Ogre[i].name);
        end;
    end;
end;
end.