Thread: Spore in 4 days.

  1. #31
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Pretty sad.

  2. #32
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by Thantos View Post
    Ok how sad is it that I just wrote a script to min/max my colony's spice production...
    May we see the source

  3. #33
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    I think this guy's reviews are funny, though he does not review any game he likes (or does not like any games....)


    http://www.escapistmagazine.com/vide...tion/218-Spore
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  4. #34
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Quote Originally Posted by abachler View Post
    May we see the source
    I wrote it in PHP and just used a brute force approach. Since there are only 3^11 possible combos it doesn't take too long to do it.

    Looks like I can't attach PHP files so I'll just copy and paste the code.
    Code:
    <?php
    
    // Default variables
    $types = array(
    	'c' => 'City Hall',
    	'h' => 'House',
    	'f' => 'Factory',
    	'e' => 'Enterainment',
    	'u' => 'Unknown',
    );
    
    $adj = array(
    	0 => array(false, true, true, false, true, true, true, false, false, false, false, false, ),
    	1 => array(true, false, true, false, false, false, false, false, false, false, false, true, ),
    	2 => array(true, true, false, true, false, false, false, true, false, false, false, false, ),
    	3 => array(false, false, true, false, true, false, false, false, false, false, false, false, ),
    	4 => array(true, false, false, true, false, false, false, false, true, false, false, false, ),
    	5 => array(true, false, false, false, false, false, false, false, true, true, false, false, ),
    	6 => array(true, false, false, false, false, false, false, false, false, false, true, true, ),
    	7 => array(false, false, true, false, false, false, false, false, false, false, false, false, ),
    	8 => array(false, false, false, false, true, true, false, false, false, true, false, false, ),
    	9 => array(false, false, false, false, false, true, false, false, true, false, true, false, ),
    	10 => array(false, false, false, false, false, false, true, false, false, true, false, true, ),
    	11 => array(false, true, false, false, false, false, true, false, false, false, true, false, ),
    );
    
    // Ok get to work!
    if (isset($_REQUEST['find']))
    {
    	$minhappy = isset($_REQUEST['minhappy']) ? (int) $_REQUEST['minhappy'] : 2;
    	$minpop = isset($_REQUEST['minpop']) ? (int) $_REQUEST['minpop'] : 0;
    	$minprod = isset($_REQUEST['minprod']) ? (int) $_REQUEST['minprod'] : 0;
    
    	$plots = array(
    		0 => 'c',
    		1 => 'u',
    		2 => 'u',
    		3 => 'u',
    		4 => 'u',
    		5 => 'u',
    		6 => 'u',
    		7 => 'u',
    		8 => 'u',
    		9 => 'u',
    		10 => 'u',
    		11 => 'u',
    	);
    
    	$best = array(
    		'score' => 0,
    		'plots' => $plots,
    	);
    
    	// Do up the adj matrix
    	if (isset($_REQUEST['adj']))
    	{
    		for($i=0; $i <= 11; $i++)
    			for($j=0; $j <= 11; $j++)
    				$adj[$i][$j] = (isset($_REQUEST['adj'][$i]) && isset($_REQUEST['adj'][$i][$j])) || (isset($_REQUEST['adj'][$j]) && isset($_REQUEST['adj'][$j][$i]));
    	}
    
    	calc_best($plots);
    	$subtemp = 'show_best';
    }
    else
    {
    	$subtemp = 'start';
    }
    
    echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml"><head> 
    	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    	<title>Spore Colony Populator</title>
    </head>
    <body>
    <div style="float: right;"><h3>Connection Reference Image</h3><img src="spore.png" alt="" /></div>
    <h1>Colony Best Fit</h1>
    ';
    
    call_user_func($subtemp);
    
    echo '
    </body>
    </html>';
    
    function start()
    {
    	global $adj, $minhappy, $minpop, $minprod;
    
    	echo '
    <h2>Adjacent Connections</h2>
    <form action="', $_SERVER['PHP_SELF'], '?find" method="post">
    <table>
    	<tr>
    		<th>&nbsp;</th>';
    
    	for ($i = 0; $i <= 11; $i++)
    		echo '
    		<th>', $i, '</th>';
    
    	echo '
    	</tr>';
    
    	for ($i = 0; $i <= 11; $i++)
    	{
    		echo '
    	<tr>
    		<td>', $i, '</td>';
    
    		for($j=0; $j <= 11; $j++)
    		{
    			echo '
    		<td>';
    			if ($j <= $i)
    				echo '
    			&nbsp;';
    			else
    			{
    				echo '
    			<input type="checkbox" name="adj[', $i, '][', $j, ']" value="1" ', !empty($adj[$i]) && !empty($adj[$i][$j]) ? ' checked="checked"' : '', ' />';
    			}
    
    			echo '
    		</td>';
    		}
    
    		echo '
    	</tr>';
    	}
    
    	echo '
    </table>
    
    Min Happiness: <input type="text" size="3" maxlength="2" name="minhappy" value="', isset($minhappy) ? $minhappy : 2, '" /><br />
    Min Production: <input type="text" size="3" maxlength="2" name="minprod" value="', isset($minprod) ? $minprod : 0, '" /><br />
    Min Population: <input type="text" size="3" maxlength="2" name="minpop" value="', isset($minpop) ? $minpop : 0, '" /><br />
    <input type="submit" value="Find best fit" />
    </form>';
    }
    
    function show_best()
    {
    	global $best, $types;
    	echo 'Best plot has a score of ', $best['score']['h'], ' happiness, ', $best['score']['m'], ' production, and ', $best['score']['p'], ' population and is in the configuration of: 
    	<table>
    		<tr>
    			<th>Plot</th>
    			<th>Type</th>
    		</tr>';
    
    	foreach($best['plots'] AS $plot => $type)
    	{
    		echo '
    		<tr>
    			<td>', $plot, '</td>
    			<td>', $types[$type], '</td>
    		</tr>';
    	}
    
    	echo '
    	</table>
    	<h1>Again</h1>';
    
    	start();
    }
    function calc_best($plots, $depth=1)
    {
    	global $best, $types, $minhappy, $minpop, $minprod;
    
    	if ($depth > 11)
    	{
    		$score = score($plots);
    
    		if ($score['h'] < $minhappy || $score['p'] < $minpop || $score['m'] < $minprod)
    			return;
    
    		if ($score['m'] > $best['score']['m'])
    			$best = array(
    				'score' => $score,
    				'plots' => $plots,
    			);
    
    		return;
    	}
    
    	foreach($types AS $type => $dummy)
    	{
    		if ($type == 'c' || $type == 'u')
    			continue;
    
    		$plots[$depth] = $type;
    		calc_best($plots, $depth+1);
    	}
    }
    
    function score($plots)
    {
    	global $adj;
    
    	$score = array(
    		'h' => 0, // Happiness
    		'm' => 0, // Money
    		'p' => 0, // Population
    	);
    
    	// Ok calc values for the building themselves.
    	foreach($plots AS $plot => $type)
    	{
    		switch($type)
    		{
    			case 'f':
    //				$score['m']++;
    				$score['h']--;
    				break;
    			case 'e':
    				$score['h']++;
    				break;
    
    			case 'h':
    			case 'c':
    				$score['p']++;
    				break;
    
    			case 'u':
    				break;
    		}
    	}
    
    	for($i=0; $i<=11; $i++)
    	{
    		for($j=$i+1; $j <= 11; $j++)
    		{
    			if (!$adj[$i][$j])
    				continue;
    
    			$s = connection_score($plots[$i], $plots[$j]);
    
    //			echo $i, ' (', $plots[$i], ')
    			$score['h'] += $s['h'];
    			$score['m'] += $s['m'];
    		}
    	}
    
    	return $score;
    }
    
    function connection_score($t1, $t2, $verbose = false)
    {
    	$val = array(
    		'h' => 0,
    		'm' => 0,
    	);
    
    	if ($t1 == 'u' || $t2 == 'u')
    		return $val;
    
    	// Center connected with something
    	if ($t1 == 'c' || $t2 == 'c')
    	{
    		switch($t1 == 'c' ? $t2 : $t1)
    		{
    			case 'f':
    				$val['m']++;
    				break;
    			case 'e':
    				$val['h']++;
    				break;
    		}
    	}
    	// House connected to something
    	elseif($t1 == 'h' || $t2 == 'h')
    	{
    		switch($t1 == 'h' ? $t2 : $t1)
    		{
    			case 'f':
    				$val['m']++;
    				break;
    			case 'e':
    				$val['h']++;
    				break;
    		}
    	}
    	elseif ($t1 == $t2)
    		; // f-f and e-e both don't change anything
    	// All that leaves is factory-entertainment
    	else
    		$val['h']--;
    
    	return $val;
    }
    The reference image is
    http://www.geekoverloaded.com/spore.png

    If you just want to run the script you can at http://www.geekoverloaded.com/spore.php

    For a min happiness of 2 the result is:
    Plot Type
    0 City Hall
    1 House
    2 Factory
    3 House
    4 Factory
    5 Factory
    6 Enterainment
    7 House
    8 House
    9 Factory
    10 House
    11 Enterainment

  5. #35
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Oh I see, you wrote a script to calculate the best configuration. I had thought of doing this is C++, i just hadn't gotten around to it. My approach was also going to be brute force. Since there are 11 slots, which can each contain 3 types of buildings and generate 17 interconnections bepending on the two buildings the connection connects.

    Since there is a racial bonus that can boost the output of your colonies, I will calculate merely the number of blue 'spice' connections, green happy connections, and white nothing connections.

    Prior to running this my current plan produces 11 spice symbols, 5 happy faces and 5 sad faces for a neutral happiness with 4 white connections. The configuration is shown below.

    I assigned each position a number from 0 to 10, with position 0 being the one that has only a single connection and moving clockwise around the town hall. I attached a picture of the config I am using now. When i finish the program ill post the source.
    Last edited by abachler; 09-23-2008 at 02:50 AM.

  6. #36
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Here is the numbering (1 - 11) subtract 1 for the index into the array obviously

  7. #37
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    It turns out that there are 42 configurations that produce 11 spice symbols, 4 of which also produce 2 Happy faces, the rest produce zero happy faces or fewer. I specifically excluded configurations that produce sad faces, although you can get up to 15 spice symbols with 6 sad faces.

    Code:
    // Spore Spice Optimizer.cpp : Defines the entry point for the console application.
    //
     
    #include <windows.h> // for the variable types I prefer
    #include <stdio.h>
     
    BYTE Building[12];
    BYTE Link_A[] = { 1 , 2 , 3 , 0 , 4 , 5 , 5 , 6 , 0 , 7 , 8 , 0 , 9 , 10 , 10 , 0 , 11 , 0 };
    BYTE Link_B[] = { 2 , 3 , 4 , 4 , 5 , 6 , 7 , 7 , 6 , 8 , 9 , 9 , 10 , 8 , 11 , 11 , 2 , 2 };
     
    int SpiceCount(BYTE* pBuilding , int* TotalHappy);
    int IsHappy(BYTE A , BYTE B);
    int IsProductive(BYTE A, BYTE B);
     
    int main(int argc, char* argv[]){
        Building[0] = 0;  // Building zero is the town hall it is always considered a 'housing' unit
        int temp = 0;
        int TotalHappy = 0;
        int CurrentBest = 0;
        for(int x = 0;x<177147;x++){
            temp = x;
            for(int z = 1;z<12;z++){
                Building[z] = temp % 3;
                temp = temp / 3;
                }
     
            temp = SpiceCount(Building , &TotalHappy);
            if(temp >= CurrentBest){
                if(TotalHappy >= 0){
                    CurrentBest = temp;
                    printf("%d , %d Output %d Happy\n" , x , temp , TotalHappy);
                    }
                }
            }
        return 0;
        }
     
    int SpiceCount(BYTE* pBuilding , int* TotalHappy){
        *TotalHappy = 0;
        int Production = 0;
        // calculate the happiness from the buildings themselves
        for(int x = 0;x<12;x++){
            if(pBuilding[x] == 1) *TotalHappy += 1;
            if(pBuilding[x] == 2) *TotalHappy -= 1;
            }
        // Calculate the Happiness and Production from the links
        for(int x = 0;x<18;x++){
            *TotalHappy += IsHappy(pBuilding[Link_A[x]] , pBuilding[Link_B[x]]);
            Production += IsProductive(pBuilding[Link_A[x]] , pBuilding[Link_B[x]]);
            }
        return Production;
        }
     
    int IsHappy(BYTE A , BYTE B){
        BYTE C = (A << 2) + B;
        switch(C){
            case 1:
            case 4:
                return 1;
            case 6:
            case 9:
                return -1;
            default:
                return 0;
            }
        return 0; // should never reach this spot
        }
     
    int IsProductive(BYTE A , BYTE B){
        BYTE C = (A << 2) + B;
        switch(C){
            case 2:
            case 8:
                return 1;
            default:
                return 0;
            }
        return 0; // should never reach this spot
        }

  8. #38
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    C'mon abachler,

    #include <windows.h> // for the variable types I prefer
    And what's so wrong with unsigned char?
    Or, if you insist, on "typedef unsigned char BYTE"?

    #include <stdio.h>
    Fine. Lets just throw away C++ stupid language rules...

    return 0; // should never reach this spot
    Can you say it can't ever reach that spot? So what on earth are you thinking?
    Last edited by Mario F.; 09-23-2008 at 04:52 AM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #39
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    So, as my new configuration I use configuration 28248, which is shown here. I will probably change to a more productive configuration once I acquire the happy generators.

  10. #40
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    That is the same configuration I gave above. Glad to see some confirmation in the final layout.

    One of the reasons I wrote it in PHP instead is so that I could easily change the min requirements and the connection information. That helped when I started a new creature and got to the civ stage as the civ stage has at least 2 different city configurations. One with 11 and one with fewer.

  11. #41
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    All you have to do is change the index arrays Link_A[] and Link_B[] to reflect the other set fo links, then change the 12 and 18 to however many buildings and links there are. In fact Ill modify it so there are #DEFINE's to easily change the numbers where they matter.

    Code:
    // Spore Spice Optimizer.cpp : Defines the entry point for the console application.
    //
    #include <windows.h> // for the variable types I prefer
    #include <stdio.h>
    
    #define BUILDINGS   12 // this includes building 0, the town hall
    #define LINKS       18 // the number of interlinks between the nodes
    
    BYTE Building[BUILDINGS];
    BYTE Link_A[] = { 1 , 2 , 3 , 0 , 4 , 5 , 5 , 6 , 0 , 7 , 8 , 0 , 9 , 10 , 10 , 0 , 11 , 0 };
    BYTE Link_B[] = { 2 , 3 , 4 , 4 , 5 , 6 , 7 , 7 , 6 , 8 , 9 , 9 , 10 , 8 , 11 , 11 , 2 , 2 };
    DWORD Cost[] = { 25600 , 12800 , 19200 };
    int SpiceCount(BYTE* pBuilding , int* TotalHappy);
    int IsHappy(BYTE A , BYTE B);
    int IsProductive(BYTE A, BYTE B);
    
    
    int main(int argc, char* argv[]){
    
        Building[0] = 0;  // Building zero is the town hall it is always considered a 'housing' unit
        int temp = 0;
        int TotalHappy = 0;
        DWORD TotalCost;
        int CurrentBest = 0;
        __int64 Combos = 1;
    
        //  this performs the pow() function, only on integers
        for(int x = 0;x<(BUILDINGS-1);x++){
            Combos *= 3;
            }
    
        for(int x = 0;x<Combos;x++){
            temp = x;
            TotalCost = 0;
            for(int z = 1;z<BUILDINGS;z++){
                Building[z] = temp &#37; 3;
                TotalCost += Cost[Building[z]];
                temp = temp / 3;
                }
    
            
            temp = SpiceCount(Building , &TotalHappy);
            if(temp >= CurrentBest){
                if(TotalHappy >= 0){
                    CurrentBest = temp;
                    printf("%d , %d Output %d Happy %d Total Cost\n" , x , temp , TotalHappy , TotalCost);
                    }
                }
            }
    
        return 0;
        }
    
    int SpiceCount(BYTE* pBuilding , int* TotalHappy){
        *TotalHappy = 0;
        int Production = 0;
    
        // calculate the happiness from the buildings themselves
        for(int x = 0;x<BUILDINGS;x++){
            if(pBuilding[x] == 1) *TotalHappy += 1;
            if(pBuilding[x] == 2) *TotalHappy -= 1;
            }
    
        // Calculate the Happiness and Production from the links
        for(int x = 0;x<LINKS;x++){
            *TotalHappy += IsHappy(pBuilding[Link_A[x]] , pBuilding[Link_B[x]]);
            Production += IsProductive(pBuilding[Link_A[x]] , pBuilding[Link_B[x]]);
            }
    
        return Production;
        }
    
    int IsHappy(BYTE A , BYTE B){
        BYTE C = (A << 2) + B;
        switch(C){
            case 1:
            case 4:
                return 1;
            case 6:
            case 9:
                return -1;
            default:
                return 0;
            }
        return 0; // should never reach this spot
        }
    
    int IsProductive(BYTE A , BYTE B){
        BYTE C = (A << 2) + B;
        switch(C){
            case 2:
            case 8:
                return 1;
            default:
                return 0;
            }
        return 0; // should never reach this spot
        }
    Last edited by abachler; 09-23-2008 at 01:36 PM.

  12. #42
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    There also seems ot be a difference between teh configurations on yoru home plaet based on what the city type was at the end of the civ phase. I havent explored the exact results, but it appears that military cities actually have more links, and thus may provide greater . Although Ive counted at least 6 unique layouts so far. The layouts of the home planet cities may be proceedurally generated, although there were a few duplicates. I have attached the 6 I fodun so far.
    Last edited by abachler; 09-23-2008 at 02:25 PM.

  13. #43
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Where does your script output the configuration?

    Hmm when I get home I'll take a look as I have one that was agressive throughout.

    I compared diplomat vs another one (can't remember but it was Green, red, red, blue (iirc)) and got the same city layout.

  14. #44
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    and the 6th is

  15. #45
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Quote Originally Posted by Thantos View Post
    Where does your script output the configuration?

    Hmm when I get home I'll take a look as I have one that was agressive throughout.

    I compared diplomat vs another one (can't remember but it was Green, red, red, blue (iirc)) and got the same city layout.
    ah, I will put that in now, I was just manually decoding the sequence number. The layouts are the same on all your colonies regardless of any othe rfactor, but the cities on your Home Planet are different based on unknown factors. The home plant only generates red spice, but it cheaper to configure than the colonies so if you have the cash you might as well boost its output.
    Last edited by abachler; 09-23-2008 at 02:30 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Advancing Days
    By nhubred in forum C++ Programming
    Replies: 0
    Last Post: 06-01-2009, 06:22 PM
  2. Plz help me C programm
    By ferroz1 in forum C Programming
    Replies: 7
    Last Post: 05-10-2008, 06:55 AM
  3. Algorithm help
    By mmyers1 in forum C++ Programming
    Replies: 7
    Last Post: 04-05-2004, 09:56 PM
  4. Counting Number of days from year zero
    By wireless in forum C++ Programming
    Replies: 4
    Last Post: 06-16-2002, 07:31 AM
  5. while, sentinel, if, switch
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 11-11-2001, 11:50 PM