Esempio n. 1
0
static int _generate_corners(uint8_t * cornersOut) {
    Perm * p = rand_perm(8);

    srand(time(NULL));

    int i;
    for (i = 0; i < 8; i++) {
        int piece = p->map[i];
        int coset = cube_perm_corner_coset(piece, i);
        int perm = rand() % 3;
        if (perm != 0) perm += 3; // perms are 0, 4, and 5
        int orientation = symmetry_operation_compose(coset, perm);
        cornersOut[i] = piece | (orientation << 4);
    }

    while (!validate_corner_orientation(cornersOut)) {
        int sym = (cornersOut[7] >> 4) & 7;
        sym = symmetry_operation_compose(sym, 4);
        cornersOut[7] &= 0xf;
        cornersOut[7] |= (sym << 4);
    }

    int parity = perm_parity(p);
    perm_free(p);
    return parity;
}
Esempio n. 2
0
static void _generate_edges(uint8_t * edgesOut, int cornerParity) {
    Perm * p = rand_perm(12);
    if (perm_parity(p) != cornerParity) {
        rand_change_parity(p);
    }
    uint16_t edgeOrientations = 0;
    int i;
    for (i = 0; i < 12; i++) {
        int piece = p->map[i];
        int s1, s2;
        cube_perm_edge_symmetries(piece, i, &s1, &s2);
        int sym = rand() % 2 == 0 ? s1 : s2;
        edgesOut[i] = piece | (sym << 4);
        if (i == 11) {
            if (!validate_edges(edgesOut)) {
                int newSym = sym == s1 ? s2 : s1;
                edgesOut[i] = piece | (newSym << 4);
            }
        }
    }

    perm_free(p);
}
Esempio n. 3
0
static char *new_game_desc(game_params *params, random_state *rs,
			   char **aux, int interactive)
{
    int gap, n, i, x;
    int x1, x2, p1, p2, parity;
    int *tiles, *used;
    char *ret;
    int retlen;

    n = params->w * params->h;

    tiles = snewn(n, int);
    used = snewn(n, int);

    for (i = 0; i < n; i++) {
        tiles[i] = -1;
        used[i] = FALSE;
    }

    gap = random_upto(rs, n);
    tiles[gap] = 0;
    used[0] = TRUE;

    /*
     * Place everything else except the last two tiles.
     */
    for (x = 0, i = n-1; i > 2; i--) {
        int k = random_upto(rs, i);
        int j;

        for (j = 0; j < n; j++)
            if (!used[j] && (k-- == 0))
                break;

        assert(j < n && !used[j]);
        used[j] = TRUE;

        while (tiles[x] >= 0)
            x++;
        assert(x < n);
        tiles[x] = j;
    }

    /*
     * Find the last two locations, and the last two pieces.
     */
    while (tiles[x] >= 0)
        x++;
    assert(x < n);
    x1 = x;
    x++;
    while (tiles[x] >= 0)
        x++;
    assert(x < n);
    x2 = x;

    for (i = 0; i < n; i++)
        if (!used[i])
            break;
    p1 = i;
    for (i = p1+1; i < n; i++)
        if (!used[i])
            break;
    p2 = i;

    /*
     * Determine the required parity of the overall permutation.
     * This is the XOR of:
     * 
     * 	- The chessboard parity ((x^y)&1) of the gap square. The
     * 	  bottom right counts as even.
     * 
     *  - The parity of n. (The target permutation is 1,...,n-1,0
     *    rather than 0,...,n-1; this is a cyclic permutation of
     *    the starting point and hence is odd iff n is even.)
     */
    parity = ((X(params, gap) - (params->w-1)) ^
	      (Y(params, gap) - (params->h-1)) ^
	      (n+1)) & 1;

    /*
     * Try the last two tiles one way round. If that fails, swap
     * them.
     */
    tiles[x1] = p1;
    tiles[x2] = p2;
    if (perm_parity(tiles, n) != parity) {
        tiles[x1] = p2;
        tiles[x2] = p1;
        assert(perm_parity(tiles, n) == parity);
    }

    /*
     * Now construct the game description, by describing the tile
     * array as a simple sequence of comma-separated integers.
     */
    ret = NULL;
    retlen = 0;
    for (i = 0; i < n; i++) {
        char buf[80];
        int k;

        k = sprintf(buf, "%d,", tiles[i]);

        ret = sresize(ret, retlen + k + 1, char);
        strcpy(ret + retlen, buf);
        retlen += k;
    }
    ret[retlen-1] = '\0';              /* delete last comma */

    sfree(tiles);
    sfree(used);

    return ret;
}