summaryrefslogtreecommitdiff
path: root/src/puzzles
diff options
context:
space:
mode:
Diffstat (limited to 'src/puzzles')
-rw-r--r--src/puzzles/distractions.c76
-rw-r--r--src/puzzles/parser.c2
-rw-r--r--src/puzzles/puzzle.h21
3 files changed, 94 insertions, 5 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);
+}
diff --git a/src/puzzles/parser.c b/src/puzzles/parser.c
index cb958e7..0f539b8 100644
--- a/src/puzzles/parser.c
+++ b/src/puzzles/parser.c
@@ -144,7 +144,7 @@ Puzzle *ReadPuzzleFromFile(const char *path) {
}
uint8_t spec_version = read_u8(file);
- printf("Version: %d\n", spec_version);
+ // printf("Version: %d\n", spec_version);
Puzzle *outp = NULL;
switch (spec_version) {
case 1:
diff --git a/src/puzzles/puzzle.h b/src/puzzles/puzzle.h
index acf5a17..bc43662 100644
--- a/src/puzzles/puzzle.h
+++ b/src/puzzles/puzzle.h
@@ -1,16 +1,18 @@
#include <stddef.h>
#include <wren.h>
-#include "../wren_inter/wren_inter.h"
#ifndef PUZZLE_H
#define PUZZLE_H
+/// The amount of seconds granted is calculated as (test_count * uniq(test_signatures).length) * DIFF_MODIFIER
+static const size_t DIFF_MODIFIER = 30;
+
// This is a param that would be placed in a slot
// https://wren.io/embedding/slots-and-handles.html#writing-slots
typedef struct {
WrenType type;
// We store this value as void * to generalize. The downside of this approach
- // is an extenciva allocation
+ // is an extencive allocation
void *value;
} PuzzleIO;
@@ -71,8 +73,8 @@ typedef struct {
enum PUZZLE_TEST_RESULT result;
} SubmitionResult;
-// Don't put anything in out_res, it will be overriten.
-// The stdout of the VM will be there
+/// Don't put anything in out_res, it will be overriten.
+/// The stdout of the VM will be there
SubmitionResult *SubmitSolution(Puzzle *self, char *script);
void PrintPuzzle(Puzzle *puzzle);
@@ -80,4 +82,15 @@ void PrintPuzzle(Puzzle *puzzle);
void FreeSunmitionResult(SubmitionResult *res);
void FreePuzzle(Puzzle *self);
+
+/// The puzzle that will pop up every now and then
+typedef struct {
+ Puzzle *puzzle;
+ /// Seconds granted by the puzzle completion
+ size_t SecondsGranted;
+} DistractionPuzzle;
+
+DistractionPuzzle *GetRandomDistraction();
+void FreeDistrationPuzzle(DistractionPuzzle *puzzle);
+
#endif // PUZZLE_H