## How to calculate how effective a Riffle is

In my previous post I mentioned about writing a program to determine how effective a riffle shuffle was. So here’s the code.

### How it works

I’m using an array of 52 chars to hold the deck. I’m only interested in the card’s position in the deck so each card is initialised with a value in the range 0-51. I’m using three other similar sized arrays.

• tempCards are used purely for doing the riffle.
• distances are used to calculate the maximum distance the card moved
• startPos tracks the cards starting position 0-51 before doing lots of rounds of riffles.

The program starts by picking up ( as a parameter) how many rounds you want it to run. It defaults to 10 if no value is input.

It then clears distances and inits cards. In each round, it starts by storing card positions in startPos. It then does seven riffles and works out how far a card has moved. If it has moved more than before (in distances) it stores it in distances.

DoRiffle works by indexing through the two 1/2 deck piles taking a card from each and a 50:50 random chance determines which of the two cards goes into the shuffled deck first and then second.

Here’s the listing.

``````// riffle.c by D. Bolton (C) 2020 Learncgames.com - TYou are free to redistribute but please keep this line in

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// #defines
#define MAXROUNDS 10
#define NUMRIFFLES 7
#define NUMCARDS 52

// variables
int NumRounds;
char cards[NUMCARDS],tempCards[NUMCARDS],startPos[NUMCARDS];
int distances[NUMCARDS];
time_t t;

// functions

// Convert string to int calling strtol
int GetIntArg(char* str) {
char* ptr;
return strtol(str, &ptr, 10);
}

// Merges two cards a and b. 50:50 chance that a above b or other way
void DoRiffle() {
// Copy cards into tempCards
memcpy(tempCards, cards, sizeof(cards));
// Merge each pair of cards tempCards[i] and TempCards[i+26]
int cardIndex = 0;
for (int i = 0; i < NUMCARDS / 2; i++) {
if (rand() % 2) {
cards[cardIndex++] = tempCards[i];
cards[cardIndex++] = tempCards[i + 26];

}
else {
cards[cardIndex++] = tempCards[i + 26];
cards[cardIndex++] = tempCards[i];
}
}
}

// Works out how far cards have moved, added to distances
void CalculateDistances() {
for (int i = 0; i < NUMCARDS; i++) {
int moved = abs(cards[i] - startPos[i]);
if (moved > distances[i])
distances[i] = moved;
}
}

void DoShuffles() {
// Clear distances and init cards
for (char i = 0; i < NUMCARDS; i++) {
distances[i] = 0;
cards[i] = i;
}
// do Numrounds  rounds
for (int round =0;round<NumRounds;round++){
// Mark where the card starts
for (char i = 0; i < NUMCARDS; i++) {
startPos[i] = cards[i];
}
// Do seven riffles
for (int i = 0; i < NUMRIFFLES; i++) {
DoRiffle();
}
CalculateDistances();
}
int furthest = 0;
for (int i = 0; i < NUMCARDS; i++) {
printf("Distance[%d]=%d\n", i, distances[i]);
if (distances[i]> furthest) {
furthest = distances[i];
}
}
printf("furthest moved is %d\n", furthest);
}

int main(int argc, char* argv[]) {
srand((unsigned)time(&t));
if (argc ==1 || argc== 2) {
NumRounds = MAXROUNDS;
if (argc == 2) {
NumRounds = GetIntArg(argv[1]);
printf("Numrounds = %d\n", NumRounds);
}
DoShuffles();
}
else {
printf("Please supply 0 or 1 arguments e.g. riffle 60\n");
}
}``````

Even with ten rounds I’ve seen cards move 51 positions. With 5,000 rounds all cards but one moved by 51 and one by 50.

## John Conways Game of Life

An English mathematician John Conway (who died not that long ago) came up with a very simple cellular automaton that he called Life. This was back in the 1970s and I remember finding his original article in Scientific American while at University.

We had no internet then and I whiled away 10 or so hours trying to make my version of Life run faster. Given that this was 1978 and it was written in BASIC, it’s not surprising that it only did a couple of generations per second on a mainframe. They didn’t give us much CPU time and it was an ICL 1900. My iPhone is probably more powerful!

The rules are simple enough to implement but it’s unlikely you’ll outperform Golly which is what the image shows. That’s written in C++ and has been under near continuous development for the last 15 years.

But part of the fun is writing your own life simulator and watching the patterns explode. I’d call it the minecraft of its day given the amount of computing time spent on this since the 1970s. There are some amazing creations all following these three simple rules.

• Any live cell with two or three live neighbours survives.
• Any dead cell with three live neighbours becomes a live cell.
• All other live cells die in the next generation. Similarly, all other dead cells stay dead.

The grid is just a simple bit field. Each cell is either on or off and the rules determine if new cells are created or if patterns die out.

There are innumerable ones on the web. Here for example is a C/SDL version. Note, it uses SDL1. When I get the time, I’ll build and run it. Comments are in French!