Populares Et Optimates, A Game Of Rome Part 2

Watching card manipulation by Dan and Dave Buck including those on their site like the demo video of the Akira flourish got me thinking quite a bit about card shuffling. After seeing some of the false shuffles and other manipulations and having read about games where the shuffling algorithm was only pseudo-random, I wanted to make sure that the card shuffling for my game was at least adequate enough to make the game work.

If you’re not familiar with Dave and Dan, check out this video advertisement for their set of DVDs over at Theory 11:

Wikipedia has a good article discussing shuffling cards and computer algorithms for shuffling.

An example shuffle algorithm in Javascript would be this implementation of Durstenfeld’s algorithm, a modern version of Fisher-Yates that looks like this:

function array_shuffle (aArray)
{
    var i, j, mTemp;
    for (i = aArray.length; i;) {
        // mTemp, j initialized here for shorter code.
        j = parseInt (Math.random () * i);
        mTemp = aArray [--i];
        aArray [i] = aArray [j];
        aArray [j] = mTemp;
    }
}

For the random number generation, I prefer this, but I haven’t exercised it in order to see if it makes a difference, though seeing parseInt in the above makes me wonder about its presence.

j = 1 + Math.floor(Math.random() * i);

As for the cards in the game, they are represented in the Javascript as objects and can be either people or actions. People cards are members of one or the other faction or a third group of loosely-aligned Romans who may be swayed to one side or the other. They have attributes including the side they belong to, whether their side may be changed, their name and current rank. Action cards represent the cards that are used during play. Actions include ranks and positions that may be assigned to People and events like riots, assassinations, and plagues. Action cards often have negative or side-effects, sometimes costing the player who uses it as much as his opponent. Other cards require votes from the Senate such as Exile or the appointment of Generals.

There are a variety of collections that I’ll refer to as decks. There are two decks of people, one for each player. Event decks include one hand for each player, the drawing deck and the discard deck. Additionally, there may be individual cards in play that belong to no particular deck.

I considered a number of names for the game including Optimates et Populares, but that doesn’t roll off the tongue. The working title that I came up with is Marius and Sulla after the two men who fought together in the Social War and then became bitter enemies. The game centers around the time where partisans identified themselves less with the espoused philosophies each represented and more with the personalities themselves. The short version of the game covers the six years following the Social War (88 BC – 82 BC).

Comments Off

SPQR Or Pontifex Maximus, A Game Of Rome Part 1

I’ve decided to create a web-based game set in early Rome. It’s intended to be about the leaders of the time with an emphasis on politics rather than military strategy. I want the latter to happen “off-screen” as it were, but with the option for legions to show up at the gates of Rome when needed to influence political events.

The biggest difficulty was selecting a time period that provided the right amount of variety, particularly political in-fighting and manuevering without too much military action (such as the wars with Carthage). In that regard, the early and late periods of the Republic offered some interesting options, as did the time of the First Triumvirate and the period following the death of Caligula, to name but a few points in the turbulent history of the Romans.

I’m particularly fond of the political manueverings described in Imperium by Robert Harris and in the BBC production of I, Claudius (for which I must confess that I haven’t read the book by Robert Graves). There’s an immediacy to the politics combined with a certain degree of brutality that keeps one from longing overmuch for the good old days. So the more I thought about it, the less Imperial Rome appealed to me and the more I wanted to go back a little further in time. At the same time, Lavinia by Ursula Leguin brings the events of Virgil’s Aeneid to life brilliantly with the interplay between the tribes of the area and the followers of Aeneas.

Out of all the time periods that I think would make for an worthwhile game, the period immediately following the Social War, a crisis point in Roman history, sounded extremely interesting. Sulla’s First Civil War with the struggle between the optimates and populares (and I’m simplifying matters greatly since it wasn’t that black and white) made for some turbulent times with lots of political and military manuevering. Throw in assassinations, exiles, plagues, riots and external threats like Mithridates of Pontus, and you have a good deal of elements to work with.

As they say, plus ça change, plus c’est la même chose. The politics of the Roman Republic and the Roman Empire have much in common with the infighting during the War of the Roses and the gangland warfare of the Roaring Twenties. For that reason, I wanted to capture some of the feel of the Avalon Hill game Kingmaker, minus the board and tediousnous of moving armies around, with the fast-paced play of Family Business, but with a more historical feel and slightly more elaborate mechanics.

Before starting work, I did some research on already existing games that covered both the time period I was interested in with the politics in a card game or simple board game version. I was positive there’d be a plethora of games of all stripes, some very similar to what I had in mind. Surprisingly, the list wasn’t nearly as long as I expected, though I’m sure I missed more than a couple. My short list of games that aren’t strategy games and that otherwise capture some of the elements I was looking for are as follows:

