perl arrays

Reply

Join Date: Jan 2009
Posts: 35
Reputation: headedtomexico is an unknown quantity at this point 
Solved Threads: 0
headedtomexico headedtomexico is offline Offline
Light Poster

perl arrays

 
0
  #1
Feb 1st, 2009
im working with some perl code, and im really unfamiliar with the language, and I have a situation. I'm working with a package of perl scripts for a game, there are about 4000 of them and counting. They are release constantly, and altering their contents isnt really an option, it would just be too time consuming. That being said, here is an example of one that fits the situation i'm having.

  1. sub EVENT_ITEM {
  2. if($item1=="7880" && $item2=="7879" && $item3=="5192"){
  3. quest::summonitem(4199);
  4. quest::exp(85); }
  5. }

This would normally be executed by the video game that would supply the EVENT_ITEM call, ass well as the summonitem, and exp functions.

I'm simmulating this invlovement on my site. There is a perl script that executes the EVENT_ITEM sub, and there are provodided summonitem and exp functions that instead spit out HTML that is returned to my php for display.

In essence they are able to simmulate game activities on the webpage before they try for real in the game.

The situation im having is with the $item1-$item4. They are hardcoded in the scripts(the ones i can't change). On the site, I will have 4 textboxes where they person can type these values in and submit them to the perl script. The issue is... if the user puts them in the wrong order the conditional wont execute. They might put item# 7880 in the 3rd box... and then it wouldnt function.

my question is this: Is there someway I can load multiple values into $item1-$item4? Something to the effect of an array that will evaluate every single value in a conditional. For instance in my main perl file that will simmulate execution of the EVENT_ITEM could I do something like

  1. $item1=array(7880,7879,5192)
  2. $item2=array(7880,7879,5192)
  3. $item3=array(7880,7879,5192)

So when $item1==7880 it will check all three values before returning its true/false. Anyone got any idea?


Sorry for the length, i know im long winded.
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 2,413
Reputation: Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough 
Solved Threads: 211
Team Colleague
Comatose's Avatar
Comatose Comatose is offline Offline
Taboo Programmer

Re: perl arrays

 
0
  #2
Feb 2nd, 2009
There is probably a cleaner and easier way to do this, but if you include this sub in your perl file somewhere:
  1. sub Compare_Items
  2. {
  3. ($ref_cmplist, $ref_udata) = @_;
  4.  
  5. foreach $udata (@{$ref_udata}) {
  6. $flags{$udata} = false;
  7. foreach $cmp_item (@{$ref_cmplist}) {
  8. if ($cmp_item eq $udata) { $flags{$udata} = true; }
  9. }
  10. }
  11.  
  12. while (($key, $value) = each %flags) {
  13. if ($value eq false) { $main_flag = false; }
  14. }
  15.  
  16. return $main_flag;
  17. }
Then you can use it by simply checking its return value. First however, there are a couple of things I should mention. There needs to be 2 arrays in order for this to work. The good news, is that this is very flexible, and can handle many arguments (not just limited to item1, item2, etc). This is basically what you need to do... make an array, which is the list of values you want to compare the user entered values against. In your example, that array would need to contain "7880", "7879", and "5192". Then, you need to take the scalars entered by the user (ie: $item1, $item2, $item3) and put those into an array. Then pass both arrays to the sub/function above. It sounds a lot more complicated than it is really. Here is the code that I used, commented and in its entirety (the code is much shorter without all the comments ):
  1. $main_flag = true;
  2.  
  3. $item1 = "7880"; # Input Would Be From Textbox, Not Assigned Like Here
  4. $item2 = "5192"; # Input Would Be From Textbox, Not Assigned Like Here
  5. $item3 = "7879"; # Input Would Be From Textbox, Not Assigned Like Here
  6.  
  7. # // This Is The List Of Items That You Want
  8. # // To Compare The User Input Against
  9. push @compare_list, "7880";
  10. push @compare_list, "7879";
  11. push @compare_list, "5192";
  12.  
  13. # // Here, We Actually Put $item1, $item2 And $item3
  14. # // Into An Array.... Yeah, It's That Easy
  15. push @userdata, $item1;
  16. push @userdata, $item2;
  17. push @userdata, $item3;
  18.  
  19.  
  20. # // Now We Call The Sub, And Pass It References
  21. # // To Both Of The Arrays. When This Line Finishes
  22. # // The Variable "$are_same" Will Be Either True
  23. # // Or False... True If All The Items Match Something
  24. # // From The Other List... False If Even One Does Not
  25. # // Match.
  26. $are_same = &Compare_Items( \@compare_list, \@userdata );
  27.  
  28. # // Display True Or False To The Screen
  29. # // ie: Do The Items All Match?
  30. # // You Should Probably Test This With
  31. # // An If, Instead Of Showing Its Value ;-)
  32. print "$are_same\n";
  33.  
  34. exit;
  35.  
  36. sub Compare_Items
  37. {
  38. ($ref_cmplist, $ref_udata) = @_;
  39.  
  40. foreach $udata (@{$ref_udata}) {
  41. $flags{$udata} = false;
  42. foreach $cmp_item (@{$ref_cmplist}) {
  43. if ($cmp_item eq $udata) { $flags{$udata} = true; }
  44. }
  45. }
  46.  
  47. while (($key, $value) = each %flags) {
  48. if ($value eq false) { $main_flag = false; }
  49. }
  50.  
  51. return $main_flag;
  52. }
let me know if you need further assistance, or if this just doesn't do what you expect or need.
Last edited by Comatose; Feb 2nd, 2009 at 1:11 am.
Reply With Quote Quick reply to this message  
Join Date: Jan 2009
Posts: 35
Reputation: headedtomexico is an unknown quantity at this point 
Solved Threads: 0
headedtomexico headedtomexico is offline Offline
Light Poster

Re: perl arrays

 
0
  #3
Feb 2nd, 2009
I don't think that would do it. Lemme give you a better example of whats being run here.

  1. $item1=$ARGV[0];
  2. $item2=$ARGV[1];
  3. $item3=$ARGV[2];
  4. $item4=$ARGV[3];
  5. $myscript=$ARGV[3];
  6.  
  7. my $TheQuest="";
  8.  
  9. sub WriteIt {
  10. $TheQuest.=$_[0]."\n";
  11. }
  12.  
  13. sub exp {
  14. WriteIt("<br><font color=yellow>You gain experience!!</font>");
  15. }
  16.  
  17. sub summonitem {
  18. WriteIt("<br><b>".$myscript." gives you : </b><a href=$main::root_url"."item.php?id=$_[0]>".$_[0]."</a>");
  19. }
  20.  
  21. eval "require '$myscript'";
  22.  
  23. EVENT_ITEM();
  24.  
  25. print $TheQuest;
  26. exit;
  27. }


