Write Your Own Simpson

The script randomly chooses characters from the show and assigns them common sitcom roles. But, there's a catch... D'oh! For some reason Homer's name never gets chosen. Figure out why.

What we get. oooooooooffffff!!!!

# lliliiLlls

module 		lllililli;
	export 




{  global llil:
		set



		[


count




]={

0x00	,




}

					;
		type 


illlllliiili:




enum
		{




illlllliiiliii,
illlllliiiliiii,
illlllliiiliiiiiiii,
illlllliiiliiiiiiiil,




	};

  global 
illill:		table




[
string
			] 
                 	of 
 string
			=
			{
    			[
"Main"


			] 

= 

	"The majority of the episode is based on what this character does",


	[


"Comic Relief"

  ]

= 


"The major of bad fortune happens to this character through the episode",
    [
		"Build Up"
	] 		
	= 

																			"The first 1/3 of the episode is about this character and sets the stage for the last 2/3",
  }	
;

			# Oh boy, here we go!
		  	global
 llllii:
  vector 


	of 

string					=


{"Homer"
	,"Marge"
		,"Lisa"
			,"Bart"
				,"Maggie"
					,"Grandpa"
						,"Ned"
							,"Krusty"
								,"Dr. Hibbert"
									,"Moe"};

	  global
 lllli:



function(
		)	;	}

function lllililli::lllli(
	) 
{
  for (
lliliiLll 			in 
lllililli::illill

	) 
	{
    local 
i 
	 			 



				=0x0		
			    	;while 
	(
i
 				in 

lllililli::llil
	) 
{		srand

	(		double_to_count

		(		time_to_double

			(		current_time

				(


))))

;


      i 
= 
rand(
	|	
lllililli::llllii
	|
)	;
    	}
    
 add 
	
		lllililli::llil[
i

				]


;

    local        

		  iillliliiililil 


= 		lllililli::llllii[i];
    local         ililllllllllilii 

= 		lliliiLll;
    local    

		  liiiiliiiiiiiiii 

= lllililli::illill[lliliiLll]

  ;

    print 			fmt
	  (


"%s %s  %s%s   %s"




		
,    iillliliiililil   , " " 
,    ililllllllllilii  , " " , liiiiliiiiiiiiii


  )
	;
 
  }
  }

event				zeek_init
  (
  ) 	&priority


= 0x00

 {
		  lllililli::lllli




(							);

							}

What!!! Lets clean that up. Quite a bit going on with the naming of variables and modules. So lets refactor that a little.

module simpson;

export {

    global randSet: set [count] = {
        0x00,
    };

    global characterType: table [string] of string = {
        ["Main"] = "The majority of the episode is based on what this character does",
        ["Comic Relief"] = "The major of bad fortune happens to this character through the episode",
        ["Build Up"] = "The first 1/3 of the episode is about this character and sets the stage for the last 2/3",
    };

    global characterNames: vector of string = {
        "Homer",
        "Marge",
        "Lisa",
        "Bart",
        "Maggie",
        "Grandpa",
        "Ned",
        "Krusty",
        "Dr. Hibbert",
        "Moe"
    };
    
    global goRun: function();

}

function simpson::goRun() {
    for (el in simpson::characterType) {
        local i=0x0;
        while (i in simpson::randSet ) {
            srand(double_to_count(time_to_double(current_time())));
            i = rand(|simpson::characterNames|);
        }

        add simpson::randSet[i];

        local name = simpson::characterNames[i];
        local usertype = el;
        local explanation = simpson::characterType[el];

        print fmt ("%s %s %s", name, usertype, explanation);
    }
}

event zeek_init ()   &priority = 0x00 {
    simpson::goRun();
}

So why would homer never be selected. Sounds like an off by one error to me. So focusing on the select function and associated variables.

    global randSet: set [count] = {
        0x00,
    };
    
    for (el in simpson::characterType) {
        local i=0x0;
        while (i in simpson::randSet ) {
            print i, i in simpson::randSet;
            srand(double_to_count(time_to_double(current_time())));
            i = rand(|simpson::characterNames|);
        }

        add simpson::randSet[i];
        print simpson::randSet;

        local name = simpson::characterNames[i];
        local usertype = el;
        local explanation = simpson::characterType[el];

        print fmt ("%s %s %s", name, usertype, explanation);
    }

The way the logic is written it won't exit from the while loop until it has chosen a unique name from the set. The value choosen should not be in the set. However since you have an initialized that set with a 0 which corrisponds with "Homer" that value will never be returned.

My Solution

The global set of count "llil", is initialized with 0x00.
The local variable i is set to 0 initially and checks membership with that set.
Since the initial value of 0 will always be "in" the global set, a different
character name from "llllii" vector of string will always be selected.

Last updated