Page 1 of 1

Code snippet: the shuffle bag

Posted: Sat Oct 12, 2013 8:38 pm
by pixelfck
Because random is sometimes more random than is good for a consistent gameplay experience, I made a tLisp version of the shuffleBag.

Code: Select all

(setq shuffleBagAdd (lambda (theBag theEntry entryCount)
	
	; Add an entry to the shuffleBag list
	; 
	; The following arguments are required
	;   theBag:         The list of entries in the shuffleBag
	;   theEntry:      The entry to add to the list of entries
	;   entryCount:      (Optional) the number of times to add the entry to the list of entries
	;
	; We return a struct with the following elements:
	;   contents:      The list of entries in the shuffleBag
	;   cursor:         The index of where to pick next from
	
	(block (contents i)
	   (setq contents (@ theBag 'contents))
	   (if entryCount
		  (for i 1 entryCount
			 (setq contents (append contents theEntry))
			 )
		  (setq contents (append contents theEntry))
		  )
	   
	   ; return value
	   {   contents: contents
		  cursor: (subtract (count contents) 1)
		  }
	   )
	))
 
 (setq shuffleBagDraw (lambda (theBag) ; NOTE: theBag is modified by reference
	
	; Pick the 'next' entry from the shuffle bag
	; 
	; The following arguments are required
	;   theBag:      The list of entries in the shuffleBag
	;
	; We return a struct with the following elements:
	;   mixed:      The entry that was picked from the shuffleBag list
	
	(block (result contents cursor)
	   (setq contents (@ theBag 'contents))
	   (setq cursor (@ theBag 'cursor))
	   (if (ls cursor 1)
		  (block Nil
			 (setq result (@ contents 0))
			 (setq cursor (subtract (count contents) 1))
			 )
		  (block (pick)
			 (setq pick (random 0 cursor))
			 (setq result (@ contents pick))
			 (set@ contents pick (@ contents cursor))
			 (set@ contents cursor result)
			 (setq cursor (subtract cursor 1))
			 )
		  )
	   (set@ theBag {
		  contents: contents
		  cursor: cursor
		  })
	   result
	   )
	))
 
 (setq shuffleBagSeededDraw (lambda (seed theBag) ; NOTE: theBag is modified by reference
 
	; Pick the 'next' entry from the shuffle bag
	; 
	; The following arguments are required
	;   seed:      The seed to base the 'random' pick
	;   theBag:      The list of entries in the shuffleBag
	;
	; We return a struct with the following elements:
	;   mixed:      The entry that was picked from the shuffleBag list
	
	(block (result contents cursor)
	   (setq contents (@ theBag 'contents))
	   (setq cursor (@ theBag 'cursor))
	   (if (ls cursor 1)
		  (block Nil
			 (setq result (@ contents 0))
			 (setq cursor (subtract (count contents) 1))
			 )
		  (block (pick)
			 (setq pick (seededRandom seed 0 cursor))
			 (setq result (@ contents pick))
			 (set@ contents pick (@ contents cursor))
			 (set@ contents cursor result)
			 (setq cursor (subtract cursor 1))
			 )
		  )
	   (set@ theBag {
		  contents: contents
		  cursor: cursor
		  })
	   result
	   )
	))
Example of usage

Code: Select all

(block (theBag result i n)
   ; Simple usage
   (setq theBag (shuffleBagAdd Nil "X"))
   (setq theBag (shuffleBagAdd theBag "O"))
   
   (for i 0 8
      (setq result (cat result (shuffleBagDraw theBag)))
      )
   (dbgLog result)
   
   ; weighted usage
   (setq theBag (shuffleBagAdd Nil "X" 2))
   (setq theBag (shuffleBagAdd theBag "O" 4))
   
   (setq result "")
   (for i 0 12
      (setq result (cat result (shuffleBagDraw theBag)))
      )
   (dbgLog result)
   )
Enjoy,

Pixelfck

Re: Code snippet: the shuffle bag

Posted: Sat Oct 12, 2013 9:55 pm
by RPC
Sweet, can't wait to try this out in a couple of months...