Jump to content
Sign in to follow this  
Rendril

Function: Mds_Is_Ctc

Recommended Posts

array|boolean mds_is_ctc(string $ctc)

Returns false if invalid CTC is supplied,
otherwise it returns an array with creature information.

Returned array will have the following structure:
["id"] : creature ID
["uid"]: owner ID

["playername"]: owner Playername
["cid"]: creature type
["tokens"]: tokens held by creature
["dateBorn"]: timestamp when creature was created
["transfercount"] : number of transfers
["tradevalue"]: trade value
["customName"]: custom name of the creature, if any
["vitality"]: creature's maximum vitality
["level"] : creature's level
["experience"] : creature's experience
["battlesWon"] : number of battles won by creatre
["age"] : creature's age in days


When inputting a creature transfer code, never use the full string, it will be treated as invalid and return false.
I find it best to copy from the CTC to MDC of the code, that is all it needs to identify the creature.


Example:

HTML

<form method="post" action="">
Pete the Bull stands guard, send the CTC's* of the creatures to defeat him<br />
<input name="ctc0" type="text" /><br />
<input name="ctc1" type="text" /><br />
<input name="ctc2" type="text" /><br />
<input name="ctc3" type="text" /><br />
<br />
<input name="submit" type="submit" value="Submit"/><br />
<br />
<font size="1px">*Copy from "CTC" to "MDC", not the entire code</font>
</form>

Script
if(isset(@input['submit']))//check that button was clicked
{
//load the "ctc"'s into an array
@vc[0]= mds_is_ctc(@input['ctc0']);
@vc[1]= mds_is_ctc(@input['ctc1']);
@vc[2]= mds_is_ctc(@input['ctc2']);
@vc[3]= mds_is_ctc(@input['ctc3']);

//check whether ctc's are valid
if(@vc[0] && (@vc[1]) && (@vc[2]) && (@vc[3]))
{
@vt = true;
//test for repeats
//set the counters of each creature type in associative array
for(@vi = 0; @vi < 3; @vi++)
{
for(@vj = @vi + 1; @vj < 4; @vj++)
{
if(@vc[@vi]['id'] == @vc[@vj]['id'])
{
@vt = false;
break;
}
}
if(isset(@vd["" . @vc[@vi]['cid']]))
++@vd["" . @vc[@vi]['cid']];
else
@vd["" . @vc[@vi]['cid']] = 1;
}
if(isset(@vd["" . @vc[3]['cid']]))
++@vd["" . @vc[3]['cid']];
else
@vd["" . @vc[3]['cid']] = 1;
//check there are no repeats
if(@vt)
{
//create an array of the creature types
@va = array(@vc[0]['cid'], @vc[1]['cid'], @vc[2]['cid'], @vc[3]['cid']);
//check if required creatures types are in the array
if((@vd['12'] == 2) && (@vd['2'] == 1) && (@vd['5'] == 1))
{
echo "you have defeated pete the bull!";
}
else
{
echo "pete laughs at your feeble attacks";
}
}
else
{
echo "pete looks at " . uv('name') . " with doubt";
}
}
else
{
echo "inva"."lid ctc(s) supplied";
}
}
else
{
//echo the html, it is not shown by default
echo @content[0];
}
Edited by Chewett

Share this post


Link to post
Share on other sites
For the example given the creator of the script would have to input the CTC to get returns and display it etc, yeah?

What about if i wanted to check that the person doing the quest had certain specific creatures?

e.g.
A fake battle senario;
Pete the Bull stands guard, you have learnt that the only way to defeat him is to attack with 2 Lorerootian Archers, an Elemental and a Grassan


Would there be a way to detect that they have those creatures?

Share this post


Link to post
Share on other sites
Example updated.
Rememeber to remove the comments.

I'm not sure how the in_array() function will perform with duplicates in the array, I will change the example if needed.

Share this post


Link to post
Share on other sites

thanks :)


