summaryrefslogtreecommitdiff
path: root/src/puzzles/puzzle.h
blob: 5af6d6e6c229f3157d43b49bdf39a888366d965a (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stddef.h>
#include <wren.h>
#include <raylib.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 extencive allocation
    void *value;
} PuzzleIO;

// Represents a WREN_TYPE_LIST in PuzzleIO
typedef struct {
    size_t length;
    PuzzleIO *elements;
} PuzzleListIO;

typedef struct {
    // https://wren.io/embedding/calling-wren-from-c.html#setting-up-a-receiver
    char *RecieverName;
    // https://wren.io/embedding/calling-wren-from-c.html#getting-a-method-handle
    char *MainMethodSignature;

    size_t argc;
    PuzzleIO *argv;
    PuzzleIO ExpectedResult;
} Test;

enum PUZZLE_TEST_RESULT {
    RESULT_OK = 0,
    RESULT_WRONG_ANSWER,
    RESULT_COMPTIME_NO_ENTRY,
    RESULT_COMPTIME_ERR,
    RESULT_RUNTIME_ERR,
    RESULT_TIMEOUT,
    RESULT_INIT_ERROR,
};

typedef struct {
    enum PUZZLE_TEST_RESULT res;
    char *message;
} TestResult;

/// The user submitted code should be evaluated by this point. 
/// The entry point should be registered and the absence of the 
/// Main method signatire will be concidered an error
TestResult RunTest(Test *test, WrenVM *vm, size_t max_op);

typedef struct {
    char *Name;
    char *Description;
    char *InitialCode;

    /// The tests that are accessible for an end user
    size_t TestC;
    Test *Tests;
} Puzzle;
    
/// A prebuilt puzzle. Used for debuging
Puzzle *GetTestPuzzle();
Puzzle *ReadPuzzleFromFile(const char *path);

typedef struct {
    char *stdout_sb;
    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
SubmitionResult *SubmitSolution(Puzzle *self, char *script);

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

typedef enum {
    COLLECTION_ELEMENT_PUZZLE,
    COLLECTION_ELEMENT_COLLECTION,
    COLLECTION_ELEMENT_UNKNOWN
} CollectionElementType;


/// A collection node. Corresponds to either a directory in the FS or a .pz file
typedef struct CollectionElement {
    /// The icon used for the puzzles in the collection
    Texture2D icon;
    /// Used in the click detection. Do not modify from user space
    Rectangle _previousFramePosition;
    /// The path to the directory/puzzle
    char *path;
    /// The display name of an element
    char *name;
    /// The tree child nodes array
    struct CollectionElement *children;
    /// The tree child nodes count
    size_t childCount;
    /// OnClick callback
    void (*callback)(struct CollectionElement *);
    /// If the element is initialized it has children and an icon loaded into mem
    bool IsInitialized;
    /// The element has an icon
    bool hasIcon;
    /// The type of the element
    CollectionElementType type;
} CollectionElement;

/// Accepts an element which children will be created and a generic callback that
/// will be called when the collection enement is selected.
/// The element passes a selected element as a callback argummment
void InitializeCollection(CollectionElement *el, void (*callback)(CollectionElement *));
void DrawCollectionElement(CollectionElement *el, CollectionElement *parent, Rectangle rec);
void UpdateCollectionElement(CollectionElement *el);
void DeinitCollectionElement(CollectionElement *el);

#endif // PUZZLE_H