scramble

a 3x3x3 Rubik's Cube scramble generator
git clone git://nihaljere.xyz/scramble
Log | Files | Refs | README | LICENSE

commit 494938cbb26671847308977bd20e7694cd313607
Author: Nihal Jere <noocsharp@gmail.com>
Date:   Wed, 29 Jan 2020 22:48:19 -0600

initial commit

Diffstat:
A.gitignore | 1+
AMakefile | 16++++++++++++++++
AREADME | 5+++++
Amain.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 109 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +scramble diff --git a/Makefile b/Makefile @@ -0,0 +1,16 @@ +PREFIX = /usr/local +CC = cc + +all: + ${CC} main.c -o scramble + +clean: + rm -f scramble + +install: all + mkdir -p ${PREFIX}/bin + cp -f scramble ${PREFIX}/bin + chmod 755 ${PREFIX}/bin/scramble + +uninstall: + rm -f ${PREFIX}/bin/scramble diff --git a/README b/README @@ -0,0 +1,5 @@ +# Scramble + +A very simple CLI 3x3 Rubik's cube scrambler - because the only other one I could find was written in Javascript. + +This one just checks for typographical repetitions rather than checking if the same state appeared previously in the scramble. I might add it later though. diff --git a/main.c b/main.c @@ -0,0 +1,87 @@ +#include <stdlib.h> +#include <time.h> +#include <stdio.h> +#include <stdint.h> +#include <sys/random.h> + +#define DEFAULT_LENGTH 25 + +static const char* pmoves[3][6] = { {"U", "D", "L", "R", "F", "B"}, {"U'", "D'", "L'", "R'", "F'", "B'"}, {"U2", "D2", "L2", "R2", "F2", "B2"} }; + +const char help[] = "usage: scramble [LENGTH]"; + +static char const** typo_scramble(uint8_t length) { + char const** moves = calloc(length, sizeof(char*)); + + if (moves == NULL) return NULL; + + uint8_t last_side = 0; + + uint8_t counter = 0; + // TODO deal with RAND_MAX + while (counter < length) { + uint8_t rval = (uint8_t) rand(); + // 3 possible values for set, so 2 bits + uint8_t set = rval & 3; + // 6 possible values for side, so 3 bits + uint8_t side = (rval >> 2) & 7; + + // prevent biasing of results that would occur if + // we just took the modulus of the values + if (set == 3 || side > 5) continue; + + // if the side is the same as before, choose another side + if (counter != 0 && side == last_side) continue; + + moves[counter++] = pmoves[set][side]; + last_side = side; + } + + return moves; +} + +int main(int argc, char** argv) { + uint8_t length = DEFAULT_LENGTH; + + if (argc > 2) { + printf("%s: Too many arguments", argv[0]); + } else if (argc == 2) { + if (argv[1] == "-h" || argv[1] == "--help") { + printf("%s\n", help); + return 0; + } + + char* endptr = NULL; + long int newlength = strtol(argv[1], &endptr, 10); + + if (*endptr != '\0') { + printf("%s: invalid length\n", argv[0]); + return -1; + } + + if (0 > newlength || newlength > 255) { + printf("%s: invalid length, max of 255\n", argv[0]); + return -2; + } + + length = newlength; + } + + uint32_t seed = 0; + getrandom((void*) &seed, 4, GRND_NONBLOCK); + srand(seed); + + const char** moves; + + + if ((moves = typo_scramble(length)) != NULL) { + for (uint8_t i = 0; i < length; ++i) { + printf("%s ", moves[i]); + } + printf("\n"); + free(moves); + } + + return 0; + +}