mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Oct 2008
Posts: 16
K
Kisuke Offline OP
Pikka bird
OP Offline
Pikka bird
K
Joined: Oct 2008
Posts: 16
It's been a bit of time since I last did any major mIRC scripting so please forgive me if this is an obvious question. But please indulge me to help me figure out the best method of doing this.

I have a bunch of individual files named after users (it's for a game, but that doesn't really matter). Inside each file is a whole bunch of ini sections (one for stats, one for location, one for this, one for that, etc etc etc, it's pretty massive already).

Now what I want to do is look at certain files (determined when something is started and active users use a certain command), take a certain value from each file, and then sort them from highest to lowest and make a single-lined list from it.

For example:

Steve 100
Bob 5
Tim 800
Cheeto 99


Then turn that into:

[InOrder]
List=Tim, Steve, Cheeto, Bob



I honestly can't think of a good way to do this in mIRC. In another programming language I would probably load them all into arrays (have the name and number in two columns) and then sort the number column. But in mIRC.. uhh what do I do? Every option I could think of might work if there's only one or two active users, but sometimes there's 10+.

Anyone have any solutions?

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
After you put the unsorted data into either a text file, a dialog control, or a custom window, you could use the /filter command.

Example with two text files:
Code:
alias filterexample {
  filter -ffcteu 2 32 infile.txt outfile.txt

  var %n = 1, %string
  while ($read(outfile.txt,n,%n) != $null) {
    %string = %string $gettok($v1,1,32)
    inc %n
  }
  ECHO -ag sorted string: %string
  ECHO -ag with commas: $replace(%string,$chr(32),$+($chr(44),$chr(32)))
}

Joined: Jul 2008
Posts: 236
S
Fjord artisan
Offline
Fjord artisan
S
Joined: Jul 2008
Posts: 236
Why are you using ini files if they get "massive"? Didn't you know they are limited to something like 65535 lines (or KB, I forget which)? Variables are also extremely limited in length, so you might want to think of what happens after your "list" of comma-separated values reaches ~4096 bytes in length... Why not use hashtables? If you use hashtables for this, you could indeed see them in a similar way to an array, or even if you're clever, a linked list. Sort just like you would in any other language... Here's a common algorithm:
1. look for the lowest item within table x
2. add this item to the end of table y
3. remove this item from table x
4. jump back to 1 if there are any items left within table x

Here's an example... but before you copy and paste, keep in mind my reaction isn't going to be good if I find you've not learnt anything from this. It might give you an idea that stops you from relying on old, extremely limited implementations such as .ini files. I want you to read it, study it and learn it. That way I get the satisfaction of realising that I've helped someone to better themselves. If there is anything you don't understand, consult the /help file or feel free to ask here.

Code:
alias test_scores {
  ; make the Scores table
  hmake Scores

  ; add values to the Scores hashtable
  hadd Scores Steve 100
  hadd Scores Bob 5
  hadd Scores Tim 800
  hadd Scores Cheeto 99

  ; save the Scores hashtable to a file
  hsave Scores Scores.file

  ; load the Scores hashtable (as a temporary table)
  hmake Scores_Temp
  hload Scores_Temp Scores.file

  ; sort the Scores hashtable
  hmake Scores_Sorted
  var %item, %data, %index, %count = $hget(Scores_Temp,0).item
  while (%count > 0) {
    ; step 1: get the lowest item
    %item = $hget(Scores_Temp,%count).item
    %data = $hget(Scores_Temp,%count).data
    %index = 1
    while (%index < %count) {
      if ($hget(Scores_Temp,%index).data < %data) {
        %item = $hget(Scores_Temp,%index).item
        %data = $hget(Scores_Temp,%index).data
      }
      inc %index
    }

    ; step 2: remove the item from the temp list
    hdel Scores_Temp %item

    ; step 3: add the item to the sorted list
    %index = sorted_ $+ $hget(Scores_Sorted,0).item
    hadd Scores_Sorted %index %item

    ; step 4: back to the beginning
    dec %count
  }
  
  ; get rid of the temp table
  hfree Scores_Temp

  echo -a - printing the items out, in their sorted order:
  %index = 0
  %count = $hget(Scores_Sorted,0).item
  while (%index < %count) {
    var %tmp = $hget(Scores_Sorted,sorted_ $+ %index)
    echo -a - %tmp has a score of $hget(Scores,%tmp)
    inc %index
  }

  echo -a - printing the items out, in their reverse sorted order:
  %index = $hget(Scores_Sorted,0).item
  while (%index > 0) {
    dec %index
    var %tmp = $hget(Scores_Sorted,sorted_ $+ %index)
    echo -a - %tmp has a score of $hget(Scores,%tmp)
  }
  
  ; get rid of the sorted table
  hfree Scores_Sorted
  
  ; get rid of the scores table
  hfree Scores
}


edit: or use Horstl's suggestion, which is likely faster in this case but more specific to mIRC, so won't really benefit you for other programming languages.

Last edited by s00p; 09/01/10 05:02 AM.
Joined: Oct 2008
Posts: 16
K
Kisuke Offline OP
Pikka bird
OP Offline
Pikka bird
K
Joined: Oct 2008
Posts: 16
Admittedly, I should probably rewrite this whole thing from scratch and upgrade it to more modern practices (such as hashtables). But this thing is old and I really don't have that kind of time any more. I just want to make a quick upgrade and change the way battle turns are calculated.

I should have been more specific in the op with what I'm wanting to do. I suppose the two options will probably work for me with adjustments, but here's exactly what I want to do.

Currently the RPG bot will start a battle. A player will !enter and it'll add his/her name to a list. When the battle starts, it'll go in the exact order that the people joined. I want to change that to be more based on the character's speeds and reorganize the list every round, adjusting for speed increases/decreases (using items or whatever to increase speed).

Player.pfile

[Battle]
HP=#
MP=#
.
.
.
speed=#


So when a player uses !enter I want it to add it to a list, as before, but then before the thing actually starts it will go through each name on the list, look at each person's speed stat, sort it by fastest to slowest, and generate who goes on which turn based on that.



The hashtable idea will probably work with some adjustments.. I'll try it out and see if I can't learn something new. As I said, it's been a very long time since I messed with mIRC scripting (2006 I think was the last time I touched it and I did even less than what I'm attempting now).

Thanks for the suggestions.

Last edited by Kisuke; 09/01/10 05:18 AM.
Joined: Jul 2008
Posts: 236
S
Fjord artisan
Offline
Fjord artisan
S
Joined: Jul 2008
Posts: 236
Again, if you're just looking for a quick fix rather than some enlightenment regarding sorting algorithms, use Horstl's suggestion.


Link Copied to Clipboard