Certainly, some of these games are ones that I’d really like to play, particularly Triumvirate. But before I do that, I’d like to get my game up and running. First up, a paper prototype. Much like website usability testing with paper mockups and wireframes, I plan to make some cards and to try some mechanics so I can see how they play out. I’ll discuss that in my next on this subject.

Comments Off

Javascript Sorting

Not too long ago, I was asked, as a theoretical question, how I might take a string of random alphabetical characters and sort them in order using Javascript. Thus, given NFARAKDMSLSJDQKJKCXLK, find a simple way to turn it into AACDDFJJKKKKLLMNQRSSX. It’s a pretty basic question for anyone who uses Javascript and I immediately thought of splitting and joining the string as an array (a quick and easy way to tokenize the string). However, for some reason, I completely forgot about the Array.sort() function that’s pretty much a universal across languages.

Instead, the first thing that came to mind was the last time I had to sort a collection and started thinking of Java sorting. In the work I’ve done, such sorting usually requires the use of comparators because the default sort order is often not the one that’s desired. As a case in point, we have a set of JSP pages for rendering content including archive and list pages that display in posting date or sequence order derived from the content. For example, here’s some code to sort by a custom “sequence” attribute using the Vignette Content Management API (this particular snippet is the work of the inimitable Yong Chen):

Comparator aComparator = new Comparator(){
	public int compare(Object obj1, Object obj2) {
		int result=0;
		try {
			Integer s1 = (Integer) ((ContentInstance) obj1).getRelations(CT_RELATION_HEALTH_PLAN)[0].getAttribute("sequence").getValue();
			Integer s2 = (Integer) ((ContentInstance) obj2).getRelations(CT_RELATION_HEALTH_PLAN)[0].getAttribute("sequence").getValue();
			result=s1.compareTo(s2);
		} catch (com.vignette.as.client.exception.ApplicationException e) {
		}
		return result;
	}
};

For debugging, I might break it out a little differently to avoid the multiple casts in a single line. I think the Vignette API is fairly robust, but I would still split the ContentInstance cast apart from the Java native Integer cast in this case. But that might just be me.

In any event, while Javascript can also use comparators without much loss of speed, for a task like the one delineated initially, a simple sort will do the job and the whole can even be condensed to a single line function like this:

function order(unsortedString) {
	return unsortedString.split("").sort().join("");
}

Depending on the browser, the sort function will be some variation on a quick sort or a merge sort. It depends on whether the browser architects chose a stable algorithm or opted for some other version based on various considerations. Mozilla used to use a quicksort prior to Firefox 3.5, but they opted for a merge sort instead in more recent versions. In the course of reading about sort implementations, I came across notes on timsort, Python’s default sort implementation, that I found particularly intriguing.

As an aside the return value for a comparator that works in Firefox may fail with Webkit (Chrome and Safari) since you need to return -1 instead of zero (and a boolean false will also fail). You can read more about Webkit’s Array.sort() handling.

With Java, it looks like this:

String unsorted = "xzya";
char[] content = unsorted.toCharArray();
java.util.Arrays.sort(content);
String sorted = new String(content);

With Perl, you can do something like:

print (join “”, sort split //,$_)

In bash, this will do the same job:

echo “teststring” | grep -o . | sort -n |tr -d ‘\n’; echo

All in all, not only did I refresh my memory about good ways to sort strings and arrays in Javascript, I also learned some new things about sort algorithms and implementations of those algorithms.

Comments Off

A Breadcrumb Story

Where I work, one of the site features is a breadcrumb trail on all pages allowing linking through the content hierarchy. All of the breadcrumbs in the breadcrumb trail was generated using a rather lengthy Javascript file. The main reason for the length was due how the folders were named and the number of exceptions or special cases. As a note, for this to work all directory names were CamelCase (lowerCamelCase, to be precise) except where they were legacy items or inconsistently named (increasing the number of special cases that needed handling).

But it worked better than much breadcrumb code I’ve seen, so all was well and good until two things happened. The first was that mysterious 404 errors began to crop up in our logs. I finally traced them back to bots crawling the site, coming across the pieces of the Javascript that constructed the links in the breadcrumbs and indexing them as valid (not processed) links. So our logs were littered with failures to find pages like about_gh/.*/badministrator/b.*)/i, or /health_plans/+howmany[i+2]+. The second thing that occurred was we began developing a new version of one of our sites and it didn’t make sense to use the existing Javascript since the majority of it’s special cases were for our main site. Further, we would just be perpetuating the log errors caused by misbehaving seach engine bots.

