Issues with Alternate Outcome Rarity

Forum
Last Post
Threads / Messages

Abronsyth

A Headache Embodied
Member
Joined
Aug 25, 2011
Messages
1,012
Points
36
Location
NY
Mysidian Dollar
73,285
Resolved

This is a little confusing.

One of my artists brought to my attention that outcomes that are supposed to be less common are, in fact, more common.

For example I have a pet that has an alternate outcome. I set the outcome chance to be 1 out of 10. However, it seems to have reversed it so that the alternate's chance of happening is 9/10, leaving the original adopt to have an outcome of 1/10. I don't really get where this is going wrong, so I'm afraid I cannot provide more information than this.

Basically the "alternate outcome chance" is doing the opposite of what it should.
 
Last edited:
Re

This is a little confusing.

One of my artists brought to my attention that outcomes that are supposed to be less common are, in fact, more common.

For example I have a pet that has an alternate outcome. I set the outcome chance to be 1 out of 10. However, it seems to have reversed it so that the alternate's chance of happening is 9/10, leaving the original adopt to have an outcome of 1/10. I don't really get where this is going wrong, so I'm afraid I cannot provide more information than this.

Basically the "alternate outcome chance" is doing the opposite of what it should.

By 1/10, are you trying to make the breed adopt have a 10% chance of appearing? Instead of inputting 1/10, try simply inserting "10"?
Also, when you check the breed adopts in your database, does the probability in the probability column look normal?

Edit: Here's what I suspect: Apparently, the ACP (at least for my version) uses an integer percent for probability. This percentage is based on 100, so 1/10 would be 10/100. If you just input "10", that's your 1/10 probability. The ACP might do something funny with fraction values? o_O
 
Last edited:
I'm not putting in a fraction, I am putting "10" in the box. The table looks as it should...so I'm not sure what's going on.
 
Re

I'm not putting in a fraction, I am putting "10" in the box. The table looks as it should...so I'm not sure what's going on.
OK, at least you know there's nothing wrong on the ACP side? In that case, I'm not sure... but here's part of my class_breeding code:
PHP:
private function advancedBreed($species){
		$speciesMap = new ArrayObject;
		$probability = new Probability;
		
        foreach($species as $breed){
			$speciesMap->offsetSet($breed->getBreedID(), $breed);
			$probability->addEvent($breed->getBreedID(), $breed->getProbability());
		}
			
        $num = rand(1, $this->settings->number);
		for($i = 0; $i < $num; $i++){
			$bid = $probability->randomEvent();
		    $adopt = $speciesMap->offsetGet($bid);
			if($this->getSurvival($adopt)) $this->offsprings->append($adopt);
		}
	}


my class_probability code:
PHP:
<?php

/**
 * The Probability Class, extends from abstract Object class.
 * It generates one or a group of random events based on probability of each.
 * @category Resource
 * @package Utility
 * @author Hall of Famer(finalized version), xyph(initial script)
 * @copyright Mysidia Adoptables Script
 * @link http://www.mysidiaadoptables.com
 * @since 1.3.3
 * @todo Not much at this point.
 * @final
 *
 */
 
final class Probability extends Object{
 
    /**
	 * This will hold our possible outcomes along with thier probabilities. 
	 * I store them with the key being the name of teh event, and the value. it's probability to show up. $this->events['name'] = probability
	 * @access private
	 * @var Array
    */
    private $events = array();

	/**
     * Constructor of Probability Class, it can generates events list immediately.      
     * @access public
     * @return Void
     */	
	public function __construct($events = ""){
	    if($events instanceof ArrayObject) $this->events = $events->getArrayCopy();
	}
        
 	/**
	 * This method will add a new event to the array. I didn't include a check to make sure a duplicate exists. 
	 * So as it is, if you call $this->addEvent( 'blue', 20 );
     * followed by $this->addEvent( 'blue', 30 ); 
	 * 'blue' will now have a value of 30.
	 * @param String  $value
	 * @param Int  $probability
	 * @access public
	 * @return Void
	*/	
    public function addEvent($value, $probability) {
        $this->events[$value] = $probability;
    }
 
  	/**
	 * Simple method to remove an event. I don't think the array_key_exists() check is needed, but it's there.
	 * @param String  $value
	 * @access public
	 * @return Void
    */		
    public function removeEvent($value){
        if(array_key_exists($value, $this->events)) unset($this->events[$value]);
    }
        