and that's why i intentionally put 2 of one of the creatures :D


will check it, what would be considered later today, although i'm about to go to sleep

Share this post


Link to post
Share on other sites
I'm not getting it... as usual XD

I reduced the code to the very basic, recognize exactly one type of creature, with:
[php]<form method="post" action=""> Pete the Bull stands guard, send the CTC's* of the creatures to defeat him<br />
<input name="ctc0" type="text" /><br /> <br />
//and i think you need to count up, not use 'ctc1' over and over again, Ren... not sure, though
<input name="submit" type="submit" value="Submit"/><br /> <br />
<font size="1px">*Copy from "CTC" to "MDC", not the entire code</font> </form>[/php]

[php]if(isset(@input['submit'])){

@vc[0]= mds_is_ctc(@input['ctc0']);

if(@vc[0])
{@va = array(@vc[0]['cid']);

if(in_array(array(33), @va))
{echo "you have defeated pete the bull!";}

else
{echo "pete laughs at your feeble attacks";}
}

else {echo "inva"."lid ctc(s) supplied";} // 'val' is restricted language
}

else {echo @content[0];}[/php]

now i go and feed it with a creature 33 (bloodpact archer), and what does pete? he laughs at my feeble attempts of creating code =(

Is it my code failing? is it me misunderstanding the cid-command? or is my poor ole Apollo not strong enough to attack petey? HELP PLEASE! Edited by Burns

Share this post


Link to post
Share on other sites
[quote name='Burns' date='27 December 2009 - 08:01 AM' timestamp='1261900864' post='51189']
I'm not getting it... as usual XD

I reduced the code to the very basic, recognize exactly one type of creature, with:
[php]<form method="post" action=""> Pete the Bull stands guard, send the CTC's* of the creatures to defeat him<br />
<input name="ctc0" type="text" /><br /> <br />
//and i think you need to count up, not use 'ctc1' over and over again, Ren... not sure, though
<input name="submit" type="submit" value="Submit"/><br /> <br />
<font size="1px">*Copy from "CTC" to "MDC", not the entire code</font> </form>[/php]

[php]if(isset(@input['submit'])){

@vc[0]= mds_is_ctc(@input['ctc0']);

if(@vc[0])
{@va = array(@vc[0]['cid']);

if(in_array(array(33), @va))
{echo "you have defeated pete the bull!";}

else
{echo "pete laughs at your feeble attacks";}
}

else {echo "inva"."lid ctc(s) supplied";} // 'val' is restricted language
}

else {echo @content[0];}[/php]

now i go and feed it with a creature 33 (bloodpact archer), and what does pete? he laughs at my feeble attempts of creating code =(

Is it my code failing? is it me misunderstanding the cid-command? or is my poor ole Apollo not strong enough to attack petey? HELP PLEASE!
[/quote]




There are a couple of problems with what you have tried to code above.

First when you are trying to test what creature the CTC code is you are using array() improperly, it is just the array value you want which is:

@va = @vc[0]['cid'];

Then you want to test to see if that value is equal to 33 or not so you should use:


if(@va == 33){
// insert code here if true
}
else{
// insert code here if false
}


So your example should be :


if(isset(@input['submit'])){

@vc[0]= mds_is_ctc(@input['ctc0']);

if(@vc[0]){
@va = @vc[0]['cid'];

if(@va == 33){
echo "you have defeated pete the bull!";
}
else{
echo "pete laughs at your feeble attacks";
}
}
else{echo "inva"."lid ctc(s) supplied";}
}
else {echo @content[0];}



The best way to test if multiple creatures are present is if you make a creature number associative array and add one to the creature number for each "real" creature present.

So you could add this line above:

@vb[@va]++; // this adds one more creature of type @va

Then you could just test to see if there are 2 creatures of type 33 one of type 29 ... etc.

if(@vb[33]== 2 && (@vb[29] == 1)){
// add code here for if true
}
else{
// add code here for if false
}


I placed the second set of parentheses around the @vb[29] part of the code so the && and @ wouldn't be immediately adjacent which will give an error.

Cheers,

Cutler

Share this post


Link to post
Share on other sites
it's a stupid little thing i'm picking up here, but

" create an array of the creature types"

needs the // in front, to mark it as help text



LE: As it stands with the updated code, i can enter the same ctc of LR archer, any way to ensure that there's actually 2 LR archers rather than the same one twice? Edited by Grido

Share this post


Link to post
Share on other sites

Added the repeat check, not sure why the comments were missing but it has been fixed.
Repeat check could be done with just 6 if-statements...but I like accomodating for expansion.
Admittedly, array size should be used rather than magic numbers :D

Share this post


Link to post
Share on other sites
[quote name='Rendril' date='26 December 2009 - 09:37 PM' timestamp='1261863428' post='51148']
[b]array[/b]|[b]boolean[/b] mds_is_ctc(string $ctc)

Returns [i]false[/i] if invalid CTC is supplied,
otherwise it returns an array with creature information.

Returned array will have the following structure:
["id"] : creature ID
["uid"]: owner ID
["cid"]: creature type
["tokens"]: tokens held by creature
["dateBorn"]: timestamp when creature was created
["transfercount"] : number of transfers
["tradevalue"]: trade value
["customName"]: custom name of the creature, if any
["vitality"]: creature's maximum vitality
["level"] : creature's level
["experience"] : creature's experience
["battlesWon"] : number of battles won by creatre
["age"] : creature's age in days


When inputting a creature transfer code, never use the full string, it will be treated as invalid and return false.
I find it best to copy from the CTC to MDC of the code, that is all it needs to identify the creature.


Example:

HTML
[code]
<form method="post" action="">
Pete the Bull stands guard, send the CTC's* of the creatures to defeat him<br />
<input name="ctc0" type="text" /><br />
<input name="ctc1" type="text" /><br />
<input name="ctc2" type="text" /><br />
<input name="ctc3" type="text" /><br />
<br />
<input name="submit" type="submit" value="Submit"/><br />
<br />
<font size="1px">*Copy from "CTC" to "MDC", not the entire code</font>
</form>[/code]

Script
[code]
if(isset(@input['submit']))//check that button was clicked
{
//load the "ctc"'s into an array
@vc[0]= mds_is_ctc(@input['ctc0']);
@vc[1]= mds_is_ctc(@input['ctc1']);
@vc[2]= mds_is_ctc(@input['ctc2']);
@vc[3]= mds_is_ctc(@input['ctc3']);

//check whether ctc's are valid
if(@vc[0] && (@vc[1]) && (@vc[2]) && (@vc[3]))
{
@vt = true;//test for repeats
for(@vi = 0; @vi < 2; @vi++)
{
for(@vj = @vi + 1; @vj < 3; @vj++)
{
if(@vc[@vi]['cid'] == @vc[@vj]['cid'])
{
@vt = false;
break;
}
}
}
//check there are no repeats
if(@vt)
{
//create an array of the creature types
@va = array(@vc[0]['cid'], @vc[1]['cid'], @vc[2]['cid'], @vc[3]['cid']);
//set the counters of each creature type in associative array
foreach(@va as @vb)
{
if(isset(@vd["" . @vb]))
++@vd["" . @vb];
else
@vd["" . @vb] = 1;
}
//check if required creatures types are in the array
if((@vd['12'] == 2) && (@vd['2'] == 1) && (@vd['5'] == 1))
{
echo "you have defeated pete the bull!";
}
else
{
echo "pete laughs at your feeble attacks";
}
}
else
{
echo "pete looks at " . uv('name') . " with doubt";
}
}
else
{
echo "inva"."lid ctc(s) supplied";
}
}
else
{
//echo the html, it is not shown by default
echo @content[0];
}
[/code]
[/quote]




I would change the way you are testing to see if two creatures are actually different or not. As it is now if you put the same exact two ctcs in boxes ctc2 and ctc3 it won't catch them (your double loop has a less than when it should have less than or equals). Also if someone just copies a slightly longer ctc code in the second time it will still show as valid and the two will seem to be different.

From a programming perspective the double nested loop is ok for very small arrays like this but there are a number of better methods in general to test for repeated elements. If you want to have a double loop you can do a full bubble sort on the elements. Or just use sort(@vc) and run through it once to see if there are equal CTC elements. I would actually test against the creature id's since those will be the same no matter what CTC fragment someone used.

For example:

sort(@vc); @vd[0]['cid']]++;

for(@vi = 0; @vi < 3; @vi++){
if(@vc[@vi]['id'] == @vc[@vi+1]['id']){
@vt = false;
break;
}
else{ @vd[@vc[@vi+1]['cid']]++; }
}
// now you have tested identity and set @vd already

if(@vt){
// put in the end part here
}

Share this post


Link to post
Share on other sites

Whoops! I meant to compare the id's, not the cid's :) Thanks for noticing