ok, so i've got the like 4000 files that this gets run on, and the contents will vary greatly. There really isn't any way for me to predict what item numbers are going to be in the game characters file. So i'll give two scenarios.

The player wants to simmulate giving items to King Tormax to see if his quest is working. So they come to my site, and "give" him 3 items to see if his quest is working. The php calls my perl with all the arguments as follow. "'questparser.pl' '7880' '7879' '5192' '0' 'King_Tormax.pl'"

This will end up including the King_Tormax file, which will have the EVENT_ITEM in it, and the calls to item1-item4. In this situation the items are set in the correct order for king tormax's quest file. which is as follows

  1. sub EVENT_ITEM {
  2. if($item1=="7880" && $item2=="7879" && $item3=="5192"){
  3. quest::summonitem(4199);
  4. quest::exp(85); }
  5. }

had they typed the items in a different oder, 7879, 7880, 5192, then the conditional in king tormax's file wouldnt go off. In the actual game the items are handed in all at once, so order is not a factor, and a user wouldnt expect it to be a factor on my site. Furthermore the quest files for each game character aren't written with the arguments in any kind of order. In this example they are in descending order, but its pure coincidence.

Another example is Veltar,
  1. sub EVENT_ITEM {
  2. if($item1=="356" && $item2=="685"){
  3. quest::say("Very well mortal...");
  4. quest::summonitem(376);
  5. quest::exp(1000); }
  6. elseif($item1=="2296" && $item2=="686"){
  7. quest::say("You have done well for me!");
  8. quest::summonitem(377);
  9. quest::exp(1000); }


as you can see, its very chaotic what to expect from the quest files. In game im really not sure how they do it. When you give the items to the game character a window opens up with 4 slots, and you hand the items in, in any order. So i'm not sure how the game server, which is written in c++, calls the perl so that these items are in order. Naturally the say, summonitem, exp functions are all provided by the game server in that case. These are the things i'm simmulating by writing my own functions that output html.

I was wondering if there was some kind of regular expression that could be used to do this. I've never really messed with the stuff, but i've seen items in []'s before. Would something like

  1. $item1="/[".$ARGV[0].",".$ARGV[1].",".$ARGV[2].",".$ARGV[3]."]/"
  2. $item2="/[".$ARGV[0].",".$ARGV[1].",".$ARGV[2].",".$ARGV[3]."]/"
  3. $item3="/[".$ARGV[0].",".$ARGV[1].",".$ARGV[2].",".$ARGV[3]."]/"
  4. $item4="/[".$ARGV[0].",".$ARGV[1].",".$ARGV[2].",".$ARGV[3]."]/"

so when the conditional of $item1=="7880" fires it will check "/[7880,5192,7879,0]/=="7880"

I know none of that is syntactically correct im shooting in the dark =P
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 2,413
Reputation: Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough 
Solved Threads: 211
Team Colleague
Comatose's Avatar
Comatose Comatose is offline Offline
Taboo Programmer

Re: perl arrays

 
0
  #4
Feb 2nd, 2009
I do believe the code I gave you above would work just fine for what you are doing... instead of manually using push to push each item, you would do a for loop and push all of the items that are arguments and that are not the last one (the filename). However, this can be done with grouping in regex similar to this:
  1. $item1 = "Fun";
  2. $retval = ($item1 =~ m/(Fun|Sucky|Cool)/i) ? true : false;
  3.  
  4. print "$retval\n";
This will set $retval to true or false depending on if $item1 contains any of the words in the group (Fun, Sucky or Cool) or not.
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 898
Reputation: KevinADC has a spectacular aura about KevinADC has a spectacular aura about 
Solved Threads: 67
KevinADC's Avatar
KevinADC KevinADC is offline Offline
Practically a Posting Shark

Re: perl arrays

 
0
  #5
Feb 2nd, 2009
so when the conditional of $item1=="7880" fires it will check "/[7880,5192,7879,0]/=="7880"
Its possible (I think). Using a hash sounds like the better approach. Very simple example:

  1. %item1 = (
  2. 7880 => [7880,7879,5192,0],
  3. 7879 => [7879,7880,5192,0],
  4. 5192 => [5192,7880,7879,0],
  5. );
  6.  
  7. $item1 = $item1{$ARGV[0]} || die "Usage: no item found\n";

In the above if $ARGV[0] equaled 7880 then $item1 will be a reference to an array : [7880,7879,5192,0]. The first value is:

$item1->[0]

And so on for the other values in the array reference. The concept is pretty straight forward, but the implementation might not be.
Last edited by KevinADC; Feb 2nd, 2009 at 3:29 pm.
Reply With Quote Quick reply to this message  
Join Date: Mar 2006
Posts: 898
Reputation: KevinADC has a spectacular aura about KevinADC has a spectacular aura about 
Solved Threads: 67
KevinADC's Avatar
KevinADC KevinADC is offline Offline
Practically a Posting Shark

Re: perl arrays

 
1
  #6
Feb 4th, 2009
Seems that maybe headedtomexico is now madeittomexico
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 56
Reputation: mitchems is an unknown quantity at this point 
Solved Threads: 2
mitchems's Avatar
mitchems mitchems is offline Offline
Junior Poster in Training

Re: perl arrays

 
0
  #7
Feb 5th, 2009
Use an perl array:

  1. @array=("1234","4231","5674");
  2. print "$array[0]\n$array[1]\n$array[2]\n";
  3. for $var (@array){
  4. print "$var\n";
  5. }

You can pass the array to a sub or an object and the sub or or object will get the array in @_ or you can shift it into a local variable.
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 2,413
Reputation: Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough 
Solved Threads: 211
Team Colleague
Comatose's Avatar
Comatose Comatose is offline Offline
Taboo Programmer

Re: perl arrays

 
0
  #8
Feb 5th, 2009
...
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Perl Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC