Author SHA1 Message Date
wiesendsi102436 e4db0beda0 fix: timers on Linux
On Linux the clock() function measures cpu time instead of wall time. This change uses the Apple code path for Linux.
2025-12-20 08:53:51 +01:00
schroederen 746b9b7219 Merge pull request 'fix: apply build FLAGS correctly' (#4) from wiesendsi102436/info2Praktikum-DobleSpiel:bugfix/makefile into main
Reviewed-on: freudenreichan/info2Praktikum-DobleSpiel#4
2025-12-15 14:20:07 +00:00
schroederen 1f3fba80ec Merge pull request 'Hinweis hinzugefügt, dass Studis auch für den bintree Unittests schreiben sollen.' (#7) from schroederen/info2Praktikum-DobleSpiel:main into main
Reviewed-on: freudenreichan/info2Praktikum-DobleSpiel#7
2025-12-15 14:17:18 +00:00
schroederen 1d363980f6 Hinweis hinzugefügt, dass Studis auch für den bintree Unittests schreiben sollen. 2025-12-15 15:16:50 +01:00
wiesendsi102436 4ce3a6aac0 fix: apply build FLAGS correctly
A typo in the dependency variable program_obj_files caused make to fall back to implicit/default rules. FLAGS was ignored because the default behavior is to use CFLAGS.
2025-11-30 10:55:37 +01:00
10 changed files with 25 additions and 308 deletions
-5
View File
@@ -1,5 +0,0 @@
*doble*
*.o
*.exe
.vscode
run*Tests
Binary file not shown.
+1 -6
View File
@@ -1,6 +1,5 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "numbers.h"
#include "timer.h"
#include "highscore.h"
@@ -40,9 +39,6 @@ int main(int argc, char *argv[])
{
int exitCode = EXIT_FAILURE;
// set seed
srand(time(NULL));
if(argc != 2)
{
fprintf(stderr, "Usage: %s <player name>\n", argv[0]);
@@ -71,7 +67,7 @@ int main(int argc, char *argv[])
userInput = inputNumber("Welche Zahl kommt doppelt vor: ");
measuredSeconds = stopTimer();
duplicate = getDuplicate(numbers, numberOfElements+1);
duplicate = getDuplicate(numbers, numberOfElements);
// check result and update highscores
if(userInput == duplicate)
@@ -87,7 +83,6 @@ int main(int argc, char *argv[])
saveHighscores(highscorePath);
clearHighscores();
free(numbers);
exitCode = EXIT_SUCCESS;
}
+5 -18
View File
@@ -1,5 +1,5 @@
CC = gcc
CFLAGS = -g -Wall -lm
FLAGS = -g -Wall -lm
ifeq ($(OS),Windows_NT)
include makefile_windows.variables
@@ -27,29 +27,16 @@ doble_initial:
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
doble : main.o $(program_obj_files)
$(CC) $(CFLAGS) $^ -o doble
$(CC) $(FLAGS) $^ -o doble
$(program_obj_files): %.o: %.c
$(CC) -c $(CFLAGS) $^ -o $@
$(CC) -c $(FLAGS) $^ -o $@
# --------------------------
# Unit Tests
# --------------------------
TEST_STACK_SOURCES = stack.c test_stack.c $(unityfolder)/unity.c
TEST_BINTREE_SOURCES = bintree.c test_bintree.c stack.c $(unityfolder)/unity.c
TEST_NUMBERS_SOURCES = stack.c numbers.c bintree.c $(unityfolder)/unity.c test_numbers.c
stackTests: $(TEST_STACK_SOURCES) stack.h
$(CC) $(CFLAGS) -I$(unityfolder) $(TEST_STACK_SOURCES) -o runStackTests
./runStackTests
bintreeTests: $(TEST_BINTREE_SOURCES) stack.h bintree.h
$(CC) $(CFLAGS) -I$(unityfolder) $(TEST_BINTREE_SOURCES) -o runBintreeTests
./runBintreeTests
numbersTests: $(TEST_NUMBERS_SOURCES) stack.h bintree.h numbers.h
$(CC) $(CFLAGS) -I$(unityfolder) $(TEST_NUMBERS_SOURCES) -o runNumbersTests
./runNumbersTests
unitTests:
echo "needs to be implemented"
# --------------------------
# Clean
+9 -48
View File
@@ -5,61 +5,22 @@
#include "numbers.h"
#include "bintree.h"
//Speicher für Array erstellen, zufällige Zahlen von 1-2xlen erzeugen, mittels Binärbaum checken, ob Zahlen einzigartig sind
//Eine Zahl duplizieren, an zufälliger Stelle einfügen und die Zahl an der Stelle ans Ende schieben
const int compare (const void *a, const void *b);
//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)
{
unsigned int *numbers = malloc (sizeof(unsigned int) * len);
unsigned int upperLimit = len * 2;
int isDuplicate = 0;
TreeNode *binTree = NULL;
for (unsigned int i = 0; i < len; i++) {
do
{
numbers[i] = rand () % upperLimit + 1;
binTree = addToTree(binTree, &numbers[i], sizeof(unsigned int), compare, &isDuplicate);
} while (isDuplicate);
}
unsigned int duplicate = numbers[rand () % len];
int indexDuplicate = rand () % len;
numbers[len] = numbers[indexDuplicate];
numbers[indexDuplicate] = duplicate;
return numbers;
}
//Vergleichsfunktion von qsort
const int compare (const void *a, const void *b) {
const unsigned int *x = a;
const unsigned int *y = b;
if (*x < *y) {
return -1;
}
else if (*x > *y) {
return 1;
}
else {
return 0;
}
}
//Sortiert Zahlen mit qsort, vergleicht dann benachbarte Elemente und gibt bei Erfolg die doppelte Zahl zurück
// Returns only the only number in numbers which is present twice. Returns zero on errors.
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
if (len < 2) {
return 0;
}
qsort((void*)numbers, len, sizeof(unsigned int), compare);
for (int i = 0; i < len-1; i++) {
if (numbers[i] == numbers [i+1]) {
return numbers[i];
}
}
return 0;
}
+7 -29
View File
@@ -1,55 +1,33 @@
#include <stdlib.h>
#include "stack.h"
// TODO: grundlegende Stackfunktionen implementieren:
//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. */
* `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)
{
// this is the new top node
StackNode *newTopNode = malloc(sizeof(StackNode));
if (newTopNode == NULL)
{
return NULL;
}
newTopNode->data = data;
newTopNode->next = stack;
return newTopNode;
}
// 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)
{
return NULL;
}
StackNode *nextNode = stack->next;
free(stack);
return nextNode;
}
// Returns the data of the top element.
void *top(StackNode *stack)
{
if (!stack)
{
return NULL;
}
return stack->data;
}
// Clears stack and releases all memory.
void clearStack(StackNode *stack)
{
while (pop(stack))
;
}
+3 -7
View File
@@ -1,17 +1,13 @@
#ifndef STACK_H
#define STACK_H
/* A stack is a special type of queue which uses the LIFO (last in, first out) principle.
This means that with each new element all other elements are pushed deeper into the stack.
/* A stack is a special type of queue which uses the LIFO (last in, first out) principle.
This means that with each new element all other elements are pushed deeper into the stack.
The latest element is taken from the stack. */
#include <stdlib.h>
typedef struct StackNode
{
struct StackNode *next;
void *data;
} StackNode;
//TODO: passenden Datentyp als struct anlegen
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data);
-39
View File
@@ -1,39 +0,0 @@
#include "unity.h"
#include "bintree.h"
#include "string.h"
void setUp(void)
{
// set stuff up here
}
void tearDown(void)
{
// set stuff up here
}
// this adds some strings and checks if they are returned in the right order
void test_insert_and_retrieve(void)
{
char *data1 = "a_this";
char *data2 = "b_is";
char *data3 = "c_testdata";
TreeNode *root = addToTree(NULL, data1, strlen(data1) + 1, (CompareFctType)&strcmp, NULL);
addToTree(root, data2, strlen(data2) + 1, (CompareFctType)&strcmp, NULL);
addToTree(root, data3, strlen(data3) + 1, (CompareFctType)&strcmp, NULL);
TEST_ASSERT_EQUAL_STRING(data1, (char *)nextTreeData(root));
TEST_ASSERT_EQUAL_STRING(data2, (char *)nextTreeData(NULL));
TEST_ASSERT_EQUAL_STRING(data3, (char *)nextTreeData(NULL));
clearTree(root);
}
int main(void)
{
printf("============================\nBintree tests\n============================\n");
UNITY_BEGIN();
RUN_TEST(test_insert_and_retrieve);
return UNITY_END();
}
-109
View File
@@ -1,109 +0,0 @@
#include "unity.h"
#include "numbers.h"
#include "stdlib.h"
static int compareInt(const void *ptr1, const void *ptr2);
void setUp(void)
{
// set stuff up here
}
void tearDown(void)
{
// set stuff up here
}
// getDuplicate on array without duplicats
// expects 0/error
void test_get_duplicate_without_duplicates(void)
{
unsigned int input[] = {1, 5, 9, 2, 4};
unsigned int len = sizeof(input) / sizeof(input[0]);
TEST_ASSERT_EQUAL_UINT(0, getDuplicate(input, len));
}
// getDuplicate() on some arrays with 1 duplicate
void test_get_duplicate(void)
{
unsigned int arr1[] = {4, 8, 32, 5, 3, 8, 8};
unsigned int len1 = sizeof(arr1) / sizeof(arr1[0]);
unsigned int arr2[] = {1, 3, 3, 7};
unsigned int len2 = sizeof(arr2) / sizeof(arr2[0]);
unsigned int arr3[] = {7, 7, 8, 4, 9, 1};
unsigned int len3 = sizeof(arr3) / sizeof(arr3[0]);
TEST_ASSERT_EQUAL_UINT(8, getDuplicate(arr1, len1));
TEST_ASSERT_EQUAL_UINT(3, getDuplicate(arr2, len2));
TEST_ASSERT_EQUAL_UINT(7, getDuplicate(arr3, len3));
}
// this tries to brute force a triple
void test_for_triple(void)
{
// this test is less effective if srand is called inside createNumbers()
for (int i = 0; i < 100000; i++)
{
unsigned int *numbers = createNumbers(3);
if (numbers[0] == numbers[1] && numbers[1] == numbers[2])
{
// fail the test
TEST_ASSERT(0);
}
free(numbers);
}
}
// checks if there is exactly 1 duplicate number at varying array sizes
void test_exactly_one_duplicate()
{
const size_t MAX_LIST_SIZE = 20; // max tested array len
const size_t ITERATIONS_PER_LEN = 20; // number of iterations for each tested array len
for (size_t len = 2; len < MAX_LIST_SIZE; len++) // start with smallest sensible size 2
{
for (size_t i = 0; i < ITERATIONS_PER_LEN; i++)
{
unsigned int *randTestList = createNumbers((unsigned int)len);
qsort(randTestList, len, sizeof(unsigned int), compareInt);
int cntDuplicate = 0;
for (size_t j = 0; j < len - 1; j++)
{
if (randTestList[j] == randTestList[j + 1])
{
cntDuplicate++;
}
}
// there should be exactly 1 duplicate
TEST_ASSERT_EQUAL_INT(1, cntDuplicate);
free(randTestList);
}
}
}
static int compareInt(const void *ptr1, const void *ptr2)
{
unsigned int num1 = *(int *)ptr1;
unsigned int num2 = *(int *)ptr2;
if (num1 < num2)
return -1;
if (num1 > num2)
return 1;
return 0;
}
int main(void)
{
printf("============================\nNumbers tests\n============================\n");
UNITY_BEGIN();
RUN_TEST(test_get_duplicate_without_duplicates);
RUN_TEST(test_for_triple);
RUN_TEST(test_exactly_one_duplicate);
RUN_TEST(test_get_duplicate);
return UNITY_END();
}
-47
View File
@@ -1,47 +0,0 @@
#include "unity.h"
#include "stack.h"
int data1 = 10;
int data2 = 20;
int data3 = 30;
StackNode *stack = NULL;
void setUp(void)
{
// set stuff up here
}
void tearDown(void)
{
clearStack(stack);
}
void test_push_and_pop(void)
{
stack = push(stack, &data1);
stack = push(stack, &data2);
stack = push(stack, &data3);
TEST_ASSERT_EQUAL_PTR(top(stack), &data3);
stack = pop(stack);
TEST_ASSERT_EQUAL_PTR(top(stack), &data2);
stack = pop(stack);
TEST_ASSERT_EQUAL_PTR(top(stack), &data1);
stack = pop(stack);
}
void test_handle_NULL(void)
{
TEST_ASSERT_NULL(pop(stack));
TEST_ASSERT_NULL(top(stack));
}
int main(void)
{
printf("============================\nStack tests\n============================\n");
UNITY_BEGIN();
RUN_TEST(test_push_and_pop);
RUN_TEST(test_handle_NULL);
return UNITY_END();
}