summaryrefslogtreecommitdiff
path: root/src/puzzles/distractions.c
blob: c2c57fbc7c0dbc67e6984b4265ddbd3caabcdbab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "puzzle.h"
#include <raylib.h>
#include <stdio.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];
        // printf("comparing %s.%s and %s.%s\n", desc->reciever_name, desc->method_signature,
                // reciever, signature);
        if ( strlen(desc->reciever_name) == reciever_len
                && strncmp(reciever, desc->reciever_name, reciever_len) == 0
                && strlen(desc->method_signature) == signature_len
                && strncmp(signature, desc->method_signature, signature_len) == 0)
            return true;
        // printf("Not equal \n");
    }
    return false;
}

// 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;
        }
    }
    // printf("stack len: %zu\n", stack_len);
    free(signatures_stack);
    return puzzle->TestC * stack_len;
}

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);
}