aboutsummaryrefslogtreecommitdiff
path: root/include/actions.c
diff options
context:
space:
mode:
authortslil clingman <tslil@posteo.de>2021-01-28 21:30:30 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commita77062ce3dc9a99ad0662010cc7eeb00dd5036a6 (patch)
tree6936b60eb7a8221d38886d0db11953fe6ee56f23 /include/actions.c
parent473797d820b3b224ee1d370a50e4bcd01d09d48e (diff)
Added license information!
Diffstat (limited to 'include/actions.c')
-rw-r--r--include/actions.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/include/actions.c b/include/actions.c
index 5085330..800a2d4 100644
--- a/include/actions.c
+++ b/include/actions.c
@@ -1,3 +1,20 @@
+/*
+ This file is part of ctak.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Takwrap. If not, see <https://www.gnu.org/licenses/>.
+*/
+
#include "actions.h"
// ===================================================================
@@ -67,6 +84,7 @@ void action_list_init(void) {
action_list_t *action_list_generate(void) {
action_list_t *list = malloc(sizeof(struct action_list_s));
+
// TODO: trap errno
list->length = 0;
list->head = NULL;
@@ -129,16 +147,22 @@ action_list_t *action_list_generate(void) {
* For each direction, generate all possible ordered integer
* partitions of 1 ≤ num ≤ count whose number of summands is
* exactly 1 ≤ summands ≤ min(end_stops[dir], num) -- we
- * write summands as steps
+ * write summands as steps.
+ *
+ * We exploit the `gaps' bijection here and elsewhere
+ * between ordered {integer partitions of n with s summands}
+ * and {binary strings of length n-1 with s-1 set bits}.
*/
for (enum MOVE_DIRECTION dir=M_UP; dir<=M_RIGHT; dir++) {
for (uint8_t num = 1; num <= count; num++) {
for (uint8_t steps = 1;
steps <= end_stops[dir] && steps <= num;
steps++) {
- // TODO: Generalise to board_size!
- uint8_t gaps = 0x07 >> (board_size-steps-1);
- // 0b0000[0111] because 4-1=3 and 5-1=4
+ uint8_t gaps =
+ ((1<<(board_size - 2)) - 1) >> (board_size-steps-1);
+ // For 5x5 this givess 0b0000[0XXX] where steps-1 of
+ // those X's are 1s (starting with LSB) because 4-1=3
+ // and 5-1=4
do {
/*
* We skip the partition if it calls for multiple
@@ -214,9 +238,12 @@ void action_take(const action_t action) {
}
}
} else {
- // not interested in whether we crushed, it will work out by
- // anyway because we overwrite the top stone type. See (*) later
- // for when we do need to know.
+ /*
+ * See the discussion around line 135 for an explanation of the
+ * encoding. Here we are not interested in whether we crushed, it
+ * will work out by anyway because we overwrite the top stone
+ * type. See (*) later for when we do need to know.
+ */
const uint8_t gaps = A_GET_DATA0(action) & 0x7F,
num = A_GET_DATA1(action) & 0x0F, // unpack
dir = A_GET_DATA1(action) >> 4;