generated from freudenreichan/info2Praktikum-DobleSpiel
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcdc1949ab | ||
| f513d63ebf | |||
|
|
f249355a30 | ||
|
|
8f3ee7b9d7 | ||
|
|
37f38cbc7d | ||
|
|
dcc90edfa3 |
@ -38,7 +38,7 @@ void test_add_multiple_elements_to_Tree()
|
||||
|
||||
for(int j = 0; j < 4; ++j)
|
||||
{
|
||||
root = addToTree(root, &value[j], sizeof(int), compare, &duplicate);
|
||||
root = addToTree(root, &value[j], sizeof(int), compare, &duplicate); //Duplikate nicht erlaubt
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(4, treeSize(root));
|
||||
@ -62,13 +62,13 @@ void test_detect_size() {
|
||||
for (int j = 0; j < 10; ++j) {
|
||||
root = addToTree(root, &values[j], sizeof(int), compare, &duplicate);
|
||||
if (duplicate) {
|
||||
// Optional: prüfen, dass ein Duplikat erkannt wurde
|
||||
// Ist der Wert schon eingefuegt? Also gibt es schon ein Duplikat?
|
||||
TEST_ASSERT_TRUE(duplicate == 1);
|
||||
}
|
||||
duplicate = 0; // zurücksetzen für nächstes Einfügen
|
||||
}
|
||||
|
||||
// Prüfen der Baumgröße ohne Duplikate
|
||||
// Prüfen der Baumgroeße ohne Duplikate
|
||||
TEST_ASSERT_EQUAL_INT(8, treeSize(root));
|
||||
|
||||
clearTree(root);
|
||||
@ -91,7 +91,7 @@ void test_add_multiplie_elements_one_dup() {
|
||||
}
|
||||
|
||||
|
||||
//Traverses the tree inorder to check wether nextTreeData works
|
||||
|
||||
// Hilfsfunktion: rekursive Inorder-Prüfung
|
||||
void inorderCheck(TreeNode *node, int expected[], int *idx) {
|
||||
if (node == NULL) return;
|
||||
@ -99,14 +99,14 @@ void inorderCheck(TreeNode *node, int expected[], int *idx) {
|
||||
// Linken Teilbaum prüfen
|
||||
inorderCheck(node->left, expected, idx);
|
||||
|
||||
// Aktuelles Element prüfen
|
||||
// Aktuelles Element prüfen -> wenn das aktuelle Element gefunden wurde, wird naechstes gesucht
|
||||
TEST_ASSERT_EQUAL_INT(expected[*idx], *(int*)node->data);
|
||||
(*idx)++;
|
||||
|
||||
// Rechten Teilbaum prüfen
|
||||
inorderCheck(node->right, expected, idx);
|
||||
}
|
||||
|
||||
//Traverses the tree inorder to check wether nextTreeData works
|
||||
void test_inorder() {
|
||||
TreeNode *root = NULL;
|
||||
int values[] = {5, 3, 7, 2, 4, 6, 8};
|
||||
@ -120,6 +120,7 @@ void test_inorder() {
|
||||
int expected[] = {2,3,4,5,6,7,8};
|
||||
|
||||
int idx = 0;
|
||||
//rekursives Pruefen der Eintraege
|
||||
inorderCheck(root, expected, &idx);
|
||||
|
||||
// Alle Einträge geprüft?
|
||||
|
||||
@ -14,7 +14,7 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
|
||||
{
|
||||
if(data!= NULL && dataSize > 0)
|
||||
{
|
||||
if(root == NULL) //Abbruchbedingung: Keine Wurzel vorhanden, deshalb fügen wir hier einen neuen Knote ein
|
||||
if(root == NULL) //Abbruchbedingung: Keine Wurzel vorhanden, deshalb fuegen wir hier einen neuen Knote ein
|
||||
{
|
||||
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
|
||||
if(newNode == NULL)
|
||||
@ -31,7 +31,7 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
|
||||
newNode->left = NULL;
|
||||
newNode->right = NULL;
|
||||
|
||||
if(isDuplicate!= NULL) //wenn Zeiger isDUplicate auf einen Wert zeigt, wird isDuplicate auf 0 gesetzt
|
||||
if(isDuplicate!= NULL) //wenn isDuplicate ungelich null, ignoriere duplikate und setze isDuplaicate 0 fuer neues Element
|
||||
{
|
||||
*isDuplicate = 0;
|
||||
}
|
||||
@ -48,7 +48,7 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDuplicate) {
|
||||
if (isDuplicate) { //Duplikate sollen ignoriert werden
|
||||
*isDuplicate = 1;
|
||||
}
|
||||
else {
|
||||
|
||||
BIN
highscore.o
Normal file
BIN
highscore.o
Normal file
Binary file not shown.
@ -1,3 +1,5 @@
|
||||
Silvana;9944
|
||||
hannes;9910
|
||||
silvana;9865
|
||||
player2;4983
|
||||
player1;3999
|
||||
|
||||
62
makefile
62
makefile
@ -1,10 +1,17 @@
|
||||
CC = gcc
|
||||
FLAGS = -g -Wall -lm
|
||||
|
||||
|
||||
raylibfolder = ./raylib
|
||||
unityfolder = ./unity
|
||||
|
||||
|
||||
FLAGS = -g -Wall -I$(unityfolder)
|
||||
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
include makefile_windows.variables
|
||||
else
|
||||
UNAME = $(shell uname)
|
||||
UNAME := $(shell uname)
|
||||
ifeq ($(UNAME),Linux)
|
||||
include makefile_linux.variables
|
||||
else
|
||||
@ -12,55 +19,48 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
raylibfolder = ./raylib
|
||||
unityfolder = ./unity
|
||||
# --------------------------
|
||||
# Objektdateien
|
||||
# --------------------------
|
||||
program_obj_files := stack.o bintree.o numbers.o timer.o highscore.o
|
||||
|
||||
# --------------------------
|
||||
# Initiales Programm bauen (zum ausprobieren)
|
||||
# --------------------------
|
||||
doble_initial:
|
||||
$(CC) -o doble_initial $(BINARIES)/libdoble_complete.a
|
||||
|
||||
# --------------------------
|
||||
# Selbst implementiertes Programm bauen
|
||||
# --------------------------
|
||||
program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
|
||||
%.o: %.c
|
||||
$(CC) $(FLAGS) -c $< -o $@
|
||||
|
||||
|
||||
doble: main.o $(program_obj_files)
|
||||
$(CC) $(FLAGS) $^ -o doble
|
||||
|
||||
$(program_obj_filesobj_files): %.o: %.c
|
||||
$(CC) -c $(FLAGS) $^ -o $@
|
||||
|
||||
doble_initial:
|
||||
$(CC) -o doble_initial $(BINARIES)/libdoble_complete.a
|
||||
|
||||
# --------------------------
|
||||
# Unit Tests
|
||||
# --------------------------
|
||||
unity_src = $(unityfolder)/unity.c
|
||||
|
||||
unitTests: numbersTest stackTest bintreeTest
|
||||
# ./runNumbersTest
|
||||
# ./runStackTest
|
||||
./runBintreeTest
|
||||
unitTests:
|
||||
@echo "needs to be implemented"
|
||||
|
||||
numbersTest: numbers.o bintree.o stack.o numbersTest.c $(unity_src)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I$(unityfolder) $^ -o runNumbersTest
|
||||
|
||||
stackTest: stack.o stackTest.c $(unity_src)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I$(unityfolder) $^ -o runStackTests
|
||||
binTreeTest: stack.o bintree.o binTreeTest.c $(unityfolder)/unity.c
|
||||
$(CC) $(FLAGS) -o runbinTreeTest binTreeTest.c bintree.o stack.o $(unityfolder)/unity.c
|
||||
|
||||
binTreeTest: bintree.o binTreeTest.c $(unity_src) stack.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I$(unityfolder) $^ -o runBinTreeTest
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
test_numbers: numbers_no_tree.o bintree.o stack.o test_numbers.c $(unityfolder)/unity.c
|
||||
$(CC) $(FLAGS) -o run_numbersTests test_numbers.c numbers_no_tree.o bintree.o stack.o $(unityfolder)/unity.c
|
||||
|
||||
|
||||
test_stack: stack.o test_stack.c $(unityfolder)/unity.c
|
||||
$(CC) $(FLAGS) -o runstackTests test_stack.c stack.o $(unityfolder)/unity.c
|
||||
|
||||
# --------------------------
|
||||
# Clean
|
||||
# Cleaning
|
||||
# --------------------------
|
||||
clean:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
del /f *.o doble
|
||||
del /f *.o doble runstackTests run_numbersTests runbintreeTests
|
||||
else
|
||||
rm -f *.o doble
|
||||
rm -f *.o doble runstackTests run_numbersTests runbintreeTests
|
||||
endif
|
||||
66
numbers.c
66
numbers.c
@ -17,13 +17,28 @@
|
||||
// Returns len random numbers between 1 and 2*len in random order,
|
||||
// all different, except for exactly one duplicate (two entries the same).
|
||||
// Uses your binary search tree implementation to check for duplicates while generating numbers.
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "numbers.h"
|
||||
#include "bintree.h"
|
||||
|
||||
int compareFct(const void *a, const void *b)
|
||||
{
|
||||
return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); // a und b werden in int konvertiert und deren Werte miteinander verglichen
|
||||
// returns 1 for a>b or -1 for a<b
|
||||
// in bintree.c wird ueberprueft, ob compare eine positive oder eine negative Zahl zurueckgibt,
|
||||
// wenn a groeßer b, positiv und dann wird links nach Teilbauemen gesucht
|
||||
}
|
||||
|
||||
// Erzeugt len Zufallszahlen zwischen 1 und 2*len
|
||||
// alle einzigartig, außer genau ein Duplikat
|
||||
unsigned int *createNumbers(unsigned int len)
|
||||
{
|
||||
if (len < 2)
|
||||
return NULL;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
unsigned int *numbers = malloc(len * sizeof(unsigned int));
|
||||
if (!numbers)
|
||||
@ -33,27 +48,30 @@ unsigned int *createNumbers(unsigned int len)
|
||||
unsigned int count = 0;
|
||||
|
||||
// Zufallszahlen generieren, bis das Array voll ist
|
||||
while (count < len) {
|
||||
while (count < len)
|
||||
{
|
||||
unsigned int random = (rand() % (2 * len)) + 1;
|
||||
|
||||
int duplicate = 0; // Anfangswert für Duplikat-Check
|
||||
|
||||
root = addToTree(root, &random, sizeof(random), compareFct, &duplicate);
|
||||
|
||||
if (root == NULL) {
|
||||
if (root == NULL)
|
||||
{
|
||||
free(numbers);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!duplicate) { // Zahl war neu → ins Array einfügen
|
||||
if (!duplicate)
|
||||
{
|
||||
numbers[count++] = random;
|
||||
}
|
||||
// duplicate == 1 → Zahl existiert schon, neue Zahl generieren
|
||||
}
|
||||
|
||||
// Jetzt len eindeutige Zahlen erzeugt → ein Duplikat erzwingen
|
||||
// genau ein Duplikat erzeugen
|
||||
unsigned int idx1 = rand() % len;
|
||||
unsigned int idx2 = rand() % len;
|
||||
while (idx2 == idx1) // sicherstellen, dass es eine andere Position ist
|
||||
while (idx2 == idx1)
|
||||
idx2 = rand() % len;
|
||||
|
||||
numbers[idx2] = numbers[idx1];
|
||||
@ -64,37 +82,23 @@ unsigned int *createNumbers(unsigned int len)
|
||||
return numbers;
|
||||
}
|
||||
|
||||
// Jetzt len eindeutige Zahlen erzeugt ⇒ wir müssen ein Duplikat erzwingen
|
||||
unsigned int idx1 = rand() % len;
|
||||
unsigned int idx2 = rand() % len;
|
||||
while (idx2 == idx1)
|
||||
idx2 = rand() % len;
|
||||
|
||||
numbers[idx2] = numbers[idx1]; // zweites Exemplar
|
||||
|
||||
clearTree(root);
|
||||
return numbers;
|
||||
}
|
||||
|
||||
|
||||
// Returns only the only number in numbers which is present twice. Returns zero on errors.
|
||||
// findet die eine doppelte Zahl im Array
|
||||
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
||||
{
|
||||
if(len>0)
|
||||
{
|
||||
unsigned int duplicate = 0;
|
||||
if (!numbers || len < 2)
|
||||
return 0;
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
unsigned int v1 = numbers[i];
|
||||
for (unsigned int j = i + 1; j < len; j++)
|
||||
{
|
||||
unsigned int v2 = numbers[j];
|
||||
if(v1==v2)
|
||||
{
|
||||
return v1;
|
||||
}
|
||||
}
|
||||
if (numbers[i] == numbers[j])
|
||||
return numbers[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef NUMBERS_H
|
||||
#define NUMBERS_H
|
||||
|
||||
|
||||
int compareFct(const void *a, const void *b);
|
||||
// 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.
|
||||
|
||||
115
numbers_no_tree.c
Normal file
115
numbers_no_tree.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#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. */
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Vergleichsfunktion für qsort (Aufsteigend sortieren)
|
||||
// -------------------------------------------------------------
|
||||
static int compareUnsignedInt(const void *a, const void *b)
|
||||
{
|
||||
const unsigned int *ia = a;
|
||||
const unsigned int *ib = b;
|
||||
|
||||
if (*ia < *ib) return -1;
|
||||
if (*ia > *ib) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// createNumbers
|
||||
// Erzeugt ein Array aus len Zufallszahlen (1..2*len), alle verschieden.
|
||||
// Danach wird genau EIN zufälliger Eintrag dupliziert.
|
||||
// Parameter: len = Anzahl der gewünschten Zufallszahlen
|
||||
// Rückgabe: Pointer auf das erzeugte Array
|
||||
// -------------------------------------------------------------
|
||||
unsigned int *createNumbers(unsigned int len)
|
||||
{
|
||||
if (len < 2)
|
||||
return NULL;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
unsigned int *numbers = malloc(len * sizeof(unsigned int));
|
||||
if (!numbers)
|
||||
return NULL;
|
||||
|
||||
unsigned int count = 0;
|
||||
|
||||
// alle Werte verschieden erzeugen
|
||||
while (count < len)
|
||||
{
|
||||
unsigned int value = (rand() % (2 * len)) + 1;
|
||||
|
||||
// Duplikatsprüfung
|
||||
int exists = 0;
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
if (numbers[i] == value) {
|
||||
exists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
numbers[count++] = value;
|
||||
}
|
||||
|
||||
// EIN Duplikat erzeugen
|
||||
unsigned int i1 = rand() % len;
|
||||
unsigned int i2 = rand() % len;
|
||||
while (i2 == i1)
|
||||
i2 = rand() % len;
|
||||
|
||||
numbers[i2] = numbers[i1];
|
||||
|
||||
return numbers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// getDuplicate
|
||||
// Findet die einzige Zahl, die im Array zweimal vorkommt.
|
||||
// Sortiert dazu eine Kopie des Arrays und vergleicht benachbarte Werte.
|
||||
// Parameter: numbers = Array von Zufallszahlen
|
||||
// len = Anzahl der Elemente
|
||||
// Rückgabe: die doppelte Zahl oder 0 bei Fehler
|
||||
// -------------------------------------------------------------
|
||||
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
|
||||
{
|
||||
if (!numbers || len < 2)
|
||||
return 0;
|
||||
|
||||
// Kopie erzeugen, damit das Original unverändert bleibt
|
||||
unsigned int *copy = malloc(len * sizeof(unsigned int));
|
||||
if (!copy)
|
||||
return 0;
|
||||
|
||||
memcpy(copy, numbers, len * sizeof(unsigned int));
|
||||
|
||||
// Sortieren
|
||||
qsort(copy, len, sizeof(unsigned int), compareUnsignedInt);
|
||||
|
||||
// benachbarte Elemente vergleichen
|
||||
unsigned int duplicate = 0;
|
||||
for (unsigned int i = 1; i < len; i++) {
|
||||
if (copy[i] == copy[i - 1]) {
|
||||
duplicate = copy[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(copy);
|
||||
return duplicate;
|
||||
}
|
||||
BIN
numbers_no_tree.o
Normal file
BIN
numbers_no_tree.o
Normal file
Binary file not shown.
Binary file not shown.
BIN
run_numbersTests.exe
Normal file
BIN
run_numbersTests.exe
Normal file
Binary file not shown.
BIN
runbintreeTests.exe
Normal file
BIN
runbintreeTests.exe
Normal file
Binary file not shown.
BIN
runstackTests.exe
Normal file
BIN
runstackTests.exe
Normal file
Binary file not shown.
25
stack.c
25
stack.c
@ -1,16 +1,14 @@
|
||||
#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)
|
||||
{
|
||||
if(stack && data){
|
||||
if (!data)
|
||||
{
|
||||
return stack; //Nichts pushen
|
||||
}
|
||||
|
||||
StackNode *t = (StackNode *)malloc(sizeof(StackNode));
|
||||
if(!t)
|
||||
{
|
||||
@ -19,7 +17,7 @@ StackNode *push(StackNode *stack, void *data)
|
||||
t->next = stack;
|
||||
t->data = data;
|
||||
return t; //Gibt den ersten StackNode des Stacks zurueck
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -27,12 +25,11 @@ StackNode *push(StackNode *stack, void *data)
|
||||
// freed by caller.)
|
||||
StackNode *pop(StackNode *stack)
|
||||
{
|
||||
if(stack)
|
||||
if(stack == NULL)
|
||||
{
|
||||
StackNode *t = stack->next; //Naechstes Element im Stack wird erstes Element
|
||||
free(stack);
|
||||
return t;
|
||||
return NULL;
|
||||
}
|
||||
return stack->next;
|
||||
}
|
||||
|
||||
// Returns the data of the top element.
|
||||
@ -50,8 +47,8 @@ void clearStack(StackNode *stack)
|
||||
{
|
||||
while(stack)
|
||||
{
|
||||
StackNode *tmp = stack;
|
||||
stack = stack->next;
|
||||
StackNode *tmp = stack; //merkt sich den momentanen obersten Knoten
|
||||
stack = stack->next; //setzt den obersten Knoten auf den Zweiten im Stack
|
||||
free(tmp->data);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
153
test_numbers.c
Normal file
153
test_numbers.c
Normal file
@ -0,0 +1,153 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
#include "numbers.h"
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Hilfsfunktion: zählt, wie oft ein Wert im Array vorkommt
|
||||
// -------------------------------------------------------------
|
||||
static unsigned int countOccurrences(const unsigned int *arr, unsigned int len, unsigned int value)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
if (arr[i] == value)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Test 1: Array wird korrekt erzeugt (nicht NULL)
|
||||
// -------------------------------------------------------------
|
||||
void test_createNumbersReturnsNotNull(void)
|
||||
{
|
||||
unsigned int len = 20;
|
||||
unsigned int *numbers = createNumbers(len);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(numbers);
|
||||
|
||||
free(numbers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Test 2: Alle Zahlen liegen im erlaubten Bereich (1..2*len)
|
||||
// -------------------------------------------------------------
|
||||
void test_numbersAreInCorrectRange(void)
|
||||
{
|
||||
unsigned int len = 50;
|
||||
unsigned int *numbers = createNumbers(len);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(numbers);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(numbers[i] >= 1);
|
||||
TEST_ASSERT_TRUE(numbers[i] <= 2 * len);
|
||||
}
|
||||
|
||||
free(numbers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Test 3: Es gibt GENAU EIN Duplikat
|
||||
// -------------------------------------------------------------
|
||||
void test_exactlyOneDuplicateExists(void)
|
||||
{
|
||||
unsigned int len = 80;
|
||||
unsigned int *numbers = createNumbers(len);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(numbers);
|
||||
|
||||
unsigned int duplicatesFound = 0;
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
unsigned int occurrences = countOccurrences(numbers, len, numbers[i]);
|
||||
if (occurrences == 2)
|
||||
duplicatesFound++;
|
||||
}
|
||||
|
||||
// Da das Duplikat an zwei Positionen vorkommt,
|
||||
// erwarten wir duplicatesFound == 2
|
||||
TEST_ASSERT_EQUAL_UINT(2, duplicatesFound);
|
||||
|
||||
free(numbers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Test 4: getDuplicate() findet die richtige doppelte Zahl
|
||||
// -------------------------------------------------------------
|
||||
void test_getDuplicateFindsCorrectValue(void)
|
||||
{
|
||||
unsigned int len = 100;
|
||||
unsigned int *numbers = createNumbers(len);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(numbers);
|
||||
|
||||
unsigned int duplicate = getDuplicate(numbers, len);
|
||||
|
||||
TEST_ASSERT_TRUE(duplicate >= 1);
|
||||
TEST_ASSERT_TRUE(duplicate <= 2 * len);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT(2, countOccurrences(numbers, len, duplicate));
|
||||
|
||||
free(numbers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Test 5: createNumbers() erzeugt len Elemente
|
||||
// -------------------------------------------------------------
|
||||
void test_arrayLengthIsCorrect(void)
|
||||
{
|
||||
unsigned int len = 30;
|
||||
unsigned int *numbers = createNumbers(len);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(numbers);
|
||||
|
||||
// Unity-Funktion prüft nicht direkt Länge, aber wir können checken,
|
||||
// ob Zugriff auf alle Elemente möglich ist (Segfault würde Test crashen).
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
TEST_ASSERT_TRUE(numbers[i] >= 1);
|
||||
|
||||
free(numbers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Leere setUp/tearDown
|
||||
// -------------------------------------------------------------
|
||||
void setUp(void) {}
|
||||
void tearDown(void) {}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Hauptprogramm für Unity-Tests
|
||||
// -------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
|
||||
printf("\n============================\nNumbers tests\n============================\n");
|
||||
|
||||
RUN_TEST(test_createNumbersReturnsNotNull);
|
||||
RUN_TEST(test_numbersAreInCorrectRange);
|
||||
RUN_TEST(test_exactlyOneDuplicateExists);
|
||||
RUN_TEST(test_getDuplicateFindsCorrectValue);
|
||||
RUN_TEST(test_arrayLengthIsCorrect);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
||||
|
||||
72
test_stack.c
Normal file
72
test_stack.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "stack.h"
|
||||
|
||||
//Testfunkionen zu push, pull, top & clearStack schreiben
|
||||
|
||||
void setUp()
|
||||
{
|
||||
}
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
void test(char *name, int condition) {
|
||||
if (condition) {
|
||||
printf("[OK] %s\n", name);
|
||||
} else {
|
||||
printf("[FAIL] %s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
StackNode *stack = NULL;
|
||||
|
||||
// Werte dynamisch anlegen
|
||||
int *val1 = malloc(sizeof(int));
|
||||
*val1 = 5;
|
||||
stack = push(stack, val1);
|
||||
test("push(5) legt 5 oben auf den Stack", *(int*)stack->data == 5);
|
||||
|
||||
int *val2 = malloc(sizeof(int));
|
||||
*val2 = 6;
|
||||
stack = push(stack, val2);
|
||||
test("push(6) legt 6 oben auf den Stack", *(int*)stack->data == 6);
|
||||
|
||||
int *val3 = malloc(sizeof(int));
|
||||
*val3 = 24;
|
||||
stack = push(stack, val3);
|
||||
test("push(24) legt 24 oben auf den Stack", *(int*)stack->data == 24);
|
||||
|
||||
// Test top()
|
||||
int t = *(int*)top(stack);
|
||||
test("top() liefert 24", t == 24);
|
||||
|
||||
// Test pop()
|
||||
StackNode *tmp;
|
||||
|
||||
tmp = stack;
|
||||
stack = pop(stack);
|
||||
free(tmp->data); // Daten freigeben
|
||||
free(tmp); // Knoten freigeben
|
||||
test("pop() entfernt 24, 6 ist jetzt oben", *(int*)stack->data == 6);
|
||||
|
||||
tmp = stack;
|
||||
stack = pop(stack);
|
||||
free(tmp->data);
|
||||
free(tmp);
|
||||
test("pop() entfernt 6, 5 ist jetzt oben", *(int*)stack->data == 5);
|
||||
|
||||
tmp = stack;
|
||||
stack = pop(stack);
|
||||
free(tmp->data);
|
||||
free(tmp);
|
||||
test("pop() entfernt 5, Stack ist jetzt leer", stack == NULL);
|
||||
|
||||
// Am Ende Stack leeren (falls noch Elemente übrig)
|
||||
clearStack(stack);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user