As for the double loop, why would it not work?.
From what I can tell it performs the 6 comparisons as needed:
0 is compared to 1, 2 and 3
1 is compared to 2 and 3
2 is compared to 3

Looking at your implementation of the linear loop, I think you misunderstood how the for-loop runs.
[code]for(@va = 0; @va < 3; @va++)[/code]
Will trigger only 3 times, from 0 to 2


I agree, my method performs in a O(n[sup]2[/sup]), more specifically, it does (n(n-1))/2 comparisons (please correct me if I am mistaken)
What you suggested is to pre-sort, then apply the linear loop.
Paying for the sort could make it less efficient then the nested loops (at least for this small scale comparison), sort() is implemented using a quicksort. So the performance gain would indeed only be present if the number of elements was larger.
Also, will it sort on id by default?
I checked the sort() reference and it seems that it is designed for sorting an array of single items rather than of arrays. There is an msort suggested however (it needs to be told the key to sort on)

You haven't initialized any of your counters, although PHP is loosely typed, I don't think it will initialize them correctly through the postfix increment.


Looking back on the code, I see that I could have performed the counting directly in the replication check, I'll add that when I have internet again.
I also realsied the owner needs to be compared. This is however, an example code for the function reference. It would be better to discuss it in the sample codes section.

Edited by Rendril

