A week off

I’m taking seven days off. Given that I’ve just published 391 blogs including tutorials over the last 391 days, I think I deserve a short break… Back soon…
Learn C Games Programming Blog
A blog about C, programming games and my ebook(s).
I’m taking seven days off. Given that I’ve just published 391 blogs including tutorials over the last 391 days, I think I deserve a short break… Back soon…
In my previous post I mentioned about writing a program to determine how effective a riffle shuffle was. So here’s the code.
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.
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.
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.
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!