Saturday, July 31, 2010

You got 25% chance of success, do you feel lucky?

I remember few years ago playing a game called Silkroad(which stolen 2 years of my life – that's another story), in this game when you do alchemy, in some situations, you have a X percent chance of success, I had a lot of successes but also failures, anyways... I was wondering how do they calculate the success? You can implement an idea in many ways...
This morning I thought of an algorithm that does just that, it returns True or False with a certain percent chance of success.
I've started the theory(in my head...) like so:
- we need a chance resolution(in this case 5%)
- we need to have an array of boolean with the number of elements equal to 100 divided by resolution(5)

Implementation:
- initialize the array of chances to false
- calculate how many 5% chances are there(if you give 20% chance, then we have to set to True 4 elements in ChanceArray
- for each 5% chance set to True a element in ChanceArray that is NOT already set to true, starting at a random index in the array
- pick a random element from the array and return it's state(True or False) as the result of the chance

Here it is, my implementation:
(add "Math" to uses clause)
function CheckSuccess(const PercentChance: Integer): Boolean;
var
  // 5% resolution
  // can give chances like 10%, 50% or 15%, 55%, 35%, etc.
  ChanceArray: array[0..19] of Boolean;
  ChanceCount: Integer;
  ChanceIndex: Integer;
  Index: Integer;

    procedure AddChance;
    begin
      ChanceIndex := RandomRange(Low(ChanceArray), High(ChanceArray));
      while ChanceArray[ChanceIndex] do begin
        Inc(ChanceIndex);
        if ChanceIndex > High(ChanceArray) then
          ChanceIndex := Low(ChanceArray);
      end; // while ChanceArray[ChanceIndex] do begin
      ChanceArray[ChanceIndex] := True;
    end; // procedure AddChance;

begin
  // you should probably call this once per application startup
  Randomize;
  // initialize chance array to false
  for Index := Low(ChanceArray) to High(ChanceArray) do
    ChanceArray[Index] := False;
  // how many 5% chances we got?
  if PercentChance > 100 then
    ChanceCount := 20
  else
    ChanceCount := (PercentChance div 5); // 5% resolution
  for Index := 1 to ChanceCount do
    AddChance;
  ChanceIndex := RandomRange(Low(ChanceArray), High(ChanceArray));
  Result := ChanceArray[ChanceIndex];
end;
Usage:
(we give the player a 25% chance of success – you can increase or decrease chance but replacing 25 with another value)
ShowMessage(BoolToStr(CheckSuccess(25), True));
P.S. Please drop me a comment with how would you implement a similar algorithm.

Friday, July 30, 2010

Delphigeist got a new skin

I've been searching for sometime now for a good blogger template and this is the best I managed to find so far, please let me know if you're happy with the load time of the page and the new layout, thank you.

Wednesday, July 28, 2010

High-Speed Laser Chips Move Data at 50 Gbps

Yes, I know... this is a programming blog, but this is something that you might want to know.
I'm not going to repost the post from wired.com so here's the link High-Speed Laser Chips Move Data at 50 Gbps.

Monday, July 12, 2010

Google App Inventor for Android

Did you know that Google has recently released a beat application called „App Inventor¯?
It allows people with now programming knowledge to develop nice and fast application for the Android platform.
All you need is your mobile phone which runs Android, a PC with Internet connection, a GMail account and some ideas.
Homepage http://appinventor.googlelabs.com

Wednesday, July 7, 2010

How to read/write a string from/to file fast

When I'm debugging large SQL inserts/updates I tend to use the following two functions
const
  szChar = SizeOf(Char);
/// 
///   saves a string to a file
/// 
procedure StringToFile(const s: string; const FileName: string);
var
  FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(FileName, fmCreate);
  try
    FileStream.WriteBuffer(Pointer(s)^, (Length(s) * szChar));
  finally
    FreeAndNil(FileStream);
  end; // try
end;

/// 
///   returns the content of the file as a string
/// 
function StringFromFile(const FileName: string): string;
var
  FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(FileName, fmOpenRead);
  try
    SetLength(Result, (FileStream.Size div szChar));
    FileStream.ReadBuffer(Pointer(Result)^, FileStream.Size);
  finally
    FreeAndNil(FileStream);
  end; // try
end;
this functions are pretty fast and you can easily find other usage for them.

How to capitalize a string

Ever needed to capitalize a string and keep the rest lower case? here's my implementation...
I use this function when the OnExit event is triggered in a edit control – usually in user name/password fields etc.
function CapitalizeString(const s: string; const CapitalizeFirst: Boolean = True): string;
const
  ALLOWEDCHARS = ['a'..'z', '_'];
var
  Index: Integer;
  bCapitalizeNext: Boolean;
begin
  bCapitalizeNext := CapitalizeFirst;
  Result := LowerCase(s);
  if Result <> EmptyStr then
    for Index := 1 to Length(Result) do
      if bCapitalizeNext then begin
        Result[Index] := UpCase(Result[Index]);
        bCapitalizeNext := False;
      end else
      if NOT CharInSet(Result[Index], ALLOWEDCHARS) then
        bCapitalizeNext := True;
end;

Blogroll(General programming and Delphi feeds)