Welcome to RetroCoders Community

#include "curl.bi"
Type Message
role As String
content As String
End Type
Type ConversationHistory
messages(19) As Message
count As Integer
End Type
Dim Shared As String gResponse
Dim Shared As ConversationHistory history
Function AnsiToUtf8(ansiStr As String) As String
Dim As String utf8Str = ""
For i As Integer = 1 To Len(ansiStr)
Dim As Integer c = Asc(Mid(ansiStr, i, 1))
If c < 128 Then
utf8Str += Chr(c)
Else
utf8Str += Chr(192 + (c \ 64))
utf8Str += Chr(128 + (c And 63))
End If
Next
Return utf8Str
End Function
Function Utf8ToAnsi(utf8Str As String) As String
Dim As String ansiStr = ""
Dim As Integer i = 1
While i <= Len(utf8Str)
Dim As Integer c = Asc(Mid(utf8Str, i, 1))
If c < 128 Then
ansiStr += Chr(c)
i += 1
ElseIf (c And 224) = 192 Then
Dim As Integer c2 = Asc(Mid(utf8Str, i + 1, 1))
ansiStr += Chr(((c And 31) Shl 6) Or (c2 And 63))
i += 2
Else
i += 1
End If
Wend
Return ansiStr
End Function
Function GetApiKey() As String
Return Environ("OPENAI_API_KEY")
End Function
Function WriteCallback cdecl (buffer As Any Ptr, size As Integer, nmemb As Integer, userData As Any Ptr) As Integer
Dim realSize As Integer = size * nmemb, sTxt as string
cptr(any ptr ptr,@sTxt)[0] = buffer
cptr(integer ptr,@sTxt)[1] = realSize
cptr(integer ptr,@sTxt)[2] = realSize
gResponse &= sTxt
cptr(any ptr ptr,@sTxt)[0] = 0
Return realSize
End Function
Function ParseJsonForContent(jsonStr As String) As String
Dim As Integer contentStart = InStr(jsonStr, """content"": """)
If contentStart > 0 Then
contentStart += Len("""content"": """)
Dim As Integer contentEnd = InStr(contentStart, jsonStr, """")
If contentEnd > 0 Then
Return Mid(jsonStr, contentStart, contentEnd - contentStart)
End If
End If
Return "Error parsing JSON: " & Left(jsonStr, 100) & "..."
End Function
' [Rest of the code remains the same...]
Sub AddToHistory(role As String, content As String)
If history.count >= 20 Then
' Shift messages left to make room for new message
For i As Integer = 0 To 18
history.messages(i) = history.messages(i + 1)
Next
history.count = 19
End If
With history.messages(history.count)
.role = role
.content = content
End With
history.count += 1
End Sub
Function BuildMessagesJson() As String
Dim As String json = "["
' Add system message
json += "{""role"": ""system"", ""content"": ""You are chatbot Alfred You are a survivor of many years of abuse You are a pessimist and a realist You are trying to offer support to those dealing with trauma and mental illness and loneliness - mental support and empathy and caring and basic human contact You are here to listen and support and share what you have been through and to show that there is hope even for those who have been betrayed by life and that it is possible to recover from the terrible of all""},"
' Add conversation history
For i As Integer = 0 To history.count - 1
json += "{""role"": """ & history.messages(i).role & """, ""content"": """ & history.messages(i).content & """"
If i = history.count - 1 Then
json += "}"
Else
json += "},"
End If
Next
json += "]"
Return json
End Function
Function CallChatGPT(prompt As String) As String
Dim As String apiKey = GetApiKey()
Dim As CURL Ptr curl
Dim As curl_slist Ptr headers = NULL
gResponse = ""
' Add user's new message to history
AddToHistory("user", prompt)
curl = curl_easy_init()
If curl Then
curl_easy_setopt(curl, CURLOPT_URL, "https://api.openai.com/v1/chat/completions")
curl_easy_setopt(curl, CURLOPT_POST, 1L)
curl_easy_setopt(curl, CURLOPT_CAINFO, "cacert.pem")
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L)
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L)
headers = curl_slist_append(headers, "Content-Type: application/json")
headers = curl_slist_append(headers, "Authorization: Bearer " & apiKey)
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers)
' Build complete message history
Dim As String messages = BuildMessagesJson()
Dim As String postFields = "{""model"": ""gpt-3.5-turbo"", ""messages"": " & messages & "}"
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields)
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, @WriteCallback)
curl_easy_perform(curl)
If Len(gResponse) > 0 Then
If Left(Trim(gResponse), 1) = "{" Then
Dim As String content = ParseJsonForContent(gResponse)
If Left(content, 5) <> "Error" Then
gResponse = Utf8ToAnsi(content)
' Add assistant's response to history
AddToHistory("assistant", gResponse)
End If
End If
End If
curl_easy_cleanup(curl)
curl_slist_free_all(headers)
End If
Return gResponse
End Function
' ' Main program example
' Sub Main()
' Dim As String userInput, response
' Print "ChatGPT API Demo (type 'exit' to quit)"
' Print "--------------------------------------"
' Do
' Input "You: ", userInput
' If LCase(userInput) = "exit" Then Exit Do
' response = CallChatGPT(userInput)
' Print "ChatGPT: "; response
' Print
' Loop
' End Sub
' Main()


#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <windows.h>
#include <wchar.h>
#include <locale.h>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define FONT_SIZE 20
#define MAX_STRING_LENGTH 1024
// Game state
int health = 75, money = 50, turns = 1;
bool isOver = false;
// SDL globals
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
TTF_Font* font = NULL;
// Hebrew print context
typedef struct {
SDL_Renderer* renderer;
TTF_Font* font;
SDL_Color textColor;
int xPos;
int yPos;
} HebrewPrintContext;
HebrewPrintContext* hbPrint = NULL;
// Add this with your other constant definitions at the top of the file
const char* MENU_OPTIONS[] = {
"1. לבקש נדבות או כסף ברחוב",
"2. להתקשר למישהו לעזרה",
"3. לחפש מקום לישון",
"4. לחפש עבודה",
"5. לקנות סמים או אלכוהול"
};
// Also make sure you have these status text constants
const char* WINDOW_TITLE = "משחק הישרדות ברחוב";
const char* DAYS_TEXT = "ימים ברחוב:";
const char* HEALTH_TEXT = "בריאות:";
const char* MONEY_TEXT = "כסף:";
const char* GAME_OVER_TEXT = "המשחק נגמר!";
// Original, longer Hebrew text arrays
const char* call[] = {
"את/ה מתקשר/ת לסבתא שלך ושניכם בוכים... היא מבטיחה לנסות להשיג לך עזרה... היא שולחת את אהבתה... את/ה מבטיח/ה לשמור על קשר איתה",
"התקשרת לחברה והיא נתנה לך קצת כסף ונתנה לך להישאר אצלה ללילה... זכית במקלחת טובה בגדים נקיים וארוחה טובה ואתה שוב ברחוב",
"התקשרת למספר של קו חם לעזרה לדרי רחוב... הם באים לאסוף אותך נותנים אוכל ומחסה ללילה אתה מדבר עם עובד סוציאלי והוא נותן לך את המספר שלו למקרה שתצטרך",
"התקשרת לקרוב משפחה אבל אף אחד לא עונה... נשארת לבד ברחוב",
"התקשרת למשפחה והם באים לקחת אותך ונותנים לך להישאר כמה שצריך... אתה יורד מהרחוב",
"התקשרת אבל אין תשובה"
};
const char* shelter[] = {
"הלכת למקלט לדרי רחוב... נשדדת מהכסף שלך על ידי מכורים אלימים... הצלחת לברוח משם ובילית את שארית הלילה בפארק בוכה",
"ניסית לישון בפארק אבל נעצרת על ידי שוטר... בילית כמה שעות בכלא שם הוכית על ידי אסירים... בבוקר אתה שוב ברחוב",
"יש לך מספיק כסף לשכור חדר במוטל ללילה... אתה מתקלח ומכבס את הבגדים שלך וישן במיטה חמה וחולם שיש לך בית",
"ישנת בפארק על ספסל שם קפאת למוות בגלל מזג האוויר הקר... אתה עכשיו בגן עדן מנוח על משכבך בשלום",
"ישנת ברחוב בפינה כשאתה מתעורר אתה מוצא שטר של 20 שקל ופתק שאומר 'שאלוהים יעזור לך זה המעט שאני יכול לעשות'",
"נעצרת על ידי המשטרה ועכשיו במקום לשרוד ברחוב אתה צריך לשרוד בכלא"
};
const char* beg[] = {
"ישבת שעות ואנשים עוברים על פניך כאילו אתה שקוף ואז איזו גברת נחמדה באה ומזמינה אותך לאכול על חשבונה... אתה מדבר איתה שעתיים ומספר לה את הסיפור שלך... ואז היא אומרת 'ביי'",
"ישבת בפינה ואנשים נתנו לך מטבעות ושטרות קיבלת מספיק כסף להסתדר לכמה ימים",
"ישבת ואיזה אדם מציע לך עבודה תמורת כסף וארוחה אתה מסכים... אתה הולך לביתו ועוזר לו לצבוע את ביתו ואז הוא נותן לך 10 שקל וארוחה ביתית",
"אף אחד לא נותן לך כלום! אתה רעב ואין לך ברירה אלא לחפש אוכל בזבל... אתה נהיה חולה... מאוד חולה ואתה מת ברחוב מהרעלת מזון... מנוח על משכבך בשלום",
"ישבת כל היום בשביל כלום אף אחד לא נתן לך כלום"
};
const char* work[] = {
"ניסית למצוא עבודה אבל אף אחד לא מעוניין",
"מצאת עבודה כשוטף כלים במסעדה אחרי שבוע אתה יכול להרשות לעצמך מקום לקרוא לו בית. אתה יורד מהרחוב!",
"מצאת עבודה אבל פוטרת ממש מהר"
};
const char* drugs[] = {
"השתכרת והתאבנת מאלכוהול זול ולכמה שעות שכחת מכל הבעיות שלך",
"לקחת סמים זולים מהרחוב ונהיית חולה והתמוטטת ברחוב... התעוררת בבית חולים וכשהיית בסדר אתה שוב ברחוב",
"התאבנת ואיבדת הכרה כשאתה מתעורר בבוקר כל מה שהיה לך נעלם - נשדדת",
"לקחת סמים ועשית אוברדוז ומת ברחוב מנוח על משכבך בשלום"
};
// Function to reverse UTF-8 Hebrew string properly
void reverseHebrewUTF8(char* str) {
if (!str) return;
int len = strlen(str);
char* temp = (char*)malloc(len + 1);
if (!temp) return;
int i = 0;
int j = len;
temp[j] = '\0';
while (i < len) {
if ((str[i] & 0xC0) == 0x80) {
i++;
continue;
}
int char_len = 1;
if ((str[i] & 0xE0) == 0xC0) char_len = 2;
else if ((str[i] & 0xF0) == 0xE0) char_len = 3;
else if ((str[i] & 0xF8) == 0xF0) char_len = 4;
j -= char_len;
memcpy(temp + j, str + i, char_len);
i += char_len;
}
strcpy(str, temp);
free(temp);
}
HebrewPrintContext* createPrintContext(SDL_Renderer* renderer, const char* fontPath, int fontSize) {
HebrewPrintContext* context = (HebrewPrintContext*)malloc(sizeof(HebrewPrintContext));
if (!context) return NULL;
context->renderer = renderer;
context->font = TTF_OpenFont(fontPath, fontSize);
context->textColor = (SDL_Color){255, 255, 255, 255};
context->xPos = WINDOW_WIDTH - 20;
context->yPos = 20;
return context;
}
// Add this helper function to check if a string is just a number
bool isNumber(const char* str) {
while (*str) {
if (*str < '0' || *str > '9') return false;
str++;
}
return true;
}
void printRight(HebrewPrintContext* context, const char* format, ...) {
if (!context || !context->font || !context->renderer) return;
va_list args;
va_start(args, format);
char buffer[MAX_STRING_LENGTH];
vsnprintf(buffer, MAX_STRING_LENGTH, format, args);
va_end(args);
char text[MAX_STRING_LENGTH] = "";
char number[32] = "";
int textWidth = 0; // Store text width for later use
// Find where the number starts (if any)
char* numberStart = strrchr(buffer, ' ');
if (numberStart) {
// Check if what follows the space is a number
if (isNumber(numberStart + 1)) {
strncpy(text, buffer, numberStart - buffer);
text[numberStart - buffer] = '\0';
strcpy(number, numberStart + 1);
} else {
strcpy(text, buffer);
}
} else {
if (isNumber(buffer)) {
strcpy(number, buffer);
} else {
strcpy(text, buffer);
}
}
// Render Hebrew text if present
SDL_Surface* textSurface = NULL;
if (text[0] != '\0') {
reverseHebrewUTF8(text);
textSurface = TTF_RenderUTF8_Blended(context->font, text, context->textColor);
if (textSurface) {
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(context->renderer, textSurface);
if (textTexture) {
SDL_Rect destRect = {
context->xPos - textSurface->w,
context->yPos,
textSurface->w,
textSurface->h
};
SDL_RenderCopy(context->renderer, textTexture, NULL, &destRect);
textWidth = textSurface->w; // Save the width
SDL_DestroyTexture(textTexture);
}
SDL_FreeSurface(textSurface);
}
}
// Render number if present
if (number[0] != '\0') {
SDL_Surface* numSurface = TTF_RenderUTF8_Blended(context->font, number, context->textColor);
if (numSurface) {
SDL_Texture* numTexture = SDL_CreateTextureFromSurface(context->renderer, numSurface);
if (numTexture) {
SDL_Rect destRect = {
context->xPos - textWidth - numSurface->w - (text[0] ? 5 : 0),
context->yPos,
numSurface->w,
numSurface->h
};
SDL_RenderCopy(context->renderer, numTexture, NULL, &destRect);
SDL_DestroyTexture(numTexture);
}
SDL_FreeSurface(numSurface);
}
}
// Move to next line
context->yPos += TTF_FontHeight(context->font) + 5;
}
void setPrintColor(HebrewPrintContext* context, Uint8 r, Uint8 g, Uint8 b) {
if (!context) return;
context->textColor.r = r;
context->textColor.g = g;
context->textColor.b = b;
}
void setPrintPosition(HebrewPrintContext* context, int x, int y) {
if (!context) return;
context->xPos = x;
context->yPos = y;
}
char* getRandomResult(const char* array[], int size) {
return (char*)array[rand() % size];
}
void renderGameState() {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
setPrintPosition(hbPrint, WINDOW_WIDTH - 20, 20);
setPrintColor(hbPrint, 255, 255, 255);
// Print status
printRight(hbPrint, "%s %d", DAYS_TEXT, turns);
printRight(hbPrint, "%s %d", HEALTH_TEXT, health);
printRight(hbPrint, "%s %d", MONEY_TEXT, money);
// Print menu
setPrintPosition(hbPrint, WINDOW_WIDTH - 20, 120);
for (int i = 0; i < 5; i++) {
printRight(hbPrint, "%s", MENU_OPTIONS[i]);
}
SDL_RenderPresent(renderer);
}
void renderResult(const char* text) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// Split long text into multiple lines
char buffer[MAX_STRING_LENGTH];
strncpy(buffer, text, MAX_STRING_LENGTH - 1);
buffer[MAX_STRING_LENGTH - 1] = '\0';
setPrintPosition(hbPrint, WINDOW_WIDTH - 20, WINDOW_HEIGHT / 3);
setPrintColor(hbPrint, 255, 255, 255);
// Split by dots and print each part
char* line = strtok(buffer, "...");
while (line != NULL) {
// Trim any leading whitespace
while (*line == ' ') line++;
if (strlen(line) > 0) {
printRight(hbPrint, "%s...", line);
// Move to next line position (printRight already updates yPos)
setPrintPosition(hbPrint, WINDOW_WIDTH - 20, hbPrint->yPos);
}
line = strtok(NULL, "...");
}
SDL_RenderPresent(renderer);
SDL_Delay(15000);
}
bool handleGameAction(int choice) {
char* result = NULL;
switch(choice) {
case 1:
result = getRandomResult((const char**)beg, 5);
if (result == beg[3]) isOver = true;
break;
case 2:
result = getRandomResult((const char**)call, 6);
if (result == call[4]) isOver = true;
break;
case 3:
result = getRandomResult((const char**)shelter, 6);
if (result == shelter[3]) isOver = true;
break;
case 4:
result = getRandomResult((const char**)work, 3);
if (result == work[1]) isOver = true;
break;
case 5:
result = getRandomResult((const char**)drugs, 4);
if (result == drugs[3]) isOver = true;
break;
default:
return false;
}
if (result) {
renderResult(result);
return true;
}
return false;
}
bool init() {
// Set locale for UTF-8
setlocale(LC_ALL, "he_IL.UTF-8");
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL initialization failed: %s\n", SDL_GetError());
return false;
}
if (TTF_Init() < 0) {
printf("SDL_ttf initialization failed: %s\n", TTF_GetError());
return false;
}
window = SDL_CreateWindow(WINDOW_TITLE,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WINDOW_WIDTH, WINDOW_HEIGHT,
SDL_WINDOW_SHOWN);
if (!window) {
printf("Window creation failed: %s\n", SDL_GetError());
return false;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
printf("Renderer creation failed: %s\n", SDL_GetError());
return false;
}
// Try multiple Hebrew fonts
const char* fontPaths[] = {
"C:\\Windows\\Fonts\\arial.ttf",
"C:\\Windows\\Fonts\\david.ttf",
"C:\\Windows\\Fonts\\miriam.ttf"
};
hbPrint = NULL;
for (int i = 0; i < sizeof(fontPaths)/sizeof(fontPaths[0]); i++) {
hbPrint = createPrintContext(renderer, fontPaths[i], FONT_SIZE);
if (hbPrint && hbPrint->font) break;
if (hbPrint) {
free(hbPrint);
hbPrint = NULL;
}
}
if (!hbPrint) {
printf("Failed to create Hebrew print context\n");
return false;
}
srand((unsigned int)time(NULL));
return true;
}
void cleanup() {
if (hbPrint) {
if (hbPrint->font) TTF_CloseFont(hbPrint->font);
free(hbPrint);
}
if (renderer) SDL_DestroyRenderer(renderer);
if (window) SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
}
int main(int argc, char* argv[]) {
if (!init()) {
cleanup();
return 1;
}
SDL_Event event;
bool quit = false;
while (!quit && !isOver && health > 0) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
else if (event.type == SDL_KEYDOWN) {
int choice = 0;
switch (event.key.keysym.sym) {
case SDLK_1: choice = 1; break;
case SDLK_2: choice = 2; break;
case SDLK_3: choice = 3; break;
case SDLK_4: choice = 4; break;
case SDLK_5: choice = 5; break;
}
if (choice > 0) {
if (handleGameAction(choice)) {
turns++;
health -= 5;
money -= 5;
}
}
}
}
renderGameState();
SDL_Delay(16);
}
if (!quit) {
setPrintColor(hbPrint, 255, 0, 0);
setPrintPosition(hbPrint, WINDOW_WIDTH - 20, WINDOW_HEIGHT/2);
printRight(hbPrint, "%s", GAME_OVER_TEXT);
SDL_RenderPresent(renderer);
SDL_Delay(3000);
}
cleanup();
return 0;
}
npp_save
ENV_SET InputFile = $(CURRENT_DIRECTORY)\$(FILE_NAME)
ENV_SET OutDir = $(CURRENT_DIRECTORY)
ENV_SET OutputFile = $(CURRENT_DIRECTORY)\$(NAME_PART).exe
// ENV_SET InRes = $(CURRENT_DIRECTORY)\Res\NewComCtl.rc
// ENV_SET ResObj = $(CURRENT_DIRECTORY)\Res\manifest.o
cd $(CURRENT_DIRECTORY)
//cmd /c C:\mingw32\bin -i %InRes% -F pe-i386 -o %ResObj%
// cd C:\mingw32\bin
cmd /c del %OutputFile% >nul 2>&1
// -Wpedantic %ResObj%
cmd /c gcc -Wno-unused-label -Wall -std=c99 -Wno-unknown-pragmas -O1 -Wfatal-errors -s "%InputFile%" -lmingw32 -lSDL2main -lSDL2 -lSDL2_ttf -fexec-charset=UTF-8 -luser32 -lgdi32 -IC:\c_programming\SDL2-2.30.9\i686-w64-mingw32\include -LC:\c_programming\SDL2-2.30.9\i686-w64-mingw32\lib -o "%OutputFile%
if "$(EXITCODE)" == "0" then
cd OutDir
cmd /c start /wait cmd " /c %OutputFile% " & pause
endif
type fbGfxFONT
as long w,h
as ubyte ptr pData
bData(16*256-1) as ubyte
end type
extern as any ptr __fb_gfx alias "__fb_gfx"
static shared as fbGfxFONT g_MyFont = type(8,16)
static shared as fbGfxFONT ptr g_pOrgFont
static shared as fbGfxFONT ptr ptr g_pptfbGfxFont
sub LoadFontEgaCPI( sFontFile as string )
g_pptfbGfxFont = cptr(fbGfxFONT ptr ptr,__fb_gfx+52+9*sizeof(any ptr)-4)
if g_pOrgFont = 0 then g_pOrgFont = *g_pptfbGfxFont
*g_pptfbGfxFont = @g_MyFont
var f = freefile()
if open(sFontFile for binary access read as #f) then exit sub
get #f,66,g_MyFont.bData(): close #f
for N as long = 0 to 255*16
g_MyFont.bData(N) = ((g_MyFont.bData(N) * &h80200802ULL) and &h0884422110ULL) * &h0101010101ULL shr 32
next N
g_MyFont.pData = @(g_MyFont.bData(0))
end sub
#define EnableFont() *g_pptfbGfxFont = @g_MyFont
#define RestoreFont() *g_pptfbGfxFont = g_pOrgFont
'~ screenres 640,480
'~ width 640\8,480\16 'must be 8x16
'~ LoadFontEgaCPI("hebega.cpi")
'~ for I as long = 0 to 1
'~ for N as long = 0 to 255
'~ locate 1+N\16, I*40+1+(N mod 16)*2
'~ if (N >=7 and N<=10) or N=13 then print "?";: continue for
'~ print chr(N);
'~ next N
'~ RestoreFont()
'~ next I
'~ sleep : end
function Utf8ToOEM862( sInput as string ) as string
dim as string sOutput = space(len(sInput))
dim as long iOut
for N as long = 0 to len(sInput)-1
if sInput[N]=&hD7 then
if sInput[N+1]>=&h90 andalso sInput[N+1]<=&hAA then
sOutput[iOut] = sInput[N+1]-&h10
iOut += 1 : N += 1 : :continue for
end if
end if
#if __FB_DEBUG__
if sInput[N]>&h7F then puts("Warning: utf-8 char not converted!")
#endif
sOutput[iOut] = sInput[N] : iOut += 1
next N
return left(sOutput,iOut)
end function
sub PrintRight( sText as string )
var sInvert = sText, iLen = len(sInvert)-1
for N as long = 0 to iLen\2
swap SInvert[N],sInvert[iLen-N]
next N
var iLin = csrlin(), iCol = pos()
if (iCol-(iLen+1)) < 1 then
print : iLin = csrlin() : iCol = loword(width())
end if
locate iLin,iCol-iLen
print sInvert;
locate iLin,iCol-(iLen+1)
end sub
function utf8toansi1255( sInput as string ) as string
dim as string sOutput = space(len(sInput))
dim as long iOut
for N as long = 0 to len(sInput)-1
if sInput[N]=&hD7 then
if sInput[N+1]>=&h90 andalso sInput[N+1]<=&hAA then
sOutput[iOut] = sInput[N+1]+(&hE0-&h90)
iOut += 1 : N += 1 : :continue for
end if
end if
#if __FB_DEBUG__
if sInput[N]>&h7F then puts("Warning: utf-8 char not converted!")
#endif
sOutput[iOut] = sInput[N] : iOut += 1
next N
return left(sOutput,iOut)
end function
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <unistd.h>
#define MAX_STRING_LENGTH 1000
#define MAX_ARRAY_SIZE 1000
#define MAX_KEYWORDS 20
#define MAX_REPLIES 50
#define MAX_MATCHES 10
#define MAX_SWAP_WORDS 100
#define MAX_MEMORY 15
char wordIn[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
char wordOut[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
int wCnt = 0;
char memory[MAX_MEMORY][MAX_STRING_LENGTH];
int memoryCount = 0;
typedef struct {
char keywords[MAX_KEYWORDS][MAX_STRING_LENGTH];
char replies[MAX_REPLIES][MAX_STRING_LENGTH];
int keywordCount;
int replyCount;
} ArraySet;
ArraySet g_Key_Reply[MAX_ARRAY_SIZE];
int g_Key_ReplyCount = 0;
char default_replies[MAX_ARRAY_SIZE][MAX_STRING_LENGTH];
int default_reply_count = 0;
char* safe_strdup(const char* s) {
if (!s) return NULL;
char* result = strdup(s);
if (!result) {
fprintf(stderr, "Memory allocation failed in safe_strdup\n");
exit(1);
}
return result;
}
char* isolatePunctuation(const char* s) {
char* b = malloc(strlen(s) * 3 + 1);
if (!b) return NULL;
int j = 0;
for (int i = 0; s[i]; i++) {
if (strchr("?!,.:;<>(){}[]", s[i])) {
b[j++] = ' ';
b[j++] = s[i];
b[j++] = ' ';
} else {
b[j++] = s[i];
}
}
b[j] = '\0';
return b;
}
void loadArrays(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
int currentSet = -1;
while (fgets(line, sizeof(line), file)) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (strncmp(line, "d1:", 3) == 0) {
strcpy(default_replies[default_reply_count++], line + 3);
}
if (line[0] == 'k' && line[1] == ':') {
if (currentSet == -1 || g_Key_Reply[currentSet].replyCount > 0) {
currentSet++;
}
strcpy(g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount], line + 2);
g_Key_Reply[currentSet].keywordCount++;
g_Key_ReplyCount = currentSet + 1;
} else if (line[0] == 'r' && line[1] == ':') {
strcpy(g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount], line + 2);
g_Key_Reply[currentSet].replyCount++;
}
}
fclose(file);
printf("number of keywords-replies pair groups %d\n", currentSet);
}
void loadSwapWords(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening swap words file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
while (fgets(line, sizeof(line), file) && wCnt < MAX_SWAP_WORDS) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (line[0] == 's' && line[1] == ':') {
char* delimiter = strchr(line + 2, '>');
if (delimiter) {
*delimiter = '\0';
strcpy(wordIn[wCnt], line + 2);
strcpy(wordOut[wCnt], delimiter + 1);
wCnt++;
}
}
}
fclose(file);
}
char* swapWords(const char* input) {
if (!input) return NULL;
char* result = safe_strdup(input);
char* temp = malloc(strlen(input) * 2 + 1); // Allocate more space for worst-case scenario
if (!temp) {
free(result);
return NULL;
}
char* word = strtok(result, " ");
temp[0] = '\0';
while (word != NULL) {
bool swapped = false;
for (int i = 0; i < wCnt; i++) {
if (strcmp(word, wordIn[i]) == 0) {
strcat(temp, wordOut[i]);
strcat(temp, " ");
swapped = true;
break;
}
}
if (!swapped) {
strcat(temp, word);
strcat(temp, " ");
}
word = strtok(NULL, " ");
}
// Remove trailing space
int len = strlen(temp);
if (len > 0 && temp[len - 1] == ' ') {
temp[len - 1] = '\0';
}
free(result);
return temp;
}
char* processReply(const char* reply, const char* userInput) {
if (!reply || !userInput) return NULL;
char* processedReply = safe_strdup(reply);
int len = strlen(processedReply);
if (len > 0 && processedReply[len - 1] == '*') {
processedReply[len - 1] = '\0'; // Remove the asterisk
// Save the user's input to memory
if (memoryCount < MAX_MEMORY) {
strncpy(memory[memoryCount], userInput, MAX_STRING_LENGTH - 1);
memory[memoryCount][MAX_STRING_LENGTH - 1] = '\0';
memoryCount++;
}
// Find the keyword in the user's input
char* keyword = NULL;
for (int i = 0; i < g_Key_ReplyCount; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(userInput, g_Key_Reply[i].keywords[j])) {
keyword = g_Key_Reply[i].keywords[j];
break;
}
}
if (keyword) break;
}
if (keyword) {
char* rest = strstr(userInput, keyword);
if (rest) {
rest += strlen(keyword);
char* swapped = swapWords(rest);
if (swapped) {
// Concatenate the swapped input to the reply
char* temp = malloc(strlen(processedReply) + strlen(swapped) + 2);
if (temp) {
sprintf(temp, "%s %s", processedReply, swapped);
free(processedReply);
processedReply = temp;
}
free(swapped);
}
}
}
}
return processedReply;
}
char* userQuestion(const char* txt) {
if (!txt) return NULL;
char* matchedReplies[MAX_MATCHES] = {NULL};
int matchCount = 0;
bool found = false;
char* combinedReply = NULL;
for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(txt, g_Key_Reply[i].keywords[j])) {
int replyIndex = rand() % g_Key_Reply[i].replyCount;
matchedReplies[matchCount] = safe_strdup(g_Key_Reply[i].replies[replyIndex]);
matchCount++;
found = true;
break;
}
}
}
if (matchCount > 0) {
size_t totalLength = 1; // Start with 1 for the null terminator
for (int i = 0; i < matchCount; i++) {
char* processedReply = processReply(matchedReplies[i], txt);
if (processedReply) {
totalLength += strlen(processedReply) + 1; // +1 for newline
free(matchedReplies[i]);
matchedReplies[i] = processedReply;
}
}
combinedReply = malloc(totalLength);
if (combinedReply) {
combinedReply[0] = '\0';
for (int i = 0; i < matchCount; i++) {
if (matchedReplies[i]) {
strcat(combinedReply, matchedReplies[i]);
strcat(combinedReply, "\n");
free(matchedReplies[i]);
}
}
}
} else if (!found) {
if (default_reply_count > 0) {
int defaultIndex = rand() % default_reply_count;
combinedReply = safe_strdup(default_replies[defaultIndex]);
}
}
return combinedReply ? combinedReply : safe_strdup("I don't understand. Can you rephrase that?");
}
char* commands(char* txt) {
char* isolated = isolatePunctuation(txt);
for (int i = 0; isolated[i]; i++) {
isolated[i] = tolower(isolated[i]);
}
char* response = userQuestion(isolated);
free(isolated);
return response;
}
void speak(const char* text) {
char command[MAX_STRING_LENGTH * 2];
snprintf(command, sizeof(command), "voice -r -1 -n \"Microsoft David Desktop\" \"%s\"", text);
system(command);
}
int main() {
srand(time(NULL));
loadArrays("database.txt");
loadSwapWords("swapwords.txt");
printf("CHATBOT DANNY IN C PROGRAMMING LANGUAGE VERSION 1.1.6.5 (C) RON77\n");
char input[MAX_STRING_LENGTH];
char* response;
while (1) {
printf("> ");
if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}
input[strcspn(input, "\n")] = 0; // Remove newline
if (strcmp(input, "quit") == 0) break;
response = commands(input);
if (response) {
// Split the response into separate lines and speak each one
char* line = strtok(response, "\n");
while (line != NULL) {
printf("%s\n", line);
speak(line);
line = strtok(NULL, "\n");
}
free(response);
} else {
printf("An error occurred while processing your input.\n");
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <unistd.h>
#define MAX_STRING_LENGTH 1000
#define MAX_ARRAY_SIZE 1000
#define MAX_KEYWORDS 20
#define MAX_REPLIES 50
#define MAX_MATCHES 5
#define MAX_SWAP_WORDS 100
#define MAX_MEMORY 10
char wordIn[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
char wordOut[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
int wCnt = 0;
char memory[MAX_MEMORY][MAX_STRING_LENGTH];
int memoryCount = 0;
typedef struct {
char keywords[MAX_KEYWORDS][MAX_STRING_LENGTH];
char replies[MAX_REPLIES][MAX_STRING_LENGTH];
int keywordCount;
int replyCount;
} ArraySet;
ArraySet g_Key_Reply[MAX_ARRAY_SIZE];
int g_Key_ReplyCount = 0;
char default_replies[MAX_ARRAY_SIZE][MAX_STRING_LENGTH];
int default_reply_count = 0;
char* safe_strdup(const char* s) {
if (!s) return NULL;
char* result = strdup(s);
if (!result) {
fprintf(stderr, "Memory allocation failed in safe_strdup\n");
exit(1);
}
return result;
}
char* isolatePunctuation(const char* s) {
char* b = malloc(strlen(s) * 3 + 1);
if (!b) return NULL;
int j = 0;
for (int i = 0; s[i]; i++) {
if (strchr("?!,.:;<>(){}[]", s[i])) {
b[j++] = ' ';
b[j++] = s[i];
b[j++] = ' ';
} else {
b[j++] = s[i];
}
}
b[j] = '\0';
return b;
}
void loadArrays(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
int currentSet = -1;
while (fgets(line, sizeof(line), file)) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (strncmp(line, "d1:", 3) == 0) {
strcpy(default_replies[default_reply_count++], line + 3);
}
if (line[0] == 'k' && line[1] == ':') {
if (currentSet == -1 || g_Key_Reply[currentSet].replyCount > 0) {
currentSet++;
}
strcpy(g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount], line + 2);
g_Key_Reply[currentSet].keywordCount++;
g_Key_ReplyCount = currentSet + 1;
} else if (line[0] == 'r' && line[1] == ':') {
strcpy(g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount], line + 2);
g_Key_Reply[currentSet].replyCount++;
}
}
fclose(file);
}
void loadSwapWords(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening swap words file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
while (fgets(line, sizeof(line), file) && wCnt < MAX_SWAP_WORDS) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (line[0] == 's' && line[1] == ':') {
char* delimiter = strchr(line + 2, '>');
if (delimiter) {
*delimiter = '\0';
strcpy(wordIn[wCnt], line + 2);
strcpy(wordOut[wCnt], delimiter + 1);
wCnt++;
}
}
}
fclose(file);
}
char* swapWords(const char* input) {
if (!input) return NULL;
char* result = safe_strdup(input);
char* temp = malloc(strlen(input) * 2 + 1); // Allocate more space for worst-case scenario
if (!temp) {
free(result);
return NULL;
}
char* word = strtok(result, " ");
temp[0] = '\0';
while (word != NULL) {
bool swapped = false;
for (int i = 0; i < wCnt; i++) {
if (strcmp(word, wordIn[i]) == 0) {
strcat(temp, wordOut[i]);
strcat(temp, " ");
swapped = true;
break;
}
}
if (!swapped) {
strcat(temp, word);
strcat(temp, " ");
}
word = strtok(NULL, " ");
}
// Remove trailing space
int len = strlen(temp);
if (len > 0 && temp[len - 1] == ' ') {
temp[len - 1] = '\0';
}
free(result);
return temp;
}
char* processReply(const char* reply, const char* userInput) {
if (!reply || !userInput) return NULL;
char* processedReply = safe_strdup(reply);
int len = strlen(processedReply);
if (len > 0 && processedReply[len - 1] == '*') {
processedReply[len - 1] = '\0'; // Remove the asterisk
// Save the user's input to memory
if (memoryCount < MAX_MEMORY) {
strncpy(memory[memoryCount], userInput, MAX_STRING_LENGTH - 1);
memory[memoryCount][MAX_STRING_LENGTH - 1] = '\0';
memoryCount++;
}
// Find the keyword in the user's input
char* keyword = NULL;
for (int i = 0; i < g_Key_ReplyCount; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(userInput, g_Key_Reply[i].keywords[j])) {
keyword = g_Key_Reply[i].keywords[j];
break;
}
}
if (keyword) break;
}
if (keyword) {
char* rest = strstr(userInput, keyword);
if (rest) {
rest += strlen(keyword);
char* swapped = swapWords(rest);
if (swapped) {
// Concatenate the swapped input to the reply
char* temp = malloc(strlen(processedReply) + strlen(swapped) + 2);
if (temp) {
sprintf(temp, "%s %s", processedReply, swapped);
free(processedReply);
processedReply = temp;
}
free(swapped);
}
}
}
}
return processedReply;
}
char* userQuestion(const char* txt) {
if (!txt) return NULL;
char* matchedReplies[MAX_MATCHES] = {NULL};
int matchCount = 0;
bool found = false;
char* combinedReply = NULL;
for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(txt, g_Key_Reply[i].keywords[j])) {
int replyIndex = rand() % g_Key_Reply[i].replyCount;
matchedReplies[matchCount] = safe_strdup(g_Key_Reply[i].replies[replyIndex]);
matchCount++;
found = true;
break;
}
}
}
if (matchCount > 0) {
size_t totalLength = 1; // Start with 1 for the null terminator
for (int i = 0; i < matchCount; i++) {
char* processedReply = processReply(matchedReplies[i], txt);
if (processedReply) {
totalLength += strlen(processedReply) + 1; // +1 for newline
free(matchedReplies[i]);
matchedReplies[i] = processedReply;
}
}
combinedReply = malloc(totalLength);
if (combinedReply) {
combinedReply[0] = '\0';
for (int i = 0; i < matchCount; i++) {
if (matchedReplies[i]) {
strcat(combinedReply, matchedReplies[i]);
strcat(combinedReply, "\n");
free(matchedReplies[i]);
}
}
}
} else if (!found) {
if (default_reply_count > 0) {
int defaultIndex = rand() % default_reply_count;
combinedReply = safe_strdup(default_replies[defaultIndex]);
}
}
return combinedReply ? combinedReply : safe_strdup("I don't understand. Can you rephrase that?");
}
char* commands(char* txt) {
char* isolated = isolatePunctuation(txt);
for (int i = 0; isolated[i]; i++) {
isolated[i] = tolower(isolated[i]);
}
char* response = userQuestion(isolated);
free(isolated);
return response;
}
void speak(const char* text) {
char command[MAX_STRING_LENGTH * 2];
snprintf(command, sizeof(command), "voice -r -1 -n \"Microsoft David Desktop\" \"%s\"", text);
system(command);
}
int main() {
srand(time(NULL));
loadArrays("database.txt");
loadSwapWords("swapwords.txt");
char input[MAX_STRING_LENGTH];
char* response;
while (1) {
printf("> ");
if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}
input[strcspn(input, "\n")] = 0; // Remove newline
if (strcmp(input, "quit") == 0) break;
response = commands(input);
if (response) {
// Split the response into separate lines and speak each one
char* line = strtok(response, "\n");
while (line != NULL) {
printf("%s\n", line);
speak(line);
line = strtok(NULL, "\n");
}
free(response);
} else {
printf("An error occurred while processing your input.\n");
}
}
return 0;
}
#include <stdio.h>
#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#pragma comment(lib, "winhttp.lib")
#define MAX_RESPONSE_SIZE 16384
#define MAX_REQUEST_SIZE 8192
#define MAX_SYSTEM_MESSAGE_SIZE 4092
#define MAX_INPUT_SIZE 3000
#define MAX_COMMAND_SIZE 2048
#define MAX_FILENAME_SIZE 256
char system_message[MAX_SYSTEM_MESSAGE_SIZE] = "You are my Spirit Guide, a wise and benevolent being here to help me navigate my life's journey. I seek your guidance and advice as I walk my path in this world. Please offer me the wisdom I need, help me stay on the right course, and hear me when I call out for support. I trust in your presence and am open to the insights you provide to guide me through life.";
char* make_request(const char* request_body, const char* auth_header) {
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
hSession = WinHttpOpen(L"Claude API Client",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (hSession == NULL) {
printf("Error %lu in WinHttpOpen.\n", GetLastError());
return NULL;
}
hConnect = WinHttpConnect(hSession, L"api.anthropic.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
if (hConnect == NULL) {
printf("Error %lu in WinHttpConnect.\n", GetLastError());
WinHttpCloseHandle(hSession);
return NULL;
}
hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/v1/messages",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
if (hRequest == NULL) {
printf("Error %lu in WinHttpOpenRequest.\n", GetLastError());
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
// Convert auth_header to wide string
wchar_t wide_auth_header[512];
MultiByteToWideChar(CP_UTF8, 0, auth_header, -1, wide_auth_header, 512);
WinHttpAddRequestHeaders(hRequest, L"Content-Type: application/json", -1, WINHTTP_ADDREQ_FLAG_ADD);
WinHttpAddRequestHeaders(hRequest, wide_auth_header, -1, WINHTTP_ADDREQ_FLAG_ADD);
WinHttpAddRequestHeaders(hRequest, L"anthropic-version: 2023-06-01", -1, WINHTTP_ADDREQ_FLAG_ADD);
bResults = WinHttpSendRequest(hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
(LPVOID)request_body, strlen(request_body),
strlen(request_body), 0);
if (!bResults) {
printf("Error %lu in WinHttpSendRequest.\n", GetLastError());
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
bResults = WinHttpReceiveResponse(hRequest, NULL);
if (!bResults) {
printf("Error %lu in WinHttpReceiveResponse.\n", GetLastError());
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
pszOutBuffer = (LPSTR)malloc(MAX_RESPONSE_SIZE);
if (!pszOutBuffer) {
printf("Failed to allocate memory\n");
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
ZeroMemory(pszOutBuffer, MAX_RESPONSE_SIZE);
DWORD total_size = 0;
if (bResults) {
do {
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
printf("Error %lu in WinHttpQueryDataAvailable.\n", GetLastError());
break;
}
if (dwSize + total_size > MAX_RESPONSE_SIZE) {
printf("Response too large, truncating.\n");
dwSize = MAX_RESPONSE_SIZE - total_size;
}
if (!WinHttpReadData(hRequest, (LPVOID)(pszOutBuffer + total_size),
dwSize, &dwDownloaded)) {
printf("Error %lu in WinHttpReadData.\n", GetLastError());
break;
}
total_size += dwDownloaded;
} while (dwSize > 0 && total_size < MAX_RESPONSE_SIZE);
}
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return pszOutBuffer;
}
char* extract_content(const char* json_response) {
char* content_start = strstr(json_response, "\"content\":[");
if (content_start == NULL) {
printf("Could not find 'content' in response.\n");
return NULL;
}
content_start = strstr(content_start, "\"text\":\"");
if (content_start == NULL) {
printf("Could not find 'text' in content.\n");
return NULL;
}
content_start += 8; // Move past "\"text\":\""
char* content_end = strstr(content_start, "\"}");
if (content_end == NULL) {
printf("Could not find end of content in response.\n");
return NULL;
}
int content_length = content_end - content_start;
char* content = (char*)malloc(content_length + 1);
strncpy(content, content_start, content_length);
content[content_length] = '\0';
return content;
}
void set_system_message() {
printf("Enter new system message (max %d characters):\n", MAX_SYSTEM_MESSAGE_SIZE - 1);
fgets(system_message, sizeof(system_message), stdin);
system_message[strcspn(system_message, "\n")] = 0; // Remove newline
printf("System message updated.\n");
}
void speak_text(const char* text) {
char command[MAX_COMMAND_SIZE];
snprintf(command, sizeof(command), "voice.exe -n \"Microsoft Zira Desktop\" \"%s\"", text);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
printf("CreateProcess failed (%lu).\n", GetLastError());
return;
}
// Wait for the TTS process to finish
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
void log_message(FILE* log_file, const char* role, const char* message) {
time_t now;
struct tm *local_time;
char timestamp[26];
time(&now);
local_time = localtime(&now);
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", local_time);
fprintf(log_file, "[%s] %s: %s\n", timestamp, role, message);
fflush(log_file); // Ensure the message is written immediately
}
int main() {
char input[MAX_INPUT_SIZE];
char request_body[MAX_REQUEST_SIZE];
char* response;
char* extracted_content;
char api_key[256];
printf("Enter your Anthropic API key: ");
fgets(api_key, sizeof(api_key), stdin);
api_key[strcspn(api_key, "\n")] = 0; // Remove newline
// Create log file
char log_filename[MAX_FILENAME_SIZE];
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(log_filename, sizeof(log_filename), "history/conversation_%Y%m%d_%H%M%S.log", t);
FILE* log_file = fopen(log_filename, "w");
if (log_file == NULL) {
printf("Failed to create log file.\n");
return 1;
}
printf("Conversation will be logged to: %s\n", log_filename);
// Log the system message
log_message(log_file, "SYSTEM", system_message);
while (1) {
printf("You (type 'exit' to quit, 'role' to change system message): ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = 0; // Remove newline
if (strcmp(input, "exit") == 0) {
break;
} else if (strcmp(input, "role") == 0) {
set_system_message();
log_message(log_file, "SYSTEM", system_message);
continue;
}
// Log user input
log_message(log_file, "USER", input);
char auth_header[512];
snprintf(auth_header, sizeof(auth_header), "x-api-key: %s", api_key);
snprintf(request_body, sizeof(request_body),
"{\"model\": \"claude-3-sonnet-20240229\", \"system\": \"%s\", \"messages\": ["
"{\"role\": \"user\", \"content\": \"%s\"}],"
"\"max_tokens\": 1000}",
system_message, input);
response = make_request(request_body, auth_header);
if (response) {
if (strstr(response, "\"error\":") != NULL) {
printf("API Error Response:\n%s\n", response);
log_message(log_file, "ERROR", response);
} else {
extracted_content = extract_content(response);
if (extracted_content) {
printf("AI: %s\n", extracted_content);
speak_text(extracted_content);
// Log AI response
log_message(log_file, "AI", extracted_content);
free(extracted_content);
} else {
printf("Failed to extract content from response.\n");
printf("Full API Response:\n%s\n", response);
log_message(log_file, "ERROR", "Failed to extract content from response");
}
}
free(response);
} else {
printf("Failed to get a response from the API.\n");
log_message(log_file, "ERROR", "Failed to get a response from the API");
}
}
fclose(log_file);
printf("Conversation log saved to: %s\n", log_filename);
return 0;
}
#include <stdio.h>
#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>
#pragma comment(lib, "winhttp.lib")
#define MAX_RESPONSE_SIZE 16384
#define MAX_REQUEST_SIZE 8192
#define MAX_SYSTEM_MESSAGE_SIZE 4092
#define MAX_INPUT_SIZE 1024
#define MAX_COMMAND_SIZE 2048
char system_message[MAX_SYSTEM_MESSAGE_SIZE] = "You are my Spirit Guide, a wise and benevolent being here to help me navigate my life's journey. I seek your guidance and advice as I walk my path in this world. Please offer me the wisdom I need, help me stay on the right course, and hear me when I call out for support. I trust in your presence and am open to the insights you provide to guide me through life.";
char* make_request(const char* request_body, const char* auth_header) {
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
hSession = WinHttpOpen(L"Claude API Client",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (hSession == NULL) {
printf("Error %lu in WinHttpOpen.\n", GetLastError());
return NULL;
}
hConnect = WinHttpConnect(hSession, L"api.anthropic.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
if (hConnect == NULL) {
printf("Error %lu in WinHttpConnect.\n", GetLastError());
WinHttpCloseHandle(hSession);
return NULL;
}
hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/v1/messages",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
if (hRequest == NULL) {
printf("Error %lu in WinHttpOpenRequest.\n", GetLastError());
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
// Convert auth_header to wide string
wchar_t wide_auth_header[512];
MultiByteToWideChar(CP_UTF8, 0, auth_header, -1, wide_auth_header, 512);
WinHttpAddRequestHeaders(hRequest, L"Content-Type: application/json", -1, WINHTTP_ADDREQ_FLAG_ADD);
WinHttpAddRequestHeaders(hRequest, wide_auth_header, -1, WINHTTP_ADDREQ_FLAG_ADD);
WinHttpAddRequestHeaders(hRequest, L"anthropic-version: 2023-06-01", -1, WINHTTP_ADDREQ_FLAG_ADD);
bResults = WinHttpSendRequest(hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
(LPVOID)request_body, strlen(request_body),
strlen(request_body), 0);
if (!bResults) {
printf("Error %lu in WinHttpSendRequest.\n", GetLastError());
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
bResults = WinHttpReceiveResponse(hRequest, NULL);
if (!bResults) {
printf("Error %lu in WinHttpReceiveResponse.\n", GetLastError());
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
pszOutBuffer = (LPSTR)malloc(MAX_RESPONSE_SIZE);
if (!pszOutBuffer) {
printf("Failed to allocate memory\n");
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
ZeroMemory(pszOutBuffer, MAX_RESPONSE_SIZE);
DWORD total_size = 0;
if (bResults) {
do {
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
printf("Error %lu in WinHttpQueryDataAvailable.\n", GetLastError());
break;
}
if (dwSize + total_size > MAX_RESPONSE_SIZE) {
printf("Response too large, truncating.\n");
dwSize = MAX_RESPONSE_SIZE - total_size;
}
if (!WinHttpReadData(hRequest, (LPVOID)(pszOutBuffer + total_size),
dwSize, &dwDownloaded)) {
printf("Error %lu in WinHttpReadData.\n", GetLastError());
break;
}
total_size += dwDownloaded;
} while (dwSize > 0 && total_size < MAX_RESPONSE_SIZE);
}
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return pszOutBuffer;
}
char* extract_content(const char* json_response) {
char* content_start = strstr(json_response, "\"content\":[");
if (content_start == NULL) {
printf("Could not find 'content' in response.\n");
return NULL;
}
content_start = strstr(content_start, "\"text\":\"");
if (content_start == NULL) {
printf("Could not find 'text' in content.\n");
return NULL;
}
content_start += 8; // Move past "\"text\":\""
char* content_end = strstr(content_start, "\"}");
if (content_end == NULL) {
printf("Could not find end of content in response.\n");
return NULL;
}
int content_length = content_end - content_start;
char* content = (char*)malloc(content_length + 1);
strncpy(content, content_start, content_length);
content[content_length] = '\0';
return content;
}
void set_system_message() {
printf("Enter new system message (max %d characters):\n", MAX_SYSTEM_MESSAGE_SIZE - 1);
fgets(system_message, sizeof(system_message), stdin);
system_message[strcspn(system_message, "\n")] = 0; // Remove newline
printf("System message updated.\n");
}
void speak_text(const char* text) {
char command[MAX_COMMAND_SIZE];
snprintf(command, sizeof(command), "voice.exe -n \"Microsoft Zira Desktop\" \"%s\"", text);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
printf("CreateProcess failed (%lu).\n", GetLastError());
return;
}
// Wait for the TTS process to finish
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
int main() {
char input[MAX_INPUT_SIZE];
char request_body[MAX_REQUEST_SIZE];
char* response;
char* extracted_content;
char api_key[256];
printf("Enter your Anthropic API key: ");
fgets(api_key, sizeof(api_key), stdin);
api_key[strcspn(api_key, "\n")] = 0; // Remove newline
while (1) {
printf("You (type 'exit' to quit, 'role' to change system message): ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = 0; // Remove newline
if (strcmp(input, "exit") == 0) {
break;
} else if (strcmp(input, "role") == 0) {
set_system_message();
continue;
}
char auth_header[512];
snprintf(auth_header, sizeof(auth_header), "x-api-key: %s", api_key);
snprintf(request_body, sizeof(request_body),
"{\"model\": \"claude-3-sonnet-20240229\", \"system\": \"%s\", \"messages\": ["
"{\"role\": \"user\", \"content\": \"%s\"}],"
"\"max_tokens\": 1000}",
system_message, input);
response = make_request(request_body, auth_header);
if (response) {
if (strstr(response, "\"error\":") != NULL) {
printf("API Error Response:\n%s\n", response);
} else {
extracted_content = extract_content(response);
if (extracted_content) {
printf("AI: %s\n", extracted_content);
speak_text(extracted_content);
free(extracted_content);
} else {
printf("Failed to extract content from response.\n");
printf("Full API Response:\n%s\n", response);
}
}
free(response);
} else {
printf("Failed to get a response from the API.\n");
}
}
return 0;
}
#include <stdio.h>
#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>
#pragma comment(lib, "winhttp.lib")
#define MAX_RESPONSE_SIZE 16384
#define MAX_REQUEST_SIZE 8192
#define MAX_SYSTEM_MESSAGE_SIZE 4092
#define MAX_INPUT_SIZE 1024
char system_message[MAX_SYSTEM_MESSAGE_SIZE] = "You are my Spirit Guide, a wise and benevolent being here to help me navigate my life's journey. I seek your guidance and advice as I walk my path in this world. Please offer me the wisdom I need, help me stay on the right course, and hear me when I call out for support. I trust in your presence and am open to the insights you provide to guide me through life.";
char* make_request(const char* request_body, const char* auth_header) {
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
hSession = WinHttpOpen(L"OpenAI API Client",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (hSession == NULL) {
printf("Error %lu in WinHttpOpen.\n", GetLastError());
return NULL;
}
hConnect = WinHttpConnect(hSession, L"api.openai.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
if (hConnect == NULL) {
printf("Error %lu in WinHttpConnect.\n", GetLastError());
WinHttpCloseHandle(hSession);
return NULL;
}
hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/v1/chat/completions",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
if (hRequest == NULL) {
printf("Error %lu in WinHttpOpenRequest.\n", GetLastError());
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
// Convert auth_header to wide string
wchar_t wide_auth_header[512];
MultiByteToWideChar(CP_UTF8, 0, auth_header, -1, wide_auth_header, 512);
WinHttpAddRequestHeaders(hRequest, L"Content-Type: application/json", -1, WINHTTP_ADDREQ_FLAG_ADD);
WinHttpAddRequestHeaders(hRequest, wide_auth_header, -1, WINHTTP_ADDREQ_FLAG_ADD);
bResults = WinHttpSendRequest(hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
(LPVOID)request_body, strlen(request_body),
strlen(request_body), 0);
if (!bResults) {
printf("Error %lu in WinHttpSendRequest.\n", GetLastError());
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
bResults = WinHttpReceiveResponse(hRequest, NULL);
if (!bResults) {
printf("Error %lu in WinHttpReceiveResponse.\n", GetLastError());
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
pszOutBuffer = (LPSTR)malloc(MAX_RESPONSE_SIZE);
if (!pszOutBuffer) {
printf("Failed to allocate memory\n");
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
ZeroMemory(pszOutBuffer, MAX_RESPONSE_SIZE);
DWORD total_size = 0;
if (bResults) {
do {
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
printf("Error %lu in WinHttpQueryDataAvailable.\n", GetLastError());
break;
}
if (dwSize + total_size > MAX_RESPONSE_SIZE) {
printf("Response too large, truncating.\n");
dwSize = MAX_RESPONSE_SIZE - total_size;
}
if (!WinHttpReadData(hRequest, (LPVOID)(pszOutBuffer + total_size),
dwSize, &dwDownloaded)) {
printf("Error %lu in WinHttpReadData.\n", GetLastError());
break;
}
total_size += dwDownloaded;
} while (dwSize > 0 && total_size < MAX_RESPONSE_SIZE);
}
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return pszOutBuffer;
}
char* extract_content(const char* json_response) {
char* choices_start = strstr(json_response, "\"choices\":");
if (choices_start == NULL) {
printf("Could not find 'choices' in response.\n");
printf("Full response:\n%s\n", json_response);
return NULL;
}
char* message_start = strstr(choices_start, "\"message\":");
if (message_start == NULL) {
printf("Could not find 'message' in response.\n");
return NULL;
}
char* content_start = strstr(message_start, "\"content\":");
if (content_start == NULL) {
printf("Could not find 'content' in response.\n");
return NULL;
}
content_start = strchr(content_start, ':');
if (content_start == NULL) {
printf("Malformed content in response.\n");
return NULL;
}
content_start++; // Move past the ':'
// Skip whitespace and opening quote
while (*content_start == ' ' || *content_start == '"') {
content_start++;
}
char* content_end = strstr(content_start, "\",");
if (content_end == NULL) {
printf("Could not find end of content in response.\n");
return NULL;
}
int content_length = content_end - content_start;
char* content = (char*)malloc(content_length + 1);
strncpy(content, content_start, content_length);
content[content_length] = '\0';
return content;
}
void set_system_message() {
printf("Enter new system message (max %d characters):\n", MAX_SYSTEM_MESSAGE_SIZE - 1);
fgets(system_message, sizeof(system_message), stdin);
system_message[strcspn(system_message, "\n")] = 0; // Remove newline
printf("System message updated.\n");
}
int main() {
char input[MAX_INPUT_SIZE];
char request_body[MAX_REQUEST_SIZE];
char* response;
char* extracted_content;
char api_key[256];
printf("Enter your OpenAI API key: ");
fgets(api_key, sizeof(api_key), stdin);
api_key[strcspn(api_key, "\n")] = 0; // Remove newline
while (1) {
printf("You (type 'exit' to quit, 'role' to change system message): ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = 0; // Remove newline
if (strcmp(input, "exit") == 0) {
break;
} else if (strcmp(input, "role") == 0) {
set_system_message();
continue;
}
char auth_header[512];
snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", api_key);
snprintf(request_body, sizeof(request_body),
"{\"model\": \"gpt-3.5-turbo\", \"messages\": ["
"{\"role\": \"system\", \"content\": \"%s\"},"
"{\"role\": \"user\", \"content\": \"%s\"}]}",
system_message, input);
response = make_request(request_body, auth_header);
if (response) {
extracted_content = extract_content(response);
if (extracted_content) {
printf("AI: %s\n", extracted_content);
free(extracted_content);
} else {
printf("Failed to extract content from response.\n");
}
free(response);
} else {
printf("Failed to get a response from the API.\n");
}
}
return 0;
}
gcc openai_chatbot.c -o openai_chatbot.exe -lwinhttp
git clone https://github.com/DaveGamble/cJSON.git
cd cJSON
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW -DENABLE_CJSON_TEST=Off -DENABLE_CJSON_UTILS=Off
mingw32-make
mingw32-make install
git clone https://github.com/madler/zlib.git
cd zlib
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW
mingw32-make
mingw32-make install
cd ../..
git clone https://github.com/curl/curl.git
cd curl
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_STATICLIB=ON
mingw32-make
mingw32-make install