Share this post


Link to post
Share on other sites

[quote name='Rendril' date='28 December 2009 - 05:49 AM' timestamp='1261979361' post='51239']
Whoops! I meant to compare the id's, not the cid's :) Thanks for noticing

As for the double loop, why would it not work?.
From what I can tell it performs the 6 comparisons as needed:
0 is compared to 1, 2 and 3
1 is compared to 2 and 3
2 is compared to 3

Looking at your implementation of the linear loop, I think you misunderstood how the for-loop runs.
[code]for(@va = 0; @va < 3; @va++)[/code]
Will trigger only 3 times, from 0 to 2


I agree, my method performs in a O(n[sup]2[/sup]), more specifically, it does (n(n-1))/2 comparisons (please correct me if I am mistaken)
What you suggested is to pre-sort, then apply the linear loop.
Paying for the sort could make it less efficient then the nested loops (at least for this small scale comparison), how is the sort() implemented?
Also, will it sort on id by default?

You haven't initialized any of your counters, although PHP is loosely typed, I don't think it will initialize them correctly through the postfix increment.


Looking back on the code, I see that I could have performed the counting directly in the replication check, I'll add that when I have internet again.
[/quote]


Yes that is correct my for loop does 3 comparisons, that is all that is needed to check for identity of 4 elements in a sorted array.

If you look back at your two nested loops, you will see that the outer one which you have :

