Compare commits

...

No commits in common. "main" and "master" have entirely different histories.
main ... master

20 changed files with 235 additions and 119 deletions

Binary file not shown.

131
bintree.c
View File

@ -1,36 +1,135 @@
#include <stdlib.h>
#include <string.h>
#include "stack.h"
#include "bintree.h"
#include "stack.h"
//TODO: binären Suchbaum implementieren
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv),
* `clearTree`: gibt den gesamten Baum frei (rekursiv),
* `treeSize`: zählt die Knoten im Baum (rekursiv),
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added).
/* Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). */
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
{
if (compareFct == NULL || data == NULL || dataSize == 0)
return root; // invalid input: do nothing
if (root == NULL)
{
TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode));
if (node == NULL)
return NULL; // allocation failed
node->data = malloc(dataSize);
if (node->data == NULL)
{
free(node);
return NULL;
}
memcpy(node->data, data, dataSize);
node->left = NULL;
node->right = NULL;
if (isDuplicate != NULL)
*isDuplicate = 0;
return node;
}
int cmp = compareFct(data, root->data);
if (cmp < 0)
{
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
}
else if (cmp > 0)
{
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
}
else // cmp == 0 -> duplicate
{
if (isDuplicate != NULL)
{
*isDuplicate = 1;
// ignore duplicate insertion
}
else
{
// duplicates allowed: insert to right subtree for stability
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
}
}
return root;
}
// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction.
// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
// push the top node and push all its left nodes.
/* Iterates over the tree given by root in-order (ascending order).
Follows the usage of strtok: If root != NULL then create/reset iterator for that tree.
If root == NULL, continue iteration from last position.
Uses stack to manage traversal state. */
void *nextTreeData(TreeNode *root)
{
// static iterator state
static StackNode *iterStack = NULL;
static TreeNode *currentRoot = NULL;
// initialize iterator for a new tree
if (root != NULL)
{
// clear any previous iterator state
clearStack(iterStack);
iterStack = NULL;
currentRoot = root;
// push root and all its left descendants
TreeNode *cur = root;
while (cur != NULL)
{
iterStack = push(iterStack, cur);
cur = cur->left;
}
}
else
{
// if user asks to continue but iterator not initialized, nothing to return
if (iterStack == NULL)
return NULL;
}
// get next node
if (iterStack == NULL)
return NULL;
// pop the top node
TreeNode *node = (TreeNode *)top(iterStack);
iterStack = pop(iterStack);
// after popping node, push its right child and all left descendants of that right child
TreeNode *r = node->right;
while (r != NULL)
{
iterStack = push(iterStack, r);
r = r->left;
}
return node->data;
}
// Releases all memory resources (including data copies).
/* Releases all memory resources (including data copies). */
void clearTree(TreeNode *root)
{
if (root == NULL)
return;
if (root->left != NULL)
clearTree(root->left);
if (root->right != NULL)
clearTree(root->right);
free(root->data);
root->data = NULL;
free(root);
}
// Returns the number of entries in the tree given by root.
/* Returns the number of entries in the tree given by root. */
unsigned int treeSize(const TreeNode *root)
{
}
if (root == NULL)
return 0;
return 1 + treeSize(root->left) + treeSize(root->right);
}

BIN
doble_initial.exe Normal file

Binary file not shown.

View File

@ -1 +1,5 @@
player_name;4993
player_name;4992
player_name;4990
player_name;4953
player1;3999

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,19 +1,9 @@
CC = gcc
FLAGS = -g -Wall -lm
BINARIES = ./windows
ifeq ($(OS),Windows_NT)
include makefile_windows.variables
else
UNAME = $(shell uname)
ifeq ($(UNAME),Linux)
include makefile_linux.variables
else
include makefile_mac.variables
endif
endif
raylibfolder = ./raylib
unityfolder = ./unity
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
# --------------------------
# Initiales Programm bauen (zum ausprobieren)
@ -24,8 +14,6 @@ doble_initial:
# --------------------------
# Selbst implementiertes Programm bauen
# --------------------------
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
doble : main.o $(program_obj_files)
$(CC) $(FLAGS) $^ -o doble
@ -42,8 +30,4 @@ unitTests:
# Clean
# --------------------------
clean:
ifeq ($(OS),Windows_NT)
del /f *.o doble
else
rm -f *.o doble
endif
rm -f *.o doble

View File

@ -1,2 +0,0 @@
LDFLAGS = -lGL -lX11 -lm
BINARIES = ./linux

View File

@ -1,3 +0,0 @@
LDFLAGS = -framework OpenGL -framework CoreFoundation -framework CoreGraphics -framework IOKit -framework Cocoa -framework CoreVideo
ARCH := $(shell uname -m)
BINARIES = ./macos-$(ARCH)

View File

@ -1,2 +0,0 @@
LDFLAGS = -lopengl32 -lgdi32 -lwinmm
BINARIES = ./windows

View File