So, for the new site, I rewrote the Javascript as a JHTML include. Since we’re using Dynamo and haven’t migrated any of our dynamic pages to be JSP pages (and encountered some problems with that due to the older version we’re running on), I learned some interesting things about using Java inline on a single page like this.

The first part of the page requires declaring any imports, like so:

<java type="import">
	java.util.regex.*;
</java>

The second part of the page is the main Java code that gets the URL and performs some operations on it:

<java>
	String originalURL = request.getRequestURL().toString();
 
	if (originalURL.indexOf("somejavaAppPathID") != -1) {
		if (originalURL.indexOf("javaApp") != -1) {
			breadcrumbPathString += divider + "<a href=\"/somespecialidentifierParent/index.jhtml\">JavaAppParent</a>" + divider + "<a href=\"/somejavaAppPathID/javaApp/JavaAppMethod?forwardUrl_success=/someAppResultLocation/javaApp/index.jhtml\">JavaApp</a>";
		}
	} else if (originalURL.indexOf("pageNameWithParam.jhtml") != -1) {
			//itemKey is the parameter that has the path to the content
			String paramKey = "paramname";
			breadcrumbPathString = makeTrail(request.getParameter( paramKey ), baseLoc, divider);
	} else {
		breadcrumbPathString = makeTrail(request.getRequestURI(), baseLoc, divider);
	}
 
	breadcrumbPathString = fixDirectories(breadcrumbPathString);
 
	out.print(breadcrumbPathString);
</java>

Originally, my thought was to use the Request Scheme like this:

String thisRequestScheme = request.getScheme();
if (thisRequestScheme.startsWith("https") == true) {
	baseLoc ="https://"+ request.getServerName() ;
} else{
	baseLoc ="http://"+ request.getServerName() ;
}
if (request.getServerPort() != 0) {
	baseLoc += ":"+request.getServerPort();
}

But since our server configuration includes F5 load balancers, that was incorrect and the request object contains different information than the URL we’re looking for. I’d prefer to use this implementation, but the previous one starting with request.getRequestURL() will work.

Lastly, I created some methods for handling special cases and doing some other work on the URLs:

