diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..302edd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +streamii.log +tamagotchi.log diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b74b95f --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +CC = gcc +CFLAGS = -Wall -Wextra -std=c11 -D_DEFAULT_SOURCE +LDFLAGS = -lncurses + +# Executable name +TARGET = streamii_tamagotchi + +# Source files +SRCS = main.c tamagotchi.c ui.c + +# Object files +OBJS = $(SRCS:.c=.o) + +# Default target +all: $(TARGET) + +# Linking the target executable +$(TARGET): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +# Compiling source files +%.o: %.c + $(CC) $(CFLAGS) -c $< + +# Clean up +clean: + rm -f $(OBJS) $(TARGET) + +# Phony targets +.PHONY: all clean \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..6cbb6fd --- /dev/null +++ b/main.c @@ -0,0 +1,95 @@ +#include <ncurses.h> +#include <unistd.h> +#include <stdio.h> +#include "tamagotchi.h" +#include "ui.h" + +int main() { + // Open a log file for debugging + FILE *log_file = fopen("streamii.log", "w"); + if (!log_file) { + perror("Failed to open log file"); + return 1; + } + + // Log start of the game + fprintf(log_file, "Streamii game started\n"); + fflush(log_file); + + // Initialize Tamagotchi + Tamagotchi streamii; + init_tamagotchi(&streamii); + fprintf(log_file, "Streamii initialized\n"); + fflush(log_file); + + // Initialize UI + init_ui(); + fprintf(log_file, "UI initialized\n"); + fflush(log_file); + + // Game loop + while (streamii.is_alive) { + // Update Tamagotchi stats + update_tamagotchi_stats(&streamii); + fprintf(log_file, "Updated Streamii stats\n"); + fflush(log_file); + + // Clear and redraw screen + clear(); + + // Draw Tamagotchi + draw_tamagotchi(&streamii); + + // Draw stats + draw_stats(&streamii); + + // Display menu + display_menu(); + + // Refresh screen + refresh(); + + // Get user input + int ch = get_user_input(); + fprintf(log_file, "User input received: %d\n", ch); + fflush(log_file); + + // Handle user input + switch (ch) { + case KEY_F(1): // F1 to feed + feed_tamagotchi(&streamii); + fprintf(log_file, "Fed Streamii\n"); + break; + case KEY_F(2): // F2 to sleep + sleep_tamagotchi(&streamii); + fprintf(log_file, "Made Streamii sleep\n"); + break; + case KEY_F(3): // F3 to play + play_with_tamagotchi(&streamii); + fprintf(log_file, "Played with Streamii\n"); + break; + case KEY_F(4): // F4 to clean + clean_tamagotchi(&streamii); + fprintf(log_file, "Cleaned Streamii\n"); + break; + case 'q': // Q to quit + case 'Q': + streamii.is_alive = 0; + fprintf(log_file, "User quit the game\n"); + break; + } + + // Small delay to control game speed + usleep(200000); // 200ms + } + + // Show game over screen + show_game_over(); + fprintf(log_file, "Game over\n"); + + // Cleanup + cleanup_ui(); + fclose(log_file); + + return 0; +} \ No newline at end of file diff --git a/main.o b/main.o new file mode 100644 index 0000000..d0528d0 Binary files /dev/null and b/main.o differ diff --git a/streamii_tamagotchi b/streamii_tamagotchi new file mode 100755 index 0000000..98359e4 Binary files /dev/null and b/streamii_tamagotchi differ diff --git a/tamagotchi.c b/tamagotchi.c new file mode 100644 index 0000000..c24be51 --- /dev/null +++ b/tamagotchi.c @@ -0,0 +1,100 @@ +#include <stdlib.h> +#include "tamagotchi.h" + +// Initialize Tamagotchi with default stats +void init_tamagotchi(Tamagotchi *tama) { + tama->hunger = 50; + tama->energy = 100; + tama->happiness = 75; + tama->cleanliness = 100; + tama->state = HAPPY; + tama->age = 0; + tama->is_alive = 1; +} + +// Feed the Tamagotchi +void feed_tamagotchi(Tamagotchi *tama) { + if (!tama->is_alive) return; + + tama->hunger += 20; + if (tama->hunger > MAX_STAT) tama->hunger = MAX_STAT; + + tama->cleanliness -= 10; + if (tama->cleanliness < MIN_STAT) tama->cleanliness = MIN_STAT; + + tama->happiness += 5; + if (tama->happiness > MAX_STAT) tama->happiness = MAX_STAT; +} + +// Make Tamagotchi sleep +void sleep_tamagotchi(Tamagotchi *tama) { + if (!tama->is_alive) return; + + tama->energy += 30; + if (tama->energy > MAX_STAT) tama->energy = MAX_STAT; + + tama->hunger -= 10; + if (tama->hunger < MIN_STAT) tama->hunger = MIN_STAT; +} + +// Play with Tamagotchi +void play_with_tamagotchi(Tamagotchi *tama) { + if (!tama->is_alive) return; + + tama->happiness += 15; + if (tama->happiness > MAX_STAT) tama->happiness = MAX_STAT; + + tama->energy -= 15; + tama->hunger -= 10; + + if (tama->energy < MIN_STAT) tama->energy = MIN_STAT; + if (tama->hunger < MIN_STAT) tama->hunger = MIN_STAT; +} + +// Clean Tamagotchi +void clean_tamagotchi(Tamagotchi *tama) { + if (!tama->is_alive) return; + + tama->cleanliness += 30; + if (tama->cleanliness > MAX_STAT) tama->cleanliness = MAX_STAT; + + tama->happiness += 5; + if (tama->happiness > MAX_STAT) tama->happiness = MAX_STAT; +} + +// Update Tamagotchi stats each game cycle +void update_tamagotchi_stats(Tamagotchi *tama) { + if (!tama->is_alive) return; + + // Gradually decrease stats + tama->hunger -= 5; + tama->energy -= 3; + tama->happiness -= 2; + tama->cleanliness -= 1; + tama->age++; + + // Determine state based on stats + if (tama->hunger <= 20) tama->state = HUNGRY; + else if (tama->energy <= 20) tama->state = SLEEPY; + else if (tama->happiness <= 20) tama->state = BORED; + else tama->state = HAPPY; + + // Check if Tamagotchi dies + if (tama->hunger <= MIN_STAT || + tama->energy <= MIN_STAT || + tama->happiness <= MIN_STAT) { + tama->is_alive = 0; + } +} + +// Get facial expression based on current state +const char* get_tamagotchi_face(Tamagotchi *tama) { + switch (tama->state) { + case HAPPY: return "^w^"; + case HUNGRY: return "T_T"; + case SLEEPY: return "~_~"; + case SICK: return "x_x"; + case BORED: return "-_-"; + default: return "o_o"; + } +} \ No newline at end of file diff --git a/tamagotchi.h b/tamagotchi.h new file mode 100644 index 0000000..2faaa82 --- /dev/null +++ b/tamagotchi.h @@ -0,0 +1,36 @@ +#ifndef TAMAGOTCHI_H +#define TAMAGOTCHI_H + +#define MAX_STAT 100 +#define MIN_STAT 0 + +// Tamagotchi states +typedef enum { + HAPPY, + HUNGRY, + SLEEPY, + SICK, + BORED +} TamaState; + +// Tamagotchi structure +typedef struct { + int hunger; // 0-100 + int energy; // 0-100 + int happiness; // 0-100 + int cleanliness; // 0-100 + TamaState state; + int age; // in game cycles + int is_alive; +} Tamagotchi; + +// Function prototypes +void init_tamagotchi(Tamagotchi *tama); +void feed_tamagotchi(Tamagotchi *tama); +void sleep_tamagotchi(Tamagotchi *tama); +void play_with_tamagotchi(Tamagotchi *tama); +void clean_tamagotchi(Tamagotchi *tama); +void update_tamagotchi_stats(Tamagotchi *tama); +const char* get_tamagotchi_face(Tamagotchi *tama); + +#endif // TAMAGOTCHI_H \ No newline at end of file diff --git a/tamagotchi.o b/tamagotchi.o new file mode 100644 index 0000000..8487ed5 Binary files /dev/null and b/tamagotchi.o differ diff --git a/ui.c b/ui.c new file mode 100644 index 0000000..327dba3 --- /dev/null +++ b/ui.c @@ -0,0 +1,101 @@ +#include <ncurses.h> +#include <string.h> +#include "ui.h" +#include "tamagotchi.h" + +// Initialize UI +void init_ui(void) { + // Initialize ncurses + initscr(); // Start ncurses mode + cbreak(); // Line buffering disabled + noecho(); // Don't echo() while we do getch + keypad(stdscr, TRUE); // We get F1, F2 etc.. + curs_set(0); // Hide cursor + timeout(100); // Set non-blocking input with 100ms delay +} + +// Cleanup UI +void cleanup_ui(void) { + endwin(); // End ncurses mode +} + +// Draw Streamii +void draw_tamagotchi(Tamagotchi *tama) { + int max_y, max_x; + getmaxyx(stdscr, max_y, max_x); + + // Streamii body + int start_y = max_y / 2 - 5; + int start_x = max_x / 2 - 10; + + // Clear previous drawing + clear(); + + // Streamii body (simplified ASCII art) + mvprintw(start_y, start_x, " /\\___/\\ "); + mvprintw(start_y + 1, start_x, " ( o o ) "); + mvprintw(start_y + 2, start_x, " / ^ \\ "); + mvprintw(start_y + 3, start_x, " / \\___/ \\ "); + + // Facial expression + const char* face = get_tamagotchi_face(tama); + mvprintw(start_y + 2, start_x + 6, "%s", face); +} + +// Draw stats +void draw_stats(Tamagotchi *tama) { + int max_y, max_x; + getmaxyx(stdscr, max_y, max_x); + + // Stats area + mvprintw(max_y - 5, 2, "Hunger: ["); + for (int i = 0; i < tama->hunger / 10; i++) + printw("#"); + mvprintw(max_y - 4, 2, "Energy: ["); + for (int i = 0; i < tama->energy / 10; i++) + printw("#"); + mvprintw(max_y - 3, 2, "Happiness: ["); + for (int i = 0; i < tama->happiness / 10; i++) + printw("#"); + mvprintw(max_y - 2, 2, "Cleanliness: ["); + for (int i = 0; i < tama->cleanliness / 10; i++) + printw("#"); + + // Age and status + mvprintw(max_y - 1, 2, "Age: %d | Status: %s", + tama->age, + tama->is_alive ? "Alive" : "DEAD"); +} + +// Display menu +void display_menu(void) { + int max_y, max_x; + getmaxyx(stdscr, max_y, max_x); + + mvprintw(max_y - 7, 2, "Controls:"); + mvprintw(max_y - 6, 2, "F1: Feed"); + mvprintw(max_y - 6, 20, "F2: Sleep"); + mvprintw(max_y - 5, 2, "F3: Play"); + mvprintw(max_y - 5, 20, "F4: Clean"); + mvprintw(max_y - 4, 2, "Q: Quit"); +} + +// Get user input +int get_user_input(void) { + return getch(); +} + +// Show game over screen +void show_game_over(void) { + int max_y, max_x; + getmaxyx(stdscr, max_y, max_x); + + clear(); + mvprintw(max_y/2, max_x/2 - 5, "GAME OVER"); + mvprintw(max_y/2 + 1, max_x/2 - 10, "Your streamii has died :("); + refresh(); + + // Wait for key press + timeout(-1); + getch(); +} \ No newline at end of file diff --git a/ui.h b/ui.h new file mode 100644 index 0000000..799ad91 --- /dev/null +++ b/ui.h @@ -0,0 +1,15 @@ +#ifndef UI_H +#define UI_H + +#include "tamagotchi.h" + +// UI function prototypes +void init_ui(void); +void cleanup_ui(void); +void draw_tamagotchi(Tamagotchi *tama); +void draw_stats(Tamagotchi *tama); +void display_menu(void); +int get_user_input(void); +void show_game_over(void); + +#endif // UI_H \ No newline at end of file diff --git a/ui.o b/ui.o new file mode 100644 index 0000000..343860a Binary files /dev/null and b/ui.o differ