    /**
	 * The randEvent method to remove an event. This is where one or multiple random events will be generated.
	 * @param Int  $num
	 * @access public
	 * @return String|Array
    */
    public function randomEvent($num = 1) {
	
        // Generate a reverse list of events, using our class method below to change the individual probabilities into comparable numbers.
        $events = array_reverse( $this->buildEvents(), TRUE );
        $sum = array_sum($this->events);
		
        // If only 1 result is needed, we want to return a string. Otherwise, we'll build an array.
        if($num == 1){
            // Generate the random number between 1 and the sum of all probabilities
            $rand = mt_rand( 1, $sum );
			
            // Loop through probabilities, greatest to lowest.
            foreach($events as $event => $probability){
  			    if($probability <= $rand) return $event;
			}	                
        } 		
		else{
            // Set up an empty array to hold the values.
            $eventList = array();
			
            // Loop through the following code $num times
            for($i = 0; $i < $num; $i++){
                // Generate our random number INSIDE the loop, so it gets changed every time
                $rand = mt_rand(1, $sum);
                foreach($events as $event => $probability){
                    if($probability <= $rand) {
                        // If so, add a new array entry. Since we don't need to loop through any more events until we generate a new random number, we use break to escape out of the foreach.
                        $eventList[] = $event; 
						break;
                    }
				}	
            }
            return $eventList;
        }
    }
	
    /**
	 * The buildEvents method, here's where we modify the events array to become more usable.
	 * We do this on the fly, rather than when we add an event because it makes removing events a much easier process. 
	 * @access private
	 * @return Array
    */        
    private function buildEvents() {
        // Create a local copy of the events array. We can change this all we want without modifying data that other class methods might still need.
        $events = $this->events;
        $total = 0;
		
        // Loop through each probability. The &$event will apply any changes made in the loop to the $events array.
        foreach($events as &$probability){
            $original = $probability;
            $probability = $total;
            $total += $original;
        }
		
        // Return the momdified event array
        return $events;
    }
}

?>

Does your code look odd in any of these places?
Does your probability work fine for other things... say, item consumption?
 
Last edited:
The only difference between the codes is in the .../classes/class_probability.php file I have this at the top (where as yours does not);
PHP:
use Resource\Native\Object;

Everything else is working perfectly fine.
 
Well the alternate outcome isnt generated from probability class, that one is used to generate one adoptable from several possible adoptable species(ie. when your two adoptables can produce offspring of multiple species).

The actual alternate status generation code is located at class_adoptable.php, in this method:
PHP:
    public function getAltStatus(){
        if($this->alternates == "enabled" and $this->altoutlevel == 0){
            $rand = mt_rand(1, $this->altchance);
            if($rand == 1) return "yes";            
        }
        return "no";
    }

As you see, this code generates alt status and it should work properly. if your altchance field is 100, it gives 1/100 chance to have alternate outcome. So theoretically, it should work if you adopt your pet through adoption center. But for breeding, I am not 100% sure so you need to test it out.
 
HoF, you mention that it should work for pets adopted through the adoption center...does this also apply to pets adopted via adopt shops (as the issue has only really been noticed with those purchased from stores)?


Edit: Fixed
Apparently there were some discrepancies in how adoptables from shops were dealt with in regards to the alternate outcome, so I replaced the getAltStatus in the file .../classes/class_stockadopt.php with the one from .../classes/class_adoptable.php and now it seems to be functioning the way it's supposed to.

Edit 2: Okay I *think* I fixed it...I'm not yet sure. I'm still testing it.
 
Last edited:
Re

Well the alternate outcome isnt generated from probability class, that one is used to generate one adoptable from several possible adoptable species(ie. when your two adoptables can produce offspring of multiple species).

The actual alternate status generation code is located at class_adoptable.php, in this method:
PHP:
    public function getAltStatus(){
        if($this->alternates == "enabled" and $this->altoutlevel == 0){
            $rand = mt_rand(1, $this->altchance);
            if($rand == 1) return "yes";            
        }
        return "no";
    }

As you see, this code generates alt status and it should work properly. if your altchance field is 100, it gives 1/100 chance to have alternate outcome. So theoretically, it should work if you adopt your pet through adoption center. But for breeding, I am not 100% sure so you need to test it out.
o_O What was I thinking? The issue was about alts, not various breeding outcomes - sorry about that. Anyhow, I hope this gets fixed.
 
Well adoptable shops surely dont work the same way as standard adoption, as it bypasses adoption conditions and the behaviors may be strange to you. Its possible to tweak adoptable shop to work the way you expect it to work though, and its not very difficult.
 
tahbikat, yep, that's the fix I used!

I'm still trying to figure out how to get conditions to work for shops XD I can sort of bypass that issue by making a copy of the adopt.php cluster of files and tweaking them a bit to display pets from specific shops, but the issue then is I'm not sure how to get the pet's price to show up then. Hopefully I'll figure it out in time!

Thanks all for the input!
 

Similar threads

Users who are viewing this thread

  • Forum Contains New Posts
  • Forum Contains No New Posts

Forum statistics

Threads
4,277
Messages
33,122
Members
1,602
Latest member
BerrieMilk
BETA

Latest Threads

Latest Posts

Top