diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2016-11-20 15:16:41 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2016-11-24 16:23:09 -0500 |
| commit | 56c9984511f016eab7e1278ba9e40d88bb59a162 (patch) | |
| tree | 1bfa6d3aeb3bf2a6ffec71387ac073cd0b8b2a51 /apps/plugins/puzzles/combi.c | |
| parent | 29648f817677b84c03c2bcfe89eb8cf53653e7db (diff) | |
| download | rockbox-puzzles.zip rockbox-puzzles.tar.gz rockbox-puzzles.tar.bz2 rockbox-puzzles.tar.xz | |
[WIP] Port of Simon Tatham's Puzzle Collectionpuzzles
Original revision: 5123b1bf68777ffa86e651f178046b26a87cf2d9
MIT Licensed. Some games still crash and others are unplayable due to
issues with controls. Still need a "real" polygon filling algorithm.
The following games are at least partially broken for various reasons:
Cube: crash with certain settings
Galaxies: crash
Inertia: crash
Keen: input issues
Loopy: weird stuff happens
Map: crash on input
Mines: weird stuff happens on target
Palisade: input issues
Signpost: crash on input
Solo: input issues
Towers: input and drawing issues
Train Tracks: drawing issues
Twiddle: weird animation on target
Undead: input and drawing issues
Unequal: input and drawing issues
Untangle: input issues
All in all, about 40% of the games are at least partially broken.
Change-Id: I7c69b6860ab115f973c8d76799502e9bb3d52368
Diffstat (limited to 'apps/plugins/puzzles/combi.c')
| -rw-r--r-- | apps/plugins/puzzles/combi.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/apps/plugins/puzzles/combi.c b/apps/plugins/puzzles/combi.c new file mode 100644 index 0000000..d39e298 --- /dev/null +++ b/apps/plugins/puzzles/combi.c @@ -0,0 +1,110 @@ +#include "rbassert.h" +#include <string.h> + +#include "puzzles.h" + +/* horrific and doesn't check overflow. */ +static long factx(long x, long y) +{ + long acc = 1, i; + + for (i = y; i <= x; i++) + acc *= i; + return acc; +} + +void reset_combi(combi_ctx *combi) +{ + int i; + combi->nleft = combi->total; + for (i = 0; i < combi->r; i++) + combi->a[i] = i; +} + +combi_ctx *new_combi(int r, int n) +{ + long nfr, nrf; + combi_ctx *combi; + + assert(r <= n); + assert(n >= 1); + + combi = snew(combi_ctx); + memset(combi, 0, sizeof(combi_ctx)); + combi->r = r; + combi->n = n; + + combi->a = snewn(r, int); + memset(combi->a, 0, r * sizeof(int)); + + nfr = factx(n, r+1); + nrf = factx(n-r, 1); + combi->total = (int)(nfr / nrf); + + reset_combi(combi); + return combi; +} + +/* returns NULL when we're done otherwise returns input. */ +combi_ctx *next_combi(combi_ctx *combi) +{ + int i = combi->r - 1, j; + + if (combi->nleft == combi->total) + goto done; + else if (combi->nleft <= 0) + return NULL; + + while (combi->a[i] == combi->n - combi->r + i) + i--; + combi->a[i] += 1; + for (j = i+1; j < combi->r; j++) + combi->a[j] = combi->a[i] + j - i; + + done: + combi->nleft--; + return combi; +} + +void free_combi(combi_ctx *combi) +{ + sfree(combi->a); + sfree(combi); +} + +/* compile this with: + * gcc -o combi.exe -DSTANDALONE_COMBI_TEST combi.c malloc.c + */ +#ifdef STANDALONE_COMBI_TEST + +#include <stdio.h> + +void fatal(char *fmt, ...) +{ + abort(); +} + +int main(int argc, char *argv[]) +{ + combi_ctx *c; + int i, r, n; + + if (argc < 3) { + fprintf(stderr, "Usage: combi R N\n"); + exit(1); + } + + r = atoi(argv[1]); n = atoi(argv[2]); + c = new_combi(r, n); + printf("combi %d of %d, %d elements.\n", c->r, c->n, c->total); + + while (next_combi(c)) { + for (i = 0; i < c->r; i++) { + printf("%d ", c->a[i]); + } + printf("\n"); + } + free_combi(c); +} + +#endif |