Everyday I’m shufflin’

Some of the people I’m play-testing against are starting to get good at this game. Proper development of supported attackers and blockading areas of the board to frustrate constructing a counter attack. The current problem is the starting ranks.

Rocks on the back row are initially pinned down, they simply can’t do anything. Papers are easy to bring out, but they can’t attack opposing rocks until there is a break in the line of scissors. The fastest and most obvious strategy is to bring scissors forward first and attack the opposing line of paper. Moving them forward also means the front rank of paper is protected by the back rank of rocks. Then it devolves into attrition. Not the most fun after a few games.

To avoid this, we’re going to mix things up a little bit. Literally. By laying out the starting pieces randomly, every game will likely make it easy to develop all types of pieces and it will leave a few well defended at the back.

Lets take a look at the current set-up code from the activity class.

//RPSChess.java
private void layoutBoard() {

		b.addPiece(R.drawable.blackrock, 0, 0);
		b.addPiece(R.drawable.blackrock, 1, 0);
		b.addPiece(R.drawable.blackrock, 2, 0);
		b.addPiece(R.drawable.blackrock, 3, 0);
 [SNIP: cut to avoid extreme tedium]
		b.addPiece(R.drawable.whitepaper, 6, 5);
		b.addPiece(R.drawable.whitepaper, 7, 5);
	}

While I’m an advocate of dumb code, 48 lines of the same line repeated with tiny differences is boring to review, and you can’t see at a glance that you’ve missed a piece on square 6,3. Lets replace that with something much shorter, hopefully clearer, and more flexible.

We will create an array for the pieces of each side and populate it randomly using a variant of the Fisher-Yates shuffle, then copy those arrays to the board using the addPiece() function on the board class.

 //RPSChess.java
private void randomSetup() {
	int[] whiteTypes = {R.drawable.whiterock
			, R.drawable.whitescissors
			, R.drawable.whitepaper}; 
	int[] blackTypes = {R.drawable.blackrock
			, R.drawable.blackscissors
			, R.drawable.blackpaper};
	int[] whitePieces = new int[24];
	int[] blackPieces = new int[24];
	//Shuffle the pieces
	for (int i = 0 ; i < whitePieces.length; i++) {
		shuffle(whitePieces, whiteTypes, i); 
	}
	for (int i = 0 ; i < blackPieces.length; i++) {
		shuffle(blackPieces, blackTypes, i);
	} 
	//place white pieces 
	placePieces(whitePieces, 5); 
	//place black pieces
	placePieces(blackPieces, 0);  
}

Shuffle() does most of the heavy lifting here, initialising and randomising the Pieces[] arrays at the same time.

//RPSChess.java
private void shuffle(int[] pieces, int[] types, int index) {
	//Fisher-Yates Shuffle
	if (index == 0) {
		pieces[0] = types[0]; 
	} else {
		Random r = new Random();
		int j = r.nextInt(index);
		pieces[index] = pieces[j];
		pieces[j] = types[(int)index/8];
	}
}

By using a types[] array, the line “pieces[j] = types[(int)index/8];” ensures that even though we are randomly arranging the array at the same time as populating it, we still get the same number of each piece.

Finally we place the shuffled arrays onto the game board.

//RPSChess.java
private void placePieces(int[] pieces, int offset) {
	for (int i = 0; i < pieces.length; i++) {
		b.addPiece(pieces[i], i%8, offset + (int)i/8);
	} 
}

Now we can rip out that tedious block in onCreate() and replace it with a call to randomSetup() and we are done. We should also be able to use this as a basis for any other layouts we choose to permit. Another obvious set-up would be random-but-reflected so both players get the same starting positions.

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	
	getBoard();
	randomSetup();
	setupMoveHandler();
}

This is getting us into our last big hurdle: Getting a new game going can be tricky. We’ve already co-opted the back button for our purposes, so lets look at making off with the menu button next.

Shufflin'

This entry was posted in android and tagged . Bookmark the permalink.