<java type="class">
	public String makeTrail(String breadCrumb, String urlPath, String thisDivider) throws IOException {
		urlPath += "/";
		String outputString =  "<a href=\""+urlPath+"index.jhtml\">Home</a>";
		String linkName = "";
		String linkString = breadCrumb;
		breadCrumb = removeDirectories(breadCrumb);
		if (breadCrumb != null) {
			String[] breadCrumbArr = breadCrumb.split("/");
			String[] linkStringArr = linkString.split("/");
			if(breadCrumbArr.length!=0) {
				for(int i=1; i<linkStringArr.length-1; i++) {
					urlPath += linkStringArr[i]+"/";
					if (breadCrumbArr[i] != null && breadCrumbArr[i].length() > 0) {
						linkName = makeProper(breadCrumbArr[i]);
						outputString +=  thisDivider+"<a href=\""+urlPath+"index.jhtml\">"+linkName+"</a>" ;
					}
				}
			}
		}
		return outputString;
	}
 
	public String makeProper(String theString) throws IOException {
		StringReader in = new StringReader(theString);
		boolean precededBySpace = true;
		boolean precededByCap = true;
		StringBuffer properCase = new StringBuffer();
		while(true) {
			int i = in.read();
			if (i == -1)  break;
			char c = (char)i;
			if (Character.isSpaceChar(c)) {
				properCase.append(c);
				precededBySpace = true;
			} else if (Character.isUpperCase(c)) {
				if (precededByCap) {
					properCase.append(c);
				} else {
					properCase.append(' ');
					properCase.append(c);
				}
				precededByCap = true;
			} else if (c == '-'||c == '_') {
				properCase.append(' ');
				precededBySpace = true;
			} else {
				if (precededBySpace) {
					properCase.append(Character.toUpperCase(c));
				} else {
					properCase.append(Character.toLowerCase(c));
				}
				precededBySpace = false;
				precededByCap = false;
			}
		}
		return properCase.toString();
	}
 
	public String removeDirectories(String theString) {
		//completely remove these directories from the breadcrumbs
		theString = replaceWith(theString,"ignore/","/");
		theString = replaceWith(theString,"anotherDirectoryToSkip/","/");
		return theString;
	}
	public String fixDirectories(String theString) {
		//replace these nonsense names with real words
		//    theString.replaceWith("(?i)\\babout[ _]us\\b","About Us"); //A weird special case since the directory name is not CamelCase
		theString = replaceWith(theString,"(?i)\\bpeople\\splaces\\b","People &amp; Places");
		theString = replaceWith(theString,"(?i)\\babbr\\b","Full Unabbreviated Directory Name");
		return theString;
	}
 
	private static String replaceWith(String aPath, String aPattern, String aReplacement ){
		Pattern pattern = Pattern.compile(aPattern, Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(aPath);
		return matcher.replaceAll(aReplacement);
	}
</java>

In reviewing this code, one thing I was unsure about was whether using

String originalURL = request.getRequestURL().toString();

was the correct way to go or if I should have used

String path = request.getPathTranslated();
path = replaceBacklash(path);

I realized that, for the way the site functions, we may pass an item parameter and we want to properly build the path to that item, not the page rendering the item. Using getRequestURL handles both situations.

Comments Off

Hashtables and form labels with jQuery forms

Javascript implements hash tables in a limited and somewhat unwieldy fashion as associative arrays. The jQuery.field plugin has some useful functions including a formHash() function that returns all the elements of the form with the field ids as the hash keys and the form values as the hash values corresponding to those keys.

Some people consider treating associative arrays as hash tables as being downright bad since they appear to have all the characteristics one would expect, but in fact, do not. For example, the way one iterates over the array and the ability to determine the size of the array (array.length).

This custom implementation solves those problems rather handily (and there’s an implentation in the comments with the Ajaxian post linked in the previous paragraph). I believe this is what people refer to when they recommend using objects rather than simple associative arrays (since arrays are, themselves, objects in Javascript).

For the purposes of the work I was doing, where it’s not intended for production and where performance (or scalability) is not a consideration, but rapid prototyping and the ability to easily correlate form fields with labels, this implementation seems to work just fine:

jQuery.fn.labelList = function(){
	var strValueList = [];
	var label = $(this).find("label");
	label.each( function (index) {
		var id = $(this).attr('for') || 'undefined';
		if (id) {
				labelText = $(this).text();
				if (labelText.substr(0,1)=="*") { labelText = labelText.substring(1, labelText.length); }
				if (labelText.substr(labelText.length-1,1) == ":") { labelText= labelText.substring(0, labelText.length-1); }
				strValueList[id] = labelText;
		}
	});
	return( strValueList );
}

Which is then used in a function something like the following which is called using:

$("#yourFormID").collectResults();
 
jQuery.fn.collectResults = function(){
	var currentForm = "";
	var myResults=$(this).formHash();
	var myLabelresults=$(this).labelList();
 
	currentForm += "
<ul>";
	$.each(myResults, function(i,item) {
		itemName = myLabelresults[i];
		if(itemName != undefined &amp;&amp; itemName != "") {
			currentForm += "
	<li>"+ itemName + ": " + item + "</li>
\n";
		}
	} );
	currentForm += "</ul>
";
	$("#outputContainerID").append(currentForm);
}

Comments Off

jquery Image Rotator

I had the opportunity to finally get my feet wet with jQuery recently and quite enjoyed the experience. One of the big parts of the site functionality that the designer was looking for was the ability to rotate through a potentially large number of logos, fading in and out from the set in order between three or four “image “slots” on the page.

What I came up with, building heavily on the work of Torsten Baldes and others, is nothing more than building an array of images within a container and then cycling through that collection by swapping items in a second array of image spots. This is the function that performs that work where “elements” is the array of images and “#logoimage”+slot is the id of a div from the list of divs we created based on how many images the user wants to display on the page at one time.

    $.imageslide.next = function(container, elements, settings, slot, addelement) {
 
		slot = slot + 1;
		if(slot > settings.count) {
			slot=1;
		}
		addelement = addelement + 1;
		if (addelement > elements.length-1) {
			addelement = 0;
		}
 
        if (settings.animationtype == 'slide') {
            $('#logoimage'+slot).slideUp(settings.speed, function() {
			$('#logoimage'+slot).empty();
			$('#logoimage'+slot).append($(elements[addelement]));
			});
            $('#logoimage'+slot).slideDown(settings.speed);
        } else if (settings.animationtype == 'fade') {
            $('#logoimage'+slot).fadeTo(settings.speed, 0, function() {
			$('#logoimage'+slot).empty();
			$('#logoimage'+slot).append($(elements[addelement]));
			});
            $('#logoimage'+slot).fadeTo(settings.speed, 1);
        } else {
            alert(settings + 'imageslide-animationtype must either be \'slide\' or \'fade\'');
			return false;
		}
 
        setTimeout((function() {
            $.imageslide.next(container, elements, settings, slot, addelement);
        }), settings.timeout);
    };

The script is invoked using

 		<script type="text/javascript">
			$(document).ready(
				function(){
					$('#slideImages').imageslide({animationtype: 'fade', speed: 750, timeout: 2000, count: 4 });} );
		</script>

and, in this case, addresses a container with an id of “slideImages” that contains a list of images.

You can download the script or see it in action if you’re so inclined.

Comments Off