summaryrefslogtreecommitdiff
path: root/src/puzzles/distractions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/puzzles/distractions.c')
-rw-r--r--src/puzzles/distractions.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/puzzles/distractions.c b/src/puzzles/distractions.c
new file mode 100644
index 0000000..bd5db87
--- /dev/null
+++ b/src/puzzles/distractions.c
@@ -0,0 +1,76 @@
+#include "puzzle.h"
+#include <raylib.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ char *reciever_name;
+ char *method_signature;
+} signatureDescriptor;
+
+// returns true if the signatures_stack contains the method with the given signature.
+// !! Returns true if any of the elements are invalid !!
+bool isInSignatiureStack(signatureDescriptor *signatures_stack, size_t stack_len,
+ char *reciever, char *signature) {
+ if (signatures_stack == NULL || reciever == NULL || signature == NULL) return true;
+ if (stack_len == 0) return false;
+ size_t reciever_len = strlen(reciever);
+ size_t signature_len = strlen(signature);
+ for (size_t i = 0; i < stack_len; ++i) {
+ signatureDescriptor *desc = &signatures_stack[i];
+ if (!strncmp(reciever, desc->reciever_name, reciever_len))
+ return false;
+ if (!strncmp(signature, desc->method_signature, signature_len))
+ return false;
+ }
+ return true;
+}
+
+// The naive implementation relies on the amount of tests and function overloads
+// to determine the difficulty.
+// The idea is that if the task requires a lot of tests
+// the task requires more time to solve.
+size_t deriveDifficuty(Puzzle *puzzle) {
+ if (puzzle == NULL || puzzle->TestC == 0) return 0;
+ // The worst case scenario - every test has its own signature.
+ // Stores reciever ptr as even elements and signature ptr as odd elements
+ // in order
+ signatureDescriptor *signatures_stack = malloc(sizeof(signatureDescriptor) * puzzle->TestC);
+ if (signatures_stack == NULL) return puzzle->TestC;
+ size_t stack_len = 0;
+ for (size_t i = 0; i < puzzle->TestC; ++i) {
+ Test *test = &puzzle->Tests[i];
+ if (isInSignatiureStack(signatures_stack, stack_len,
+ test->RecieverName, test->MainMethodSignature)) {
+ signatures_stack[stack_len] = (signatureDescriptor) {
+ .reciever_name = test->RecieverName,
+ .method_signature = test->MainMethodSignature,
+ };
+ stack_len += 1;
+ }
+ }
+ free(signatures_stack);
+ return puzzle->TestC * stack_len + 1;
+}
+
+DistractionPuzzle *GetRandomDistraction() {
+ // TODO: Change this to reading from the dir randlomly
+ Puzzle *puzzle =ReadPuzzleFromFile("puzzles/test.pz");
+
+
+ DistractionPuzzle *outp = malloc(sizeof(DistractionPuzzle));
+ if (outp == NULL) {
+ FreePuzzle(puzzle); // Temp
+ return NULL;
+ }
+ outp->puzzle = puzzle;
+ outp->SecondsGranted = deriveDifficuty(puzzle);
+ return outp;
+}
+
+void FreeDistrationPuzzle(DistractionPuzzle *puzzle) {
+ if (puzzle == NULL) return;
+ if (puzzle->puzzle != NULL)
+ FreePuzzle(puzzle->puzzle);
+ free(puzzle);
+}