for(@vi = 0; @vi < 2; @vi++)
{

only runs from @vi = 0 to 1.


If that doesn't make sense, just take your loops and put an echo inside which will print out what numbers it runs over:

for(@vi = 0; @vi < 2; @vi++)
{
for(@vj = @vi + 1; @vj < 3; @vj++)
{
echo "<br> @vi @vj";
}
}



If you run that you will see that it only runs over the values


@vi,@vj
0,1
0,2
1,2

it is missing the comparisons with the final ctc value. If you replace the 2 and 3 respectively by 3 and 4 it will be correct ie.


for(@vi = 0; @vi < 3; @vi++){
for(@vj = @vi + 1; @vj < 4; @vj++){
echo "<br> @vi @vj";
}}

Not a big issue, but it is important to have the loops test the whole set of values especially when it is for an example for people not used to dealing with loops.

Cheers,

Cutler

Share this post


Link to post
Share on other sites

might it be that battleswon-function doesn't work yet? i tried exchanging cid inthe most basic script from cutler (post6) with various other variables and had them echoed, and battleswon refused to work... unfortunately that was the one i wanted xD

so, is it the function not being working yet or a typo in the description you made, or something else i'm not aware of? for this one time, [s]it's not about me coding it wrong[/s], uid, cid, id, experience and age work perfectly fine with my script... yeah, i'm a bit proud of that :)
[color="#000080"]
>.< Darn, of course it was about my coding abilities... again -.- Thanks for your help^^[/color]

since we're at it...

those are the stats of apollo, the empty fields are functions that don't work:

id: 276671
uid: 53832
cid: 33
tokens: claw1
dateborn: 1242880400
transfercount: 2
[color="#FF0000"]tradevalue: 0 ( <-- that should be something over 200 for Apollo, is that my fault again? >.<)[/color]
customname: Apollo
vitality: 5000
level: 6
experience: 605983
battleswon: 701
age: 225

okay, solved that so far... but tradevalue, even written as 'trade'.strtolower(v).'alue' always gives me a 0 as result so far... and i dearly hope that getting a 0 out of it is not my fault again :/

Edited by Burns

Share this post


Link to post
Share on other sites

It's due to the way the indexes are named.
MD script turns all your text to lowercase, so when you have ["battlesWon"], the script reads ["battleswon"] (lower case)
To solve this use any method of your choosing to uppercase the letter.
You will find that indexes which didn't work were the ones with uppercase letters.

The lowercasing is a hassle, but was added for security. It will possibly be remvoed in future.

Edit: [quote name='Burns' date='01 January 2010 - 12:29 PM' timestamp='1262341765' post='51581']
okay, solved that so far... but tradevalue, even written as 'trade'.[b]strtolower[/b](v).'alue' always gives me a 0 as result so far... and i dearly hope that getting a 0 out of it is not my fault again :/
[/quote]

Try use strtoupper() insread of strtolower() :)

Edited by Rendril

Share this post


Link to post
Share on other sites
lolz, no, uppercase brings no result at all, i guess because the function is written in lowercase

'tradevalue' results in restricted language

'tradev'.'alue' and similar things that seperate the _val_ in some way leads to 0

'trade'.strtoupper(v).'alue' or uppercasing the T and anything else only got me no results at all... ://

Share this post


Link to post
Share on other sites
It's inconsistent, but it should actually be ["tradevalue"], so ["tradev" . "alue"] ought to work.
Age and tradevalue are the only fields that are of type float (numbers with decimals), since the age displays correctly, it is not a type conversion error.

My guess is that the trade value for creatures traded prior to the trade value implementation, will be 0, perhaps until traded.
Are you trying it with an old creature that was traded? If so, try it with a new creature that gets traded and see if the same thing happens. Edited by Rendril

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Forum Statistics

    15,832
    Total Topics
    173,490
    Total Posts
  • Recently Browsing

    No registered users viewing this page.

  • Upcoming Events

    No upcoming events found
  • Recent Event Reviews

×
×
  • Create New...