@ -5,22 +5,92 @@
#include "numbers.h"
#include "bintree.h"
//TODO: getDuplicate und createNumbers implementieren
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
* Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
* Duplizieren eines zufälligen Eintrags im Array.
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */
// Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries.
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
// creating random numbers.
unsigned int *createNumbers(unsigned int len)
// --- Hilfsfunktion: Vergleich von unsigned int ------------------
static int compareUInt(const void *a, const void *b)
{
unsigned int ua = *(const unsigned int *)a;
unsigned int ub = *(const unsigned int *)b;
if (ua < ub) return -1;
if (ua > ub) return 1;
return 0;
}
// Returns only the only number in numbers which is present twice. Returns zero on errors.
// Returns len random numbers between 1 and 2x len in random order which are all different,
// except for two entries. Uses the binary search tree to avoid duplicates.
unsigned int *createNumbers(unsigned int len)
{
if (len < 2)
return NULL;
unsigned int *arr = malloc(sizeof(unsigned int) * len);
if (!arr)
return NULL;
srand((unsigned int)time(NULL));
TreeNode *root = NULL;
unsigned int count = 0;
while (count < len - 1) // generate len-1 UNIQUE numbers
{
unsigned int val = (rand() % (2 * len)) + 1;
int isDup = 0;
root = addToTree(root, &val, sizeof(unsigned int), compareUInt, &isDup);
if (!isDup)
{
arr[count++] = val;
}
}
// pick a random existing value to duplicate
unsigned int duplicateIndex = rand() % (len - 1);
arr[len - 1] = arr[duplicateIndex];
clearTree(root);
return arr;
}
// Returns the only number in the array that occurs twice.
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
if (!numbers || len < 2)
return 0;
}
// copy array
unsigned int *copy = malloc(sizeof(unsigned int) * len);
if (!copy)
return 0;
memcpy(copy, numbers, sizeof(unsigned int) * len);
// sort
for (unsigned int i = 0; i < len - 1; i++)
{
for (unsigned int j = i + 1; j < len; j++)
{
if (copy[j] < copy[i])
{
unsigned int t = copy[i];
copy[i] = copy[j];
copy[j] = t;
}
}
}
// find adjacent duplicate
unsigned int duplicate = 0;
for (unsigned int i = 0; i < len - 1; i++)
{
if (copy[i] == copy[i + 1])
{
duplicate = copy[i];
break;
}
}
free(copy);
return duplicate;
}

30
stack.c
View File

@ -1,33 +1,45 @@
#include <stdlib.h>
#include "stack.h"
//TODO: grundlegende Stackfunktionen implementieren:
/* * `push`: legt ein Element oben auf den Stack,
* `pop`: entfernt das oberste Element,
* `top`: liefert das oberste Element zurück,
* `clearStack`: gibt den gesamten Speicher frei. */
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data)
{
StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));
if (newNode == NULL)
return stack; // allocation failed: return unchanged stack
newNode->data = data;
newNode->next = stack;
return newNode;
}
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
// freed by caller.)
StackNode *pop(StackNode *stack)
{
if (stack == NULL)
return NULL;
StackNode *next = stack->next;
free(stack);
return next;
}
// Returns the data of the top element.
void *top(StackNode *stack)
{
if (stack == NULL)
return NULL;
return stack->data;
}
// Clears stack and releases all memory.
void clearStack(StackNode *stack)
{
}
while (stack != NULL)
{
StackNode *next = stack->next;
free(stack);
stack = next;
}
}

View File

@ -8,6 +8,10 @@ The latest element is taken from the stack. */
#include <stdlib.h>
//TODO: passenden Datentyp als struct anlegen
typedef struct StackNode {
void *data;
struct StackNode *next;
} StackNode;
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data);

0
test_numbers.c Normal file
View File

0
test_stack.c Normal file
View File

38
timer.c
View File

@ -1,37 +1,6 @@
#include <time.h>
#include "timer.h"
#if __APPLE__
#include <sys/time.h>
static struct timespec start = {0, 0};
// Starts the timer.
void startTimer()
{
clock_gettime(CLOCK_MONOTONIC, &start);
}
// Returns the time in seconds since startTimer() was called.
double stopTimer()
{
struct timespec end;
clock_gettime(CLOCK_MONOTONIC, &end);
unsigned long long delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
double measuredSeconds = (double)delta_us / 1000000.;
if(start.tv_nsec > 0) {
start.tv_nsec = 0;
start.tv_sec = 0;
}
else
measuredSeconds = -1;
return measuredSeconds;
}
#else
#include <time.h>
static clock_t startClocks = 0;
// Starts the timer.
@ -49,7 +18,6 @@ double stopTimer()
startClocks = 0;
else
measuredSeconds = -1;
return measuredSeconds;
}
#endif
}

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

3
unity/makefile Normal file
View File

@ -0,0 +1,3 @@
unity: unity.c unity.h
gcc -c -Wall -o unity.o unity.c
ar rcs libunity.a unity.o

Binary file not shown.