Code: Select all
#include <curl/curl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CYCLES 10000
struct MemoryStruct {
char *memory;
size_t size;
};
// global variables/player stats
struct MemoryStruct chunk; // variable which will hold the retrieved HTML
uint32_t player_level, dungeon_level, XP, no_of_cycles;
int32_t hitpoints;
char entry, weapon[50], inventory[3][30], inv[300], grid[9], movestring[10];
uint8_t no_of_items, position, stairs_pos;
bool north, east, south, west, stairs, fighting, go_downstairs, pick_up;
FILE* logfile;
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if (mem->memory == NULL)
{
printf("not enough memory (realloc returned NULL)\n");
exit(EXIT_FAILURE);
}
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
void getHTML(void)
{
CURL *curl_handle;
CURLcode errorcode;
// free the memory before allocating anew
if(chunk.memory)
free(chunk.memory);
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
chunk.size = 0; /* no data at this point */
curl_handle = curl_easy_init();
char* URLstring = "http://www.hacker.org/challenge/misc/d/cavern.php?";
char* Userstring = "name=<user name>&spw=<submit password>";
char Submitstring[200];
strcpy(Submitstring, URLstring);
strcat(Submitstring, movestring);
strcat(Submitstring, Userstring);
curl_easy_setopt(curl_handle, CURLOPT_URL, Submitstring);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
errorcode = curl_easy_perform(curl_handle);
curl_easy_cleanup(curl_handle);
if(errorcode != 0)
{
printf("Error while retrieving URL\n");
free(chunk.memory);
curl_global_cleanup();
fclose(logfile);
exit(-1);
}
}
void parseHTML(void)
{
if(hitpoints <= 0)
{
printf("Character died\n");
fprintf(logfile, "Died.\ncycles: %5d, entry: %c, dungeon lvl: %d, player lvl: %d\n",
no_of_cycles, entry, dungeon_level, player_level);
free(chunk.memory);
curl_global_cleanup();
fclose(logfile);
exit(-1);
}
fighting = false;
if( strstr(chunk.memory, "Attack") != NULL)
fighting = true;
if( (fighting == true) && ( strstr(chunk.memory, "Big monster") == NULL) )
{
printf("Boss is up!\n");
fprintf(logfile, "Boss reached.\ncycles: %5d, entry: %c, dungeon lvl: %d, player lvl: %d\n",
no_of_cycles, entry, dungeon_level, player_level);
// to get the name
fprintf(logfile, "\n\n%s", chunk.memory);
free(chunk.memory);
curl_global_cleanup();
fclose(logfile);
exit(0);
}
char *pch = strstr(chunk.memory, "Dungeon Level");
pch = pch + 14;
dungeon_level = atoi(pch);
pch = strstr(chunk.memory, "<tr><td>") + 8;
player_level = atoi(pch);
pch = strstr(chunk.memory, "</td><td>") + 9;
hitpoints = atoi(pch);
pch = strstr(pch, "</td><td>") + 9;
XP = atoi(pch);
pch = strstr(pch, "</td><td>") + 9;
strncpy(weapon, pch, 49);
pch = strstr(weapon, "<");
*pch = '\0';
pick_up = false;
if( strstr(chunk.memory, "Pick up") != NULL)
pick_up = true;
go_downstairs = false;
if(player_level >= dungeon_level + 4)
go_downstairs = true;
north = east = south = west = stairs = false;
if( strstr(chunk.memory, "North") != NULL) north = true;
if( strstr(chunk.memory, "East") != NULL) east = true;
if( strstr(chunk.memory, "South") != NULL) south = true;
if( strstr(chunk.memory, "West") != NULL) west = true;
if (!north && east && south && !west) position = 0;
else if (!north && east && south && west) position = 1;
else if (!north && !east && south && west) position = 2;
else if ( north && east && south && !west) position = 3;
else if ( north && east && south && west) position = 4;
else if ( north && !east && south && west) position = 5;
else if ( north && east && !south && !west) position = 6;
else if ( north && east && !south && west) position = 7;
else if ( north && !east && !south && west) position = 8;
if( strstr(chunk.memory, "Down Stairs") != NULL)
{
stairs_pos = position;
stairs = true;
}
memset(grid, '.', 9);
if(stairs_pos < 9)
grid[stairs_pos] = 'S';
}
void makeDecision(void)
{
strcpy(movestring, "");
if(fighting)
{
strcpy(movestring, "attack=1&");
entry = 'a';
}
else if (pick_up == true) // pick up stuff
{
strcpy(movestring, "tres=1&");
entry = 'p';
}
else // move around randomly
{
bool dir_found = false;
int dir;
while(dir_found != true)
{
dir = rand() % 4;
if (dir==0 && north) { dir_found = true; strcpy(movestring, "m=n&"); entry = 'n'; }
else if(dir==1 && east) { dir_found = true; strcpy(movestring, "m=e&"); entry = 'e'; }
else if(dir==2 && south) { dir_found = true; strcpy(movestring, "m=s&"); entry = 's'; }
else if(dir==3 && west) { dir_found = true; strcpy(movestring, "m=w&"); entry = 'w'; }
}
}
if(go_downstairs == true && stairs == true && !fighting)
{
go_downstairs = stairs = false;
strcpy(movestring, "m=d&");
entry = 'd';
}
no_of_cycles++;
if(no_of_cycles >= MAX_CYCLES && !fighting)
entry = 'x';
printf("%4d The script sets entry to: %c\n", no_of_cycles, entry);
if(entry == 'x')
printf("Number of cycles = %d, terminating\n", no_of_cycles);
fprintf(logfile, "cycles: %5d, entry: %c, dungeon lvl: %d, player lvl: %d\n",
no_of_cycles, entry, dungeon_level, player_level);
fflush (logfile);
}
int main()
{
// initialize the variables
entry = ' ';
fighting = false;
player_level = 0;
dungeon_level = 0;
hitpoints = 1;
no_of_items = 0;
no_of_cycles = 0;
north = east = south = west = stairs = go_downstairs = pick_up = false;
position = 4;
stairs_pos = 9;
strcpy(weapon, "Standard Weapon");
inventory[0][0] = '\0';
inventory[1][0] = '\0';
inventory[2][0] = '\0';
movestring[0] = '\0';
logfile = fopen("logfile.txt", "w");
srand(time(NULL));
curl_global_init(CURL_GLOBAL_ALL);
// main loop
while(entry != 'x')
{
getHTML();
parseHTML();
makeDecision();
}
fclose(logfile);
free(chunk.memory);
curl_global_cleanup();
return 0;
}