Rendril Posted December 26, 2009 Report Posted December 26, 2009 (edited) 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> Scriptif(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 June 9, 2013 by Chewett Quote
Grido Posted December 26, 2009 Report Posted December 26, 2009 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? Quote
Rendril Posted December 27, 2009 Author Report Posted December 27, 2009 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. Quote
Grido Posted December 27, 2009 Report Posted December 27, 2009 thanks and that's why i intentionally put 2 of one of the creatures will check it, what would be considered later today, although i'm about to go to sleep Quote
Burns Posted December 27, 2009 Report Posted December 27, 2009 (edited) 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 December 27, 2009 by Burns Quote
cutler121 Posted December 27, 2009 Report Posted December 27, 2009 [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 Quote
Rendril Posted December 27, 2009 Author Report Posted December 27, 2009 Cutler, I like your duplicate solution, I have updated the example to reflect it. I also fixed the typos, thank you for pointing them out, Burns. Quote
Grido Posted December 27, 2009 Report Posted December 27, 2009 (edited) 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 December 27, 2009 by Grido Quote
Rendril Posted December 27, 2009 Author Report Posted December 27, 2009 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 Quote
cutler121 Posted December 28, 2009 Report Posted December 28, 2009 [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 } Quote
Rendril Posted December 28, 2009 Author Report Posted December 28, 2009 (edited) 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 December 28, 2009 by Rendril Quote
cutler121 Posted December 28, 2009 Report Posted December 28, 2009 [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 Quote
Rendril Posted December 28, 2009 Author Report Posted December 28, 2009 Absolutely right, seems I'm losing my marbles Example has been updated. Quote
Burns Posted January 1, 2010 Report Posted January 1, 2010 (edited) 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 January 1, 2010 by Burns Orlando Gardiner 1 Quote
Rendril Posted January 1, 2010 Author Report Posted January 1, 2010 (edited) 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 January 2, 2010 by Rendril Quote
Burns Posted January 2, 2010 Report Posted January 2, 2010 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... :// Orlando Gardiner and Rendril 1 1 Quote
Rendril Posted January 2, 2010 Author Report Posted January 2, 2010 (edited) 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 January 2, 2010 by Rendril Quote
Root Admin Chewett Posted June 9, 2013 Root Admin Report Posted June 9, 2013 Added playername to returned data Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.