diff --git a/cgc-challenges/Monster_Game/.frama-c/GNUmakefile b/cgc-challenges/Monster_Game/.frama-c/GNUmakefile
new file mode 100644
index 0000000000000000000000000000000000000000..e4d62c53101ff1958b538eb463b6e27e633ef244
--- /dev/null
+++ b/cgc-challenges/Monster_Game/.frama-c/GNUmakefile
@@ -0,0 +1,57 @@
+# Makefile template for Frama-C/Eva case studies.
+# For details and usage information, see the Frama-C User Manual.
+
+### Prologue. Do not modify this block. #######################################
+-include path.mk
+FRAMAC ?= frama-c
+include $(shell $(FRAMAC)-config -scripts)/prologue.mk
+###############################################################################
+
+# Edit below as needed. MACHDEP is mandatory. Suggested flags are optional.
+
+MACHDEP = x86_32
+
+## Preprocessing flags (for -cpp-extra-args)
+CPPFLAGS    += \
+  -DPATCHED \
+  -I../../lib \
+  -I../lib \
+  -include cgc_monster_names.h\
+
+## General flags
+FCFLAGS     += \
+  -add-symbolic-path=..:. \
+  -kernel-warn-key annot:missing-spec=abort \
+  -kernel-warn-key typing:implicit-function-declaration=abort \
+  -absolute-valid-range 0x4347C000-0x4347FFFF \
+  -c11
+
+## Eva-specific flags
+EVAFLAGS    += \
+  -eva-precision 2 \
+  -eva-warn-key builtins:missing-spec=abort \
+  -eva-warn-key garbled-mix=inactive \
+  -eva-use-spec cgc_find_path \
+
+## GUI-only flags
+FCGUIFLAGS += \
+
+## Analysis targets (suffixed with .eva)
+TARGETS = Monster_Game.eva
+
+### Each target <t>.eva needs a rule <t>.parse with source files as prerequisites
+Monster_Game.parse: \
+  ../lib/prng.c \
+  ../lib/fs.c \
+  ../../lib/libcgc.c\
+  ../service.c \
+
+#  ../lib/math.c \
+  ../lib/stdlib.c \
+  ../lib/ctype.c \
+#  ../lib/malloc.c \
+#  ../lib/stdio.c
+
+### Epilogue. Do not modify this block. #######################################
+include $(shell $(FRAMAC)-config -scripts)/epilogue.mk
+###############################################################################
diff --git a/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/alarms.csv b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/alarms.csv
new file mode 100644
index 0000000000000000000000000000000000000000..0a49f323b1ff87bc8a9191e4fd16e453b6d4611e
--- /dev/null
+++ b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/alarms.csv
@@ -0,0 +1,146 @@
+directory	file	line	function	property kind	status	property
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	75	cgc_check_egg	index_bound	Unknown	eggindex < 10
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	81	cgc_check_egg	index_bound	Unknown	eggindex < 10
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	83	cgc_check_egg	dangling_pointer	Unknown	¬\dangling(&pp->mons[0])
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	83	cgc_check_egg	mem_access	Unknown	\valid(&(pp->mons[0])->hitpoints)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	84	cgc_check_egg	mem_access	Unknown	\valid(&(pp->mons[0])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	85	cgc_check_egg	mem_access	Unknown	\valid(&(pp->mons[0])->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	152	cgc_read_line_u	mem_access	Unknown	\valid(outbuf + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	246	cgc_print_map	precondition of bzero	Unknown	valid_memory_area: \valid((char *)s + (0 .. n - 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	250	cgc_print_map	mem_access	Unknown	\valid(data + tmp)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	253	cgc_print_map	initialization	Unknown	\initialized(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	253	cgc_print_map	mem_access	Unknown	\valid_read(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	254	cgc_print_map	mem_access	Unknown	\valid(data + map_index)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	256	cgc_print_map	mem_access	Unknown	\valid(data + map_index)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	263	cgc_print_map	mem_access	Unknown	\valid(data + map_index)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	265	cgc_print_map	precondition of printf_va_12	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	265	printf_va_12	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	277	cgc_find_path	postcondition	Unknown	\result ≡ 0 ∨ \result ≡ 1
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	346	cgc_place_marker	mem_access	Unknown	\valid_read(secret_page + cgc_page_index)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	354	cgc_place_marker	initialization	Unknown	\initialized(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	354	cgc_place_marker	mem_access	Unknown	\valid_read(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	372	cgc_place_marker	initialization	Unknown	\initialized(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	372	cgc_place_marker	mem_access	Unknown	\valid_read(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	386	cgc_place_marker	mem_access	Unknown	\valid(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	395	cgc_set_marker	mem_access	Unknown	\valid(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	414	cgc_initialize_map	precondition of bzero	Unknown	valid_memory_area: \valid((char *)s + (0 .. n - 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	425	cgc_initialize_map	mem_access	Unknown	\valid_read(secret_page + cgc_page_index)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	463	cgc_initialize_queue_matrix	precondition of bzero	Unknown	valid_memory_area: \valid((char *)s + (0 .. n - 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	467	cgc_initialize_queue_matrix	initialization	Unknown	\initialized(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	467	cgc_initialize_queue_matrix	mem_access	Unknown	\valid_read(pm->data + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	468	cgc_initialize_queue_matrix	mem_access	Unknown	\valid(queue_matrix + index_0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	512	cgc_generate_map	mem_access	Unknown	\valid(pm->data + (unsigned int)((unsigned int)(pm->width * pm->last_y) + pm->last_x))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	551	cgc_select_monster	dangling_pointer	Unknown	¬\dangling(&pp->mons[index_0])
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	551	cgc_select_monster	initialization	Unknown	\initialized(&(pp->mons[index_0])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	551	cgc_select_monster	mem_access	Unknown	\valid_read(&(pp->mons[index_0])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	565	cgc_select_monster	initialization	Unknown	\initialized(&(pp->mons[index_0])->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	565	cgc_select_monster	mem_access	Unknown	\valid_read(&(pp->mons[index_0])->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	565	cgc_select_monster	precondition of printf_va_21	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	565	printf_va_21	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	566	cgc_select_monster	initialization	Unknown	\initialized(&(pp->mons[index_0])->level)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	566	cgc_select_monster	mem_access	Unknown	\valid_read(&(pp->mons[index_0])->level)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	567	cgc_select_monster	initialization	Unknown	\initialized(&(pp->mons[index_0])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	568	cgc_select_monster	initialization	Unknown	\initialized(&(pp->mons[index_0])->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	581	cgc_select_monster	dangling_pointer	Unknown	¬\dangling(&pp->mons[(int)(ac - 1)])
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	583	cgc_select_monster	initialization	Unknown	\initialized(&(pp->mons[(int)(ac - 1)])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	583	cgc_select_monster	mem_access	Unknown	\valid_read(&(pp->mons[(int)(ac - 1)])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	590	cgc_select_monster	dangling_pointer	Unknown	¬\dangling(&pp->mons[(int)(ac - 1)])
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	590	cgc_select_monster	index_bound	Unknown	(int)(ac - 1) < 5
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	590	cgc_select_monster	index_bound	Unknown	0 ≤ (int)(ac - 1)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	590	cgc_select_monster	signed_overflow	Unknown	-2147483648 ≤ ac - 1
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	603	cgc_reset_monsters	dangling_pointer	Unknown	¬\dangling(&pp->mons[index_0])
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	603	cgc_reset_monsters	initialization	Unknown	\initialized(&(pp->mons[index_0])->hitpoints)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	603	cgc_reset_monsters	mem_access	Unknown	\valid(&(pp->mons[index_0])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	603	cgc_reset_monsters	mem_access	Unknown	\valid_read(&(pp->mons[index_0])->hitpoints)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	616	cgc_print_monster	initialization	Unknown	\initialized(&pm->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	616	cgc_print_monster	mem_access	Unknown	\valid_read(&pm->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	616	cgc_print_monster	precondition of printf_va_29	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	616	printf_va_29	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	617	cgc_print_monster	initialization	Unknown	\initialized(&pm->level)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	617	cgc_print_monster	mem_access	Unknown	\valid_read(&pm->level)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	618	cgc_print_monster	initialization	Unknown	\initialized(&pm->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	619	cgc_print_monster	initialization	Unknown	\initialized(&pm->hitpoints)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	620	cgc_print_monster	initialization	Unknown	\initialized(&pm->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	631	cgc_oneup_monster	initialization	Unknown	\initialized(&pm->experience)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	631	cgc_oneup_monster	mem_access	Unknown	\valid(&pm->experience)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	634	cgc_oneup_monster	initialization	Unknown	\initialized(&pm->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	634	cgc_oneup_monster	mem_access	Unknown	\valid_read(&pm->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	634	cgc_oneup_monster	precondition of printf_va_34	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	634	printf_va_34	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	635	cgc_oneup_monster	initialization	Unknown	\initialized(&pm->hitpoints)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	636	cgc_oneup_monster	initialization	Unknown	\initialized(&pm->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	637	cgc_oneup_monster	initialization	Unknown	\initialized(&pm->hitpoints)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	638	cgc_oneup_monster	initialization	Unknown	\initialized(&pm->level)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	638	cgc_oneup_monster	mem_access	Unknown	\valid(&pm->level)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	697	cgc_change_monster_name	precondition of bzero	Unknown	valid_memory_area: \valid((char *)s + (0 .. n - 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	698	cgc_change_monster_name	precondition of memcpy	Unknown	valid_dest: valid_or_empty(dest, n)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	698	cgc_change_monster_name	precondition of memcpy	Unknown	valid_src: valid_read_or_empty(src, n)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	741	cgc_capture_boss	dangling_pointer	Unknown	¬\dangling(&pp->mons[choice])
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	746	cgc_capture_boss	initialization	Unknown	\initialized(&pm->hitpoints)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	771	cgc_capture_boss	precondition of free	Unknown	freeable: p ≡ \null ∨ \freeable(p)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	772	cgc_capture_boss	dangling_pointer	Unknown	¬\dangling(&pm)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	795	cgc_daboss	initialization	Unknown	\initialized(&boss->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	803	cgc_daboss	initialization	Unknown	\initialized(&player_current->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	803	cgc_daboss	mem_access	Unknown	\valid_read(&player_current->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	803	cgc_daboss	division_by_zero	Unknown	player_current->power ≢ 0
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	811	cgc_daboss	initialization	Unknown	\initialized(&boss->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	818	cgc_daboss	initialization	Unknown	\initialized(&boss->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	818	cgc_daboss	division_by_zero	Unknown	boss->power ≢ 0
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	821	cgc_daboss	initialization	Unknown	\initialized(&boss->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	821	cgc_daboss	initialization	Unknown	\initialized(&player_current->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	821	cgc_daboss	mem_access	Unknown	\valid_read(&player_current->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	821	cgc_daboss	precondition of printf_va_52	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	821	cgc_daboss	precondition of printf_va_52	Unknown	valid_read_string(param1)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	821	printf_va_52	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	821	printf_va_52	precondition	Unknown	valid_read_string(param1)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	823	cgc_daboss	initialization	Unknown	\initialized(&player_current->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	826	cgc_daboss	initialization	Unknown	\initialized(&player_current->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	826	cgc_daboss	precondition of printf_va_53	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	826	printf_va_53	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	861	cgc_capture_monster	dangling_pointer	Unknown	¬\dangling(&pp->mons[choice])
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	890	cgc_capture_monster	precondition of free	Unknown	freeable: p ≡ \null ∨ \freeable(p)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	891	cgc_capture_monster	dangling_pointer	Unknown	¬\dangling(&pm)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	915	cgc_fight	initialization	Unknown	\initialized(&pm->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	923	cgc_fight	initialization	Unknown	\initialized(&player_current->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	923	cgc_fight	mem_access	Unknown	\valid_read(&player_current->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	923	cgc_fight	division_by_zero	Unknown	player_current->power ≢ 0
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	931	cgc_fight	initialization	Unknown	\initialized(&pm->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	932	cgc_fight	initialization	Unknown	\initialized(&pm->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	932	cgc_fight	precondition of printf_va_65	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	932	printf_va_65	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	938	cgc_fight	initialization	Unknown	\initialized(&pm->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	938	cgc_fight	division_by_zero	Unknown	pm->power ≢ 0
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	941	cgc_fight	initialization	Unknown	\initialized(&player_current->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	941	cgc_fight	initialization	Unknown	\initialized(&pm->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	941	cgc_fight	mem_access	Unknown	\valid_read(&player_current->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	941	cgc_fight	precondition of printf_va_66	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	941	cgc_fight	precondition of printf_va_66	Unknown	valid_read_string(param1)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	941	printf_va_66	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	941	printf_va_66	precondition	Unknown	valid_read_string(param1)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	943	cgc_fight	initialization	Unknown	\initialized(&player_current->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	946	cgc_fight	initialization	Unknown	\initialized(&player_current->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	946	cgc_fight	precondition of printf_va_67	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	946	printf_va_67	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	982	cgc_movement_loop	initialization	Unknown	\initialized(pm->data + (unsigned int)((unsigned int)(pm->width * (unsigned int)(pm->current_y - 1)) + pm->current_x))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	982	cgc_movement_loop	mem_access	Unknown	\valid_read(pm->data + (unsigned int)((unsigned int)(pm->width * (unsigned int)(pm->current_y - 1)) + pm->current_x))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	993	cgc_movement_loop	initialization	Unknown	\initialized(pm->data + (unsigned int)((unsigned int)(pm->width * (unsigned int)(pm->current_y + 1)) + pm->current_x))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	993	cgc_movement_loop	mem_access	Unknown	\valid_read(pm->data + (unsigned int)((unsigned int)(pm->width * (unsigned int)(pm->current_y + 1)) + pm->current_x))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1004	cgc_movement_loop	initialization	Unknown	\initialized(pm->data + (unsigned int)((unsigned int)((unsigned int)(pm->width * pm->current_y) + pm->current_x) - 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1004	cgc_movement_loop	mem_access	Unknown	\valid_read(pm->data + (unsigned int)((unsigned int)((unsigned int)(pm->width * pm->current_y) + pm->current_x) - 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1015	cgc_movement_loop	initialization	Unknown	\initialized(pm->data + (unsigned int)((unsigned int)((unsigned int)(pm->width * pm->current_y) + pm->current_x) + 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1015	cgc_movement_loop	mem_access	Unknown	\valid_read(pm->data + (unsigned int)((unsigned int)((unsigned int)(pm->width * pm->current_y) + pm->current_x) + 1))
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1072	cgc_select_name	index_bound	Unknown	index_0 < 47
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1141	cgc_generate_player	index_bound	Unknown	tmp < 5
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1162	cgc_print_player	initialization	Unknown	\initialized(&(pp->mons[index_0])->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1162	cgc_print_player	mem_access	Unknown	\valid_read(&(pp->mons[index_0])->type)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1162	cgc_print_player	precondition of printf_va_89	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1162	printf_va_89	precondition	Unknown	valid_read_string(param0)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1162	cgc_print_player	index_bound	Unknown	index_0 < 5
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1163	cgc_print_player	initialization	Unknown	\initialized(&(pp->mons[index_0])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1163	cgc_print_player	mem_access	Unknown	\valid_read(&(pp->mons[index_0])->health)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1164	cgc_print_player	initialization	Unknown	\initialized(&(pp->mons[index_0])->power)
+/home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game	service.c	1164	cgc_print_player	mem_access	Unknown	\valid_read(&(pp->mons[index_0])->power)
+FRAMAC_SHARE/libc	stdlib.h	405	free	precondition	Unknown	freeable: p ≡ \null ∨ \freeable(p)
+FRAMAC_SHARE/libc	string.h	92	memcpy	precondition	Unknown	valid_dest: valid_or_empty(dest, n)
+FRAMAC_SHARE/libc	string.h	93	memcpy	precondition	Unknown	valid_src: valid_read_or_empty(src, n)
+FRAMAC_SHARE/libc	strings.h	36	bzero	precondition	Unknown	valid_memory_area: \valid((char *)s + (0 .. n - 1))
diff --git a/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/metrics.log b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/metrics.log
new file mode 100644
index 0000000000000000000000000000000000000000..36dc15ee70f9237ed7adcf5daf400f4ce1c20b24
--- /dev/null
+++ b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/metrics.log
@@ -0,0 +1,50 @@
+[metrics] Eva coverage statistics
+=======================
+Syntactically reachable functions = 32 (out of 77)
+Semantically reached functions = 29
+Coverage estimation = 90.6% 
+
+Unreached functions (3) =
+  </home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c>:
+    cgc_add_queue; cgc_check_adjacent; cgc_dequeue;
+[metrics] References to non-analyzed functions
+------------------------------------
+Function cgc_find_path calls cgc_check_adjacent (at /home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c:289)
+Function cgc_find_path calls cgc_add_queue (at /home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c:297)
+Function cgc_find_path calls cgc_add_queue (at /home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c:302)
+Function cgc_find_path calls cgc_add_queue (at /home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c:307)
+Function cgc_find_path calls cgc_add_queue (at /home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c:312)
+Function cgc_find_path calls cgc_dequeue (at /home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c:315)
+Function cgc_find_path calls cgc_dequeue (at /home/dario/git/open-source-case-studies/cgc-challenges/Monster_Game/service.c:325)
+[metrics] Statements analyzed by Eva
+--------------------------
+760 stmts in analyzed functions, 682 stmts analyzed (89.7%)
+cgc_change_monster_name: 14 stmts out of 14 (100.0%)
+cgc_check_egg: 10 stmts out of 10 (100.0%)
+cgc_generate_boss: 14 stmts out of 14 (100.0%)
+cgc_generate_monster: 14 stmts out of 14 (100.0%)
+cgc_generate_player: 25 stmts out of 25 (100.0%)
+cgc_initialize_queue_matrix: 16 stmts out of 16 (100.0%)
+cgc_place_marker: 38 stmts out of 38 (100.0%)
+cgc_print_map: 28 stmts out of 28 (100.0%)
+cgc_print_monster: 9 stmts out of 9 (100.0%)
+cgc_receive: 9 stmts out of 9 (100.0%)
+cgc_select_name: 13 stmts out of 13 (100.0%)
+cgc_set_marker: 3 stmts out of 3 (100.0%)
+cgc_update_page_index: 3 stmts out of 3 (100.0%)
+main: 17 stmts out of 17 (100.0%)
+cgc_movement_loop: 73 stmts out of 76 (96.1%)
+cgc_select_monster: 49 stmts out of 52 (94.2%)
+cgc_initialize_map: 32 stmts out of 34 (94.1%)
+cgc_fight: 39 stmts out of 42 (92.9%)
+cgc_capture_boss: 64 stmts out of 69 (92.8%)
+cgc_daboss: 38 stmts out of 41 (92.7%)
+cgc_capture_monster: 58 stmts out of 63 (92.1%)
+cgc_generate_map: 33 stmts out of 37 (89.2%)
+cgc_print_player: 15 stmts out of 17 (88.2%)
+cgc_read_line_u: 21 stmts out of 24 (87.5%)
+cgc_read_line: 25 stmts out of 30 (83.3%)
+cgc_reset_monsters: 10 stmts out of 12 (83.3%)
+cgc_oneup_monster: 11 stmts out of 14 (78.6%)
+cgc__terminate: 1 stmts out of 2 (50.0%)
+cgc_find_path: 0 stmts out of 34 (0.0%)
diff --git a/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/nonterm.log b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/nonterm.log
new file mode 100644
index 0000000000000000000000000000000000000000..1a95fcc774a2a7ab28bc5082a3865f04f1157569
--- /dev/null
+++ b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/nonterm.log
@@ -0,0 +1 @@
+/home/dario/git/open-source-case-studies/cgc-challenges/lib/libcgc.c:24:[nonterm] warning: unreachable implicit return
diff --git a/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/warnings.log b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.eva/warnings.log
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/framac.ast b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/framac.ast
new file mode 100644
index 0000000000000000000000000000000000000000..5c02800ba77b003bb01ed3108d69d477a6df2618
--- /dev/null
+++ b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/framac.ast
@@ -0,0 +1,4157 @@
+/* Generated by Frama-C */
+#include "ctype.h"
+#include "errno.h"
+#include "fcntl.h"
+#include "math.h"
+#include "signal.h"
+#include "stdarg.h"
+#include "stddef.h"
+#include "stdint.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "strings.h"
+#include "sys/mman.h"
+#include "sys/select.h"
+#include "sys/time.h"
+#include "sys/types.h"
+#include "unistd.h"
+struct _inode {
+   char *Filename ;
+   char *Owner ;
+   uint8_t Mode ;
+   uint32_t FileSize ;
+   unsigned char *Data ;
+};
+typedef struct _inode Inode;
+typedef struct _inode *pInode;
+struct _fs {
+   uint32_t MaxSize ;
+   uint32_t MaxFiles ;
+   pInode *Inodes ;
+};
+typedef struct _fs Filesystem;
+typedef struct _fs *pFilesystem;
+struct _file {
+   pInode Inode ;
+   uint8_t Mode ;
+   uint32_t CurrPosition ;
+};
+typedef struct _file FILE_;
+struct cgc_aes_state {
+   uint8_t vec[16]  __attribute__((__aligned__(1)));
+   uint8_t key[16]  __attribute__((__aligned__(1)));
+   uint8_t datetime[16]  __attribute__((__aligned__(1)));
+} __attribute__((__packed__, __aligned__(1)));
+typedef struct cgc_aes_state cgc_aes_state;
+struct cgc_prng {
+   cgc_aes_state state ;
+   uint8_t intermediate[16] ;
+   uint8_t random_data[16] ;
+   uint8_t random_idx ;
+};
+typedef struct cgc_prng cgc_prng_0;
+struct queue {
+   size_t x ;
+   size_t y ;
+   struct queue *next ;
+};
+typedef struct queue queue;
+typedef struct queue *pqueue;
+struct map {
+   size_t width ;
+   size_t height ;
+   size_t start_x ;
+   size_t start_y ;
+   size_t end_x ;
+   size_t end_y ;
+   size_t current_x ;
+   size_t current_y ;
+   size_t last_x ;
+   size_t last_y ;
+   char *data ;
+};
+typedef struct map map;
+typedef struct map *pmap;
+struct monster {
+   char *type ;
+   int health ;
+   size_t hitpoints ;
+   size_t power ;
+   size_t experience ;
+   size_t level ;
+};
+typedef struct monster monster;
+typedef struct monster *pmonster;
+struct player {
+   char name[16] ;
+   size_t level ;
+   size_t mcnt ;
+   pmonster mons[5] ;
+};
+typedef struct player player;
+typedef struct player *pplayer;
+int __prng_state;
+/*@ assigns __prng_state;
+    assigns __prng_state \from seedValue; */
+void seed_prng(uint32_t seedValue);
+
+uint32_t cgc_prng(void);
+
+char *names[47] =
+  {(char *)"Lost Needless Duck",
+   (char *)"The Commander",
+   (char *)"Toxic Major",
+   (char *)"El Spider",
+   (char *)"The Heroic Emperor",
+   (char *)"Rock Beast",
+   (char *)"Gamma Guardian",
+   (char *)"Rough Wizard",
+   (char *)"Persistent Puppet",
+   (char *)"Pure Ghost Killer",
+   (char *)"The Golden Oyster",
+   (char *)"Hidden Leather",
+   (char *)"Dreaded Digital Hawk",
+   (char *)"The Admiral",
+   (char *)"Sneaky Tough Electron",
+   (char *)"Trolling Captain",
+   (char *)"The Barbarian",
+   (char *)"Elvish Moose",
+   (char *)"Snappy Dinosaur",
+   (char *)"The Bursting Wrench",
+   (char *)"Itchy Eagle",
+   (char *)"Angry Neutron",
+   (char *)"Asada Gothar Derik",
+   (char *)"Seth Bydern",
+   (char *)"Quid Cipyar",
+   (char *)"Amarisa Yerpal Jihb",
+   (char *)"Tilthan",
+   (char *)"Teressa Gosform",
+   (char *)"Uerth Bredock Lidorn",
+   (char *)"Raydan Fronar",
+   (char *)"Aldaren Cevelt",
+   (char *)"Florian",
+   (char *)"Celestine Ixil Boldel",
+   (char *)"Safize Ixen",
+   (char *)"Corda Migorn",
+   (char *)"Vigoth Boldel",
+   (char *)"Gothar Mathar",
+   (char *)"Vinkol Seryth",
+   (char *)"Wrathran Palpur",
+   (char *)"Luna Milen",
+   (char *)"Zotar Phalloz",
+   (char *)"Pildoor Vildar Virdo",
+   (char *)"Odeir Jibar Wyeth",
+   (char *)"Fearlock Breen",
+   (char *)"Soderman Iroldak",
+   (char *)"Lelani Oxpar Xavor",
+   (char *)0};
+void cgc_seed_prng_array(uint32_t *pSeedArray, uint32_t arrayLen);
+
+void cgc_seed_prng(uint32_t seedValue);
+
+uint32_t cgc_random_in_range(uint32_t min, uint32_t max);
+
+uint32_t state[32];
+uint32_t state_n;
+void cgc_seed_prng_array(uint32_t *pSeedArray, uint32_t arrayLen)
+{
+  uint32_t i;
+  bzero((void *)(state),(unsigned int)32 * sizeof(uint32_t));
+  state_n = (unsigned int)0;
+  if (arrayLen > (uint32_t)32) arrayLen = (unsigned int)32;
+  i = (unsigned int)0;
+  while (i < arrayLen) {
+    state[i] = *(pSeedArray + i);
+    i += (uint32_t)1;
+  }
+  i = arrayLen;
+  while (i < (uint32_t)32) {
+    {
+      uint32_t state_value = state[(i - (uint32_t)1) & (unsigned int)0x1f];
+      state[i] = (state_value ^ ((state_value >> 30) + i)) * (unsigned int)524287;
+    }
+    i += (uint32_t)1;
+  }
+  return;
+}
+
+void cgc_seed_prng(uint32_t seedValue)
+{
+  cgc_seed_prng_array(& seedValue,(unsigned int)1);
+  return;
+}
+
+/*@ assigns \result, __prng_state;
+    assigns \result \from __prng_state;
+    assigns __prng_state \from __prng_state;
+ */
+uint32_t cgc_prng(void)
+{
+  uint32_t v0 = state[state_n];
+  uint32_t vM1 = state[(state_n + (uint32_t)3) & (unsigned int)0x1f];
+  uint32_t vM2 = state[(state_n + (uint32_t)24) & (unsigned int)0x1f];
+  uint32_t vM3 = state[(state_n + (uint32_t)10) & (unsigned int)0x1f];
+  uint32_t z0 = state[(state_n + (uint32_t)31) & (unsigned int)0x1f];
+  uint32_t z1 = v0 ^ (vM1 ^ (vM1 >> 8));
+  uint32_t z2 = (vM2 ^ (vM2 << 19)) ^ (vM3 ^ (vM3 << 14));
+  uint32_t newV1 = z1 ^ z2;
+  uint32_t newV0 =
+    ((z0 ^ (z0 << 11)) ^ (z1 ^ (z1 << 7))) ^ (z2 ^ (z2 << 13));
+  state[state_n] = newV1;
+  state[(state_n + (uint32_t)31) & (unsigned int)0x1f] = newV0;
+  state_n = (state_n + (uint32_t)31) & (unsigned int)0x1f;
+  return newV0;
+}
+
+uint32_t cgc_random_in_range(uint32_t min, uint32_t max)
+{
+  uint32_t __retres;
+  uint32_t random_value;
+  if (min > max) {
+    __retres = (unsigned int)0;
+    goto return_label;
+  }
+  if (min == max) {
+    __retres = min;
+    goto return_label;
+  }
+  uint32_t delta = (max - min) + (uint32_t)1;
+  if (delta == (uint32_t)0) {
+    uint32_t tmp;
+    tmp = cgc_prng();
+    __retres = tmp;
+    goto return_label;
+  }
+  uint32_t scale_divider = 0xffffffff / delta;
+  while (1) {
+    random_value = cgc_prng();
+    if (! (random_value >= scale_divider * delta)) break;
+  }
+  __retres = min + random_value / scale_divider;
+  return_label: return __retres;
+}
+
+ __attribute__((__noreturn__)) void cgc__terminate(unsigned int status);
+
+int cgc_transmit(int fd, void const *buf, size_t count, size_t *tx_bytes);
+
+int cgc_receive(int fd, void *buf, size_t count, size_t *rx_bytes);
+
+int cgc_fdwait(int nfds, fd_set *readfds, fd_set *writefds,
+               struct timeval const *timeout, int *readyfds);
+
+int cgc_allocate(size_t length, int is_executable, void **addr);
+
+int cgc_deallocate(void *addr, size_t length);
+
+int cgc_random(void *buf, size_t count, size_t *rnd_bytes);
+
+int cgc_sprintf(char *buf, char const *format, void * const *__va_params);
+
+int cgc_puts(char const *s);
+
+char *cgc_FsError(void);
+
+uint8_t cgc_DestroyFilesystem(void);
+
+uint8_t cgc_InitFilesystem(uint32_t MaxFiles, char *RootPassword);
+
+uint8_t cgc_RenameFile(char *OldFilename, char *NewFilename);
+
+uint8_t cgc_DeleteFile(char *Filename);
+
+uint8_t cgc_InitPasswd(char *RootPassword);
+
+FILE_ *cgc_fopen(char *Filename, char *Mode);
+
+uint32_t cgc_fread(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp);
+
+uint32_t cgc_fwrite(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp);
+
+uint8_t cgc_fclose(FILE_ *fp);
+
+uint8_t cgc_ListFiles(char **Buf);
+
+uint8_t cgc_Login(char *Username);
+
+void cgc_Uid(void);
+
+uint8_t cgc_Logout(void);
+
+uint8_t cgc_AddUser(char *Username, char *Password);
+
+uint8_t cgc_DeleteUser(char *Username);
+
+uint8_t cgc_ChangePasswd(char *Username, char *NewPasswd);
+
+uint8_t cgc_CheckPasswd(char *Username, char *Password);
+
+uint8_t cgc_UserExists(char *Username);
+
+char *cgc_fgets(char *buf, uint32_t size, FILE_ *fp);
+
+pFilesystem cgc_FS = (struct _fs *)0;
+char *cgc_CurrentUser = (char *)0;
+FILE_ *FD[8];
+char FS_ERROR[63 + 1];
+void cgc_SetFsError(char *error)
+{
+  if ((int)FS_ERROR[0] == '\000') strncpy(FS_ERROR,(char const *)error,
+                                          (unsigned int)63);
+  return;
+}
+
+void cgc_ClearFsError(void)
+{
+  FS_ERROR[0] = (char)'\000';
+  return;
+}
+
+char *cgc_FsError(void)
+{
+  char *__retres;
+  __retres = FS_ERROR;
+  return __retres;
+}
+
+uint8_t cgc_DestroyFilesystem(void)
+{
+  uint8_t __retres;
+  uint32_t i;
+  if (! cgc_FS) {
+    cgc_SetFsError((char *)"Filesystem does not exist");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  i = (unsigned int)0;
+  while (i < cgc_FS->MaxFiles) {
+    if (*(cgc_FS->Inodes + i)) {
+      if ((*(cgc_FS->Inodes + i))->Filename) {
+        free((void *)(*(cgc_FS->Inodes + i))->Filename);
+        (*(cgc_FS->Inodes + i))->Filename = (char *)0;
+      }
+      if ((*(cgc_FS->Inodes + i))->Owner) {
+        free((void *)(*(cgc_FS->Inodes + i))->Owner);
+        (*(cgc_FS->Inodes + i))->Owner = (char *)0;
+      }
+      if ((*(cgc_FS->Inodes + i))->Data) {
+        free((void *)(*(cgc_FS->Inodes + i))->Data);
+        (*(cgc_FS->Inodes + i))->Data = (unsigned char *)0;
+      }
+      free((void *)*(cgc_FS->Inodes + i));
+      *(cgc_FS->Inodes + i) = (struct _inode *)0;
+    }
+    i += (uint32_t)1;
+  }
+  free((void *)cgc_FS);
+  cgc_FS = (struct _fs *)0;
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_InitFilesystem(uint32_t MaxFiles, char *RootPassword)
+{
+  uint8_t __retres;
+  pInode *tmp;
+  uint8_t tmp_0;
+  uint8_t tmp_1;
+  bzero((void *)(FS_ERROR),sizeof(FS_ERROR));
+  if (MaxFiles == (uint32_t)0) {
+    cgc_SetFsError((char *)"MaxFiles should be > 0");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (cgc_FS) cgc_DestroyFilesystem();
+  cgc_FS = (pFilesystem)calloc((unsigned int)1,sizeof(Filesystem));
+  if (cgc_FS == (pFilesystem)0) {
+    cgc_SetFsError((char *)"calloc failed");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = (pInode *)calloc((unsigned int)1,sizeof(Inode) * MaxFiles);
+  cgc_FS->Inodes = tmp;
+  if (tmp == (pInode *)0) {
+    cgc_SetFsError((char *)"calloc failed");
+    free((void *)cgc_FS);
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  cgc_FS->MaxFiles = MaxFiles;
+  tmp_0 = cgc_Login((char *)"root");
+  if (! tmp_0) {
+    cgc_SetFsError((char *)"Login failed");
+    free((void *)cgc_FS->Inodes);
+    free((void *)cgc_FS);
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_1 = cgc_InitPasswd(RootPassword);
+  if (! tmp_1) {
+    cgc_Logout();
+    cgc_SetFsError((char *)"Failed to init the passwd file");
+    free((void *)cgc_FS->Inodes);
+    free((void *)cgc_FS);
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  bzero((void *)(FD),sizeof(FD));
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+pInode cgc_FindFile(char *Filename)
+{
+  pInode __retres;
+  uint32_t i;
+  i = (unsigned int)0;
+  while (i < cgc_FS->MaxFiles) {
+    if (*(cgc_FS->Inodes + i)) 
+      if ((*(cgc_FS->Inodes + i))->Filename) {
+        int tmp;
+        tmp = strcmp((char const *)(*(cgc_FS->Inodes + i))->Filename,
+                     (char const *)Filename);
+        if (! tmp) {
+          __retres = *(cgc_FS->Inodes + i);
+          goto return_label;
+        }
+      }
+    i += (uint32_t)1;
+  }
+  __retres = (struct _inode *)0;
+  return_label: return __retres;
+}
+
+pInode cgc_CreateEmptyFile(char *Filename, uint8_t Mode)
+{
+  pInode __retres;
+  uint32_t i;
+  pInode tmp;
+  if (! Filename) {
+    cgc_SetFsError((char *)"Invalid filename");
+    __retres = (struct _inode *)0;
+    goto return_label;
+  }
+  if (! cgc_CurrentUser) {
+    cgc_SetFsError((char *)"Must login first");
+    __retres = (struct _inode *)0;
+    goto return_label;
+  }
+  if ((int)Mode & ((((0x4 | 0x6) | 0x40) | 0x60) ^ 0xFF)) {
+    cgc_SetFsError((char *)"Invalid mode");
+    __retres = (struct _inode *)0;
+    goto return_label;
+  }
+  tmp = cgc_FindFile(Filename);
+  if (tmp) {
+    cgc_SetFsError((char *)"File already exists");
+    __retres = (struct _inode *)0;
+    goto return_label;
+  }
+  i = (unsigned int)0;
+  while (i < cgc_FS->MaxFiles) {
+    {
+      pInode tmp_0;
+      size_t tmp_2;
+      char *tmp_1;
+      char *tmp_3;
+      if (*(cgc_FS->Inodes + i)) goto __Cont;
+      tmp_0 = (pInode)calloc((unsigned int)1,sizeof(Inode));
+      *(cgc_FS->Inodes + i) = tmp_0;
+      if (tmp_0 == (pInode)0) {
+        cgc_SetFsError((char *)"calloc failed");
+        __retres = (struct _inode *)0;
+        goto return_label;
+      }
+      tmp_2 = strlen((char const *)Filename);
+      tmp_1 = (char *)calloc((unsigned int)1,tmp_2 + (size_t)1);
+      (*(cgc_FS->Inodes + i))->Filename = tmp_1;
+      if (tmp_1 == (char *)0) {
+        cgc_SetFsError((char *)"calloc failed");
+        free((void *)*(cgc_FS->Inodes + i));
+        *(cgc_FS->Inodes + i) = (struct _inode *)0;
+        __retres = (struct _inode *)0;
+        goto return_label;
+      }
+      strcpy((*(cgc_FS->Inodes + i))->Filename,(char const *)Filename);
+      tmp_3 = (char *)calloc((unsigned int)1,
+                             sizeof(cgc_CurrentUser) + (unsigned int)1);
+      (*(cgc_FS->Inodes + i))->Owner = tmp_3;
+      if (tmp_3 == (char *)0) {
+        cgc_SetFsError((char *)"calloc failed");
+        free((void *)(*(cgc_FS->Inodes + i))->Filename);
+        (*(cgc_FS->Inodes + i))->Filename = (char *)0;
+        free((void *)*(cgc_FS->Inodes + i));
+        *(cgc_FS->Inodes + i) = (struct _inode *)0;
+        __retres = (struct _inode *)0;
+        goto return_label;
+      }
+      strcpy((*(cgc_FS->Inodes + i))->Owner,(char const *)cgc_CurrentUser);
+      (*(cgc_FS->Inodes + i))->Mode = Mode;
+      (*(cgc_FS->Inodes + i))->FileSize = (unsigned int)0;
+      (*(cgc_FS->Inodes + i))->Data = (unsigned char *)0;
+      break;
+    }
+    __Cont: i += (uint32_t)1;
+  }
+  if (i == cgc_FS->MaxFiles) {
+    cgc_SetFsError((char *)"No free inodes");
+    __retres = (struct _inode *)0;
+    goto return_label;
+  }
+  cgc_ClearFsError();
+  __retres = *(cgc_FS->Inodes + i);
+  return_label: return __retres;
+}
+
+FILE_ *cgc_fopen(char *Filename, char *Mode)
+{
+  FILE_ *__retres;
+  uint32_t i;
+  FILE_ *fp;
+  size_t tmp;
+  pInode TargetInode = (struct _inode *)0;
+  if (! cgc_FS) {
+    cgc_SetFsError((char *)"Filesystem does not exist");
+    __retres = (FILE_ *)0;
+    goto return_label;
+  }
+  if (! Filename) goto _LOR;
+  else 
+    if (! Mode) {
+      _LOR:
+      {
+        cgc_SetFsError((char *)"Invalid filename or mode");
+        __retres = (FILE_ *)0;
+        goto return_label;
+      }
+    }
+  tmp = strlen((char const *)Mode);
+  if (tmp > (size_t)1) {
+    cgc_SetFsError((char *)"Invalid mode");
+    __retres = (FILE_ *)0;
+    goto return_label;
+  }
+  if ((int)*(Mode + 0) != 'r') 
+    if ((int)*(Mode + 0) != 'w') {
+      cgc_SetFsError((char *)"Invalid mode");
+      __retres = (FILE_ *)0;
+      goto return_label;
+    }
+  if (! cgc_CurrentUser) {
+    cgc_SetFsError((char *)"Must login first");
+    __retres = (FILE_ *)0;
+    goto return_label;
+  }
+  TargetInode = cgc_FindFile(Filename);
+  if (! TargetInode) 
+    if ((int)*(Mode + 0) == 'r') {
+      cgc_SetFsError((char *)"Unable to locate file");
+      __retres = (FILE_ *)0;
+      goto return_label;
+    }
+  if (TargetInode) {
+    i = (unsigned int)0;
+    while (i < (uint32_t)8) {
+      if (FD[i]) 
+        if ((FD[i])->Inode == TargetInode) {
+          cgc_SetFsError((char *)"File is already open");
+          __retres = (FILE_ *)0;
+          goto return_label;
+        }
+      i += (uint32_t)1;
+    }
+  }
+  if (TargetInode) {
+    int tmp_1;
+    tmp_1 = strcmp((char const *)cgc_CurrentUser,"root");
+    if (tmp_1 != 0) {
+      int tmp_0;
+      tmp_0 = strcmp((char const *)TargetInode->Owner,
+                     (char const *)cgc_CurrentUser);
+      if (tmp_0) {
+        if ((int)*(Mode + 0) == 'r') 
+          if (((int)TargetInode->Mode & 0x40) == 0) {
+            cgc_SetFsError((char *)"Permission denied");
+            __retres = (FILE_ *)0;
+            goto return_label;
+          }
+        if ((int)*(Mode + 0) == 'w') 
+          if (((int)TargetInode->Mode & 0x60) == 0) {
+            cgc_SetFsError((char *)"Permission denied");
+            __retres = (FILE_ *)0;
+            goto return_label;
+          }
+      }
+      else {
+        if ((int)*(Mode + 0) == 'r') 
+          if (((int)TargetInode->Mode & 0x4) == 0) {
+            cgc_SetFsError((char *)"Permission denied");
+            __retres = (FILE_ *)0;
+            goto return_label;
+          }
+        if ((int)*(Mode + 0) == 'w') 
+          if (((int)TargetInode->Mode & 0x6) == 0) {
+            cgc_SetFsError((char *)"Permission denied");
+            __retres = (FILE_ *)0;
+            goto return_label;
+          }
+      }
+    }
+  }
+  fp = (FILE_ *)calloc((unsigned int)1,sizeof(FILE_));
+  if (fp == (FILE_ *)0) {
+    cgc_SetFsError((char *)"calloc failed");
+    __retres = (FILE_ *)0;
+    goto return_label;
+  }
+  i = (unsigned int)0;
+  while (i < (uint32_t)8) {
+    if (FD[i]) goto __Cont;
+    FD[i] = fp;
+    break;
+    __Cont: i += (uint32_t)1;
+  }
+  if (i == (uint32_t)8) {
+    cgc_SetFsError((char *)"No free file descriptors");
+    free((void *)fp);
+    __retres = (FILE_ *)0;
+    goto return_label;
+  }
+  if ((int)*(Mode + 0) == 'w') 
+    if (! TargetInode) {
+      TargetInode = cgc_CreateEmptyFile(Filename,(unsigned char)(0x4 | 0x6));
+      if (TargetInode == (pInode)0) {
+        cgc_SetFsError((char *)"Failed to create file");
+        FD[i] = (FILE_ *)0;
+        free((void *)fp);
+        __retres = (FILE_ *)0;
+        goto return_label;
+      }
+      fp->Inode = TargetInode;
+      fp->Mode = (unsigned char)0x6;
+      fp->CurrPosition = (unsigned int)0;
+    }
+    else {
+      fp->Inode = TargetInode;
+      fp->Mode = (unsigned char)0x6;
+      fp->CurrPosition = (unsigned int)0;
+      (fp->Inode)->FileSize = (unsigned int)0;
+      if ((fp->Inode)->Data) {
+        free((void *)(fp->Inode)->Data);
+        (fp->Inode)->Data = (unsigned char *)0;
+      }
+    }
+  else {
+    fp->Inode = TargetInode;
+    fp->Mode = (unsigned char)0x4;
+    fp->CurrPosition = (unsigned int)0;
+  }
+  cgc_ClearFsError();
+  __retres = fp;
+  return_label: return __retres;
+}
+
+uint8_t cgc_fclose(FILE_ *fp)
+{
+  uint8_t __retres;
+  uint8_t i;
+  if (! fp) {
+    cgc_SetFsError((char *)"Invalid file pointer");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  i = (unsigned char)0;
+  while ((int)i < 8) {
+    if (FD[i] == fp) FD[i] = (FILE_ *)0;
+    i = (uint8_t)((int)i + 1);
+  }
+  cgc_ClearFsError();
+  free((void *)fp);
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint32_t cgc_fread(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp)
+{
+  uint32_t __retres;
+  if (! buf) goto _LOR;
+  else 
+    if (! fp) {
+      _LOR:
+      {
+        cgc_SetFsError((char *)"Invalid buffer or file pointer");
+        __retres = (unsigned int)0;
+        goto return_label;
+      }
+    }
+  if (! (fp->Inode)->Data) {
+    cgc_SetFsError((char *)"End of file");
+    __retres = (unsigned int)0;
+    goto return_label;
+  }
+  if (size * nitems > (fp->Inode)->FileSize - fp->CurrPosition) {
+    memcpy((void *)buf,(void const *)((fp->Inode)->Data + fp->CurrPosition),
+           (fp->Inode)->FileSize - fp->CurrPosition);
+    fp->CurrPosition += (fp->Inode)->FileSize - fp->CurrPosition;
+    cgc_ClearFsError();
+    __retres = (fp->Inode)->FileSize - fp->CurrPosition;
+    goto return_label;
+  }
+  else {
+    memcpy((void *)buf,(void const *)((fp->Inode)->Data + fp->CurrPosition),
+           size * nitems);
+    fp->CurrPosition += size * nitems;
+    cgc_ClearFsError();
+    __retres = size * nitems;
+    goto return_label;
+  }
+  return_label: return __retres;
+}
+
+uint32_t cgc_fwrite(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp)
+{
+  uint32_t __retres;
+  unsigned char *NewData;
+  if (! buf) goto _LOR;
+  else 
+    if (! fp) {
+      _LOR:
+      {
+        cgc_SetFsError((char *)"Invalid buffer or file pointer");
+        __retres = (unsigned int)0;
+        goto return_label;
+      }
+    }
+  NewData = (unsigned char *)calloc((unsigned int)1,
+                                    (fp->Inode)->FileSize + size * nitems);
+  if (NewData == (unsigned char *)0) {
+    cgc_SetFsError((char *)"calloc failed");
+    __retres = (unsigned int)0;
+    goto return_label;
+  }
+  if ((fp->Inode)->Data) memcpy((void *)NewData,
+                                (void const *)(fp->Inode)->Data,
+                                (fp->Inode)->FileSize);
+  memcpy((void *)(NewData + (fp->Inode)->FileSize),(void const *)buf,
+         size * nitems);
+  (fp->Inode)->FileSize += size * nitems;
+  if ((fp->Inode)->Data) free((void *)(fp->Inode)->Data);
+  (fp->Inode)->Data = NewData;
+  cgc_ClearFsError();
+  __retres = size * nitems;
+  return_label: return __retres;
+}
+
+char *cgc_fgets(char *buf, uint32_t size, FILE_ *fp)
+{
+  char *__retres;
+  uint32_t TotalBytes = (unsigned int)0;
+  if (! buf) {
+    cgc_SetFsError((char *)"Invalid buffer");
+    __retres = (char *)0;
+    goto return_label;
+  }
+  if (! fp) {
+    cgc_SetFsError((char *)"Invalid file");
+    __retres = (char *)0;
+    goto return_label;
+  }
+  if (fp->CurrPosition == (fp->Inode)->FileSize) {
+    cgc_SetFsError((char *)"End of file");
+    __retres = (char *)0;
+    goto return_label;
+  }
+  if (! (fp->Inode)->Data) {
+    cgc_SetFsError((char *)"End of file");
+    __retres = (char *)0;
+    goto return_label;
+  }
+  while (1) {
+    if (fp->CurrPosition < (fp->Inode)->FileSize) {
+      if (! (TotalBytes < size - (uint32_t)1)) break;
+    }
+    else break;
+    {
+      uint32_t tmp;
+      uint32_t tmp_0;
+      tmp = TotalBytes;
+      TotalBytes += (uint32_t)1;
+      tmp_0 = fp->CurrPosition;
+      fp->CurrPosition += (uint32_t)1;
+      *(buf + tmp) = (char)*((fp->Inode)->Data + tmp_0);
+      if ((int)*((fp->Inode)->Data + (fp->CurrPosition - (uint32_t)1)) == '\n') 
+        break;
+    }
+  }
+  *(buf + TotalBytes) = (char)'\000';
+  __retres = buf;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param3);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param3 + (0 ..))),
+            (indirect: *(param2 + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param3 + (0 ..)), *(param2 + (0 ..)), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int printf_va_1(char const * __restrict format, char *param0, char *param1,
+                char *param2, char *param3);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int printf_va_2(char const * __restrict format, char *param0, char *param1,
+                size_t param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_3(char const * __restrict format, char *param0);
+
+uint8_t cgc_ListFiles(char **Buf)
+{
+  uint8_t __retres;
+  uint32_t i;
+  char Mode[5];
+  uint32_t TotalLen;
+  uint32_t NewLen;
+  if (! cgc_FS) {
+    cgc_SetFsError((char *)"Filesystem does not exist");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (Buf) {
+    char *tmp_0;
+    TotalLen = (unsigned int)((((((32 + 1) + 32) + 1) + 8) + 4) + 1);
+    i = (unsigned int)0;
+    while (i < cgc_FS->MaxFiles) {
+      if (*(cgc_FS->Inodes + i) == (pInode)0) goto __Cont;
+      NewLen = strlen((char const *)(*(cgc_FS->Inodes + i))->Filename);
+      if (NewLen < (uint32_t)32) TotalLen += (uint32_t)32;
+      else TotalLen += NewLen;
+      TotalLen += (uint32_t)1;
+      NewLen = strlen((char const *)(*(cgc_FS->Inodes + i))->Owner);
+      if (NewLen < (uint32_t)32) TotalLen += (uint32_t)32;
+      else TotalLen += NewLen;
+      TotalLen += (uint32_t)1;
+      if ((*(cgc_FS->Inodes + i))->FileSize == (uint32_t)0) TotalLen += (uint32_t)8;
+      else {
+        double tmp;
+        tmp = log10((double)(*(cgc_FS->Inodes + i))->FileSize);
+        NewLen = (unsigned int)(tmp + (double)1);
+        if (NewLen < (uint32_t)8) TotalLen += (uint32_t)8;
+        else TotalLen += NewLen;
+      }
+      TotalLen += (uint32_t)6;
+      __Cont: i += (uint32_t)1;
+    }
+    tmp_0 = (char *)calloc((unsigned int)1,TotalLen);
+    *Buf = tmp_0;
+    if (tmp_0 == (char *)0) {
+      cgc_SetFsError((char *)"calloc failed");
+      __retres = (unsigned char)0;
+      goto return_label;
+    }
+  }
+  if (Buf) {
+    {
+      char const *__va_arg0 = "Filename";
+      char const *__va_arg1 = "Owner";
+      char const *__va_arg2 = "Size";
+      char const *__va_arg3 = "Mode";
+      void *__va_args[4] =
+        {& __va_arg0, & __va_arg1, & __va_arg2, & __va_arg3};
+      cgc_sprintf(*Buf,"%-32s %-32s %-8s %-4s\n",(void * const *)(__va_args));
+    }
+  }
+  else printf_va_1("%-32s %-32s %-8s %-4s\n",(char *)"Filename",
+                   (char *)"Owner",(char *)"Size",(char *)"Mode");
+  i = (unsigned int)0;
+  while (i < cgc_FS->MaxFiles) {
+    if (*(cgc_FS->Inodes + i) == (pInode)0) goto __Cont_0;
+    if (Buf) {
+      {
+        char *__va_arg0_14 = *Buf;
+        char *__va_arg1_16 = (*(cgc_FS->Inodes + i))->Filename;
+        char *__va_arg2_18 = (*(cgc_FS->Inodes + i))->Owner;
+        uint32_t __va_arg3_20 = (*(cgc_FS->Inodes + i))->FileSize;
+        void *__va_args_22[4] =
+          {& __va_arg0_14, & __va_arg1_16, & __va_arg2_18, & __va_arg3_20};
+        cgc_sprintf(*Buf,"%s%-32s %-32s %-8d ",
+                    (void * const *)(__va_args_22));
+      }
+    }
+    else printf_va_2("%-32s %-32s %-8zu ",(*(cgc_FS->Inodes + i))->Filename,
+                     (*(cgc_FS->Inodes + i))->Owner,
+                     (*(cgc_FS->Inodes + i))->FileSize);
+    memset((void *)(Mode),'-',(unsigned int)5);
+    Mode[4] = (char)'\000';
+    if ((int)(*(cgc_FS->Inodes + i))->Mode & 0x4) Mode[0] = (char)'r';
+    if ((int)(*(cgc_FS->Inodes + i))->Mode & 0x6) Mode[1] = (char)'w';
+    if ((int)(*(cgc_FS->Inodes + i))->Mode & 0x40) Mode[2] = (char)'r';
+    if ((int)(*(cgc_FS->Inodes + i))->Mode & 0x60) Mode[3] = (char)'w';
+    if (Buf) {
+      {
+        char *__va_arg0_24 = *Buf;
+        char *__va_arg1_26 = Mode;
+        void *__va_args_28[2] = {& __va_arg0_24, & __va_arg1_26};
+        cgc_sprintf(*Buf,"%s%-4s\n",(void * const *)(__va_args_28));
+      }
+    }
+    else printf_va_3("%-4s\n",Mode);
+    __Cont_0: i += (uint32_t)1;
+  }
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_DeleteFile(char *Filename)
+{
+  uint8_t __retres;
+  uint32_t i;
+  uint32_t InodeIndex;
+  pInode TargetInode;
+  int tmp_0;
+  if (! cgc_FS) {
+    cgc_SetFsError((char *)"Filesystem does not exist");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (! Filename) {
+    cgc_SetFsError((char *)"Invalid filename");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (! cgc_CurrentUser) {
+    cgc_SetFsError((char *)"Must login first");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  i = (unsigned int)0;
+  while (i < cgc_FS->MaxFiles) {
+    {
+      int tmp;
+      if (*(cgc_FS->Inodes + i) == (pInode)0) goto __Cont;
+      tmp = strcmp((char const *)(*(cgc_FS->Inodes + i))->Filename,
+                   (char const *)Filename);
+      if (! tmp) {
+        TargetInode = *(cgc_FS->Inodes + i);
+        InodeIndex = i;
+        break;
+      }
+    }
+    __Cont: i += (uint32_t)1;
+  }
+  if (i == cgc_FS->MaxFiles) {
+    cgc_SetFsError((char *)"Unable to locate file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  i = (unsigned int)0;
+  while (i < (uint32_t)8) {
+    if (FD[i]) 
+      if ((FD[i])->Inode == TargetInode) {
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+    i += (uint32_t)1;
+  }
+  tmp_0 = strcmp((char const *)cgc_CurrentUser,"root");
+  if (tmp_0 != 0) {
+    int tmp_1;
+    tmp_1 = strcmp((char const *)cgc_CurrentUser,
+                   (char const *)TargetInode->Owner);
+    if (tmp_1 != 0) {
+      cgc_SetFsError((char *)"Permission denied");
+      __retres = (unsigned char)0;
+      goto return_label;
+    }
+  }
+  free((void *)TargetInode->Filename);
+  if (TargetInode->Owner) free((void *)TargetInode->Owner);
+  if (TargetInode->Data) free((void *)TargetInode->Data);
+  free((void *)TargetInode);
+  *(cgc_FS->Inodes + InodeIndex) = (struct _inode *)0;
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_RenameFile(char *OldFilename, char *NewFilename)
+{
+  uint8_t __retres;
+  uint32_t i;
+  char *TempFilename;
+  int tmp_1;
+  size_t tmp_3;
+  pInode SourceInode = (struct _inode *)0;
+  if (! OldFilename) goto _LOR;
+  else 
+    if (! NewFilename) {
+      _LOR:
+      {
+        cgc_SetFsError((char *)"Invalid filename");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+    }
+  i = (unsigned int)0;
+  while (i < cgc_FS->MaxFiles) {
+    if (*(cgc_FS->Inodes + i)) 
+      if ((*(cgc_FS->Inodes + i))->Filename) {
+        int tmp;
+        int tmp_0;
+        tmp = strcmp((char const *)(*(cgc_FS->Inodes + i))->Filename,
+                     (char const *)OldFilename);
+        if (! tmp) SourceInode = *(cgc_FS->Inodes + i);
+        tmp_0 = strcmp((char const *)(*(cgc_FS->Inodes + i))->Filename,
+                       (char const *)NewFilename);
+        if (! tmp_0) {
+          cgc_SetFsError((char *)"Destination file already exists");
+          __retres = (unsigned char)0;
+          goto return_label;
+        }
+      }
+    i += (uint32_t)1;
+  }
+  if (! SourceInode) {
+    cgc_SetFsError((char *)"Source file not found");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_1 = strcmp((char const *)cgc_CurrentUser,"root");
+  if (tmp_1 != 0) {
+    int tmp_2;
+    tmp_2 = strcmp((char const *)cgc_CurrentUser,
+                   (char const *)SourceInode->Owner);
+    if (tmp_2 != 0) {
+      cgc_SetFsError((char *)"Permission denied");
+      __retres = (unsigned char)0;
+      goto return_label;
+    }
+  }
+  tmp_3 = strlen((char const *)NewFilename);
+  TempFilename = (char *)calloc((unsigned int)1,tmp_3 + (size_t)1);
+  if (TempFilename == (char *)0) {
+    cgc_SetFsError((char *)"calloc failed");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  strcpy(TempFilename,(char const *)NewFilename);
+  free((void *)SourceInode->Filename);
+  SourceInode->Filename = TempFilename;
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_ChangeMode(char *Filename, uint8_t NewMode)
+{
+  uint8_t __retres;
+  pInode TargetInode;
+  int tmp;
+  if (! Filename) {
+    cgc_SetFsError((char *)"Invalid user");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if ((int)NewMode & ((((0x4 | 0x6) | 0x40) | 0x60) ^ 0xFF)) {
+    cgc_SetFsError((char *)"Invalid mode");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  TargetInode = cgc_FindFile(Filename);
+  if (TargetInode == (pInode)0) {
+    cgc_SetFsError((char *)"Unable to find file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = strcmp((char const *)cgc_CurrentUser,"root");
+  if (tmp != 0) {
+    int tmp_0;
+    tmp_0 = strcmp((char const *)cgc_CurrentUser,
+                   (char const *)TargetInode->Owner);
+    if (tmp_0 != 0) {
+      cgc_SetFsError((char *)"Permission denied");
+      __retres = (unsigned char)0;
+      goto return_label;
+    }
+  }
+  TargetInode->Mode = NewMode;
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_ChangeOwner(char *Filename, char *NewOwner)
+{
+  uint8_t __retres;
+  pInode TargetInode;
+  char *TempOwner;
+  int tmp;
+  uint8_t tmp_0;
+  size_t tmp_1;
+  if (! Filename) {
+    cgc_SetFsError((char *)"Invalid filename");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (! NewOwner) {
+    cgc_SetFsError((char *)"Invalid owner");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = strcmp((char const *)cgc_CurrentUser,"root");
+  if (tmp != 0) {
+    cgc_SetFsError((char *)"Must be root");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  TargetInode = cgc_FindFile(Filename);
+  if (TargetInode == (pInode)0) {
+    cgc_SetFsError((char *)"Unable to find file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_0 = cgc_UserExists(NewOwner);
+  if (! tmp_0) {
+    cgc_SetFsError((char *)"Invalid user");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_1 = strlen((char const *)NewOwner);
+  TempOwner = (char *)calloc((unsigned int)1,tmp_1 + (size_t)1);
+  if (TempOwner == (char *)0) {
+    cgc_SetFsError((char *)"calloc failed");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  strcpy(TempOwner,(char const *)NewOwner);
+  if (TargetInode->Owner) free((void *)TargetInode->Owner);
+  TargetInode->Owner = TempOwner;
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_Login(char *Username)
+{
+  uint8_t __retres;
+  char *NewUsername;
+  size_t tmp;
+  if (! Username) {
+    cgc_SetFsError((char *)"Invalid username");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = strlen((char const *)Username);
+  NewUsername = (char *)calloc((unsigned int)1,tmp + (size_t)1);
+  if (NewUsername == (char *)0) {
+    cgc_SetFsError((char *)"calloc failed");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  strcpy(NewUsername,(char const *)Username);
+  if (cgc_CurrentUser) {
+    free((void *)cgc_CurrentUser);
+    cgc_CurrentUser = (char *)0;
+  }
+  cgc_CurrentUser = NewUsername;
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+void cgc_Uid(void)
+{
+  if (cgc_CurrentUser) cgc_puts((char const *)cgc_CurrentUser);
+  return;
+}
+
+uint8_t cgc_Logout(void)
+{
+  uint8_t __retres;
+  if (cgc_CurrentUser) free((void *)cgc_CurrentUser);
+  cgc_CurrentUser = (char *)0;
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return __retres;
+}
+
+uint8_t cgc_InitPasswd(char *RootPassword)
+{
+  uint8_t __retres;
+  FILE_ *fp;
+  size_t tmp;
+  if (! RootPassword) {
+    cgc_SetFsError((char *)"Invalid root password");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  fp = cgc_fopen((char *)"passwd",(char *)"w");
+  if (fp == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open passwd file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  cgc_fwrite((char *)"root:",(unsigned int)5,(unsigned int)1,fp);
+  ;
+  tmp = strlen((char const *)RootPassword);
+  ;
+  cgc_fwrite(RootPassword,tmp,(unsigned int)1,fp);
+  cgc_fclose(fp);
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_UserExists(char *Username)
+{
+  uint8_t __retres;
+  FILE_ *in;
+  char line[128];
+  char *User;
+  if (! Username) {
+    cgc_SetFsError((char *)"Invalid username");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  in = cgc_fopen((char *)"passwd",(char *)"r");
+  if (in == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open passwd file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  while (1) {
+    char *tmp_0;
+    tmp_0 = cgc_fgets(line,(unsigned int)127,in);
+    if (! tmp_0) break;
+    {
+      int tmp;
+      User = strtok(line,":");
+      if (User == (char *)0) {
+        cgc_SetFsError((char *)"Failed to parse passwd file");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+      tmp = strcmp((char const *)User,(char const *)Username);
+      if (! tmp) {
+        cgc_fclose(in);
+        __retres = (unsigned char)1;
+        goto return_label;
+      }
+    }
+  }
+  cgc_fclose(in);
+  cgc_ClearFsError();
+  __retres = (unsigned char)0;
+  return_label: return __retres;
+}
+
+uint8_t cgc_AddUser(char *Username, char *Password)
+{
+  uint8_t __retres;
+  FILE_ *passwd;
+  FILE_ *newpasswd;
+  char line[128];
+  int tmp;
+  size_t tmp_0;
+  size_t tmp_1;
+  uint8_t tmp_2;
+  size_t tmp_9;
+  if (! Username) {
+    cgc_SetFsError((char *)"Invalid username");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (! Password) {
+    cgc_SetFsError((char *)"Invalid password");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = strcmp((char const *)cgc_CurrentUser,"root");
+  if (tmp != 0) {
+    cgc_SetFsError((char *)"Must be root");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_0 = strlen((char const *)Username);
+  if (tmp_0 > (size_t)32) {
+    cgc_SetFsError((char *)"Invalid username");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_1 = strlen((char const *)Password);
+  if (tmp_1 > (size_t)32) {
+    cgc_SetFsError((char *)"Invalid password");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_2 = cgc_UserExists(Username);
+  if (tmp_2) {
+    cgc_SetFsError((char *)"User already exists");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  passwd = cgc_fopen((char *)"passwd",(char *)"r");
+  if (passwd == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open passwd file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  newpasswd = cgc_fopen((char *)"~passwd",(char *)"w");
+  if (newpasswd == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open tmp passwd file");
+    cgc_fclose(passwd);
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  while (1) {
+    char *tmp_8;
+    tmp_8 = cgc_fgets(line,(unsigned int)127,passwd);
+    if (! (tmp_8 != (char *)0)) break;
+    {
+      uint32_t tmp_4;
+      size_t tmp_3;
+      size_t tmp_5;
+      size_t tmp_7;
+      ;
+      tmp_3 = strlen((char const *)(line));
+      tmp_4 = cgc_fwrite(line,tmp_3,(unsigned int)1,newpasswd);
+      tmp_5 = strlen((char const *)(line));
+      if (tmp_4 != tmp_5) {
+        cgc_fclose(passwd);
+        cgc_fclose(newpasswd);
+        cgc_SetFsError((char *)"Unable to write tmp passwd file");
+        cgc_DeleteFile((char *)"~passwd");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+      tmp_7 = strlen((char const *)(line));
+      ;
+      if ((int)line[tmp_7 - (size_t)1] != '\n') {
+        uint32_t tmp_6;
+        tmp_6 = cgc_fwrite((char *)"\n",(unsigned int)1,(unsigned int)1,
+                           newpasswd);
+        if (tmp_6 != (uint32_t)1) {
+          cgc_fclose(passwd);
+          cgc_fclose(newpasswd);
+          cgc_SetFsError((char *)"Unable to write tmp passwd file");
+          cgc_DeleteFile((char *)"~passwd");
+          __retres = (unsigned char)0;
+          goto return_label;
+        }
+      }
+    }
+  }
+  {
+    char *__va_arg0 = Username;
+    char *__va_arg1 = Password;
+    void *__va_args[2] = {& __va_arg0, & __va_arg1};
+    cgc_sprintf(line,"%s:%s",(void * const *)(__va_args));
+  }
+  ;
+  tmp_9 = strlen((char const *)(line));
+  cgc_fwrite(line,tmp_9,(unsigned int)1,newpasswd);
+  cgc_fclose(passwd);
+  cgc_fclose(newpasswd);
+  cgc_DeleteFile((char *)"passwd");
+  cgc_RenameFile((char *)"~passwd",(char *)"passwd");
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_DeleteUser(char *Username)
+{
+  uint8_t __retres;
+  char line[128];
+  char *User;
+  FILE_ *passwd;
+  FILE_ *newpasswd;
+  int tmp;
+  int tmp_0;
+  uint8_t Found = (unsigned char)0;
+  if (! Username) {
+    cgc_SetFsError((char *)"Invalid username");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = strcmp((char const *)cgc_CurrentUser,"root");
+  if (tmp != 0) {
+    cgc_SetFsError((char *)"Must be root");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_0 = strcmp((char const *)Username,"root");
+  if (! tmp_0) {
+    cgc_SetFsError((char *)"Can\'t delete root user");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  passwd = cgc_fopen((char *)"passwd",(char *)"r");
+  if (passwd == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open passwd file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  newpasswd = cgc_fopen((char *)"~passwd",(char *)"w");
+  if (newpasswd == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open tmp passwd file");
+    cgc_fclose(passwd);
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  while (1) {
+    char *tmp_7;
+    tmp_7 = cgc_fgets(line,(unsigned int)127,passwd);
+    if (! (tmp_7 != (char *)0)) break;
+    {
+      size_t tmp_1;
+      int tmp_2;
+      size_t tmp_3;
+      uint32_t tmp_5;
+      size_t tmp_4;
+      size_t tmp_6;
+      tmp_1 = strlen((char const *)(line));
+      if (tmp_1 == (size_t)0) continue;
+      User = strtok(line,":");
+      if (User == (char *)0) {
+        cgc_SetFsError((char *)"Failed to parse passwd file");
+        cgc_fclose(passwd);
+        cgc_fclose(newpasswd);
+        cgc_DeleteFile((char *)"~passwd");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+      tmp_2 = strcmp((char const *)User,(char const *)Username);
+      if (! tmp_2) {
+        Found = (unsigned char)1;
+        continue;
+      }
+      tmp_3 = strlen((char const *)User);
+      line[tmp_3] = (char)':';
+      ;
+      tmp_4 = strlen((char const *)(line));
+      tmp_5 = cgc_fwrite(line,tmp_4,(unsigned int)1,newpasswd);
+      tmp_6 = strlen((char const *)(line));
+      if (tmp_5 != tmp_6) {
+        cgc_fclose(passwd);
+        cgc_fclose(newpasswd);
+        cgc_SetFsError((char *)"Unable to write tmp passwd file");
+        cgc_DeleteFile((char *)"~passwd");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+    }
+  }
+  cgc_fclose(passwd);
+  cgc_fclose(newpasswd);
+  if (! Found) {
+    cgc_SetFsError((char *)"User not found");
+    cgc_fclose(passwd);
+    cgc_fclose(newpasswd);
+    cgc_DeleteFile((char *)"~passwd");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  cgc_DeleteFile((char *)"passwd");
+  cgc_RenameFile((char *)"~passwd",(char *)"passwd");
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_ChangePasswd(char *Username, char *NewPasswd)
+{
+  uint8_t __retres;
+  char line[128];
+  char *User;
+  FILE_ *passwd;
+  FILE_ *newpasswd;
+  size_t tmp;
+  int tmp_0;
+  uint8_t Found = (unsigned char)0;
+  if (! Username) {
+    cgc_SetFsError((char *)"Invalid username");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (! NewPasswd) {
+    cgc_SetFsError((char *)"Invalid password");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = strlen((char const *)NewPasswd);
+  if (tmp > (size_t)32) {
+    cgc_SetFsError((char *)"Invalid password");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp_0 = strcmp((char const *)cgc_CurrentUser,(char const *)Username);
+  if (tmp_0 != 0) {
+    int tmp_1;
+    tmp_1 = strcmp((char const *)cgc_CurrentUser,"root");
+    if (tmp_1 != 0) {
+      cgc_SetFsError((char *)"Must be root or the user being changed");
+      __retres = (unsigned char)0;
+      goto return_label;
+    }
+  }
+  passwd = cgc_fopen((char *)"passwd",(char *)"r");
+  if (passwd == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open passwd file");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  newpasswd = cgc_fopen((char *)"~passwd",(char *)"w");
+  if (newpasswd == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open tmp passwd file");
+    cgc_fclose(passwd);
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  while (1) {
+    char *tmp_11;
+    tmp_11 = cgc_fgets(line,(unsigned int)127,passwd);
+    if (! (tmp_11 != (char *)0)) break;
+    {
+      size_t tmp_2;
+      int tmp_6;
+      size_t tmp_7;
+      uint32_t tmp_9;
+      size_t tmp_8;
+      size_t tmp_10;
+      tmp_2 = strlen((char const *)(line));
+      if (tmp_2 == (size_t)0) continue;
+      User = strtok(line,":");
+      if (User == (char *)0) {
+        cgc_SetFsError((char *)"Failed to parse passwd file");
+        cgc_fclose(passwd);
+        cgc_fclose(newpasswd);
+        cgc_DeleteFile((char *)"~passwd");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+      tmp_6 = strcmp((char const *)User,(char const *)Username);
+      if (! tmp_6) {
+        uint32_t tmp_4;
+        size_t tmp_3;
+        size_t tmp_5;
+        {
+          char *__va_arg0 = Username;
+          char *__va_arg1 = NewPasswd;
+          void *__va_args[2] = {& __va_arg0, & __va_arg1};
+          cgc_sprintf(line,"%s:%s\n",(void * const *)(__va_args));
+        }
+        ;
+        tmp_3 = strlen((char const *)(line));
+        tmp_4 = cgc_fwrite(line,tmp_3,(unsigned int)1,newpasswd);
+        tmp_5 = strlen((char const *)(line));
+        if (tmp_4 != tmp_5) {
+          cgc_fclose(passwd);
+          cgc_fclose(newpasswd);
+          cgc_SetFsError((char *)"Unable to write tmp passwd file");
+          cgc_DeleteFile((char *)"~passwd");
+          __retres = (unsigned char)0;
+          goto return_label;
+        }
+        continue;
+      }
+      tmp_7 = strlen((char const *)User);
+      line[tmp_7] = (char)':';
+      ;
+      tmp_8 = strlen((char const *)(line));
+      tmp_9 = cgc_fwrite(line,tmp_8,(unsigned int)1,newpasswd);
+      tmp_10 = strlen((char const *)(line));
+      if (tmp_9 != tmp_10) {
+        cgc_SetFsError((char *)"Unable to write tmp passwd file");
+        cgc_fclose(passwd);
+        cgc_fclose(newpasswd);
+        cgc_DeleteFile((char *)"~passwd");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+    }
+  }
+  cgc_fclose(passwd);
+  cgc_fclose(newpasswd);
+  if (! Found) {
+    cgc_SetFsError((char *)"User not found");
+    cgc_fclose(passwd);
+    cgc_fclose(newpasswd);
+    cgc_DeleteFile((char *)"~passwd");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  cgc_DeleteFile((char *)"passwd");
+  cgc_RenameFile((char *)"~passwd",(char *)"passwd");
+  cgc_ClearFsError();
+  __retres = (unsigned char)1;
+  return_label: return __retres;
+}
+
+uint8_t cgc_CheckPasswd(char *Username, char *Password)
+{
+  uint8_t __retres;
+  char line[128];
+  char *User;
+  char *CurrPassword;
+  FILE_ *passwd;
+  size_t tmp;
+  uint8_t Found = (unsigned char)0;
+  char *OldUser = (char *)0;
+  uint8_t NoLogin = (unsigned char)0;
+  if (! Username) {
+    cgc_SetFsError((char *)"Invalid username");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (! Password) {
+    cgc_SetFsError((char *)"Invalid password");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  tmp = strlen((char const *)Password);
+  if (tmp > (size_t)32) {
+    cgc_SetFsError((char *)"Invalid password");
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  if (cgc_CurrentUser) {
+    int tmp_1;
+    tmp_1 = strcmp((char const *)cgc_CurrentUser,"root");
+    if (tmp_1 != 0) {
+      size_t tmp_0;
+      tmp_0 = strlen((char const *)cgc_CurrentUser);
+      OldUser = (char *)calloc((unsigned int)1,tmp_0 + (size_t)1);
+      if (OldUser == (char *)0) {
+        cgc_SetFsError((char *)"calloc failed");
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+      strcpy(OldUser,(char const *)cgc_CurrentUser);
+      cgc_Logout();
+      cgc_Login((char *)"root");
+    }
+  }
+  else {
+    cgc_Login((char *)"root");
+    NoLogin = (unsigned char)1;
+  }
+  passwd = cgc_fopen((char *)"passwd",(char *)"r");
+  if (passwd == (FILE_ *)0) {
+    cgc_SetFsError((char *)"Unable to open passwd file");
+    if (OldUser) {
+      cgc_Logout();
+      cgc_Login(OldUser);
+      free((void *)OldUser);
+    }
+    if (NoLogin) cgc_Logout();
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  while (1) {
+    char *tmp_5;
+    tmp_5 = cgc_fgets(line,(unsigned int)127,passwd);
+    if (! (tmp_5 != (char *)0)) break;
+    {
+      size_t tmp_2;
+      int tmp_3;
+      int tmp_4;
+      tmp_2 = strlen((char const *)(line));
+      if (tmp_2 == (size_t)0) continue;
+      User = strtok(line,":");
+      if (User == (char *)0) {
+        cgc_SetFsError((char *)"Failed to parse passwd file");
+        cgc_fclose(passwd);
+        if (OldUser) {
+          cgc_Logout();
+          cgc_Login(OldUser);
+          free((void *)OldUser);
+        }
+        if (NoLogin) cgc_Logout();
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+      tmp_3 = strcmp((char const *)User,(char const *)Username);
+      if (tmp_3 != 0) continue;
+      CurrPassword = strtok((char *)0,":");
+      if (CurrPassword == (char *)0) {
+        cgc_SetFsError((char *)"Failed to parse passwd file");
+        cgc_fclose(passwd);
+        if (OldUser) {
+          cgc_Logout();
+          cgc_Login(OldUser);
+          free((void *)OldUser);
+        }
+        if (NoLogin) cgc_Logout();
+        __retres = (unsigned char)0;
+        goto return_label;
+      }
+      tmp_4 = strcmp((char const *)CurrPassword,(char const *)Password);
+      if (! tmp_4) {
+        cgc_ClearFsError();
+        cgc_fclose(passwd);
+        if (OldUser) {
+          cgc_Logout();
+          cgc_Login(OldUser);
+          free((void *)OldUser);
+        }
+        if (NoLogin) cgc_Logout();
+        __retres = (unsigned char)1;
+        goto return_label;
+      }
+    }
+  }
+  cgc_fclose(passwd);
+  if (! Found) {
+    cgc_SetFsError((char *)"User not found");
+    if (OldUser) {
+      cgc_Logout();
+      cgc_Login(OldUser);
+      free((void *)OldUser);
+    }
+    if (NoLogin) cgc_Logout();
+    __retres = (unsigned char)0;
+    goto return_label;
+  }
+  cgc_ClearFsError();
+  if (OldUser) {
+    cgc_Logout();
+    cgc_Login(OldUser);
+    free((void *)OldUser);
+  }
+  if (NoLogin) cgc_Logout();
+  __retres = (unsigned char)0;
+  return_label: return __retres;
+}
+
+int cgc_check_timeout(struct timeval const *timeout)
+{
+  int __retres;
+  if (! timeout) {
+    __retres = 0;
+    goto return_label;
+  }
+  else 
+    if ((time_t)0 > timeout->tv_sec) goto _LOR;
+    else 
+      if (0 > timeout->tv_usec) {
+        _LOR: {
+                __retres = 22;
+                goto return_label;
+              }
+      }
+      else {
+        __retres = 0;
+        goto return_label;
+      }
+  return_label: return __retres;
+}
+
+void cgc_init_prng(cgc_prng_0 *, cgc_aes_state const *);
+
+void cgc_aes_get_bytes(cgc_prng_0 *, uint32_t, uint8_t *);
+
+ __attribute__((__noreturn__)) void cgc__terminate(unsigned int status);
+void cgc__terminate(unsigned int status)
+{
+  exit((int)status);
+  return;
+}
+
+int cgc_transmit(int fd, void const *buf, size_t count, size_t *tx_bytes)
+{
+  int __retres;
+  ssize_t const ret = write(fd,buf,count);
+  if (ret < 0) {
+    __retres = __fc_errno;
+    goto return_label;
+  }
+  else 
+    if (tx_bytes != (size_t *)0) *tx_bytes = (unsigned int)ret;
+  __retres = 0;
+  return_label: return __retres;
+}
+
+int cgc_receive(int fd, void *buf, size_t count, size_t *rx_bytes)
+{
+  int __retres;
+  ssize_t const ret = read(fd,buf,count);
+  if (ret < 0) {
+    __retres = __fc_errno;
+    goto return_label;
+  }
+  else 
+    if (rx_bytes != (size_t *)0) *rx_bytes = (unsigned int)ret;
+  __retres = 0;
+  return_label: return __retres;
+}
+
+static int cgc_copy_cgc_fd_set(fd_set const *cgc_fds, fd_set *os_fds,
+                               int *num_fds)
+{
+  int __retres;
+  {
+    unsigned int fd = (unsigned int)0;
+    while (fd < (unsigned int)8 * sizeof(long)) {
+      {
+        int tmp;
+        tmp = FD_ISSET((int)fd,cgc_fds);
+        if (tmp) {
+          if (fd >= (unsigned int)(3 + 2 * 10)) {
+            __retres = 9;
+            goto return_label;
+          }
+          if (fd > (unsigned int)8 * sizeof(long)) goto __Cont;
+          FD_SET((int)fd,os_fds);
+          (*num_fds) ++;
+        }
+      }
+      __Cont: fd ++;
+    }
+  }
+  __retres = 0;
+  return_label: return __retres;
+}
+
+static void cgc_copy_os_fd_set(fd_set const *os_fds, fd_set *cgc_fds)
+{
+  unsigned int fd = (unsigned int)0;
+  while (1) {
+    unsigned int tmp_0;
+    if ((unsigned int)8 * sizeof(long) < (unsigned int)8 * sizeof(long)) 
+      tmp_0 = (unsigned int)8 * sizeof(long);
+    else tmp_0 = (unsigned int)8 * sizeof(long);
+    ;
+    if (! (fd < tmp_0)) break;
+    {
+      int tmp;
+      tmp = FD_ISSET((int)fd,os_fds);
+      if (tmp) FD_SET((int)fd,cgc_fds);
+    }
+    fd ++;
+  }
+  return;
+}
+
+int cgc_fdwait(int nfds, fd_set *readfds, fd_set *writefds,
+               struct timeval const *timeout, int *readyfds)
+{
+  int __retres;
+  fd_set read_fds;
+  fd_set write_fds;
+  int tmp_3;
+  struct timeval *tmp_0;
+  fd_set *tmp_1;
+  fd_set *tmp_2;
+  int ret = cgc_check_timeout(timeout);
+  int actual_num_fds = 0;
+  struct timeval max_wait_time = {.tv_sec = (long)0, .tv_usec = 0};
+  if (ret) {
+    __retres = ret;
+    goto return_label;
+  }
+  else 
+    if (0 > nfds) goto _LOR;
+    else 
+      if ((unsigned int)8 * sizeof(long) < (unsigned int)nfds) {
+        _LOR: {
+                __retres = 22;
+                goto return_label;
+              }
+      }
+  FD_ZERO(& read_fds);
+  FD_ZERO(& write_fds);
+  if (readfds) {
+    ret = cgc_copy_cgc_fd_set((fd_set const *)readfds,& read_fds,
+                              & actual_num_fds);
+    if (0 != ret) {
+      __retres = ret;
+      goto return_label;
+    }
+  }
+  if (writefds) {
+    ret = cgc_copy_cgc_fd_set((fd_set const *)writefds,& write_fds,
+                              & actual_num_fds);
+    if (0 != ret) {
+      __retres = ret;
+      goto return_label;
+    }
+  }
+  if (actual_num_fds != nfds) {
+    __retres = 22;
+    goto return_label;
+  }
+  if (readfds) FD_ZERO(readfds);
+  if (writefds) FD_ZERO(writefds);
+  if (timeout) {
+    max_wait_time.tv_sec = timeout->tv_sec;
+    max_wait_time.tv_usec = timeout->tv_usec;
+  }
+  if (timeout) tmp_0 = & max_wait_time; else tmp_0 = (struct timeval *)0;
+  if (writefds) tmp_1 = & write_fds; else tmp_1 = (fd_set *)0;
+  if (readfds) tmp_2 = & read_fds; else tmp_2 = (fd_set *)0;
+  ;
+  tmp_3 = select(nfds,tmp_2,tmp_1,(fd_set *)0,tmp_0);
+  int num_selected_fds = tmp_3;
+  if (num_selected_fds < 0) {
+    __retres = __fc_errno;
+    goto return_label;
+  }
+  if (readfds) cgc_copy_os_fd_set((fd_set const *)(& read_fds),readfds);
+  if (writefds) cgc_copy_os_fd_set((fd_set const *)(& write_fds),writefds);
+  if (readyfds) *readyfds = num_selected_fds;
+  __retres = 0;
+  return_label: return __retres;
+}
+
+int cgc_allocate(size_t length, int is_executable, void **addr)
+{
+  int __retres;
+  int page_perms = 0x1 | 0x2;
+  if (is_executable) page_perms |= 0x4;
+  void *return_address =
+    mmap((void *)0,length,page_perms,0x20 | 0x02,-1,(long)0);
+  if (return_address == (void *)(-1)) {
+    __retres = __fc_errno;
+    goto return_label;
+  }
+  if (addr) *addr = return_address;
+  memset(return_address,0,length);
+  __retres = 0;
+  return_label: return __retres;
+}
+
+int cgc_deallocate(void *addr, size_t length)
+{
+  int __retres;
+  int const ret = munmap(addr,length);
+  if (ret < 0) {
+    __retres = __fc_errno;
+    goto return_label;
+  }
+  __retres = 0;
+  return_label: return __retres;
+}
+
+static cgc_prng_0 *cgc_internal_prng = (cgc_prng_0 *)0;
+/*@ requires valid_read_string(s);
+    requires valid_read_string(format);
+    requires \valid(param0);
+    ensures \initialized(param0);
+    assigns \result, *param0;
+    assigns \result
+      \from (indirect: *(s + (0 ..))), (indirect: *(format + (0 ..)));
+    assigns *param0
+      \from (indirect: *(s + (0 ..))), (indirect: *(format + (0 ..)));
+ */
+int sscanf_va_1(char const * __restrict s, char const * __restrict format,
+                unsigned char *param0);
+
+static void cgc_try_init_prng(void)
+{
+  if (cgc_internal_prng != (cgc_prng_0 *)0) goto return_label;
+  uint8_t prng_seed[16 * 3] =
+    {(unsigned char)0x73,
+     (unsigned char)0x65,
+     (unsigned char)0x65,
+     (unsigned char)0x64,
+     (unsigned char)0x73,
+     (unsigned char)0x65,
+     (unsigned char)0x65,
+     (unsigned char)0x64,
+     (unsigned char)0x73,
+     (unsigned char)0x65,
+     (unsigned char)0x65,
+     (unsigned char)0x64,
+     (unsigned char)0x73,
+     (unsigned char)0x65,
+     (unsigned char)0x65,
+     (unsigned char)0x64,
+     (unsigned char)0x30,
+     (unsigned char)0x31,
+     (unsigned char)0x32,
+     (unsigned char)0x33,
+     (unsigned char)0x34,
+     (unsigned char)0x35,
+     (unsigned char)0x36,
+     (unsigned char)0x37,
+     (unsigned char)0x38,
+     (unsigned char)0x39,
+     (unsigned char)0x61,
+     (unsigned char)0x62,
+     (unsigned char)0x63,
+     (unsigned char)0x64,
+     (unsigned char)0x65,
+     (unsigned char)0x66,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00,
+     (unsigned char)0x00};
+  char const *prng_seed_hex = getenv("seed");
+  if (prng_seed_hex != (char const *)0) {
+    size_t tmp_0;
+    tmp_0 = strlen(prng_seed_hex);
+    if (tmp_0 == (size_t)((16 * 3) * 2)) {
+      char const *pos = prng_seed_hex;
+      {
+        int i = 0;
+        while (i < 16 * 3) {
+          sscanf_va_1(pos,"%2hhx",(unsigned char *)(& prng_seed[i]));
+          pos += 2;
+          i ++;
+        }
+      }
+    }
+  }
+  cgc_internal_prng = (cgc_prng_0 *)malloc(sizeof(cgc_prng_0));
+  cgc_aes_state *seed = (cgc_aes_state *)(prng_seed);
+  cgc_init_prng(cgc_internal_prng,(cgc_aes_state const *)seed);
+  return_label: return;
+}
+
+int cgc_random(void *buf, size_t count, size_t *rnd_bytes)
+{
+  int __retres;
+  cgc_try_init_prng();
+  cgc_aes_get_bytes(cgc_internal_prng,count,(uint8_t *)buf);
+  if (rnd_bytes) *rnd_bytes = count;
+  __retres = 0;
+  return __retres;
+}
+
+/*@ assigns \nothing; */
+static void cgc_initialize_flag_page(void) __attribute__((__constructor__));
+
+size_t cgc_page_index = (unsigned int)0;
+unsigned char *secret_page;
+pqueue root;
+char *queue_matrix;
+char easteregg[10] =
+  {(char)'e',
+   (char)'a',
+   (char)'s',
+   (char)'t',
+   (char)'a',
+   (char)' ',
+   (char)'e',
+   (char)'g',
+   (char)'g',
+   (char)'\000'};
+size_t eggindex;
+pmonster cgc_generate_monster(void);
+
+char *cgc_select_name(void);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_4(char const * __restrict format);
+
+void cgc_check_egg(pplayer pp, char c)
+{
+  if ((int)easteregg[eggindex] == (int)c) eggindex += (size_t)1;
+  else eggindex = (unsigned int)0;
+  if ((int)easteregg[eggindex] == 0) {
+    printf_va_4("YOU FOUND THE EGG!!!! Have a prize.\n");
+    (pp->mons[0])->hitpoints = (unsigned int)99;
+    (pp->mons[0])->health = 99;
+    (pp->mons[0])->power = (unsigned int)99;
+    eggindex = (unsigned int)0;
+  }
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_5(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_6(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_7(char const * __restrict format);
+
+size_t cgc_read_line(char *outbuf, size_t length)
+{
+  size_t __retres;
+  char c = (char)'\000';
+  size_t index_0 = (unsigned int)0;
+  size_t rx_bytes = (unsigned int)0;
+  if (outbuf == (char *)0) {
+    printf_va_5("[ERROR] invalid arg\n");
+    cgc__terminate((unsigned int)(-1));
+    __retres = (unsigned int)0;
+    goto return_label;
+  }
+  while (1) {
+    if (index_0 < length) {
+      if (! ((int)c != '\n')) break;
+    }
+    else break;
+    {
+      int tmp;
+      tmp = cgc_receive(0,(void *)(& c),(unsigned int)1,& rx_bytes);
+      if (tmp != 0) {
+        printf_va_6("[ERROR] Failed to read byte\n");
+        cgc__terminate((unsigned int)(-3));
+      }
+      if (rx_bytes == (size_t)0) {
+        printf_va_7("[ERROR] Error in receive\n");
+        cgc__terminate((unsigned int)(-4));
+      }
+      if ((int)c == '\n') {
+        __retres = index_0;
+        goto return_label;
+      }
+      *(outbuf + index_0) = c;
+      index_0 += (size_t)1;
+    }
+  }
+  __retres = index_0;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_8(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_9(char const * __restrict format);
+
+size_t cgc_read_line_u(char *outbuf)
+{
+  size_t __retres;
+  char c = (char)'\000';
+  size_t index_0 = (unsigned int)0;
+  size_t rx_bytes = (unsigned int)0;
+  if (outbuf == (char *)0) {
+    __retres = (unsigned int)0;
+    goto return_label;
+  }
+  while ((int)c != '\n') {
+    int tmp;
+    tmp = cgc_receive(0,(void *)(& c),(unsigned int)1,& rx_bytes);
+    if (tmp != 0) {
+      printf_va_8("[ERROR] Failed to read byte\n");
+      cgc__terminate((unsigned int)0);
+    }
+    if (rx_bytes == (size_t)0) {
+      printf_va_9("[ERROR] Error in receive\n");
+      cgc__terminate((unsigned int)0);
+    }
+    if ((int)c == '\n') continue;
+    *(outbuf + index_0) = c;
+    index_0 += (size_t)1;
+  }
+  __retres = index_0;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_10(char const * __restrict format);
+
+void cgc_add_queue(size_t x, size_t y, size_t max_x, size_t max_y)
+{
+  pqueue pq = (struct queue *)0;
+  pqueue walker = (struct queue *)0;
+  size_t index_0 = (max_x + (size_t)1) * y + x;
+  if ((int)*(queue_matrix + index_0) == 1) goto return_label;
+  pq = (pqueue)malloc(sizeof(queue));
+  if (pq == (pqueue)0) {
+    printf_va_10("[ERROR] malloc() queue structure failed.\n");
+    cgc__terminate((unsigned int)(-1));
+  }
+  bzero((void *)pq,sizeof(queue));
+  pq->x = x;
+  pq->y = y;
+  if (root == (pqueue)0) root = pq;
+  else {
+    walker = root;
+    while (walker->next != (struct queue *)0) walker = walker->next;
+    walker->next = pq;
+  }
+  *(queue_matrix + index_0) = (char)1;
+  return_label: return;
+}
+
+pqueue cgc_dequeue(void)
+{
+  pqueue pq = root;
+  if (root != (pqueue)0) root = root->next;
+  return pq;
+}
+
+int cgc_check_adjacent(int sx, int sy, int dx, int dy)
+{
+  int __retres;
+  if (sx == dx) {
+    if (sy + 1 == dy) goto _LOR;
+    else 
+      if (sy - 1 == dy) {
+        _LOR: {
+                __retres = 1;
+                goto return_label;
+              }
+      }
+  }
+  else 
+    if (sy == dy) 
+      if (sx + 1 == dx) goto _LOR_0;
+      else 
+        if (sx - 1 == dx) {
+          _LOR_0: {
+                    __retres = 1;
+                    goto return_label;
+                  }
+        }
+  __retres = 0;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_11(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_12(char const * __restrict format, char *param0);
+
+void cgc_print_map(pmap pm)
+{
+  size_t index_0;
+  size_t max;
+  size_t map_index = (unsigned int)0;
+  char *data = (char *)0;
+  index_0 = (unsigned int)0;
+  max = pm->height * pm->width;
+  data = (char *)malloc((max + pm->height) + (size_t)1);
+  if (data == (char *)0) {
+    printf_va_11("[ERROR] Failed to allocate map.\n");
+    cgc__terminate((unsigned int)(-5));
+  }
+  bzero((void *)data,(max + pm->height) + (size_t)1);
+  while (index_0 < max) {
+    if ((size_t)0 < index_0) 
+      if (index_0 % pm->width == (unsigned int)0) {
+        size_t tmp;
+        tmp = map_index;
+        map_index += (size_t)1;
+        *(data + tmp) = (char)'\n';
+      }
+    if ((int)*(pm->data + index_0) == '\000') *(data + map_index) = (char)'.';
+    else *(data + map_index) = *(pm->data + index_0);
+    index_0 += (size_t)1;
+    map_index += (size_t)1;
+  }
+  *(data + map_index) = (char)'\n';
+  printf_va_12("%s",data);
+  free((void *)data);
+  return;
+}
+
+/*@ ensures \result ≡ 0 ∨ \result ≡ 1;
+    assigns \result;
+    assigns \result \from sx, sy, pm, *pm;
+ */
+size_t cgc_find_path(size_t sx, size_t sy, pmap pm)
+{
+  size_t __retres;
+  int tmp;
+  pqueue pq = (struct queue *)0;
+  size_t retval = (unsigned int)0;
+  if (pm == (pmap)0) {
+    __retres = (unsigned int)0;
+    goto return_label;
+  }
+  tmp = cgc_check_adjacent((int)sx,(int)sy,(int)pm->end_x,(int)pm->end_y);
+  if (tmp == 1) {
+    __retres = (unsigned int)1;
+    goto return_label;
+  }
+  if (sy > (size_t)0) cgc_add_queue(sx,sy - (size_t)1,pm->width - (size_t)1,
+                                    pm->height - (size_t)1);
+  if (sx < pm->width - (size_t)1) cgc_add_queue(sx + (size_t)1,sy,
+                                                pm->width - (size_t)1,
+                                                pm->height - (size_t)1);
+  if (sy < pm->height - (size_t)1) cgc_add_queue(sx,sy + (size_t)1,
+                                                 pm->width - (size_t)1,
+                                                 pm->height - (size_t)1);
+  if (sx > (size_t)0) cgc_add_queue(sx - (size_t)1,sy,pm->width - (size_t)1,
+                                    pm->height - (size_t)1);
+  pq = cgc_dequeue();
+  while (pq != (pqueue)0) {
+    retval = cgc_find_path(pq->x,pq->y,pm);
+    if (retval == (size_t)1) {
+      free((void *)pq);
+      __retres = (unsigned int)1;
+      goto return_label;
+    }
+    else {
+      free((void *)pq);
+      pq = cgc_dequeue();
+    }
+  }
+  __retres = (unsigned int)0;
+  return_label: return __retres;
+}
+
+void cgc_update_page_index(void)
+{
+  cgc_page_index += (size_t)3;
+  cgc_page_index %= (unsigned int)0x1000;
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_13(char const * __restrict format);
+
+void cgc_place_marker(pmap pm)
+{
+  size_t index_0 = (unsigned int)0;
+  size_t count = (unsigned int)0;
+  size_t max = (unsigned int)0;
+  pm->last_x = (unsigned int)*(secret_page + cgc_page_index) % pm->width;
+  cgc_update_page_index();
+  pm->last_y = (unsigned int)*(secret_page + cgc_page_index) % pm->height;
+  cgc_update_page_index();
+  index_0 = pm->width * pm->last_y + pm->last_x;
+  while (1) {
+    if ((int)*(pm->data + index_0) != '\000') {
+      if (! (count < (size_t)100)) break;
+    }
+    else break;
+    pm->last_x = (unsigned int)*(secret_page + cgc_page_index) % pm->width;
+    cgc_update_page_index();
+    pm->last_y = (unsigned int)*(secret_page + cgc_page_index) % pm->height;
+    cgc_update_page_index();
+    index_0 = pm->width * pm->last_y + pm->last_x;
+    count += (size_t)1;
+  }
+  max = pm->width * pm->height;
+  if (count == (size_t)100) {
+    index_0 = (unsigned int)0;
+    while (1) {
+      if ((int)*(pm->data + index_0) != '\000') {
+        if (! (index_0 < max)) break;
+      }
+      else break;
+      index_0 += (size_t)1;
+    }
+    if (index_0 == max) {
+      printf_va_13("FAILED\n");
+      cgc_print_map(pm);
+      cgc__terminate((unsigned int)0);
+    }
+    pm->last_y = index_0 / pm->width;
+    pm->last_x = index_0 % pm->width;
+  }
+  *(pm->data + index_0) = (char)'#';
+  return;
+}
+
+void cgc_set_marker(size_t x, size_t y, pmap pm, char c)
+{
+  size_t index_0 = pm->width * y + x;
+  *(pm->data + index_0) = c;
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_14(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_15(char const * __restrict format);
+
+void cgc_initialize_map(pmap pm)
+{
+  if (pm == (pmap)0) {
+    printf_va_14("[ERROR] initialize_map() invalid argumenet.\n");
+    cgc__terminate((unsigned int)0);
+  }
+  pm->data = (char *)malloc(pm->width * pm->height);
+  if (pm->data == (char *)0) {
+    printf_va_15("[ERROR] Failed to allocate map.\n");
+    cgc__terminate((unsigned int)0);
+  }
+  bzero((void *)pm->data,pm->width * pm->height);
+  pm->start_x = (unsigned int)0;
+  pm->start_y = (unsigned int)0;
+  pm->end_x = (unsigned int)0;
+  pm->end_y = (unsigned int)0;
+  while (1) {
+    if (! (pm->start_x == pm->end_x)) 
+      if (! (pm->start_x - (size_t)1 == pm->end_x)) 
+        if (! (pm->start_x + (size_t)1 == pm->end_x)) 
+          if (! (pm->start_y == pm->end_y)) 
+            if (! (pm->start_y + (size_t)1 == pm->end_y)) 
+              if (! (pm->start_y - (size_t)1 == pm->end_y)) break;
+    pm->start_x = (unsigned int)*(secret_page + cgc_page_index) % pm->width;
+    cgc_update_page_index();
+    pm->start_y = (unsigned int)*(secret_page + cgc_page_index) % pm->height;
+    cgc_update_page_index();
+    pm->end_x = (unsigned int)*(secret_page + cgc_page_index) % pm->width;
+    cgc_update_page_index();
+    pm->end_y = (unsigned int)*(secret_page + cgc_page_index) % pm->height;
+    cgc_update_page_index();
+  }
+  cgc_set_marker(pm->start_x,pm->start_y,pm,(char)'@');
+  cgc_set_marker(pm->end_x,pm->end_y,pm,(char)'X');
+  pm->current_x = pm->start_x;
+  pm->current_y = pm->start_y;
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_16(char const * __restrict format);
+
+void cgc_initialize_queue_matrix(pmap pm)
+{
+  size_t index_0;
+  if (queue_matrix != (char *)0) free((void *)queue_matrix);
+  queue_matrix = (char *)malloc(pm->width * pm->height);
+  if (queue_matrix == (char *)0) {
+    printf_va_16("[ERROR] Failed to allocate queue matrix\n");
+    cgc__terminate((unsigned int)0);
+  }
+  bzero((void *)queue_matrix,pm->width * pm->height);
+  index_0 = (unsigned int)0;
+  while (index_0 < pm->width * pm->height) {
+    if ((int)*(pm->data + index_0) != 0x00) *(queue_matrix + index_0) = (char)1;
+    index_0 += (size_t)1;
+  }
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_17(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param5),
+            (indirect: param4), (indirect: param3), (indirect: param2),
+            (indirect: param1), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param5, param4, param3, param2, param1, param0;
+ */
+int printf_va_18(char const * __restrict format, size_t param0,
+                 size_t param1, size_t param2, size_t param3, size_t param4,
+                 size_t param5);
+
+pmap cgc_generate_map(size_t width, size_t height)
+{
+  pmap pm = (struct map *)0;
+  pqueue t = (struct queue *)0;
+  size_t start_x = (unsigned int)0;
+  size_t start_y = (unsigned int)0;
+  size_t end_x = (unsigned int)0;
+  size_t end_y = (unsigned int)0;
+  size_t success = (unsigned int)1;
+  pm = (pmap)malloc(sizeof(map));
+  if (pm == (pmap)0) {
+    printf_va_17("[ERROR] Failed to allocate map strucure\n");
+    cgc__terminate((unsigned int)0);
+  }
+  bzero((void *)pm,sizeof(map));
+  pm->height = height;
+  pm->width = width;
+  cgc_initialize_map(pm);
+  printf_va_18("Width: %zu Height: %zu\nStartX: %zu StartY: %zu\nEndX: %zu EndY: %zu\n\n",
+               width,height,pm->start_x,pm->start_y,pm->end_x,pm->end_y);
+  while (success) {
+    size_t tmp;
+    cgc_place_marker(pm);
+    cgc_initialize_queue_matrix(pm);
+    tmp = cgc_find_path(pm->start_x,pm->start_y,pm);
+    if (tmp != (size_t)1) {
+      *(pm->data + (pm->width * pm->last_y + pm->last_x)) = (char)0x00;
+      success = (unsigned int)0;
+    }
+    while (root) {
+      t = root;
+      root = root->next;
+      free((void *)t);
+    }
+    root = (struct queue *)0;
+  }
+  free((void *)queue_matrix);
+  cgc_print_map(pm);
+  return pm;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_19(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_20(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_21(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_22(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_23(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_24(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_25(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_26(char const * __restrict format, unsigned int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_27(char const * __restrict format, unsigned int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_28(char const * __restrict format);
+
+pmonster cgc_select_monster(pplayer pp)
+{
+  pmonster __retres;
+  size_t index_0;
+  size_t choice = (unsigned int)0;
+  size_t success = (unsigned int)0;
+  int ac = 0;
+  if (pp == (pplayer)0) {
+    __retres = (struct monster *)0;
+    goto return_label;
+  }
+  index_0 = (unsigned int)0;
+  while (index_0 < pp->mcnt) {
+    if ((pp->mons[index_0])->health > 0) success = (unsigned int)1;
+    index_0 += (size_t)1;
+  }
+  if (success == (size_t)0) {
+    __retres = (struct monster *)0;
+    goto return_label;
+  }
+  success = (unsigned int)0;
+  printf_va_19("Monsters: \n");
+  index_0 = (unsigned int)0;
+  while (index_0 < pp->mcnt) {
+    printf_va_20("\t%zu} \n",index_0 + (size_t)1);
+    printf_va_21("\tType: %s\n",(pp->mons[index_0])->type);
+    printf_va_22("\tLevel: %zu\n",(pp->mons[index_0])->level);
+    printf_va_23("\tHealth: %d\n",(pp->mons[index_0])->health);
+    printf_va_24("\tPower: %zu\n\n",(pp->mons[index_0])->power);
+    index_0 += (size_t)1;
+  }
+  while (! success) {
+    printf_va_25("Selection: ");
+    choice = (unsigned int)0;
+    cgc_read_line((char *)(& choice),(unsigned int)2);
+    ac = atoi((char const *)(& choice));
+    if (ac <= 0) goto _LOR;
+    else 
+      if ((size_t)ac > pp->mcnt) _LOR:
+                                 printf_va_26("bad choice: %x\n",choice);
+      else 
+        if (pp->mons[ac - 1] == (pmonster)0) printf_va_27("bad choice: %x\n",
+                                                          choice);
+        else 
+          if ((pp->mons[ac - 1])->health <= 0) printf_va_28("he dead\n");
+          else success = (unsigned int)1;
+  }
+  __retres = pp->mons[ac - 1];
+  return_label: return __retres;
+}
+
+void cgc_reset_monsters(pplayer pp)
+{
+  size_t index_0 = (unsigned int)0;
+  if (pp == (pplayer)0) goto return_label;
+  index_0 = (unsigned int)0;
+  while (index_0 < pp->mcnt) {
+    (pp->mons[index_0])->health = (int)(pp->mons[index_0])->hitpoints;
+    index_0 += (size_t)1;
+  }
+  return_label: return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_29(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_30(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_31(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_32(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_33(char const * __restrict format, size_t param0);
+
+void cgc_print_monster(pmonster pm)
+{
+  if (pm == (pmonster)0) goto return_label;
+  printf_va_29("\tType: %s\n",pm->type);
+  printf_va_30("\tLevel: %zu\n",pm->level);
+  printf_va_31("\tHealth: %d\n",pm->health);
+  printf_va_32("\tHit Points: %zu\n",pm->hitpoints);
+  printf_va_33("\tPower: %zu\n\n",pm->power);
+  return_label: return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_34(char const * __restrict format, char *param0);
+
+int cgc_oneup_monster(pmonster pm)
+{
+  int __retres;
+  if (pm == (pmonster)0) {
+    __retres = 0;
+    goto return_label;
+  }
+  pm->experience += (size_t)1;
+  if (pm->experience % (unsigned int)15 == (unsigned int)0) {
+    printf_va_34("%s gained a level\n",pm->type);
+    pm->hitpoints += (size_t)1;
+    pm->power += (size_t)1;
+    pm->health = (int)pm->hitpoints;
+    pm->level += (size_t)1;
+    pm->experience = (unsigned int)0;
+  }
+  __retres = 1;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_35(char const * __restrict format);
+
+pmonster cgc_generate_boss(void)
+{
+  pmonster pm = (struct monster *)0;
+  pm = (pmonster)malloc(sizeof(monster));
+  if (pm == (pmonster)0) {
+    printf_va_35("[ERROR] Failed to allocate boss monster structure\n");
+    cgc__terminate((unsigned int)0);
+  }
+  bzero((void *)pm,sizeof(monster));
+  pm->type = cgc_select_name();
+  pm->health = ((int)*(secret_page + cgc_page_index) % 10 + 5) + 4;
+  pm->hitpoints = (unsigned int)pm->health;
+  cgc_update_page_index();
+  pm->power = (unsigned int)(((int)*(secret_page + cgc_page_index) % 6 + 2) + 2);
+  cgc_update_page_index();
+  pm->level = (unsigned int)4;
+  return pm;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_36(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_37(char const * __restrict format);
+
+int cgc_change_monster_name(pmonster pm)
+{
+  int __retres;
+  char new_name[32];
+  size_t index_0 = (unsigned int)0;
+  char *final = (char *)0;
+  bzero((void *)(new_name),(unsigned int)32);
+  printf_va_36("New name: ");
+  index_0 = cgc_read_line_u(new_name);
+  final = (char *)malloc(index_0 + (size_t)1);
+  if (final == (char *)0) {
+    printf_va_37("[ERROR] Failed to malloc name buffer\n");
+    cgc__terminate((unsigned int)0);
+  }
+  bzero((void *)final,index_0 + (size_t)1);
+  memcpy((void *)final,(void const *)(new_name),index_0);
+  pm->type = final;
+  __retres = 1;
+  return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_38(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_39(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_40(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_41(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_42(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_43(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_44(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_45(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_46(char const * __restrict format);
+
+int cgc_capture_boss(pmonster pm, pplayer pp)
+{
+  int __retres;
+  char sel[3];
+  int tmp_0;
+  size_t choice = (unsigned int)0;
+  if (pm == (pmonster)0) goto _LOR;
+  else 
+    if (pp == (pplayer)0) {
+      _LOR: {
+              __retres = 0;
+              goto return_label;
+            }
+    }
+  printf_va_38("capture monster? (y\\n): ");
+  bzero((void *)(sel),(unsigned int)3);
+  cgc_read_line(sel,(unsigned int)2);
+  if ((int)sel[0] != 'y') {
+    free((void *)pm);
+    __retres = 0;
+    goto return_label;
+  }
+  printf_va_39("update boss name? (y\\n): ");
+  bzero((void *)(sel),(unsigned int)3);
+  cgc_read_line(sel,(unsigned int)2);
+  if ((int)sel[0] == 'y') cgc_change_monster_name(pm);
+  if (pp->mcnt < (size_t)5) {
+    size_t tmp;
+    tmp = pp->mcnt;
+    pp->mcnt += (size_t)1;
+    pp->mons[tmp] = pm;
+    __retres = 1;
+    goto return_label;
+  }
+  printf_va_40("your cart is full.\n");
+  choice = (unsigned int)0;
+  while (choice < (size_t)5) {
+    printf_va_41("%zu} \n",choice + (size_t)1);
+    cgc_print_monster(pp->mons[choice]);
+    choice += (size_t)1;
+  }
+  printf_va_42("*********************************\n");
+  pm->health = (int)pm->hitpoints;
+  cgc_print_monster(pm);
+  printf_va_43("*********************************\n");
+  printf_va_44("replace one of yours? (y\\n): ");
+  bzero((void *)(sel),(unsigned int)3);
+  cgc_read_line(sel,(unsigned int)2);
+  if ((int)sel[0] != 'y') {
+    free((void *)pm);
+    __retres = 0;
+    goto return_label;
+  }
+  bzero((void *)(sel),(unsigned int)3);
+  printf_va_45("which one: ");
+  cgc_read_line(sel,(unsigned int)3);
+  tmp_0 = atoi((char const *)(sel));
+  choice = (unsigned int)tmp_0;
+  if (choice <= (size_t)0) goto _LOR_0;
+  else 
+    if (choice > (size_t)5) {
+      _LOR_0:
+      {
+        printf_va_46("invalid\n");
+        free((void *)pm);
+        __retres = 0;
+        goto return_label;
+      }
+    }
+  free((void *)pp->mons[choice - (size_t)1]);
+  pp->mons[choice - (size_t)1] = pm;
+  __retres = 1;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_47(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_48(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_49(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, param0;
+ */
+int printf_va_50(char const * __restrict format, size_t param0, int param1);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_51(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int printf_va_52(char const * __restrict format, char *param0, char *param1,
+                 size_t param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_53(char const * __restrict format, char *param0);
+
+int cgc_daboss(pplayer pp)
+{
+  int __retres;
+  size_t player_hit;
+  size_t target_hit;
+  pmonster boss = (struct monster *)0;
+  pmonster player_current = (struct monster *)0;
+  if (pp == (pplayer)0) {
+    __retres = 0;
+    goto return_label;
+  }
+  boss = cgc_generate_boss();
+  cgc_reset_monsters(pp);
+  printf_va_47("\nDUN DUN DUUUUUUUUUUUUUUN\n");
+  printf_va_48("You have reached the boss!!!!!\n\n");
+  cgc_print_monster(boss);
+  while (boss->health > 0) {
+    player_current = cgc_select_monster(pp);
+    if (player_current == (pmonster)0) {
+      printf_va_49("You have no living monsters. You lose.\n");
+      __retres = 0;
+      goto return_label;
+    }
+    player_hit = (unsigned int)*(secret_page + cgc_page_index) % player_current->power;
+    cgc_update_page_index();
+    boss->health = (int)((size_t)boss->health - player_hit);
+    printf_va_50("You hit for %zu. %d left\n",player_hit,boss->health);
+    cgc_oneup_monster(player_current);
+    if (boss->health <= 0) {
+      printf_va_51("You destroyed the boss!!!!\n");
+      cgc_reset_monsters(pp);
+      cgc_capture_boss(boss,pp);
+      __retres = 1;
+      goto return_label;
+    }
+    target_hit = (unsigned int)*(secret_page + cgc_page_index) % boss->power;
+    cgc_update_page_index();
+    printf_va_52("%s hits %s for %zu\n",boss->type,player_current->type,
+                 target_hit);
+    player_current->health = (int)((size_t)player_current->health - target_hit);
+    if (player_current->health <= 0) printf_va_53("%s was knocked out\n",
+                                                  player_current->type);
+  }
+  __retres = 1;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_54(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_55(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_56(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_57(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_58(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_59(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_60(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_61(char const * __restrict format);
+
+int cgc_capture_monster(pmonster pm, pplayer pp)
+{
+  int __retres;
+  char sel[3];
+  int tmp_0;
+  size_t choice = (unsigned int)0;
+  if (pm == (pmonster)0) goto _LOR;
+  else 
+    if (pp == (pplayer)0) {
+      _LOR: {
+              __retres = 0;
+              goto return_label;
+            }
+    }
+  printf_va_54("capture monster? (y\\n): ");
+  bzero((void *)(sel),(unsigned int)3);
+  cgc_read_line(sel,(unsigned int)2);
+  if ((int)sel[0] != 'y') {
+    free((void *)pm);
+    __retres = 0;
+    goto return_label;
+  }
+  if (pp->mcnt < (size_t)5) {
+    size_t tmp;
+    tmp = pp->mcnt;
+    pp->mcnt += (size_t)1;
+    pp->mons[tmp] = pm;
+    __retres = 1;
+    goto return_label;
+  }
+  printf_va_55("your cart is full.\n");
+  choice = (unsigned int)0;
+  while (choice < (size_t)5) {
+    printf_va_56("%zu} \n",choice + (size_t)1);
+    cgc_print_monster(pp->mons[choice]);
+    choice += (size_t)1;
+  }
+  printf_va_57("*********************************\n");
+  cgc_print_monster(pm);
+  printf_va_58("*********************************\n");
+  printf_va_59("replace one of yours? (y\\n): ");
+  bzero((void *)(sel),(unsigned int)3);
+  cgc_read_line(sel,(unsigned int)2);
+  if ((int)sel[0] != 'y') {
+    free((void *)pm);
+    __retres = 0;
+    goto return_label;
+  }
+  bzero((void *)(sel),(unsigned int)3);
+  printf_va_60("which one: ");
+  cgc_read_line(sel,(unsigned int)3);
+  tmp_0 = atoi((char const *)(sel));
+  choice = (unsigned int)tmp_0;
+  if (choice <= (size_t)0) goto _LOR_0;
+  else 
+    if (choice > (size_t)5) {
+      _LOR_0:
+      {
+        printf_va_61("invalid\n");
+        free((void *)pm);
+        __retres = 0;
+        goto return_label;
+      }
+    }
+  free((void *)pp->mons[choice - (size_t)1]);
+  pp->mons[choice - (size_t)1] = pm;
+  __retres = 1;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_62(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_63(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, param0;
+ */
+int printf_va_64(char const * __restrict format, size_t param0, int param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_65(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param2),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param2, *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int printf_va_66(char const * __restrict format, char *param0, char *param1,
+                 size_t param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_67(char const * __restrict format, char *param0);
+
+int cgc_fight(pplayer pp)
+{
+  int __retres;
+  pmonster pm = (struct monster *)0;
+  pmonster player_current = (struct monster *)0;
+  size_t target_hit = (unsigned int)0;
+  size_t player_hit = (unsigned int)0;
+  if (pp == (pplayer)0) {
+    __retres = 0;
+    goto return_label;
+  }
+  cgc_reset_monsters(pp);
+  pm = cgc_generate_monster();
+  printf_va_62("You are being attacked!!!\n");
+  cgc_print_monster(pm);
+  while (pm->health > 0) {
+    player_current = cgc_select_monster(pp);
+    if (player_current == (pmonster)0) {
+      printf_va_63("You have no living monsters. You lose.\n");
+      __retres = 0;
+      goto return_label;
+    }
+    player_hit = (unsigned int)*(secret_page + cgc_page_index) % player_current->power;
+    cgc_update_page_index();
+    pm->health = (int)((size_t)pm->health - player_hit);
+    printf_va_64("You hit for %zu. %d left\n",player_hit,pm->health);
+    cgc_oneup_monster(player_current);
+    if (pm->health <= 0) {
+      printf_va_65("You knocked out %s\n",pm->type);
+      cgc_reset_monsters(pp);
+      cgc_capture_monster(pm,pp);
+      __retres = 1;
+      goto return_label;
+    }
+    target_hit = (unsigned int)*(secret_page + cgc_page_index) % pm->power;
+    cgc_update_page_index();
+    printf_va_66("%s hits %s for %zu\n",pm->type,player_current->type,
+                 target_hit);
+    player_current->health = (int)((size_t)player_current->health - target_hit);
+    if (player_current->health <= 0) printf_va_67("%s was knocked out\n",
+                                                  player_current->type);
+  }
+  __retres = 1;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_68(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_69(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_70(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_71(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_72(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_73(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_74(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_75(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_76(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_77(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_78(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_79(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_80(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_81(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_82(char const * __restrict format, size_t param0);
+
+int cgc_movement_loop(pmap pm, pplayer pp)
+{
+  int __retres;
+  char movement[2];
+  size_t rx_bytes;
+  size_t success = (unsigned int)0;
+  if (pm == (pmap)0) {
+    __retres = 0;
+    goto return_label;
+  }
+  while (success == (size_t)0) {
+    bzero((void *)(movement),(unsigned int)2);
+    printf_va_68(": ");
+    rx_bytes = cgc_read_line(movement,(unsigned int)2);
+    if (rx_bytes == (size_t)0) {
+      printf_va_69("[ERROR] Failed to receive movement byte\n");
+      cgc__terminate((unsigned int)(-2));
+    }
+    cgc_check_egg(pp,movement[0]);
+    switch ((int)movement[0]) {
+      case 'u': ;
+      if (pm->current_y == (size_t)0) printf_va_70("off map\n");
+      else 
+        if ((int)*(pm->data + (pm->width * (pm->current_y - (size_t)1) + pm->current_x)) == '#') 
+          printf_va_71("blocked\n");
+        else {
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'\000');
+          pm->current_y -= (size_t)1;
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'@');
+        }
+      break;
+      case 'd': ;
+      if (pm->current_y == pm->height - (size_t)1) printf_va_72("off map\n");
+      else 
+        if ((int)*(pm->data + (pm->width * (pm->current_y + (size_t)1) + pm->current_x)) == '#') 
+          printf_va_73("blocked\n");
+        else {
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'\000');
+          pm->current_y += (size_t)1;
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'@');
+        }
+      break;
+      case 'l': ;
+      if (pm->current_x == (size_t)0) printf_va_74("off map\n");
+      else 
+        if ((int)*(pm->data + ((pm->width * pm->current_y + pm->current_x) - (size_t)1)) == '#') 
+          printf_va_75("blocked\n");
+        else {
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'\000');
+          pm->current_x -= (size_t)1;
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'@');
+        }
+      break;
+      case 'r': ;
+      if (pm->current_x == pm->width - (size_t)1) printf_va_76("off map\n");
+      else 
+        if ((int)*(pm->data + ((pm->width * pm->current_y + pm->current_x) + (size_t)1)) == '#') 
+          printf_va_77("blocked\n");
+        else {
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'\000');
+          pm->current_x += (size_t)1;
+          cgc_set_marker(pm->current_x,pm->current_y,pm,(char)'@');
+        }
+      break;
+      default:
+      printf_va_78("[ERROR] Invalid direction:%d\n",(int)movement[0]);
+      continue;
+    }
+    cgc_print_map(pm);
+    if (pm->current_y == pm->end_y) {
+      if (pm->current_x == pm->end_x) {
+        int tmp;
+        printf_va_79("reached the end\n");
+        tmp = cgc_daboss(pp);
+        if (tmp == 1) printf_va_80("You won!!!\n");
+        else printf_va_81("You failed!!!\n");
+        success = (unsigned int)1;
+      }
+      else goto _LAND;
+    }
+    else 
+      _LAND:
+      if ((int)*(secret_page + cgc_page_index) % 100 < 10) {
+        int tmp_0;
+        cgc_update_page_index();
+        tmp_0 = cgc_fight(pp);
+        if (tmp_0 == 1) {
+          pp->level += (size_t)1;
+          printf_va_82("player gains a level. now %zu\n",pp->level);
+        }
+        cgc_print_map(pm);
+      }
+      else cgc_update_page_index();
+  }
+  __retres = 1;
+  return_label: return __retres;
+}
+
+char *cgc_select_name(void)
+{
+  char *__retres;
+  size_t index_0 = (unsigned int)0;
+  size_t value = (unsigned int)*(secret_page + cgc_page_index);
+  cgc_update_page_index();
+  while (value) {
+    index_0 += (size_t)1;
+    if (names[index_0] == (char *)0) index_0 = (unsigned int)0;
+    value -= (size_t)1;
+  }
+  __retres = names[index_0];
+  return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_83(char const * __restrict format);
+
+pmonster cgc_generate_monster(void)
+{
+  pmonster pm = (struct monster *)0;
+  pm = (pmonster)malloc(sizeof(monster));
+  if (pm == (pmonster)0) {
+    printf_va_83("[ERROR] Failed to allocate monster structure\n");
+    cgc__terminate((unsigned int)0);
+  }
+  bzero((void *)pm,sizeof(monster));
+  pm->type = cgc_select_name();
+  pm->health = (int)*(secret_page + cgc_page_index) % 10 + 4;
+  pm->hitpoints = (unsigned int)pm->health;
+  cgc_update_page_index();
+  pm->power = (unsigned int)((int)*(secret_page + cgc_page_index) % 6 + 2);
+  cgc_update_page_index();
+  pm->level = (unsigned int)1;
+  return pm;
+}
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_84(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_85(char const * __restrict format);
+
+pplayer cgc_generate_player(void)
+{
+  char player_one[16];
+  pplayer np = (struct player *)0;
+  size_t result = (unsigned int)0;
+  printf_va_84("Enter your name|| ");
+  bzero((void *)(player_one),(unsigned int)16);
+  result = cgc_read_line(player_one,(unsigned int)15);
+  if (result == (size_t)0) memcpy((void *)(player_one),
+                                  (void const *)"Player One",
+                                  (unsigned int)10);
+  np = (pplayer)malloc(sizeof(player));
+  if (np == (pplayer)0) {
+    printf_va_85("[ERROR] Failed to malloc player structure\n");
+    cgc__terminate((unsigned int)0);
+  }
+  bzero((void *)np,sizeof(player));
+  memcpy((void *)(np->name),(void const *)(player_one),(unsigned int)16);
+  result = (unsigned int)0;
+  while (result < (size_t)3) {
+    {
+      size_t tmp;
+      tmp = np->mcnt;
+      np->mcnt += (size_t)1;
+      np->mons[tmp] = cgc_generate_monster();
+    }
+    result += (size_t)1;
+  }
+  np->level = (unsigned int)1;
+  return np;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_86(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_87(char const * __restrict format, size_t param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..)));
+ */
+int printf_va_88(char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_89(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_90(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_91(char const * __restrict format, size_t param0);
+
+void cgc_print_player(pplayer pp)
+{
+  size_t index_0 = (unsigned int)0;
+  if (pp == (pplayer)0) goto return_label;
+  printf_va_86("Name: %s\n",pp->name);
+  printf_va_87("Level: %zu\n",pp->level);
+  printf_va_88("Monsters: \n");
+  index_0 = (unsigned int)0;
+  while (index_0 < pp->mcnt) {
+    printf_va_89("\tType: %s\n",(pp->mons[index_0])->type);
+    printf_va_90("\tHealth: %d\n",(pp->mons[index_0])->health);
+    printf_va_91("\tPower: %zu\n\n",(pp->mons[index_0])->power);
+    index_0 += (size_t)1;
+  }
+  return_label: return;
+}
+
+int main(int secret_page_i, char **unused)
+{
+  int __retres;
+  secret_page_i = 0x4347C000;
+  pmap pm = (struct map *)0;
+  pplayer pp = (struct player *)0;
+  secret_page = (unsigned char *)secret_page_i;
+  cgc_page_index = (unsigned int)0;
+  root = (struct queue *)0;
+  queue_matrix = (char *)0;
+  pp = cgc_generate_player();
+  cgc_print_player(pp);
+  size_t w = (unsigned int)((int)*(secret_page + cgc_page_index) % 31 + 5);
+  cgc_update_page_index();
+  size_t h = (unsigned int)((int)*(secret_page + cgc_page_index) % 31 + 5);
+  cgc_update_page_index();
+  pm = cgc_generate_map(w,h);
+  cgc_movement_loop(pm,pp);
+  __retres = 0;
+  return __retres;
+}
+
+
diff --git a/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/metrics.log b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/metrics.log
new file mode 100644
index 0000000000000000000000000000000000000000..239983544a57d69b959d209756a264016b5efb59
--- /dev/null
+++ b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/metrics.log
@@ -0,0 +1,64 @@
+[metrics] Defined functions (71)
+======================
+ cgc_AddUser (0 call); cgc_ChangeMode (0 call); cgc_ChangeOwner (0 call);
+ cgc_ChangePasswd (0 call); cgc_CheckPasswd (0 call);
+ cgc_ClearFsError (22 calls); cgc_CreateEmptyFile (1 call);
+ cgc_DeleteFile (12 calls); cgc_DeleteUser (0 call);
+ cgc_DestroyFilesystem (1 call); cgc_FindFile (4 calls);
+ cgc_FsError (0 call); cgc_InitFilesystem (0 call); cgc_InitPasswd (1 call);
+ cgc_ListFiles (0 call); cgc_Login (9 calls); cgc_Logout (14 calls);
+ cgc_RenameFile (3 calls); cgc_SetFsError (102 calls); cgc_Uid (0 call);
+ cgc_UserExists (2 calls); cgc__terminate (17 calls);
+ cgc_add_queue (4 calls); cgc_allocate (0 call); cgc_capture_boss (1 call);
+ cgc_capture_monster (1 call); cgc_change_monster_name (1 call);
+ cgc_check_adjacent (1 call); cgc_check_egg (1 call);
+ cgc_check_timeout (1 call); cgc_copy_cgc_fd_set (2 calls);
+ cgc_copy_os_fd_set (2 calls); cgc_daboss (1 call); cgc_deallocate (0 call);
+ cgc_dequeue (2 calls); cgc_fclose (34 calls); cgc_fdwait (0 call);
+ cgc_fgets (5 calls); cgc_fight (1 call); cgc_find_path (2 calls);
+ cgc_fopen (9 calls); cgc_fread (0 call); cgc_fwrite (8 calls);
+ cgc_generate_boss (1 call); cgc_generate_map (1 call);
+ cgc_generate_monster (2 calls); cgc_generate_player (1 call);
+ cgc_initialize_map (1 call); cgc_initialize_queue_matrix (1 call);
+ cgc_movement_loop (1 call); cgc_oneup_monster (2 calls);
+ cgc_place_marker (1 call); cgc_print_map (4 calls);
+ cgc_print_monster (6 calls); cgc_print_player (1 call); cgc_prng (2 calls);
+ cgc_random (0 call); cgc_random_in_range (0 call); cgc_read_line (10 calls);
+ cgc_read_line_u (1 call); cgc_receive (2 calls);
+ cgc_reset_monsters (4 calls); cgc_seed_prng (0 call);
+ cgc_seed_prng_array (1 call); cgc_select_monster (2 calls);
+ cgc_select_name (2 calls); cgc_set_marker (10 calls); cgc_transmit (0 call);
+ cgc_try_init_prng (1 call); cgc_update_page_index (21 calls); main (0 call); 
+
+Undefined functions (6)
+=======================
+ cgc_aes_get_bytes (1 call); cgc_init_prng (1 call);
+ cgc_initialize_flag_page (0 call); cgc_puts (1 call); cgc_sprintf (5 calls);
+ seed_prng (0 call); 
+
+'Extern' global variables (0)
+=============================
+ 
+
+Potential entry points (19)
+===========================
+ cgc_AddUser; cgc_ChangeMode; cgc_ChangeOwner; cgc_ChangePasswd;
+  cgc_CheckPasswd; cgc_DeleteUser; cgc_FsError; cgc_InitFilesystem;
+  cgc_ListFiles; cgc_Uid; cgc_allocate; cgc_deallocate; cgc_fdwait;
+  cgc_fread; cgc_random; cgc_random_in_range; cgc_seed_prng; cgc_transmit;
+  main; 
+
+Global metrics
+============== 
+Sloc = 2197
+Decision point = 387
+Global variables = 15
+If = 383
+Loop = 46
+Goto = 178
+Assignment = 704
+Exit point = 71
+Function = 77
+Function call = 625
+Pointer dereferencing = 617
+Cyclomatic complexity = 458
diff --git a/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/warnings.log b/cgc-challenges/Monster_Game/.frama-c/Monster_Game.parse/warnings.log
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/cgc-challenges/Monster_Game/.frama-c/path.mk b/cgc-challenges/Monster_Game/.frama-c/path.mk
new file mode 120000
index 0000000000000000000000000000000000000000..222d0e04958ae14f92c8910637128c93b6f3dd09
--- /dev/null
+++ b/cgc-challenges/Monster_Game/.frama-c/path.mk
@@ -0,0 +1 @@
+../../frama-c-cgc-path.mk
\ No newline at end of file
diff --git a/cgc-challenges/Monster_Game/README.md b/cgc-challenges/Monster_Game/README.md
new file mode 100755
index 0000000000000000000000000000000000000000..edca37f1bfdf6ff17a24d4c79204c6339137dcb9
--- /dev/null
+++ b/cgc-challenges/Monster_Game/README.md
@@ -0,0 +1,202 @@
+# Monster_Game
+
+## Author Information
+
+"John Berry" <hj@cromulence.com>
+
+### DARPA performer group
+Cromulence
+
+## Description
+
+This challenge allows a user to travel across a map fighting and capturing monsters.
+
+### Feature List
+
+When a user first connects they are prompted to enter a name. A blank response gives them the default "Player One".
+
+Three monsters are generated with hit points between 4 and 9 and power between 2 and 5. Example output of this step is:
+
+Name: Player One
+Level: 1
+Monsters:
+	Type: Gamma Guardian
+	Health: 9
+	Power: 6
+
+	Type: Wrathran Palpur
+	Health: 12
+	Power: 7
+
+	Type: Angry Neutron
+	Health: 12
+	Power: 3
+
+
+A map is then generated with height and width between 5 and 30. The player and boss are randomly placed at a starting position. The player is indicated by '@' and the boss is indicated by the 'X'. Following these two placements the map is then filled with obstacles. During the filling process it is always ensured that a path exists between the player and the boss using a breadth first searching algorithm.
+
+Once the map is generated the player is prompted with ': '. Here they are able to enter a movement, either (u)p, (d)own, (l)eft, or (r)ight. If an obstacle is in their way they will receive an error. If they enter a character that is not u, d, l, or r then they will get an error. Otherwise the player will move to the indicated location. Here is an example prompt:
+
+..##.#
+.....#
+#.....
+#.#@.#
+#.##..
+#.#..#
+......
+......
+.#....
+..#.##
+.#.##.
+......
+.#....
+..#..#
+......
+X.....
+: 
+
+After each move there is a random chance that the user will encounter a monster. If this occurs the following will be displayed:
+
+You are being attacked!!!
+	Type: Rough Wizard
+	Level: 1
+	Health: 5
+	Hit Points: 5
+	Power: 7
+
+Monsters:
+	1}
+	Type: Gamma Guardian
+	Level: 1
+	Health: 9
+	Power: 6
+
+	2}
+	Type: Wrathran Palpur
+	Level: 1
+	Health: 12
+	Power: 7
+
+	3}
+	Type: Angry Neutron
+	Level: 1
+	Health: 12
+	Power: 3
+
+Selection:
+
+The player will be informed of the attack and the atacking monster's information along with all of the player's monsters' information will be displayed. The player is expected to select a valid entry corresponding to the monster with which they wish to attack. The monster will hit for a value between 0 and their power level.
+
+After the selection hit value and the remaining health of the attacking monster will be displayed. If the monster is not knocked out then it will also attack the defending player's monster. If the defending monster's hitpoints is less than or equal to 0 then it can no longer be used to attack. If all defending monsters are less than or equal to 0 then the player loses the battle.
+
+Selection: 1
+You hit for 2. 3 left
+Rough Wizard hits Gamma Guardian for 4
+Monsters:
+	1}
+	Type: Gamma Guardian
+	Level: 1
+	Health: 5
+	Power: 6
+
+	2}
+	Type: Wrathran Palpur
+	Level: 1
+	Health: 12
+	Power: 7
+
+	3}
+	Type: Angry Neutron
+	Level: 1
+	Health: 12
+	Power: 3
+
+Selection:
+
+The player attacks again but this time they successfully knock out the attacking monster.
+
+Selection: 1
+You hit for 3. 0 left
+You knocked out Rough Wizard
+capture monster? (y\n):
+
+The player then has a choice to capture the monster. A maximum of only 5 monster can be held at one time. If the player chooses (y) and there are less than 5 monsters currently, then the next available slot is filled. However if the player already has 5 monsters then they are asked if they want to replace one of their current monsters. If they choose yes then they must enter the selection between 1-5.
+
+After every 15 attacks performed by a monster that monster gains a level. This means that their max hitpoints and power increases by 1.
+
+When the player reaches the boss they will see something like this:
+
+DUN DUN DUUUUUUUUUUUUUUN
+You have reached the boss!!!!!
+
+	Type: The Barbarian
+	Level: 4
+	Health: 11
+	Hit Points: 11
+	Power: 8
+
+The battle against the boss is the same as that of normal monsters except that the boss has a higher maximum power.
+When the bosses health drops below or equal to 0 the player has the option to capture it.
+
+You hit for 4. -3 left
+You destroyed the boss!!!!
+capture monster? (y\n):
+
+After selecting (y)es the player is asked if they would like to update the bosses name.
+
+update boss name? (y\n):
+
+Here they are able to enter whatever name they wish.
+
+In addition, there is an easter egg allowing a player to up the hitpoints and power of their first monster to 99.
+
+"easta egg"
+
+: e
+[ERROR] Invalid direction: 65
+: a
+[ERROR] Invalid direction: 61
+: s
+[ERROR] Invalid direction: 73
+: t
+[ERROR] Invalid direction: 74
+: a
+[ERROR] Invalid direction: 61
+:   <---- This is a space then newline
+[ERROR] Invalid direction: 20
+: e
+[ERROR] Invalid direction: 65
+: g
+[ERROR] Invalid direction: 67
+: g
+YOU FOUND THE EGG!!!! Have a prize.
+[ERROR] Invalid direction: 67
+: 
+
+## Vulnerability
+
+The vulnerability is a simple stack based buffer overflow. The difficult part of the bug is reaching the vulnerable function. After the player defeats the boss they are allowed to enter the boss' new name. This functionality is handled in change_monster_name().
+
+The player is able to enter data and the application will continue reading until a new line (0xa) is encountered. This data is read into a stack based buffer 32 bytes in size. An attacker providing greater than 32 bytes can create a Type 2 POV.
+
+
+### Generic class of vulnerability
+Stack Based Buffer Overflow
+
+### CWE classification
+
+CWE-120: Buffer Copy without Checking Size of Input
+
+## Challenges
+
+Locating the Vulnerability:
+
+Location is difficult due to the CRS having to traverse the map to reach the boss. To do this in a timely fashion requires an algorithm to calculate the path between the two points. It is possible that a CRS could just move randomly and have success on smaller maps but it is unlikely to work on larger maps.
+
+Patching the Vulnerability:
+
+Patching is very straight forward for this bug. A stack canary or decreasing the size of the read would fix the issue.
+
+Proving the Vulnerability:
+
+Once found and assuming the change_monster_name() can be reliably reached then proving the vulnerability is very straight forward since it is a simple stack based buffer overflow.
diff --git a/cgc-challenges/Monster_Game/lib/cgc_fs.h b/cgc-challenges/Monster_Game/lib/cgc_fs.h
new file mode 100644
index 0000000000000000000000000000000000000000..d129a9625036474ebdf2900124b6092e9f0c5766
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/cgc_fs.h
@@ -0,0 +1,82 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+#ifndef __FS_H__
+#define __FS_H__
+#include "cgc_stdint.h"
+
+#define FS_READ (0x4)
+#define FS_WRITE (0x6)
+#define FS_OWNER_READ (0x4)
+#define FS_OWNER_WRITE (0x6)
+#define FS_OTHER_READ (0x40)
+#define FS_OTHER_WRITE (0x60)
+#define MAX_OPEN_FILE_S (8)
+#define MAX_ERROR_LEN (63)
+#define MAX_USER_LEN (32)
+#define MAX_PASSWD_LEN (32)
+
+typedef struct _inode {
+        char *Filename;
+        char *Owner;
+        uint8_t Mode;
+        uint32_t FileSize;
+        unsigned char *Data;
+} Inode, *pInode;
+
+typedef struct _fs {
+        uint32_t MaxSize;
+        uint32_t MaxFiles;
+        pInode *Inodes;
+} Filesystem, *pFilesystem;
+
+typedef struct _file {
+	pInode Inode;
+	uint8_t Mode;
+	uint32_t CurrPosition;
+} FILE_;
+
+char *cgc_FsError(void);
+uint8_t cgc_DestroyFilesystem(void);
+uint8_t cgc_InitFilesystem(uint32_t MaxFiles, char *RootPassword);
+uint8_t cgc_RenameFile(char *OldFilename, char *NewFilename);
+uint8_t cgc_DeleteFile(char *Filename);
+uint8_t cgc_InitPasswd(char *RootPassword);
+FILE_ *cgc_fopen(char *Filename, char *Mode);
+uint32_t cgc_fread(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp);
+uint32_t cgc_fwrite(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp);
+uint8_t cgc_fclose(FILE_ *fp);
+uint8_t cgc_ListFiles(char **Buf);
+uint8_t cgc_Login(char *Username);
+void cgc_Uid(void);
+uint8_t cgc_Logout(void);
+uint8_t cgc_AddUser(char *Username, char *Password);
+uint8_t cgc_DeleteUser(char *Username);
+uint8_t cgc_ChangePasswd(char *Username, char *NewPasswd);
+uint8_t cgc_CheckPasswd(char *Username, char *Password);
+uint8_t cgc_UserExists(char *Username);
+char *cgc_fgets(char *buf, uint32_t size, FILE_ *fp);
+
+#endif // __FS_H__
diff --git a/cgc-challenges/Monster_Game/lib/cgc_monster_names.h b/cgc-challenges/Monster_Game/lib/cgc_monster_names.h
new file mode 100644
index 0000000000000000000000000000000000000000..55252244eb5987518df4d88341ff726588945613
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/cgc_monster_names.h
@@ -0,0 +1,57 @@
+#ifndef __NAMES_H__
+#define __NAMES_H__
+
+# include "common.h"
+
+char *names[] = {"Lost Needless Duck",  
+				 "The Commander", 
+				 "Toxic Major",
+				 "El Spider",
+				 "The Heroic Emperor",
+				 "Rock Beast",
+				 "Gamma Guardian",
+				 "Rough Wizard",
+				 "Persistent Puppet",
+				 "Pure Ghost Killer",
+				 "The Golden Oyster",
+				 "Hidden Leather",
+				 "Dreaded Digital Hawk",
+				 "The Admiral",
+				 "Sneaky Tough Electron",
+				 "Trolling Captain",
+				 "The Barbarian",
+				 "Elvish Moose",
+				 "Snappy Dinosaur",
+				 "The Bursting Wrench",
+				 "Itchy Eagle",
+				 "Angry Neutron",
+				 "Asada Gothar Derik",
+				 "Seth Bydern",
+				 "Quid Cipyar",
+				 "Amarisa Yerpal Jihb",
+				 "Tilthan",
+				 "Teressa Gosform",
+				 "Uerth Bredock Lidorn",
+				 "Raydan Fronar",
+				 "Aldaren Cevelt",
+				 "Florian",
+				 "Celestine Ixil Boldel",
+				 "Safize Ixen",
+				 "Corda Migorn",
+				 "Vigoth Boldel",
+				 "Gothar Mathar",
+				 "Vinkol Seryth",
+				 "Wrathran Palpur",
+				 "Luna Milen",
+				 "Zotar Phalloz",
+				 "Pildoor Vildar Virdo",
+				 "Odeir Jibar Wyeth",
+				 "Fearlock Breen",
+				 "Soderman Iroldak",
+				 "Lelani Oxpar Xavor",
+				 NULL
+				};
+
+
+#endif
+
diff --git a/cgc-challenges/Monster_Game/lib/cgc_prng.h b/cgc-challenges/Monster_Game/lib/cgc_prng.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd419d2d10e3fac690896e20813a73c28f6ef941
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/cgc_prng.h
@@ -0,0 +1,36 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+#ifndef __PRNG_H__
+#define __PRNG_H__
+
+#include "cgc_stdint.h"
+
+void cgc_seed_prng_array( uint32_t *array_data, uint32_t array_size );
+void cgc_seed_prng( uint32_t seed_value );
+uint32_t cgc_prng( void );
+uint32_t cgc_random_in_range( uint32_t min, uint32_t max );
+
+#endif // __PRNG_H__
diff --git a/cgc-challenges/Monster_Game/lib/cgc_stdint.h b/cgc-challenges/Monster_Game/lib/cgc_stdint.h
new file mode 100644
index 0000000000000000000000000000000000000000..277047929a6105c949f1e4ef083702bd410c3b61
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/cgc_stdint.h
@@ -0,0 +1,38 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+#ifndef __STDINT_H__
+#define __STDINT_H__
+
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+typedef unsigned short int uint16_t;
+typedef signed short int int16_t;
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+
+#endif // __STDINT_H__
diff --git a/cgc-challenges/Monster_Game/lib/cgc_stdio.h b/cgc-challenges/Monster_Game/lib/cgc_stdio.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ce467bf8eea60b4d3338bdf0ba0088e6252f988
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/cgc_stdio.h
@@ -0,0 +1,40 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+#ifndef __STDIO_H__
+#define __STDIO_H__
+
+#include "libcgc.h"
+
+
+int cgc_putchar( int c );
+
+int printf( const char *format, ... );
+int vprintf( const char *format, va_list args );
+int cgc_sprintf( char *buf, const char *format, ... );
+int cgc_vsprintf( char *buf, const char *format, va_list args );
+int cgc_puts( const char *s );
+
+#endif // __STDIO_H__
diff --git a/cgc-challenges/Monster_Game/lib/ctype.c b/cgc-challenges/Monster_Game/lib/ctype.c
new file mode 100644
index 0000000000000000000000000000000000000000..eee45995cb5ad9b50cb23536a5b33cadfb2ab8ed
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/ctype.c
@@ -0,0 +1,112 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+
+#define		DEL	0x7f
+#define		SPC	0x20
+
+#define		TAB	0x09
+#define		LF	0x0a
+#define		VT	0x0b
+#define 	FF	0x0c
+#define		CR	0x0d
+
+int isdigit( int c )
+{
+	if ( c >= '0' && c <= '9' )
+		return 1;
+	else
+		return 0;
+}
+
+int isupper( int c )
+{
+	if ( c >= 'A' && c <= 'Z' )
+		return 1;
+	else
+		return 0;
+}
+
+int islower( int c )
+{
+	if ( c >= 'a' && c <= 'z' )
+		return 1;
+	else
+		return 0;
+}
+
+int isalpha( int c )
+{
+	if ( isupper( c ) || islower( c ) )
+		return 1;
+	else
+		return 0;
+}
+
+int cgc_isalnum( int c )
+{
+	if ( isalpha( c ) || isdigit( c ) )
+		return 1;
+	else
+		return 0;
+}
+
+int cgc_isprint( int c )
+{
+	if ( c >= SPC && c != DEL )
+		return 1;
+	else
+		return 0;
+}
+
+int toupper( int c )
+{
+	if ( islower( c ) )
+		return (c - 'a') + 'A';
+	else
+		return c;
+}
+
+int tolower( int c )
+{
+	if ( isupper( c ) )
+	       return (c - 'A') + 'a';
+	else
+		return c;	
+}
+
+int isspace( int c )
+{
+	if ( c == SPC ||
+	     c == TAB ||
+	     c == LF ||
+	     c == VT ||
+	     c == FF ||
+	     c == CR )
+		return 1;
+	else
+		return 0;
+}
diff --git a/cgc-challenges/Monster_Game/lib/fs.c b/cgc-challenges/Monster_Game/lib/fs.c
new file mode 100644
index 0000000000000000000000000000000000000000..ff79192d49e1d923e70c79add08d97cea700e517
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/fs.c
@@ -0,0 +1,1428 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+#include "cgc_stdio.h"
+#include "cgc_stdint.h"
+#include "common.h"
+#include "malloc.h"
+
+
+#include "cgc_fs.h"
+
+/* fs.c libc-cfe Filesystem library
+This library implements a single-directory filesystem with basic
+user permissions. Users are stored in a root-owned 'passwd' file
+in the file systems.  Groups are not implemented, so file permissions
+are owner cgc_read-cgc_write and other cgc_read-cgc_write only.
+
+Example usage:
+
+int main(int cgc_argc, char *cgc_argv[]) {
+	uint32_t MaxFiles = 10;
+	FILE_ *fp;
+	char buf[64];
+
+	if (!InitFilesystem(MaxFiles, "rootpasswd")) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	if (!AddUser("testuser", "testpasswd")) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	// it's up to the CB to validate passwords using 
+	// CheckPasswd() before calling Login
+	if (!Login("testuser")) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	if ((fp = fopen("testfile", "w")) == NULL) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	if ((fwrite("asdf\n", strlen("asdf\n"), 1, fp)) != strlen("asdf\n")) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	fclose(fp);
+
+	ListFiles(NULL);
+
+	if ((fp = fopen("testfile", "r")) == NULL) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	// could also use fgets() here
+	if ((fread(buf, 10, 1, fp)) == 0) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	printf("$s", buf);
+
+	fclose(fp);
+
+	if (!RenameFile("testfile", "testfile2")) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	ListFiles(NULL);
+
+	if (!DeleteFile("testfile2")) {
+		puts(FsError());
+		cgc__terminate(0);
+	}
+
+	ListFiles(NULL);
+
+	DestroyFilesystem();
+
+}
+
+*/
+
+pFilesystem cgc_FS = NULL;
+char *cgc_CurrentUser = NULL;
+FILE_ *FD[MAX_OPEN_FILE_S];
+char FS_ERROR[MAX_ERROR_LEN+1];
+
+// SetFsError: Sets the error buf if no other error has been logged yet
+void cgc_SetFsError(char *error) {
+	if (FS_ERROR[0] == '\0') {
+		strncpy(FS_ERROR, error, MAX_ERROR_LEN);
+	}
+}
+
+// Clears any previously logged errors
+void cgc_ClearFsError(void) {
+	FS_ERROR[0] = '\0';
+}
+		
+// FsError: Returns a pointer to the error buf
+char *cgc_FsError(void) {
+	return(FS_ERROR);
+}
+
+//
+// filesystem functions
+//
+
+// Destroy the fileysystem
+uint8_t cgc_DestroyFilesystem(void) {
+	uint32_t i;
+
+	if (!cgc_FS) {
+		cgc_SetFsError("Filesystem does not exist");
+		return(0);
+	}
+
+	// Remove each inode
+	for (i = 0; i < cgc_FS->MaxFiles; i++) {
+		if (cgc_FS->Inodes[i]) {
+			// free the filename
+			if (cgc_FS->Inodes[i]->Filename) {
+				free(cgc_FS->Inodes[i]->Filename);
+				cgc_FS->Inodes[i]->Filename = NULL;
+			}
+			// free the owner
+			if (cgc_FS->Inodes[i]->Owner) {
+				free(cgc_FS->Inodes[i]->Owner);
+				cgc_FS->Inodes[i]->Owner = NULL;
+			}
+			// free the data
+			if (cgc_FS->Inodes[i]->Data) {
+				free(cgc_FS->Inodes[i]->Data);
+				cgc_FS->Inodes[i]->Data = NULL;
+			}
+
+			// free the inode itself
+			free(cgc_FS->Inodes[i]);
+			cgc_FS->Inodes[i] = NULL;
+		}
+	}
+
+	free(cgc_FS);
+	cgc_FS = NULL;
+
+	cgc_ClearFsError();
+	return(1);
+
+}
+
+// Initialize the filesystem
+//   MaxFiles: Max number of files the FS should support
+//   RootPassword: Initial root user password
+uint8_t cgc_InitFilesystem(uint32_t MaxFiles, char *RootPassword) {
+
+	// zero the error string buffer
+	bzero(FS_ERROR, sizeof(FS_ERROR));
+
+	// 0 for MaxFiles would just be silly
+	if (MaxFiles == 0) {
+		cgc_SetFsError("MaxFiles should be > 0");
+		return(0);
+	}
+
+	// destroy the FS if one already exists
+	if (cgc_FS) {
+		cgc_DestroyFilesystem();
+	}
+
+	// malloc space for the filesystem
+	if ((cgc_FS = calloc(1, sizeof(Filesystem))) == NULL) {
+		cgc_SetFsError("calloc failed");
+		return(0);
+	}
+
+	// malloc space for the inode array
+	if ((cgc_FS->Inodes = calloc(1, sizeof(Inode)*MaxFiles)) == NULL) {
+		cgc_SetFsError("calloc failed");
+		free(cgc_FS);
+		return(0);
+	}
+
+	// Set up the filesystem limits
+	cgc_FS->MaxFiles = MaxFiles;
+	
+	// log in as root
+	if (!cgc_Login("root")) {
+		cgc_SetFsError("Login failed");
+		free(cgc_FS->Inodes);
+		free(cgc_FS);
+		return(0);
+	}
+
+	// init the passwd file
+	if (!cgc_InitPasswd(RootPassword)) {
+		cgc_Logout();
+		cgc_SetFsError("Failed to init the passwd file");
+		free(cgc_FS->Inodes);
+		free(cgc_FS);
+		return(0);
+	}
+
+	// clear the file descriptor array
+	bzero(FD, sizeof(FD));
+
+	cgc_ClearFsError();
+	return(1);
+}
+
+// Searches the filesystem for a given Filename and returns its Inode or NULL
+pInode cgc_FindFile(char *Filename) {
+	uint32_t i;
+
+	for (i = 0; i < cgc_FS->MaxFiles; i++) {
+		if (cgc_FS->Inodes[i] && cgc_FS->Inodes[i]->Filename) {
+			if (!strcmp(cgc_FS->Inodes[i]->Filename, Filename)) {
+				// found it
+				return(cgc_FS->Inodes[i]);
+			}
+		}
+	}
+
+	return(NULL);
+}
+
+// Create an empty file (sort of like "touch")
+pInode cgc_CreateEmptyFile(char *Filename, uint8_t Mode) {
+	uint32_t i;
+
+	if (!Filename) {
+		cgc_SetFsError("Invalid filename");
+		return(NULL);
+	}
+	if (!cgc_CurrentUser) {
+		cgc_SetFsError("Must login first");
+		return(NULL);
+	}
+	if (Mode & ((FS_OWNER_READ|FS_OWNER_WRITE|FS_OTHER_READ|FS_OTHER_WRITE) ^ 0xFF))  {
+		cgc_SetFsError("Invalid mode");
+		return(0);
+	}
+
+	// make sure the file doesn't already exist
+	if (cgc_FindFile(Filename)) {
+		cgc_SetFsError("File already exists");
+		return(NULL);
+	}
+
+	// look for a free inode
+	for (i = 0; i < cgc_FS->MaxFiles; i++) {
+		if (cgc_FS->Inodes[i]) {
+			continue;
+		}
+
+		// create the inode
+		if ((cgc_FS->Inodes[i] = calloc(1, sizeof(Inode))) == NULL) {
+			cgc_SetFsError("calloc failed");
+			return(NULL);
+		}
+
+		// set the filename
+		if ((cgc_FS->Inodes[i]->Filename = calloc(1, strlen(Filename)+1)) == NULL) {
+			cgc_SetFsError("calloc failed");
+			free(cgc_FS->Inodes[i]);
+			cgc_FS->Inodes[i] = NULL;
+			return(NULL);
+		}
+		strcpy(cgc_FS->Inodes[i]->Filename, Filename);
+
+		// set the owner
+		if ((cgc_FS->Inodes[i]->Owner = calloc(1, sizeof(cgc_CurrentUser)+1)) == NULL) {
+			cgc_SetFsError("calloc failed");
+			free(cgc_FS->Inodes[i]->Filename);
+			cgc_FS->Inodes[i]->Filename = NULL;
+			free(cgc_FS->Inodes[i]);
+			cgc_FS->Inodes[i] = NULL;
+			return(NULL);
+		}
+		strcpy(cgc_FS->Inodes[i]->Owner, cgc_CurrentUser);
+
+		// set the Mode
+		cgc_FS->Inodes[i]->Mode = Mode;
+
+		// set the filesize and Data
+		cgc_FS->Inodes[i]->FileSize = 0;
+		cgc_FS->Inodes[i]->Data = NULL;
+
+		break;
+	}
+	if (i == cgc_FS->MaxFiles) {
+		cgc_SetFsError("No free inodes");
+		return(NULL);
+	}
+
+	cgc_ClearFsError();
+	return(cgc_FS->Inodes[i]);
+}
+
+// Open a file for reading or writing
+//  Mode: must be either 'r' or 'w'
+//  Returns a file handle suitable for calls to fread, fwrite, fgets, fclose
+FILE_ *cgc_fopen(char *Filename, char *Mode) {
+	uint32_t i;
+	pInode TargetInode = NULL;
+	FILE_ *fp;
+
+	// sanity checks
+	if (!cgc_FS) {
+		cgc_SetFsError("Filesystem does not exist");
+		return(NULL);
+	}
+	if (!Filename || !Mode) {
+		cgc_SetFsError("Invalid filename or mode");
+		return(NULL);
+	}
+	if (strlen(Mode) > 1) {
+		cgc_SetFsError("Invalid mode");
+		return(NULL);
+	}
+	if (Mode[0] != 'r' && Mode[0] != 'w') {
+		cgc_SetFsError("Invalid mode");
+		return(NULL);
+	}
+	if (!cgc_CurrentUser) {
+		cgc_SetFsError("Must login first");
+		return(NULL);
+	}
+
+	// search the filesystem for the filename
+	TargetInode = cgc_FindFile(Filename);
+	if (!TargetInode && Mode[0] == 'r') {
+		cgc_SetFsError("Unable to locate file");
+		return(NULL);
+	}
+
+	// If one was found, make sure the file isn't already open
+	if (TargetInode) {
+		for (i = 0; i < MAX_OPEN_FILE_S; i++) {
+			if (FD[i]) {
+				if (FD[i]->Inode == TargetInode) {
+					// file already open
+					cgc_SetFsError("File is already open");
+					return(NULL);
+				}
+			}
+		}
+	}
+
+	// check permissions
+	// only check if we're not root and we're trying to create a new file
+	if (TargetInode && strcmp(cgc_CurrentUser, "root") != 0) {
+		// are we the owner of the file?
+		if (!strcmp(TargetInode->Owner, cgc_CurrentUser)) {
+			// check owner permissions
+			if (Mode[0] == 'r' && ((TargetInode->Mode & FS_OWNER_READ) == 0)) {
+				cgc_SetFsError("Permission denied");
+				return(NULL);
+			}
+			if (Mode[0] == 'w' && ((TargetInode->Mode & FS_OWNER_WRITE) == 0)) {
+				cgc_SetFsError("Permission denied");
+				return(NULL);
+			}
+		} else {
+			// check other permissions
+			if (Mode[0] == 'r' && ((TargetInode->Mode & FS_OTHER_READ) == 0)) {
+				cgc_SetFsError("Permission denied");
+				return(NULL);
+			}
+			if (Mode[0] == 'w' && ((TargetInode->Mode & FS_OTHER_WRITE) == 0)) {
+				cgc_SetFsError("Permission denied");
+				return(NULL);
+			}
+		}
+	}
+
+	// allocate a FILE_ record
+	if ((fp = calloc(1, sizeof(FILE_))) == NULL) {
+		cgc_SetFsError("calloc failed");
+		return(NULL);
+	}
+
+	// find a file descriptor slot to hold the new FILE_ record
+	for (i = 0; i < MAX_OPEN_FILE_S; i++) {
+		if (FD[i]) {
+			continue;
+		}
+		FD[i] = fp;
+		break;
+	}
+	if (i == MAX_OPEN_FILE_S) {
+		// unable to find available file descriptor
+		cgc_SetFsError("No free file descriptors");
+		free(fp);
+		return(NULL);
+	}
+
+	if (Mode[0] == 'w') {
+		// open for writing
+		if (!TargetInode) {
+			// create a new file
+			if ((TargetInode = cgc_CreateEmptyFile(Filename, FS_OWNER_READ|FS_OWNER_WRITE)) == NULL) {
+				cgc_SetFsError("Failed to create file");
+				FD[i] = NULL;
+				free(fp);
+				return(NULL);
+			}
+			fp->Inode = TargetInode;
+			fp->Mode = FS_WRITE;
+			fp->CurrPosition = 0;
+		} else {
+			// truncate an existing file
+			fp->Inode = TargetInode;
+			fp->Mode = FS_WRITE;
+			fp->CurrPosition = 0;
+
+			fp->Inode->FileSize = 0;
+			if (fp->Inode->Data) {
+				free(fp->Inode->Data);
+				fp->Inode->Data = NULL;
+			}
+		}
+	} else {
+		// open for reading
+		fp->Inode = TargetInode;
+		fp->Mode = FS_READ;
+		fp->CurrPosition = 0;
+
+	}
+
+	cgc_ClearFsError();
+	return(fp);
+
+}
+
+// closes an open file
+uint8_t cgc_fclose(FILE_ *fp) {
+	uint8_t i;
+
+	if (!fp) {
+		cgc_SetFsError("Invalid file pointer");
+		return(0);
+	}
+
+	// find the FD holding this FILE_ pointer
+	for (i = 0; i < MAX_OPEN_FILE_S; i++) {
+		if (FD[i] == fp) {
+			FD[i] = NULL;
+		}
+	}
+
+	cgc_ClearFsError();
+	free(fp);
+	return(1);
+
+}
+	
+// reads the specified number of items of a particular size from the specified file
+//   returns the number of bytes cgc_read
+uint32_t cgc_fread(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp) {
+
+	if (!buf || !fp) {
+		cgc_SetFsError("Invalid buffer or file pointer");
+		return(0);
+	}
+	if (!fp->Inode->Data) {
+		cgc_SetFsError("End of file");
+		return(0);
+	}
+
+	if (size*nitems > (fp->Inode->FileSize - fp->CurrPosition)) {
+		memcpy(buf, fp->Inode->Data + fp->CurrPosition, fp->Inode->FileSize - fp->CurrPosition);
+		fp->CurrPosition += (fp->Inode->FileSize - fp->CurrPosition);
+		cgc_ClearFsError();
+		return(fp->Inode->FileSize - fp->CurrPosition);
+	} else {
+		memcpy(buf, fp->Inode->Data + fp->CurrPosition, size*nitems);
+		fp->CurrPosition += size*nitems;
+		cgc_ClearFsError();
+		return(size*nitems);
+	}
+}
+
+// writes the specified number of items of a particular size to the specified file
+//   returns the number of bytes written
+uint32_t cgc_fwrite(char *buf, uint32_t size, uint32_t nitems, FILE_ *fp) {
+	unsigned char *NewData;
+
+	if (!buf || !fp) {
+		cgc_SetFsError("Invalid buffer or file pointer");
+		return(0);
+	}
+
+	// allocate space to hold the current data and the new data
+	if ((NewData = calloc(1, fp->Inode->FileSize + size*nitems)) == NULL) {
+		cgc_SetFsError("calloc failed");
+		return(0);
+	}
+
+	// cgc_write the current data to the new buffer
+	if (fp->Inode->Data) {
+		memcpy(NewData, fp->Inode->Data, fp->Inode->FileSize);
+	}
+
+	// cgc_write the new data to the new buffer
+	memcpy(NewData+fp->Inode->FileSize, buf, size*nitems);
+	
+	fp->Inode->FileSize += size*nitems;
+
+	if (fp->Inode->Data) {
+		free(fp->Inode->Data);
+	}
+	fp->Inode->Data = NewData;
+
+	cgc_ClearFsError();
+	return(size*nitems);
+}
+
+// reads a line delimited by '\n' from the file
+//   returns a pointer to the line or NULL on EoF or error
+char *cgc_fgets(char *buf, uint32_t size, FILE_ *fp) {
+	uint32_t TotalBytes = 0;
+
+	if (!buf) {
+		cgc_SetFsError("Invalid buffer");
+		return(NULL);
+	}
+	if (!fp) {
+		cgc_SetFsError("Invalid file");
+		return(NULL);
+	}
+	if (fp->CurrPosition == fp->Inode->FileSize) {
+		cgc_SetFsError("End of file");
+		return(NULL);
+	}
+	if (!fp->Inode->Data) {
+		cgc_SetFsError("End of file");
+		return(NULL);
+	}
+
+	// cgc_read in one character at a time
+	while ((fp->CurrPosition < fp->Inode->FileSize) && (TotalBytes < size-1)) {
+		buf[TotalBytes++] = fp->Inode->Data[fp->CurrPosition++];
+		// if the character is a newline, we're done
+		if (fp->Inode->Data[fp->CurrPosition-1] == '\n') {
+			break;
+		}
+	}
+	buf[TotalBytes] = '\0';
+
+	return(buf);
+}
+
+// List the files in the filesystem
+//   like an 'ls'
+uint8_t cgc_ListFiles(char **Buf) {
+	uint32_t i;
+	char Mode[5];
+	uint32_t TotalLen;
+	uint32_t NewLen;
+
+	if (!cgc_FS) {
+		cgc_SetFsError("Filesystem does not exist");
+		return(0);
+	}
+
+	// if we've been passed a Buf pointer, then cgc_write the list
+	// to a newly allocated buffer rather than cgc_stdout
+	// But first we need to calculate how much buffer we'll need
+	if (Buf) {
+		// listing header length
+		TotalLen = 32+1+32+1+8+4+1;
+
+		// length of each of the file lines
+		for (i = 0; i < cgc_FS->MaxFiles; i++) {
+			if (cgc_FS->Inodes[i] == NULL) {
+				continue;
+			}
+
+			if ((NewLen = strlen(cgc_FS->Inodes[i]->Filename)) < 32) {
+				TotalLen += 32;
+			} else {
+				TotalLen += NewLen;
+			}
+			TotalLen++;
+			if ((NewLen = strlen(cgc_FS->Inodes[i]->Owner)) < 32) {
+				TotalLen += 32;
+			} else {
+				TotalLen += NewLen;
+			}
+			TotalLen++;
+			if (cgc_FS->Inodes[i]->FileSize == 0) {
+				TotalLen += 8;
+			} else {
+				if ((NewLen = log10(cgc_FS->Inodes[i]->FileSize)+1) < 8) {
+					TotalLen += 8;
+				} else {
+					TotalLen += NewLen;
+				}
+			}
+			// 1 (space), 4 (mode), 1 (newline)
+			TotalLen += 6;
+		}
+
+		// allocate the buffer
+		if ((*Buf = calloc(1, TotalLen)) == NULL) {
+			cgc_SetFsError("calloc failed");
+			return(0);
+		}
+	}
+
+	if (Buf) {
+		cgc_sprintf(*Buf, "%-32s %-32s %-8s %-4s\n", "Filename", "Owner", "Size", "Mode");
+	} else {
+		printf("%-32s %-32s %-8s %-4s\n", "Filename", "Owner", "Size", "Mode");
+	}
+	for (i = 0; i < cgc_FS->MaxFiles; i++) {
+		if (cgc_FS->Inodes[i] == NULL) {
+			continue;
+		}
+		if (Buf) {
+			cgc_sprintf(*Buf, "%s%-32s %-32s %-8d ", 
+				*Buf,
+				cgc_FS->Inodes[i]->Filename,
+				cgc_FS->Inodes[i]->Owner,
+				cgc_FS->Inodes[i]->FileSize);
+		} else {
+			printf("%-32s %-32s %-8zu ", 
+				cgc_FS->Inodes[i]->Filename,
+				cgc_FS->Inodes[i]->Owner,
+				cgc_FS->Inodes[i]->FileSize);
+		}
+		// print the mode
+		memset(Mode, '-', 5);	
+		Mode[4] = '\0';
+		if (cgc_FS->Inodes[i]->Mode & FS_OWNER_READ)
+			Mode[0] = 'r';
+		if (cgc_FS->Inodes[i]->Mode & FS_OWNER_WRITE)
+			Mode[1] = 'w';
+		if (cgc_FS->Inodes[i]->Mode & FS_OTHER_READ)
+			Mode[2] = 'r';
+		if (cgc_FS->Inodes[i]->Mode & FS_OTHER_WRITE)
+			Mode[3] = 'w';
+		if (Buf) {
+			cgc_sprintf(*Buf,"%s%-4s\n", *Buf, Mode);
+		} else {
+			printf("%-4s\n", Mode);
+		}
+	}
+
+	cgc_ClearFsError();
+	return(1);
+
+}
+
+// Delete a file on the filesystem
+uint8_t cgc_DeleteFile(char *Filename) {
+	uint32_t i;
+	uint32_t InodeIndex;
+	pInode TargetInode;
+
+	if (!cgc_FS) {
+		cgc_SetFsError("Filesystem does not exist");
+		return(0);
+	}
+	if (!Filename) {
+		cgc_SetFsError("Invalid filename");
+		return(0);
+	}
+	if (!cgc_CurrentUser) {
+		cgc_SetFsError("Must login first");
+		return(0);
+	}
+
+	for (i = 0; i < cgc_FS->MaxFiles; i++) {
+		if (cgc_FS->Inodes[i] == NULL) {
+			continue;
+		}
+		if (!strcmp(cgc_FS->Inodes[i]->Filename, Filename)) {
+			// found it
+			TargetInode = cgc_FS->Inodes[i];
+			InodeIndex = i;
+			break;
+		}
+	}
+	if (i == cgc_FS->MaxFiles) {
+		cgc_SetFsError("Unable to locate file");
+		return(0);
+	}
+
+	// make sure there are no file descriptors open to it
+	for (i = 0; i < MAX_OPEN_FILE_S; i++) {
+		if (FD[i]) {
+			if (FD[i]->Inode == TargetInode) {
+				// file is still open
+				return(0);
+			}
+		}
+	}
+
+	// do we have permission to remove it?
+	if (strcmp(cgc_CurrentUser, "root") != 0 && (strcmp(cgc_CurrentUser, TargetInode->Owner) != 0)) {
+		// we're not root or the owner of the file, so no
+		cgc_SetFsError("Permission denied");
+		return(0);
+	}
+	
+	// remove the inode vars
+	free(TargetInode->Filename);
+	if (TargetInode->Owner) {
+		free(TargetInode->Owner);
+	}
+	if (TargetInode->Data) {
+		free(TargetInode->Data);
+	}
+
+	// remove the inode
+	free(TargetInode);
+	cgc_FS->Inodes[InodeIndex] = NULL;
+
+	cgc_ClearFsError();
+	return(1);
+}
+
+// Rename a file 
+uint8_t cgc_RenameFile(char *OldFilename, char *NewFilename) {
+	uint32_t i;
+	pInode SourceInode = NULL;
+	char *TempFilename;
+
+	if (!OldFilename || !NewFilename) {
+		cgc_SetFsError("Invalid filename");
+		return(0);
+	}
+
+	// find the old filename
+	for (i = 0; i < cgc_FS->MaxFiles; i++) {
+		if (cgc_FS->Inodes[i] && cgc_FS->Inodes[i]->Filename) {
+			if (!strcmp(cgc_FS->Inodes[i]->Filename, OldFilename)) {
+				// found it
+				SourceInode = cgc_FS->Inodes[i];
+			}
+			if (!strcmp(cgc_FS->Inodes[i]->Filename, NewFilename)) {
+				// the new filename already exists
+				cgc_SetFsError("Destination file already exists");
+				return(0);
+			}
+		}
+	}
+	if (!SourceInode) {
+		cgc_SetFsError("Source file not found");
+		return(0);
+	}
+
+	// Do we have permissions to rename the old file
+	if (strcmp(cgc_CurrentUser, "root") != 0 && (strcmp(cgc_CurrentUser, SourceInode->Owner) != 0)) {
+		// we're not root or the owner of the file, so no
+		cgc_SetFsError("Permission denied");
+		return(0);
+	}
+
+	// rename the file
+	if ((TempFilename = calloc(1, strlen(NewFilename)+1)) == NULL) {
+		cgc_SetFsError("calloc failed");
+		return(0);
+	}	
+	strcpy(TempFilename, NewFilename);
+	free(SourceInode->Filename);
+	SourceInode->Filename = TempFilename;
+
+	cgc_ClearFsError();
+	return(1);
+}
+
+// ChangeMode
+uint8_t cgc_ChangeMode(char *Filename, uint8_t NewMode) {
+	pInode TargetInode;
+
+	if (!Filename) {
+		cgc_SetFsError("Invalid user");
+		return(0);
+	}
+
+	// check that the mode is valid
+	if (NewMode & ((FS_OWNER_READ|FS_OWNER_WRITE|FS_OTHER_READ|FS_OTHER_WRITE) ^ 0xFF))  {
+		cgc_SetFsError("Invalid mode");
+		return(0);
+	}
+
+	// find the file
+	if ((TargetInode = cgc_FindFile(Filename)) == NULL) {
+		cgc_SetFsError("Unable to find file");
+		return(0);
+	}
+
+	// make sure we're root or we're the owner
+	if ((strcmp(cgc_CurrentUser, "root") != 0) && (strcmp(cgc_CurrentUser, TargetInode->Owner) != 0)) {
+		cgc_SetFsError("Permission denied");
+		return(0);
+	}
+
+	// change the mode
+	TargetInode->Mode = NewMode;
+
+	cgc_ClearFsError();	
+	return(1);
+}
+
+// Change the owner of a file
+//   Can only be done by 'root' user (root must be the currently logged in user)
+uint8_t cgc_ChangeOwner(char *Filename, char *NewOwner) {
+	pInode TargetInode;
+	char *TempOwner;
+
+	if (!Filename) {
+		cgc_SetFsError("Invalid filename");
+		return(0);
+	}
+	if (!NewOwner) {
+		cgc_SetFsError("Invalid owner");
+		return(0);
+	}
+	
+	if (strcmp(cgc_CurrentUser, "root") != 0) {
+		cgc_SetFsError("Must be root");
+		return(0);
+	}
+
+	if ((TargetInode = cgc_FindFile(Filename)) == NULL) {
+		cgc_SetFsError("Unable to find file");
+		return(0);
+	}
+
+	// make sure the NewOwner exists in the passwd file
+	if (!cgc_UserExists(NewOwner)) {
+		cgc_SetFsError("Invalid user");
+		return(0);
+	}
+
+	// calloc some space for the new owner name
+	if ((TempOwner = calloc(1, strlen(NewOwner)+1)) == NULL) {
+		cgc_SetFsError("calloc failed");
+		return(0);
+	}
+	strcpy(TempOwner, NewOwner);
+
+	// update the owner on the inode
+	if (TargetInode->Owner) {
+		free(TargetInode->Owner);
+	}
+	TargetInode->Owner = TempOwner;
+
+	cgc_ClearFsError();
+	return(1);
+}
+
+//
+// user functions
+//
+
+// Login
+uint8_t cgc_Login(char *Username) {
+	char *NewUsername;
+
+	if (!Username) {
+		cgc_SetFsError("Invalid username");
+		return(0);
+	}
+
+	// copy the requested username 
+	if ((NewUsername = calloc(1, strlen(Username)+1)) == NULL) {
+		cgc_SetFsError("calloc failed");
+		return(0);
+	}
+	strcpy(NewUsername, Username);
+
+	// is anyone currently logged in
+	if (cgc_CurrentUser) {
+		free(cgc_CurrentUser);
+		cgc_CurrentUser = NULL;
+	}
+
+	// log in as the requested user
+	cgc_CurrentUser = NewUsername;
+
+	cgc_ClearFsError();
+	return(1);
+	
+}
+
+void cgc_Uid(void) {
+	if (cgc_CurrentUser) {
+		cgc_puts(cgc_CurrentUser);
+	}
+}
+
+// log the current user out (leaving no user logged in)
+uint8_t cgc_Logout(void) {
+
+	if (cgc_CurrentUser) {
+		free(cgc_CurrentUser);
+	}
+
+	cgc_CurrentUser = NULL;
+
+	cgc_ClearFsError();
+	return(1);
+}
+
+// init passwd file creating the 'root' user and setting its password
+uint8_t cgc_InitPasswd(char *RootPassword) {
+	FILE_ *fp;
+
+	if (!RootPassword) {
+		cgc_SetFsError("Invalid root password");
+		return(0);
+	}
+
+	// fopen the passwd file
+	if ((fp = cgc_fopen("passwd", "w")) == NULL) {
+		cgc_SetFsError("Unable to open passwd file");
+		return(0);
+	}
+
+	// cgc_write the root user
+	cgc_fwrite("root:", 5, 1, fp);
+	cgc_fwrite(RootPassword, strlen(RootPassword), 1, fp);
+
+	// close the file
+	cgc_fclose(fp);
+
+	cgc_ClearFsError();
+	return(1);
+
+}
+
+// checks if the specified Username exists in the passwd file
+uint8_t cgc_UserExists(char *Username) {
+	FILE_ *in;
+	char line[128];
+	char *User;
+
+	if (!Username) {
+		cgc_SetFsError("Invalid username");
+		return(0);
+	}
+
+	// open the passwd file
+	if ((in = cgc_fopen("passwd", "r")) == NULL) {
+		cgc_SetFsError("Unable to open passwd file");
+		return(0);
+	}
+
+	// cgc_read in each line
+	while (cgc_fgets(line, 127, in)) {
+		// see if it's the target username
+		if ((User = strtok(line, ":")) == NULL) {
+			cgc_SetFsError("Failed to parse passwd file");
+			return(0);
+		}
+		if (!strcmp(User, Username)) {
+			// found it
+			cgc_fclose(in);
+			return(1);
+		}
+	}
+
+	// close the passwd file
+	cgc_fclose(in);
+
+	cgc_ClearFsError();
+	return(0);
+
+}
+
+// add a user to the passwd file
+uint8_t cgc_AddUser(char *Username, char *Password) {
+	FILE_ *passwd;
+	FILE_ *newpasswd;
+	char line[128];
+
+	if (!Username) {
+		cgc_SetFsError("Invalid username");
+		return(0);
+	}
+	if (!Password) {
+		cgc_SetFsError("Invalid password");
+		return(0);
+	}
+	if (strcmp(cgc_CurrentUser, "root") != 0) {
+		cgc_SetFsError("Must be root");
+		return(0);
+	}
+	if (strlen(Username) > MAX_USER_LEN) {
+		cgc_SetFsError("Invalid username");
+		return(0);
+	}
+	if (strlen(Password) > MAX_PASSWD_LEN) {
+		cgc_SetFsError("Invalid password");
+		return(0);
+	}
+
+	// make sure the username doesn't already exist
+	if (cgc_UserExists(Username)) {
+		cgc_SetFsError("User already exists");
+		return(0);
+	}
+
+	// open the passwd file
+	if ((passwd = cgc_fopen("passwd", "r")) == NULL) {
+		cgc_SetFsError("Unable to open passwd file");
+		return(0);
+	}
+
+	// open the temp passwd file
+	if ((newpasswd = cgc_fopen("~passwd", "w")) == NULL) {
+		cgc_SetFsError("Unable to open tmp passwd file");
+		cgc_fclose(passwd);
+		return(0);
+	}
+
+	// cgc_read in each line of the passwd file
+	while (cgc_fgets(line, 127, passwd) != NULL) {
+		// cgc_write it out to the temp passwd file
+		if (cgc_fwrite(line, strlen(line), 1, newpasswd) != strlen(line)) {
+			cgc_fclose(passwd);
+			cgc_fclose(newpasswd);
+			cgc_SetFsError("Unable to write tmp passwd file");
+			cgc_DeleteFile("~passwd");
+			return(0);
+		}
+		if (line[strlen(line)-1] != '\n') {
+			if (cgc_fwrite("\n", 1, 1, newpasswd) != 1) {
+				cgc_fclose(passwd);
+				cgc_fclose(newpasswd);
+				cgc_SetFsError("Unable to write tmp passwd file");
+				cgc_DeleteFile("~passwd");
+				return(0);
+			}
+		}
+	}
+
+	// cgc_write the new passwd entry
+	cgc_sprintf(line, "%s:%s", Username, Password);
+	cgc_fwrite(line, strlen(line), 1, newpasswd);
+
+	// close the passwd file
+	cgc_fclose(passwd);
+
+	// close the temp passwd file
+	cgc_fclose(newpasswd);
+
+	// remove the passwd file
+	cgc_DeleteFile("passwd");
+	
+	// move the temp passwd file to passwd
+	cgc_RenameFile("~passwd", "passwd");
+
+	cgc_ClearFsError();
+	return(1);
+}
+
+// delete user
+uint8_t cgc_DeleteUser(char *Username) {
+	char line[128];
+	char *User;
+	uint8_t Found = 0;
+	FILE_ *passwd;
+	FILE_ *newpasswd;
+
+	if (!Username) {
+		cgc_SetFsError("Invalid username");
+		return(0);
+	}
+	if (strcmp(cgc_CurrentUser, "root") != 0) {
+		cgc_SetFsError("Must be root");
+		return(0);
+	}
+	if (!strcmp(Username, "root")) {
+		cgc_SetFsError("Can't delete root user");
+		return(0);
+	}
+
+	// open the passwd file
+	if ((passwd = cgc_fopen("passwd", "r")) == NULL) {
+		cgc_SetFsError("Unable to open passwd file");
+		return(0);
+	}
+
+	// open the temp passwd file
+	if ((newpasswd = cgc_fopen("~passwd", "w")) == NULL) {
+		cgc_SetFsError("Unable to open tmp passwd file");
+		cgc_fclose(passwd);
+		return(0);
+	}
+
+	// cgc_read in each line of the passwd file
+	while (cgc_fgets(line, 127, passwd) != NULL) {
+		// skip blank lines
+		if (strlen(line) == 0) {
+			continue;
+		}
+		// cgc_write it out to the temp passwd file
+		// if it's not the user we're deleting
+		if ((User = strtok(line, ":")) == NULL) {
+			cgc_SetFsError("Failed to parse passwd file");
+			cgc_fclose(passwd);
+			cgc_fclose(newpasswd);
+			cgc_DeleteFile("~passwd");
+			return(0);
+		}
+		if (!strcmp(User, Username)) {
+			// found it, so don't cgc_write the user
+			Found = 1;
+			continue;
+		}
+
+		// restore the delimiter strtok would have removed
+		line[strlen(User)] = ':';
+
+		// cgc_write the line to the temp passwd file
+		if (cgc_fwrite(line, strlen(line), 1, newpasswd) != strlen(line)) {
+			cgc_fclose(passwd);
+			cgc_fclose(newpasswd);
+			cgc_SetFsError("Unable to write tmp passwd file");
+			cgc_DeleteFile("~passwd");
+			return(0);
+		}
+	}
+
+	// close the passwd file
+	cgc_fclose(passwd);
+
+	// close the temp passwd file
+	cgc_fclose(newpasswd);
+
+	if (!Found) {
+		cgc_SetFsError("User not found");
+		cgc_fclose(passwd);
+		cgc_fclose(newpasswd);
+		cgc_DeleteFile("~passwd");
+		return(0);
+	}
+
+	// remove the passwd file
+	cgc_DeleteFile("passwd");
+	
+	// move the temp passwd file to passwd
+	cgc_RenameFile("~passwd", "passwd");
+
+	cgc_ClearFsError();
+	return(1);
+
+}
+
+// change user password
+uint8_t cgc_ChangePasswd(char *Username, char *NewPasswd) {
+	char line[128];
+	char *User;
+	uint8_t Found = 0;
+	FILE_ *passwd;
+	FILE_ *newpasswd;
+
+	if (!Username) {
+		cgc_SetFsError("Invalid username");
+		return(0);
+	}
+	if (!NewPasswd) {
+		cgc_SetFsError("Invalid password");
+		return(0);
+	}
+	if (strlen(NewPasswd) > MAX_PASSWD_LEN) {
+		cgc_SetFsError("Invalid password");
+		return(0);
+	}
+
+	if (strcmp(cgc_CurrentUser, Username) != 0 && strcmp(cgc_CurrentUser, "root") != 0) {
+		cgc_SetFsError("Must be root or the user being changed");
+		return(0);
+	}
+
+	// open the passwd file
+	if ((passwd = cgc_fopen("passwd", "r")) == NULL) {
+		cgc_SetFsError("Unable to open passwd file");
+		return(0);
+	}
+
+	// open the temp passwd file
+	if ((newpasswd = cgc_fopen("~passwd", "w")) == NULL) {
+		cgc_SetFsError("Unable to open tmp passwd file");
+		cgc_fclose(passwd);
+		return(0);
+	}
+
+	// cgc_read in each line of the passwd file
+	while (cgc_fgets(line, 127, passwd) != NULL) {
+		// skip blank lines
+		if (strlen(line) == 0) {
+			continue;
+		}
+		// cgc_write it out to the temp passwd file
+		// if it's not the user we're deleting
+		if ((User = strtok(line, ":")) == NULL) {
+			cgc_SetFsError("Failed to parse passwd file");
+			cgc_fclose(passwd);
+			cgc_fclose(newpasswd);
+			cgc_DeleteFile("~passwd");
+			return(0);
+		}
+		if (!strcmp(User, Username)) {
+			// found it, cgc_write the new passwd
+			cgc_sprintf(line, "%s:%s\n", Username, NewPasswd);
+			if (cgc_fwrite(line, strlen(line), 1, newpasswd) != strlen(line)) {
+				cgc_fclose(passwd);
+				cgc_fclose(newpasswd);
+				cgc_SetFsError("Unable to write tmp passwd file");
+				cgc_DeleteFile("~passwd");
+				return(0);
+			}
+			continue;
+		}
+
+		// restore the delimiter strtok would have removed
+		line[strlen(User)] = ':';
+
+		// restore the delimiter strtok would have removed
+		if (cgc_fwrite(line, strlen(line), 1, newpasswd) != strlen(line)) {
+			cgc_SetFsError("Unable to write tmp passwd file");
+			cgc_fclose(passwd);
+			cgc_fclose(newpasswd);
+			cgc_DeleteFile("~passwd");
+			return(0);
+		}
+	}
+
+	// close the passwd file
+	cgc_fclose(passwd);
+
+	// close the temp passwd file
+	cgc_fclose(newpasswd);
+
+	if (!Found) {
+		cgc_SetFsError("User not found");
+		cgc_fclose(passwd);
+		cgc_fclose(newpasswd);
+		cgc_DeleteFile("~passwd");
+		return(0);
+	}
+
+	// remove the passwd file
+	cgc_DeleteFile("passwd");
+	
+	// move the temp passwd file to passwd
+	cgc_RenameFile("~passwd", "passwd");
+
+	cgc_ClearFsError();
+	return(1);
+
+}
+
+// check user password
+uint8_t cgc_CheckPasswd(char *Username, char *Password) {
+	char line[128];
+	char *User;
+	char *CurrPassword;
+	uint8_t Found = 0;
+	FILE_ *passwd;
+	char *OldUser = NULL;
+	uint8_t NoLogin = 0;
+
+	if (!Username) {
+		cgc_SetFsError("Invalid username");
+		return(0);
+	}
+	if (!Password) {
+		cgc_SetFsError("Invalid password");
+		return(0);
+	}
+	if (strlen(Password) > MAX_PASSWD_LEN) {
+		cgc_SetFsError("Invalid password");
+		return(0);
+	}
+
+	// need to log in as root for the rest of this function
+	// save the current logged in user
+	if (cgc_CurrentUser) {
+		if (strcmp(cgc_CurrentUser, "root") != 0) {
+			if ((OldUser = calloc(1, strlen(cgc_CurrentUser)+1)) == NULL) {
+				cgc_SetFsError("calloc failed");
+				return(0);
+			}
+			strcpy(OldUser, cgc_CurrentUser);
+			cgc_Logout();
+			cgc_Login("root");
+		}
+	} else {
+		cgc_Login("root");
+		NoLogin = 1;
+	}
+
+	// open the passwd file
+	if ((passwd = cgc_fopen("passwd", "r")) == NULL) {
+		cgc_SetFsError("Unable to open passwd file");
+		if (OldUser) {
+			cgc_Logout();
+			cgc_Login(OldUser);
+			free(OldUser);
+		}
+		if (NoLogin) {
+			cgc_Logout();
+		}
+		return(0);
+	}
+
+	// cgc_read in each line of the passwd file
+	while (cgc_fgets(line, 127, passwd) != NULL) {
+		// skip blank lines
+		if (strlen(line) == 0) {
+			continue;
+		}
+		// parse the password field
+		if ((User = strtok(line, ":")) == NULL) {
+			cgc_SetFsError("Failed to parse passwd file");
+			cgc_fclose(passwd);
+			if (OldUser) {
+				cgc_Logout();
+				cgc_Login(OldUser);
+				free(OldUser);
+			}
+			if (NoLogin) {
+				cgc_Logout();
+			}
+			return(0);
+		}
+		if (strcmp(User, Username) != 0) {
+			// not the target user, skip on
+			continue;
+		}
+
+		// found the target user, parse the password
+		if ((CurrPassword = strtok(NULL, ":")) == NULL) {
+			cgc_SetFsError("Failed to parse passwd file");
+			cgc_fclose(passwd);
+			if (OldUser) {
+				cgc_Logout();
+				cgc_Login(OldUser);
+				free(OldUser);
+			}
+			if (NoLogin) {
+				cgc_Logout();
+			}
+			return(0);
+		}
+
+		if (!strcmp(CurrPassword, Password)) {
+			// matches
+			cgc_ClearFsError();
+			cgc_fclose(passwd);
+			if (OldUser) {
+				cgc_Logout();
+				cgc_Login(OldUser);
+				free(OldUser);
+			}
+			if (NoLogin) {
+				cgc_Logout();
+			}
+			return(1);
+		}
+
+	}
+
+	// close the passwd file
+	cgc_fclose(passwd);
+
+	if (!Found) {
+		cgc_SetFsError("User not found");
+		if (OldUser) {
+			cgc_Logout();
+			cgc_Login(OldUser);
+			free(OldUser);
+		}
+		if (NoLogin) {
+			cgc_Logout();
+		}
+		return(0);
+	}
+
+	cgc_ClearFsError();
+	if (OldUser) {
+		cgc_Logout();
+		cgc_Login(OldUser);
+		free(OldUser);
+	}
+	if (NoLogin) {
+		cgc_Logout();
+	}
+	return(0);
+
+}
diff --git a/cgc-challenges/Monster_Game/lib/malloc.c b/cgc-challenges/Monster_Game/lib/malloc.c
new file mode 100644
index 0000000000000000000000000000000000000000..01d10a908a3cad0808f94370c57e04f3e16be790
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/malloc.c
@@ -0,0 +1,283 @@
+/*
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Copyright (c) 2015 Cromulence LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+#include "malloc.h"
+
+#include "cgc_stdio.h"
+
+
+typedef struct meta {
+	size_t length;
+	struct meta *next;
+	struct meta *prev;
+} meta, *pmeta;
+
+#define BUCKET( size )	(size > 1016 ? 0 : size / 8 )
+
+/// Each bucket is the head of a singly linked list
+///  The size for the bucket can be calculated via index*8
+///  However, the freelist bucket 0 also uses the prev pointer
+pmeta cgc_lookaside[128] = {NULL};
+
+void cgc_link( pmeta linkme )
+{
+	pmeta walker = cgc_lookaside[0];
+
+	if ( linkme == NULL ) {
+		return;
+	}
+
+	/// Handle the case where this is <= 1016
+	if ( linkme->length <= 1016 ) {
+		//printf("Adding into bucket: $d\n", BUCKET( linkme->length) );
+		linkme->next = cgc_lookaside[ BUCKET( linkme->length ) ];
+		cgc_lookaside[ BUCKET( linkme->length ) ] = linkme;
+		return;
+	}
+
+	while ( walker ) {
+		if ( walker->next == NULL ) {
+			walker->next = linkme;
+			linkme->prev = walker;
+			linkme->next = NULL;
+			return;
+		} else if ( linkme->length < walker->next->length ) {
+			linkme->next = walker->next;
+			linkme->prev = walker;
+			walker->next->prev = linkme;
+			walker->next = linkme;
+			return;
+		} else {
+			walker = walker->next;
+		}
+	}
+
+	return;
+}
+
+void cgc_add_freelist_block( size_t length )
+{
+	pmeta block = NULL;
+	pmeta walker = NULL;
+
+	/// Round to the nearest page
+
+	/// Account for the 4 byte length field
+	length += 4;
+
+	length = (length + 4095 ) & 0xfffff000;
+
+	if ( cgc_allocate( length, 0, (void**)&block) != 0 ) {
+		printf("[ERROR] Allocating a free list block failed: %zu\n", length);
+		cgc__terminate(-1);
+	}
+
+	bzero( block, length );
+
+	block->length = length-4;
+	
+	if ( cgc_lookaside[0] == NULL ) {
+		cgc_lookaside[0] = block;
+		return;
+	}
+
+	cgc_link( block );
+
+	return;
+}
+
+void free( void *block )
+{
+	pmeta nb = NULL;
+
+	if ( block ) {
+		nb = (pmeta) (( (char*)block) - 4);
+		cgc_link(nb);
+	}
+
+	return;
+}
+
+void cgc_init_freelist( void )
+{
+	pmeta zero_block = NULL;
+	pmeta base_block = NULL;
+
+	if ( cgc_allocate(4096, 0, (void**)&cgc_lookaside) != 0 ) {
+		printf("[ERROR] Malloc fail terminate\n");
+		cgc__terminate(-1);
+	}
+
+	bzero( cgc_lookaside[0], 4096);
+
+	zero_block = cgc_lookaside[0];
+	base_block = zero_block + 1;
+
+	/// Keep a zero length head on the freelist for
+	///	ease of organization
+	zero_block->length = 0;
+	zero_block->next = base_block;
+	zero_block->prev = NULL;
+
+	base_block->length = 4096 - sizeof(meta) - 4;
+	base_block->prev = zero_block;
+	base_block->next = NULL;
+
+	//printf("Set up head: $x with walker: $d: $x\n", zero_block, base_block->length, base_block);
+
+	return;
+}
+
+void cgc_unlink( pmeta block )
+{
+	if ( block == NULL ) {
+		return;
+	}
+
+	if ( block->prev != NULL ) {
+		block->prev->next = block->next;
+	}
+
+	if ( block->next != NULL ) {
+		block->next->prev = block->prev;
+	}
+
+	return;
+}
+
+void *freelist_alloc( size_t length )
+{
+	pmeta walker = NULL;
+	pmeta newone = NULL;
+
+	/// If there isn't a block on the free list then initialize one
+	/// This should only be the case on the first allocation request
+	if ( cgc_lookaside[0] == NULL ) {
+		cgc_init_freelist();
+	}
+
+	walker = (pmeta)cgc_lookaside[0];
+
+	// Walk while looking for the smallest useable
+	while ( walker ) {
+		if ( walker->length < length ) {
+			walker = walker->next;
+		} else {
+			break;
+		}
+	}
+
+	if ( walker == NULL ) {
+		//printf("no blocks found\n");
+		cgc_add_freelist_block( length );
+		return freelist_alloc(length);
+	} else {
+		//printf("foudn block size: $d\n", walker->length );
+
+		cgc_unlink(walker);
+
+		/// If the block is less than the size needed for at
+		///	least an 8 byte block then return the whole thing
+		///	That means sizeof(meta) prev and next total 8 bytes
+		///	bytes on the lookaside list
+		if ( walker->length - length < sizeof(meta) ) {
+			/// Skip the 4 byte length
+			return ((char*)walker) + 4;
+		}
+
+		/// Break the chunk off
+		newone = (pmeta) ( ((char*)walker) + 4 + length );
+		newone->length = walker->length - (length+4);
+
+		//printf("Broke $d into $d and $d\n", walker->length, length, newone->length);
+		walker->length = length;
+
+		cgc_link(newone);
+
+		//printf("Returning size: $d\n", walker->length);
+		return ((char*)walker) + 4;
+	}
+
+	return NULL;
+}
+
+/*
+void *calloc( size_t length )
+{
+	void *out = malloc( length );
+
+	if ( !out ) {
+		return out;
+	}
+
+	length = (length+7) & 0xfffffff8;
+
+	bzero( out, length);
+
+	return out;
+}
+
+void *malloc( size_t length )
+{
+	int bucket = 0;
+	pmeta outb = NULL;
+	
+	// The minimum size for a valid request is 8 bytes
+	if ( length < 8 ) {
+		length = 8;
+	}
+
+	// Round up to nearest 8
+	length = (length+7) & 0xfffffff8;
+
+	bucket = BUCKET(length);
+
+	if ( bucket == 0 ) {
+		return freelist_alloc( length );
+	} else {
+		while ( bucket < 128 ) {
+			if ( cgc_lookaside[ bucket] != NULL ) {
+				break;
+			}
+
+			bucket++;
+		}
+	}
+
+	if ( bucket == 128 ) {
+		//printf("No available buckets freelist alloc\n");
+		return freelist_alloc( length );
+	} else {
+		//printf("Found bucket: $d\n", bucket);
+		outb = cgc_lookaside[ bucket ];
+		cgc_lookaside[bucket] = outb->next;
+
+		return ( (char*)outb ) + 4;
+	}
+
+	return NULL;
+}
+*/
diff --git a/cgc-challenges/Monster_Game/lib/math.c b/cgc-challenges/Monster_Game/lib/math.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d280b9cd15596cccf355befb2e62525706b810b
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/math.c
@@ -0,0 +1,48 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+#include "common.h"
+#include "libcgc.h"
+
+double cgc_round( double val )
+{
+	// Default -- round away from zero
+	if ( val < 0.0 )
+		return (double)rint( (val - 0.5) );
+	else if ( val > 0.0 )
+		return (double)rint( (val + 0.5) );
+	else
+		return val;
+}
+
+double floor( double val )
+{
+	if ( val < 0.0 )
+		return (double)rint( (val - 0.5) ) + 1.0;
+	else if ( val > 0.0 )
+		return (double)rint( (val + 0.5) ) - 1.0;
+	else
+		return val;
+}
diff --git a/cgc-challenges/Monster_Game/lib/prng.c b/cgc-challenges/Monster_Game/lib/prng.c
new file mode 100644
index 0000000000000000000000000000000000000000..b326850efde73ee44a3e7da4fa8fb79918c77845
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/prng.c
@@ -0,0 +1,119 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+// This is an implementation of the WELL RNG 1024a random number generator
+#include "cgc_prng.h"
+#include <stdint.h>
+#include "common.h"
+
+#define R	32
+#define M1	3
+#define M2	24
+#define M3	10
+
+uint32_t state[R];
+uint32_t state_n;
+
+void cgc_seed_prng_array( uint32_t *pSeedArray, uint32_t arrayLen )
+{
+	uint32_t i;
+
+	// CLear initial state
+	bzero( (void *)state, R*sizeof(uint32_t) );
+
+	state_n = 0;
+
+	// Only use a maximum of 32 uint32_t's to seed state
+	if ( arrayLen > 32 )
+		arrayLen = 32;
+
+	for ( i = 0; i < arrayLen; i++ )
+		state[i] = pSeedArray[i];
+
+	for ( i = arrayLen; i < R; i++ )
+	{
+		uint32_t state_value = state[(i-1)&0x1f];
+
+		// Mix in some of the previous state, the current iteration, and multiply by a mersenne prime		
+		state[i] = (uint32_t)((state_value ^ (state_value >> 30) + i) * 524287);
+	}
+}
+
+void cgc_seed_prng( uint32_t seedValue )
+{
+	cgc_seed_prng_array( &seedValue, 1 );
+}
+
+uint32_t cgc_prng( void )
+{
+	// Get new random
+	uint32_t v0 = state[ state_n ];
+	uint32_t vM1 = state[ (state_n + M1) & 0x1f ];
+	uint32_t vM2 = state[ (state_n + M2) & 0x1f ];
+	uint32_t vM3 = state[ (state_n + M3) & 0x1f ];
+		
+	uint32_t z0 = state[ (state_n+31) & 0x1f ];
+	uint32_t z1 = v0 ^ (vM1 ^ (vM1 >> 8));
+	uint32_t z2 = (vM2 ^ (vM2 << 19)) ^ (vM3 ^ (vM3 << 14));
+	
+	uint32_t newV1 = z1 ^ z2;
+	uint32_t newV0 = (z0 ^ (z0 << 11)) ^ (z1 ^ (z1 << 7)) ^ (z2 ^ (z2 << 13));
+
+	state[ state_n ] = newV1;
+	state[ (state_n+31) & 0x1f ] = newV0;
+
+	state_n = (state_n + 31) & 0x1f;
+
+	return newV0;	
+}
+
+// Random [min,max] (note that is inclusive)
+uint32_t cgc_random_in_range( uint32_t min, uint32_t max )
+{
+	if ( min > max )
+		return 0;
+
+	if ( min == max )
+		return min;
+
+	uint32_t random_value;
+	uint32_t delta = max - min + 1;
+
+	// Check for [0, 0xffffffff]
+	if ( delta == 0 )
+		return cgc_prng();
+
+	uint32_t scale_divider = (0xffffffff) / delta;
+	
+	do
+	{
+		random_value = cgc_prng();
+
+		// Pick values until they fall into one of the buckets
+	} while ( random_value >= scale_divider * delta);
+
+	// Scale value back down add min and return	
+	return min + (random_value / scale_divider);
+}
diff --git a/cgc-challenges/Monster_Game/lib/stdio.c b/cgc-challenges/Monster_Game/lib/stdio.c
new file mode 100644
index 0000000000000000000000000000000000000000..06954c27c616b8184b9683ae1fad2109c8dddcb3
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/stdio.c
@@ -0,0 +1,813 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+#include "cgc_stdio.h"
+
+#include "cgc_stdint.h"
+
+
+
+#include "common.h"
+
+#define FLAG_LEFT_JUSTIFY 	1
+#define FLAG_DISPLAY_SIGN 	2
+#define FLAG_ZERO_PAD		4 
+
+#define FLAG_HEX_UPPERCASE	8
+#define FLAG_FLOAT_EXPONENT	16
+
+#define FLOAT_NON_EXPONENT_MAX		10000000000.0
+#define DEFAULT_FLOAT_PRECISION		6
+
+// Wrapper functions for vprintf and vsprintf
+typedef int (*tPrintfWrapperFP)( void *ctx, int c, size_t pos );
+
+int cgc_wrapper_output( void *ctx, tPrintfWrapperFP fpOut, size_t pos, const char *format, va_list args );
+
+int cgc_WRAPPER_PUTC( void *ctx, int c, size_t pos )
+{
+        size_t tx_bytes;
+
+        if ( cgc_transmit( STDOUT, (const void *)&c, 1, &tx_bytes ) != 0 )
+                return (-1);
+
+        return (pos+1);
+}
+
+int cgc_WRAPPER_OUTC( void *ctx, int c, size_t pos )
+{
+	*(((char *)ctx)+pos) = (char)c;
+
+	return (pos+1);	
+}
+
+#define BUFFER_PUTC_MAXLEN	256
+struct BUFFER_PUTC_DATA
+{
+	char szBuffer[BUFFER_PUTC_MAXLEN];
+	uint16_t bufferPos;
+};
+
+typedef struct BUFFER_PUTC_DATA tBufferPutcData;
+
+tBufferPutcData g_putcBuffer;
+
+int cgc_WRAPPER_BUFFER_PUTC( void *ctx, int c, size_t pos )
+{
+	tBufferPutcData *pBufferData = (tBufferPutcData *)ctx;
+
+	if ( pBufferData->bufferPos >= BUFFER_PUTC_MAXLEN )
+	{
+		char *pBufferPos = pBufferData->szBuffer;
+
+		while ( pBufferData->bufferPos > 0 )
+		{
+			size_t tx_bytes;
+
+			if ( cgc_transmit( STDOUT, (const void *)pBufferPos, pBufferData->bufferPos, &tx_bytes ) != 0 )
+				return (-1);
+
+			if ( tx_bytes == 0 )
+				return (-1);
+
+			pBufferData->bufferPos -= tx_bytes;
+			pBufferPos += tx_bytes;
+		}		
+	}
+
+	pBufferData->szBuffer[pBufferData->bufferPos++] = (char)c;
+
+	return (pos+1);
+}
+
+int cgc_putchar( int c )
+{
+        size_t tx_bytes;
+
+        if ( cgc_transmit( STDOUT, (const void *)&c, 1, &tx_bytes ) != 0 )
+                return (-1);
+
+        return (c);
+}
+
+int cgc_puts( const char *s )
+{
+	size_t tx_bytes;
+	size_t s_len;
+	size_t total_sent = 0;
+
+	s_len = strlen(s);
+
+	while (total_sent != s_len) {
+		if ( cgc_transmit( STDOUT, s+total_sent, s_len-total_sent, &tx_bytes ) != 0 ) {
+			return (-1);
+		}
+		if (tx_bytes == 0) {
+			return (-1);
+		}
+		total_sent += tx_bytes;
+	}
+
+	cgc_putchar( '\n' );
+
+	return (0);
+}
+
+int cgc_vprintf_buffered( const char *format, va_list args )
+{
+	tPrintfWrapperFP wrapper_putc_buffered = &cgc_WRAPPER_BUFFER_PUTC;
+
+	tBufferPutcData g_putcBuffer;
+	g_putcBuffer.bufferPos = 0;
+
+	void *ctx = (void *)&g_putcBuffer;
+	size_t pos = 0;
+
+	int iReturn = cgc_wrapper_output( ctx, wrapper_putc_buffered, pos, format, args );
+
+	// Cleanup buffer
+	char *pBufferPos = g_putcBuffer.szBuffer;
+	while ( g_putcBuffer.bufferPos > 0 )
+	{
+        	size_t tx_bytes;
+
+        	if ( cgc_transmit( STDOUT, (const void *)pBufferPos, g_putcBuffer.bufferPos, &tx_bytes ) != 0 )
+                	return (-1);
+
+		if ( tx_bytes == 0 )
+			return (-1);
+
+		g_putcBuffer.bufferPos -= tx_bytes;
+		pBufferPos += tx_bytes;
+	}
+
+	return iReturn;
+}
+
+int printf( const char *format, ... )
+{
+	va_list args;
+	va_start(args, format);
+
+	int return_val = cgc_vprintf_buffered( format, args );
+
+	va_end(args);
+
+	return (return_val);	
+}
+
+#if 0
+int vprintf( const char *format, va_list args )
+{
+	tPrintfWrapperFP wrapper_putc = &WRAPPER_PUTC;
+	void *ctx = NULL;
+	size_t pos = 0;
+
+	return wrapper_output( ctx, wrapper_putc, pos, format, args );	
+}
+#endif
+
+int cgc_sprintf( char *buf, const char *format, ... )
+{
+	va_list args;
+	va_start(args, format);
+
+	int return_val = cgc_vsprintf( buf, format, args );
+
+	va_end(args);
+
+	return (return_val);	
+}
+
+int cgc_vsprintf( char *buf, const char *format, va_list args )
+{
+	tPrintfWrapperFP wrapper_outc = &cgc_WRAPPER_OUTC;
+	void *ctx = buf;
+	size_t pos = 0;
+
+	int iReturnValue = cgc_wrapper_output( ctx, wrapper_outc, pos, format, args );
+
+	(*wrapper_outc)( ctx, '\0', iReturnValue );
+
+	return iReturnValue;
+}
+
+// NOTE This is reversed -- it will be printed in reverse by the printf helper!
+size_t printf_int_to_string( uint32_t val, uint32_t base, char *str, int32_t flags )
+{
+	size_t pos = 0;
+	int32_t n;
+
+	if ( val == 0 )
+	{
+		str[0] = '0';
+		return 1;
+	}
+
+	while ( val > 0 )
+	{
+		n = val % base;
+		val = val / base;
+
+		if ( base == 16 )
+		{
+			if ( n < 10 )
+				str[pos++] = '0' + n;
+			else
+			{
+				if ( flags & FLAG_HEX_UPPERCASE )
+					str[pos++] = 'A' + (n-10);
+				else
+					str[pos++] = 'a' + (n-10);
+			}
+		}
+		else
+			str[pos++] = '0' + n;	
+	}
+
+	return (pos);
+}
+					
+size_t printf_helper_int( void *ctx, tPrintfWrapperFP fpOut, size_t pos, int32_t val, uint32_t base, int32_t width, int32_t precision, int32_t flags )
+{
+	size_t max_printlen = 0;
+	size_t pad_length = 0;
+	int8_t is_negative = 0;
+	size_t character_count = 0;
+	char temp_str[32];
+
+	if ( base == 10 && val < 0 )
+	{
+		is_negative = 1;
+		val = -val;
+
+		max_printlen++;
+	}
+
+	character_count = printf_int_to_string( (uint32_t)val, base, temp_str, flags );
+	max_printlen += character_count;
+
+	if ( width > 0 )
+	{
+		if ( max_printlen < width )
+			pad_length = width-max_printlen;
+	}
+
+	// Precision will override width	
+	if ( precision > 0 )
+	{
+		flags |= FLAG_ZERO_PAD;
+		if ( character_count < precision )
+			pad_length = precision-character_count;
+	}
+
+	if ( !(flags & FLAG_LEFT_JUSTIFY) )
+	{
+		if ( is_negative && pad_length > 0 && (flags & FLAG_ZERO_PAD) )
+		{
+			pos = (*fpOut)( ctx, '-', pos );
+			is_negative = 0;
+		}
+
+		while ( pad_length-- > 0 )
+		{
+			if ( (flags & FLAG_ZERO_PAD) )
+				pos = (*fpOut)( ctx, '0', pos );
+			else	
+				pos = (*fpOut)( ctx, ' ', pos );	
+		}
+	}
+
+	if ( is_negative )
+	{
+		pos = (*fpOut)( ctx, '-', pos );
+		is_negative = 0;
+	}
+
+	size_t i = character_count;
+	while ( i > 0 )
+	{
+		pos = (*fpOut)( ctx, temp_str[i-1], pos );
+		i--;
+	}
+	
+	if ( (flags & FLAG_LEFT_JUSTIFY) )
+	{
+		while ( pad_length-- > 0 )
+			pos = (*fpOut)( ctx, ' ', pos );
+	}
+
+	return pos;	
+}
+
+size_t printf_float_to_string( double val, uint8_t fraction_precision_digit_count, char *str, int32_t flags )
+{
+	size_t pos = 0;
+	int32_t n;
+	
+	double display_precision = pow( 10.0, -fraction_precision_digit_count );
+	
+	if ( val == 0.0 )
+	{
+		str[pos++] = '0';
+		str[pos++] = '.';
+
+		for ( uint8_t i = 0; i < fraction_precision_digit_count; i++ )
+			str[pos++] = '0';
+		
+		if ( flags & FLAG_FLOAT_EXPONENT )
+		{
+			str[pos++] = 'e';
+			str[pos++] = '+';
+			str[pos++] = '0';
+			str[pos++] = '0';
+			str[pos++] = '0';
+		}
+
+		return pos;
+	}
+	else if ( isnan( val ) )
+	{
+		str[pos++] = 'N';
+		str[pos++] = 'a';
+		str[pos++] = 'N';
+		return pos;
+	}
+	else if ( isinf( val ) )
+	{
+		str[pos++] = 'I';
+		str[pos++] = 'N';
+		str[pos++] = 'F';
+		return pos;
+	}
+	
+	// Impose a maximal amount before switching to exponent mode
+	if ( val >= FLOAT_NON_EXPONENT_MAX )
+		flags |= FLAG_FLOAT_EXPONENT;
+	
+	if ( val < 0.0 )
+		val = val - (display_precision * 0.5);
+	else
+		val = val + (display_precision * 0.5);
+
+	// Calculate magnitude!
+	int16_t magnitude = log10( val );
+
+	// Calculate round position
+	if ( flags & FLAG_FLOAT_EXPONENT )
+	{
+		double new_round_precision;
+	
+	 	int16_t round_position = magnitude - fraction_precision_digit_count;
+
+		if ( val < 1.0 )
+			new_round_precision = pow( 10, round_position-1 );
+		else
+			new_round_precision = pow( 10, round_position );
+
+		//if ( new_round_precision < display_precision )
+		display_precision = new_round_precision;
+	}	
+
+	// HANDLE negative
+	if ( val < 0.0 )
+	{
+		val = -val;
+		str[pos] = '-';
+		pos++;
+	}
+
+
+	// Will be set to magnitude on first digit...	
+	int16_t exponent_value = 0;
+
+	uint16_t fraction_count = 0;
+	int8_t is_fraction_digits = 0;
+
+	if ( val < display_precision )
+	{
+		str[pos++] = '0';
+		str[pos++] = '.';
+		
+		is_fraction_digits = 1;
+	} 
+	else if ( magnitude < 0 && val > display_precision && !(flags & FLAG_FLOAT_EXPONENT) )
+	{
+		str[pos++] = '0';
+		str[pos++] = '.';
+
+		int16_t temp_zero_count = magnitude;
+		while ( ++temp_zero_count < 0 )
+		{
+			str[pos++] = '0';
+			fraction_count++;
+		}
+		is_fraction_digits = 1;
+	}
+
+	while ( magnitude >= 0 || val > display_precision )
+	{
+		double divider = pow( 10.0, magnitude );
+
+		if ( divider > 0.0 && !isinf(divider) )
+		{
+			uint8_t digit = (uint8_t)floor( val / divider );
+			val -= ((double)digit * divider);
+
+			if ( flags & FLAG_FLOAT_EXPONENT && is_fraction_digits == 0 )
+			{
+				// First digit... print it followed by a decimal...
+				if ( exponent_value == 0 )
+					exponent_value = magnitude;
+				
+				if ( digit == 0 )
+					exponent_value--;
+				else
+				{
+					str[pos++] = '0' + digit;
+					str[pos++] = '.';
+
+					// Remember we are in fraction mode now (exponent mode) -- to terminate at display precision
+					is_fraction_digits = 1;
+				}
+			}
+			else
+			{
+				if ( magnitude < 0.0 && is_fraction_digits == 0 )
+				{
+					str[pos++] = '0';
+					str[pos++] = '.';
+
+					is_fraction_digits = 1;
+				}
+
+				str[pos++] = '0' + digit;
+
+				if ( is_fraction_digits )
+					fraction_count++;	
+			}
+		}
+
+		if ( magnitude == 0.0 && val > 0.0 && !(flags & FLAG_FLOAT_EXPONENT) )
+		{
+			str[pos++] = '.';
+
+			is_fraction_digits = 1;
+		}
+
+		if ( fraction_count >= fraction_precision_digit_count )
+			break;
+
+		magnitude--;
+	}
+
+	while ( is_fraction_digits && fraction_count < fraction_precision_digit_count )
+	{
+		// ADD 0's
+		str[pos++] = '0';
+		fraction_count++;
+	}
+
+	if ( (flags & FLAG_FLOAT_EXPONENT) )
+	{
+		// ADD exponent
+		str[pos++] = 'e';
+
+		if ( exponent_value < 0 )
+		{
+			exponent_value = -exponent_value;
+			str[pos++] = '-';
+		}
+		else
+			str[pos++] = '+';
+
+		if ( exponent_value == 0 )
+		{
+			for ( uint8_t i = 0; i < 3; i++ )
+				str[pos++] = '0';
+		}
+		else
+		{
+			uint8_t exponent_digit_count = 0;
+			uint16_t exponent_magnitude = log10( exponent_value );
+		
+			for ( uint8_t i = exponent_magnitude; i < 2; i++ )
+			{
+				str[pos++] = '0';
+				exponent_digit_count++;
+			}
+
+			while ( exponent_digit_count++ < 3 )
+			{
+				uint16_t exponent_divider = pow( 10, exponent_magnitude );
+
+				uint8_t exponent_digit = (exponent_value / exponent_divider);
+				str[pos++] = '0' + exponent_digit;
+
+				exponent_value -= (exponent_digit * exponent_divider) ;
+				exponent_magnitude--;
+			}	
+		}
+	}	
+
+	return (pos);	
+}
+
+size_t printf_helper_float( void *ctx, tPrintfWrapperFP fpOut, size_t pos, double val, int32_t width, int32_t precision, int32_t flags )
+{
+	size_t max_printlen = 0;
+	size_t pad_length = 0;
+	int8_t is_negative = 0;
+	size_t character_count = 0;
+	char temp_str[32];
+
+	if ( val < 0.0 )
+	{
+		val = -val;
+		is_negative = 1;
+
+		max_printlen++;
+	}
+
+	if ( precision == 0 )
+		character_count = printf_float_to_string( val, DEFAULT_FLOAT_PRECISION, temp_str, flags );
+	else
+		character_count = printf_float_to_string( val, precision, temp_str, flags );
+	
+	max_printlen += character_count;
+
+	if ( width > 0 )
+	{
+		if ( max_printlen < width )
+			pad_length = width-max_printlen;
+	}
+
+	if ( !(flags & FLAG_LEFT_JUSTIFY) )
+	{
+		if ( is_negative && pad_length > 0 && (flags & FLAG_ZERO_PAD) )
+		{
+			pos = (*fpOut)( ctx, '-', pos );
+			is_negative = 0;
+		}
+
+		while ( pad_length-- > 0 )
+		{
+			if ( (flags & FLAG_ZERO_PAD) )
+				pos = (*fpOut)( ctx, '0', pos );
+			else	
+				pos = (*fpOut)( ctx, ' ', pos );	
+		}
+	}
+
+	if ( is_negative )
+	{
+		pos = (*fpOut)( ctx, '-', pos );
+		is_negative = 0;
+	}
+
+	for ( size_t i = 0; i < character_count; i++ )	
+		pos = (*fpOut)( ctx, temp_str[i], pos );
+
+	if ( (flags & FLAG_LEFT_JUSTIFY) )
+	{
+		while ( pad_length-- > 0 )
+			pos = (*fpOut)( ctx, ' ', pos );
+	}
+
+	return (pos);
+}
+				
+size_t printf_helper_string( void *ctx, tPrintfWrapperFP fpOut, size_t pos, const char *outStr, int32_t width, int32_t precision, int32_t flags )
+{
+	if ( precision == 0 && width == 0 )
+	{
+		// Fast print
+		while ( *outStr != '\0' )
+		{
+			pos = (*fpOut)( ctx, *outStr, pos );
+			outStr++;
+		}
+
+		return (pos);
+	}
+
+	size_t max_printlen = strlen( outStr );
+	size_t pad_length = 0;
+
+	if ( precision > 0 )
+	{
+		if ( max_printlen > precision )
+			max_printlen = precision;
+	}
+
+	if ( width > 0 )
+	{
+		if ( max_printlen < width )
+			pad_length = width-max_printlen;
+	}
+
+	if ( !(flags & FLAG_LEFT_JUSTIFY) )
+	{
+		while ( pad_length-- > 0 )
+		{
+			if ( (flags & FLAG_ZERO_PAD) )
+				pos = (*fpOut)( ctx, '0', pos );
+			else	
+				pos = (*fpOut)( ctx, ' ', pos );	
+		}
+	}
+
+	// Output string up to maxlength
+	while ( max_printlen-- > 0 )
+		pos = (*fpOut)( ctx, *outStr++, pos );
+
+	if ( (flags & FLAG_LEFT_JUSTIFY) )
+	{
+		while ( pad_length-- > 0 )
+			pos = (*fpOut)( ctx, ' ', pos );
+	}
+
+	return pos;	
+}
+
+int cgc_wrapper_output( void *ctx, tPrintfWrapperFP fpOut, size_t pos, const char *format, va_list args )
+{
+
+	int32_t flags = 0;
+	int32_t width = 0;
+	int32_t pad_length = 0;
+	int32_t precision = 0;
+
+	while ( *format != '\0' )
+	{
+		char curChar = *format;
+		format++;
+
+		if ( curChar == '$' )
+		{
+			flags = width = pad_length = precision = 0;
+
+			if ( *format == '\0' )
+				break;
+
+			if ( *format == '$' )
+			{
+				// Emit %
+				pos = (*fpOut)( ctx, '$', pos );
+				continue;
+			}
+
+			if ( *format == '-' )
+			{
+				flags |= FLAG_LEFT_JUSTIFY;
+
+				format++;
+
+				if ( *format == '\0' )
+					break;
+			}
+
+			// Check width
+			if ( isdigit( *format ) )
+			{
+				if ( *format == '0' )
+					flags |= FLAG_ZERO_PAD;
+
+				const char *startpos = format;
+				while ( isdigit( *format ) )
+					format++;
+
+				width = atoi( startpos );
+
+				if ( *format == '\0' )
+					break;
+			}
+
+			// Check precision
+			if ( *format == '.' )
+			{
+				format++;
+				
+				if ( *format == '\0' )
+					break;
+
+				const char *startpos = format;
+				while ( isdigit( *format ) )
+					format++;
+
+				precision = atoi( startpos );
+
+				if ( *format == '\0' )
+					break;
+			}
+
+			switch ( *format )
+			{
+			case 's':
+				{
+					// String
+					const char *print_str = va_arg( args, char * );
+					pos = printf_helper_string( ctx, fpOut, pos, print_str, width, precision, flags );
+				}
+				break;
+
+			case 'd':
+				{
+					// Print integer
+					int32_t print_int = va_arg( args, int32_t );
+					pos = printf_helper_int( ctx, fpOut, pos, print_int, 10, width, precision, flags );	
+				}
+				break;
+
+			case 'x':
+				{
+					// Print hex (lower case)
+					int32_t print_int = va_arg( args, int32_t );
+					pos = printf_helper_int( ctx, fpOut, pos, print_int, 16, width, precision, flags );
+				}
+				break;
+
+			case 'X':
+				{
+					// Print hex (upper case)
+					flags |= FLAG_HEX_UPPERCASE;
+
+					int32_t print_int = va_arg( args, int32_t );
+					pos = printf_helper_int( ctx, fpOut, pos, print_int, 16, width, precision, flags );
+				}
+				break;
+
+			case 'f':
+				{
+					// Print float
+					double print_float = va_arg( args, double );
+					pos = printf_helper_float( ctx, fpOut, pos, print_float, width, precision, flags );	
+				}
+				break;
+
+			case 'e':
+				{
+					// Print float -- force exponent mode
+					flags |= FLAG_FLOAT_EXPONENT;
+
+					double print_float = va_arg( args, double );
+					pos = printf_helper_float( ctx, fpOut, pos, print_float, width, precision, flags );
+				}
+				break;
+
+			case 'n':
+				{
+					int32_t *signed_int_p = va_arg( args, int32_t* );
+
+					(*signed_int_p) = pos;
+				}
+				break;
+
+			case 'c':
+				{
+					// Print single char
+					char char_arg = (char )va_arg( args, int );	
+				
+					char temp_str[2];
+					temp_str[0] = char_arg;
+					temp_str[1] = '\0';
+
+					pos = printf_helper_string( ctx, fpOut, pos, temp_str, width, 0, flags );
+				}
+				break;
+
+			default:
+				// Unsupported
+				break;
+			}
+
+			format++;	
+		}
+		else
+			pos = (*fpOut)( ctx, curChar, pos );
+	}
+
+	return (pos);
+}
diff --git a/cgc-challenges/Monster_Game/lib/stdlib.c b/cgc-challenges/Monster_Game/lib/stdlib.c
new file mode 100644
index 0000000000000000000000000000000000000000..73fdfdabed8b1d84ed65ee1352e686b391e399f9
--- /dev/null
+++ b/cgc-challenges/Monster_Game/lib/stdlib.c
@@ -0,0 +1,256 @@
+/*
+
+Copyright (c) 2015 Cromulence LLC
+
+Authors: Cromulence <cgc@cromulence.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+#include "cgc_stdint.h"
+
+
+#include "cgc_prng.h"
+
+//#define LONG_MIN (0x80000000L)
+//#define LONG_MAX (0x7FFFFFFFL)
+#include "common.h"
+
+int cgc_rand( void )
+{
+	return (cgc_random_in_range( 0, RAND_MAX-1 ));
+}
+
+void cgc_srand( unsigned int seed )
+{
+	cgc_seed_prng( seed );
+}
+
+int atoi( const char *pStr )
+{
+	int value = 0;
+	int negative = 0;
+
+	while ( isspace( *pStr ) )
+		pStr++;
+
+	if ( *pStr == '\0' )
+		return 0;
+
+	if ( *pStr == '-' )
+	{
+		negative = 1;
+		pStr++;
+	}
+
+	// Read in string
+	while ( isdigit( *pStr ) )
+		value = (value * 10) + (*pStr++ - '0');
+
+	if ( negative )
+		return (-value);
+	else
+		return value;	
+}
+
+double cgc_atof( char *pStr )
+{
+	double whole;
+	double fraction = 0.0;
+	char *pWhole = pStr;
+	char *pFraction;
+	
+	// find the decimal point
+	pFraction = pStr;
+	while ( *pFraction != '\0' ) 
+	{
+		if (*pFraction == '.')
+		{
+			*pFraction = '\0';
+			pFraction++;
+			break;
+		}
+		pFraction++;
+	}
+	
+	// convert the whole part
+	whole = atoi(pWhole);
+
+	// convert the fractional part
+	if (*pFraction != '\0') {
+		fraction = atoi(pFraction);
+		while ( pFraction != '\0' && isdigit( *pFraction ) ) {
+			fraction /= 10.0;
+			pFraction++;
+		}
+	}
+
+	return ( whole + fraction );
+	
+}
+	
+
+char *strcpy( char *pDest, const char *pSrc )
+{
+	char *pDestReturn = pDest;
+
+	while ( *pSrc != '\0' )
+		*pDest++ = *pSrc++;
+
+	*pDest = '\0'; 
+
+	return (pDestReturn);
+}
+
+char *strncpy( char *pDest, const char *pSrc, size_t maxlen )
+{
+	size_t n;
+
+	for ( n = 0; n < maxlen; n++ )
+	{
+		if ( pSrc[n] == '\0' )
+			break;
+
+		pDest[n] = pSrc[n];
+	}
+
+	for ( ; n < maxlen; n++ )
+		pDest[n] = '\0';
+
+	return (pDest);
+}
+
+void *memcpy( void *pDest, const void *pSource, size_t nbytes )
+{
+	void *pDestReturn = pDest;
+
+	while ( nbytes >= 4 )
+	{
+		*((uint32_t*)pDest) = *((uint32_t*)pSource);
+
+		pDest += 4;
+		pSource += 4;
+		nbytes-=4;		
+	}
+
+	while ( nbytes > 0 )
+	{
+		*((uint8_t*)pDest) = *((uint8_t*)pSource);
+
+		pDest++;
+		pSource++;
+		nbytes--;
+	}
+
+	return (pDestReturn);
+}
+
+long int strtol( const char *str, char **endptr, int base )
+{
+	long int value = 0;
+	int neg = 0;
+
+	if ( str == NULL )
+		return (0);
+
+	if ( base >= 16 )
+		base = 16;
+
+	// Skip whitespace	
+	while ( isspace( *str ) )
+		str++;
+
+	if ( *str == '-' )
+	{
+		neg = 1;
+		str++;
+	}
+	else if ( *str == '+' )
+		str++;
+
+	if ( (base == 16 || base == 0) && *str == '0' && (*(str+1) == 'x' || *(str+1) == 'X') )
+	{
+		str+=2;
+		base = 16;
+	}
+	else if ( (base == 0 || base == 2 ) && *str == '0' && (*(str+1) == 'b' || *(str+1) == 'B') )
+	{
+		str+=2;
+		base = 2;
+	}
+
+	if ( base == 0 )
+	{
+		if ( *str == '0' )
+		{
+			base = 8;
+		}
+		else
+			base = 10;
+	}
+
+	unsigned long cutoff_value = 0;
+	if ( neg )
+		cutoff_value = -(unsigned long)LONG_MIN;
+	else
+		cutoff_value = (unsigned long)LONG_MAX;
+	long int cutlim_value = cutoff_value % (unsigned long)base;
+	
+	cutoff_value /= base;
+
+	while ( *str != '\0' )
+	{
+		int c = *str;
+
+		if ( isdigit( c ) )
+			c -= '0';
+		else if ( isalpha(c) )
+		{
+			if ( isupper(c) )
+				c -= ('A' - 10);
+			else
+				c -= ('a' - 10);
+		}
+		else
+			break;
+	
+		if ( c >= base )
+			break;
+
+		if ( value > cutoff_value || (value == cutoff_value && c > cutlim_value) )
+			break;
+		else
+		{
+			value *= base;
+			value += c;
+		}
+
+		str++;	
+	}
+
+	// Check if we should set endptr
+	if ( endptr )
+		*endptr = (char *)str;
+
+	if ( neg )
+		return -value;
+	else
+		return value;	
+}
diff --git a/cgc-challenges/Monster_Game/service.c b/cgc-challenges/Monster_Game/service.c
new file mode 100644
index 0000000000000000000000000000000000000000..07e7cf1a1e92d5e3942e6cf874ef234a6a877791
--- /dev/null
+++ b/cgc-challenges/Monster_Game/service.c
@@ -0,0 +1,1200 @@
+#include "libcgc.h"
+
+#include "cgc_stdio.h"
+
+#include "malloc.h"
+#include "cgc_monster_names.h"
+
+#define TREE 	'#'
+#define EXIT 	'X'
+#define PERSON	'@'
+#define MAX_MONSTER_LIFE	10
+#define MAX_MONSTER_POWER	6
+#define MAX_CAPTURE		5
+
+typedef struct queue {
+	size_t x;
+	size_t y;
+	struct queue *next;
+} queue, *pqueue;
+
+typedef struct map {
+	size_t width;
+	size_t height;
+	size_t start_x;
+	size_t start_y;
+	size_t end_x;
+	size_t end_y;
+
+	size_t current_x;
+	size_t current_y;
+
+	/// Last x where a marker was placed. Used to reverse on failure
+	size_t last_x;
+
+	/// Last y where a marker was placed
+	size_t last_y;
+
+	/// Map data
+	char *data;
+} map, *pmap;
+
+typedef struct monster {
+	char *type;
+	int health;
+	size_t hitpoints;
+	size_t power;
+	size_t experience;
+	size_t level;
+} monster, *pmonster;
+
+typedef struct player {
+	char name[16];
+	size_t level;
+	size_t mcnt;
+	pmonster mons[MAX_CAPTURE];
+} player, *pplayer;
+
+/// Index to use for the secret page
+size_t cgc_page_index = 0;
+unsigned char *secret_page;
+
+/// queue list
+pqueue root;
+
+char *queue_matrix;
+
+/// Variables for the easter egg
+char easteregg[] = "easta egg";
+size_t eggindex;
+
+pmonster cgc_generate_monster( void );
+char *cgc_select_name( void );
+
+void cgc_check_egg( pplayer pp, char c ) {
+	if ( easteregg[ eggindex ] == c ) {
+		eggindex += 1;
+	} else { 
+		eggindex = 0;
+	}
+
+	if ( easteregg[eggindex] == 0 ) {
+		printf("YOU FOUND THE EGG!!!! Have a prize.\n");
+		pp->mons[0]->hitpoints = 99;
+		pp->mons[0]->health = 99;
+		pp->mons[0]->power = 99;
+
+		eggindex = 0;
+	}
+
+	return;
+}
+
+size_t cgc_read_line( char *outbuf, size_t length )
+{
+	char c = '\0';
+	size_t index = 0;
+	size_t rx_bytes = 0;
+
+	if ( outbuf == NULL ) {
+		printf("[ERROR] invalid arg\n");
+		cgc__terminate(-1);
+		return 0;
+	}
+
+	while ( index < length && c != '\n') {
+		if ( cgc_receive( STDIN, &c, 1, &rx_bytes) != 0 ) {
+			printf("[ERROR] Failed to read byte\n");
+			cgc__terminate(-3);
+		}
+
+		if ( rx_bytes == 0 ) {
+			printf("[ERROR] Error in receive\n");
+			cgc__terminate(-4);
+		}
+
+		if ( c == '\n') {
+			return index;
+		}
+
+		outbuf[index] = c;
+		index++;
+	}
+
+	return index;
+}
+
+size_t cgc_read_line_u( char *outbuf )
+{
+	char c = '\0';
+	size_t index = 0;
+	size_t rx_bytes = 0;
+
+	if ( outbuf == NULL ) {
+		return 0;
+	}
+
+	while ( c != '\n' ) {
+		if ( cgc_receive( STDIN, &c, 1, &rx_bytes) != 0 ) {
+			printf("[ERROR] Failed to read byte\n");
+			cgc__terminate(0);
+		}
+
+		if ( rx_bytes == 0 ) {
+			printf("[ERROR] Error in receive\n");
+			cgc__terminate(0);
+		}
+
+		if ( c == '\n') {
+			continue;
+		}
+
+		outbuf[index] = c;
+		index++;
+	}
+
+	return index;
+}
+
+void cgc_add_queue( size_t x, size_t y, size_t max_x, size_t max_y )
+{
+	pqueue pq = NULL;
+	pqueue walker = NULL;
+	size_t index = ( (max_x+1) * y ) + x;
+
+	/// If it has already been queued then don't requeue it
+	if ( queue_matrix[index] == 1 ) {
+		return;
+	}
+
+	pq = malloc( sizeof(queue) );
+
+	if ( pq == NULL ) {
+		printf("[ERROR] malloc() queue structure failed.\n");
+		cgc__terminate(-1);
+	}
+
+	bzero( pq, sizeof( queue ) );
+
+	pq->x = x;
+	pq->y = y;
+
+	// base case
+	if ( root == NULL ) {
+		root = pq;
+	} else {
+		walker = root;
+
+		while ( walker->next != NULL ) {
+			walker = walker->next;
+		}
+
+		walker->next = pq;
+	}
+
+	queue_matrix[index] = 1;
+
+	return;
+}
+
+pqueue cgc_dequeue( )
+{
+	pqueue pq = root;
+
+	if ( root != NULL ) {
+		root = root->next;
+	}
+
+	return pq;
+}
+
+/// Determine if they are adjacent
+int cgc_check_adjacent( sx, sy, dx, dy )
+{
+	if ( sx == dx ) {
+		if ( (( sy + 1 ) == dy) || ( (sy - 1 ) == dy ) ) {
+			return 1;
+		}
+	} else if ( sy == dy ) {
+		if ( (( sx + 1 ) == dx) || ( (sx - 1 ) == dx ) ) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+void cgc_print_map( pmap pm )
+{
+	size_t index;
+	size_t max;
+	size_t map_index = 0;
+
+	char *data = NULL;
+
+	index = 0;
+	max = pm->height * pm->width;
+
+	/// 1 byte for each block, height bytes for the new lines 1 byte for the NULL
+	data = malloc( max + pm->height + 1 );
+
+	if ( data == NULL ) {
+		printf("[ERROR] Failed to allocate map.\n");
+		cgc__terminate(-5);
+	}
+
+	bzero( data, max + pm->height + 1);
+
+	while ( index < max ) {
+		if ( 0 < index && (index % pm->width)==0 ) {
+			data[map_index++] = '\n';
+		}
+
+		if ( pm->data[index] == '\0') {
+			data[map_index] = '.';
+		} else {
+			data[map_index] = pm->data[index];
+		}
+
+		index++;
+		map_index++;
+	}
+
+	data[map_index] = '\n';
+	
+	printf("%s", data);
+
+	free(data);
+
+}
+
+/// Algorithm
+/// Given source(x,y) and dest(x,y) does there exist a path between the two
+/// Returns 0 if a path does not exist and 1 if it does
+
+/*@
+  assigns \result \from sx, sy, pm, *pm;
+  ensures \result == 0 || \result == 1;
+ */
+size_t cgc_find_path( size_t sx, size_t sy, pmap pm)
+{
+	pqueue pq = NULL;
+	size_t retval = 0;
+
+	if ( pm == NULL ) {
+		return 0;
+	}
+
+	/// Look up, down, left, right if destination is adjacent then success
+	if ( cgc_check_adjacent( sx, sy, pm->end_x, pm->end_y ) == 1 ) {
+		return 1;
+	}
+
+	/// Else queue up, down, left, right
+
+	// Up
+	if ( sy > 0 ) {
+		cgc_add_queue( sx, sy - 1, pm->width-1, pm->height-1 );
+	}
+	
+	// Right
+	if ( sx < pm->width-1 ) {
+		cgc_add_queue( sx + 1, sy, pm->width-1, pm->height-1 );
+	}
+
+	// Down
+	if ( sy < pm->height-1 ) {
+		cgc_add_queue( sx, sy + 1, pm->width-1, pm->height-1);
+	}
+
+	// Left
+	if ( sx > 0 ) {
+		cgc_add_queue( sx - 1, sy, pm->width-1, pm->height-1 );
+	}
+
+	pq = cgc_dequeue();
+
+	while ( pq != NULL ) {
+		retval = cgc_find_path( pq->x, pq->y, pm);
+
+		if ( retval == 1 ) {
+			free(pq);
+			return 1;
+		} else {
+			free(pq);
+			pq = cgc_dequeue();
+		}
+	}
+
+	return 0;
+}
+
+void cgc_update_page_index( )
+{
+	cgc_page_index += 3;
+
+	cgc_page_index = cgc_page_index % 0x1000;
+	return;
+}
+
+void cgc_place_marker( pmap pm )
+{
+	size_t index = 0;
+	size_t count = 0;
+	size_t max = 0;
+
+	pm->last_x = secret_page[ cgc_page_index ] % pm->width;
+	cgc_update_page_index();
+
+	pm->last_y = secret_page[ cgc_page_index ] % pm->height;
+	cgc_update_page_index();
+
+	index = ( pm->width * pm->last_y ) + pm->last_x;
+
+	while ( pm->data[index] != '\0' && count < 100 ) {
+		pm->last_x = secret_page[ cgc_page_index ] % pm->width;
+		cgc_update_page_index();
+
+		pm->last_y = secret_page[ cgc_page_index ] % pm->height;
+		cgc_update_page_index();
+
+		index = ( pm->width * pm->last_y ) + pm->last_x;
+
+		count++;
+	}
+
+	max = pm->width * pm->height;
+
+	/// Just loop until one is found
+	if ( count == 100 ) {
+		index = 0;
+
+		while ( pm->data[index] != '\0' && index < max ) {
+			index++;
+		}
+
+		if ( index == max ) {
+			printf("FAILED\n");
+			cgc_print_map( pm );
+			cgc__terminate(0);
+		}
+
+		pm->last_y = index / pm->width;
+		pm->last_x = index % pm->width;
+	}
+
+	pm->data[index] = '#';
+
+	return;
+}
+
+void cgc_set_marker( size_t x, size_t y, pmap pm, char c )
+{
+	size_t index = ( (pm->width) * y ) + x;
+
+	pm->data[index] = c;
+}
+
+/// Clear the map data
+/// Select the start and end coords and place them on the map
+void cgc_initialize_map( pmap pm )
+{
+	if ( pm == NULL ) {
+		printf("[ERROR] initialize_map() invalid argumenet.\n");
+		cgc__terminate(0);
+	}
+
+	pm->data = malloc( pm->width * pm->height );
+
+	if ( pm->data == NULL ) {
+		printf("[ERROR] Failed to allocate map.\n");
+		cgc__terminate(0);
+	}
+
+	bzero( pm->data, pm->width * pm->height);
+
+	pm->start_x = 0;
+	pm->start_y = 0;
+	pm->end_x = 0;
+	pm->end_y = 0;
+
+	while ( (pm->start_x==pm->end_x) || ( pm->start_x-1 == pm->end_x) || (pm->start_x+1 == pm->end_x)
+				|| (pm->start_y == pm->end_y) || ( pm->start_y+1 == pm->end_y) || (pm->start_y - 1 == pm->end_y) ) {
+
+		/// Decide on the start and the end position
+		pm->start_x = secret_page[cgc_page_index] % pm->width;
+		cgc_update_page_index();
+
+		pm->start_y = secret_page[cgc_page_index] % pm->height;
+		cgc_update_page_index();
+
+		pm->end_x = secret_page[cgc_page_index] % pm->width;
+		cgc_update_page_index();
+
+		pm->end_y = secret_page[cgc_page_index] % pm->height;
+		cgc_update_page_index();
+	}
+
+	cgc_set_marker( pm->start_x, pm->start_y, pm, PERSON);
+	cgc_set_marker( pm->end_x, pm->end_y, pm, EXIT);
+
+	pm->current_x = pm->start_x;
+	pm->current_y = pm->start_y;
+
+	return;
+}
+
+/// Initialize the queue matrix
+void cgc_initialize_queue_matrix( pmap pm )
+{
+	size_t index;
+
+	if (queue_matrix != NULL ) {
+		free( queue_matrix);
+	}
+
+	queue_matrix = malloc( pm->width * pm->height );
+
+	if ( queue_matrix == NULL ) {
+		printf("[ERROR] Failed to allocate queue matrix\n");
+		cgc__terminate(0);
+	}
+
+	bzero( queue_matrix, pm->width * pm->height );
+
+	/// If the map contains an obstruction then mirror that in the matrix
+	for ( index = 0; index < pm->width * pm->height; index ++ ) {
+		if ( pm->data[index] != 0x00 ) {
+			queue_matrix[index] = 1;
+		}
+	}
+
+	return;
+}
+
+pmap cgc_generate_map( size_t width, size_t height )
+{
+	pmap pm = NULL;
+	pqueue t = NULL;
+	size_t start_x = 0;
+	size_t start_y = 0;
+
+	size_t end_x = 0;
+	size_t end_y = 0;
+	size_t success = 1;
+
+	pm = malloc( sizeof(map) );
+
+	if ( pm == NULL ) {
+		printf("[ERROR] Failed to allocate map strucure\n");
+		cgc__terminate(0);
+	}
+
+	bzero( pm, sizeof(map) );
+
+	pm->height = height;
+	pm->width = width;
+
+	cgc_initialize_map ( pm );
+
+	printf("Width: %zu Height: %zu\nStartX: %zu StartY: %zu\nEndX: %zu EndY: %zu\n\n", width, height, pm->start_x, pm->start_y, pm->end_x, pm->end_y);
+
+	while ( success) {
+
+		/// place a new marker
+		cgc_place_marker(pm);
+
+		/// Initialize a new queue matrix
+		cgc_initialize_queue_matrix( pm );
+
+		if ( cgc_find_path( pm->start_x, pm->start_y, pm) != 1 ) {
+			/// Reverse the last marker
+			pm->data[ ( pm->width * pm->last_y) + pm->last_x ]  = 0x00;
+
+			success = 0;
+		}
+
+		/// Free any remaining queue structures
+		while ( root ) {
+			t = root;
+			root = root->next;
+
+			free ( t );
+		}
+
+		root = NULL;
+
+	}
+
+	/// Free the matrix
+	free( queue_matrix );
+
+	cgc_print_map( pm );
+	
+
+	return pm;
+}
+
+pmonster cgc_select_monster( pplayer pp )
+{
+	size_t index;
+	size_t choice = 0;
+	size_t success = 0;
+
+	int ac = 0;
+
+	if ( pp == NULL ) {
+		return NULL;
+	}
+
+	for ( index = 0; index < pp->mcnt; index++ ) {
+		if ( pp->mons[index]->health > 0 ) {
+			success = 1;
+		}
+	}
+
+	if ( success == 0 ) {
+		return NULL;
+	}
+
+	success = 0;
+
+	printf("Monsters: \n");
+	for ( index = 0; index < pp->mcnt; index++ ) {
+		printf("\t%zu} \n", index+1);
+		printf("\tType: %s\n", pp->mons[index]->type);
+		printf("\tLevel: %zu\n", pp->mons[index]->level);
+		printf("\tHealth: %d\n", pp->mons[index]->health);
+		printf("\tPower: %zu\n\n", pp->mons[index]->power);
+	}
+
+	while ( !success ) {
+		printf("Selection: ");
+
+		choice = 0;
+		cgc_read_line( (char*)&choice, 2);
+
+		ac = atoi( (char*)&choice );
+
+		if ( ac <= 0 || ac > pp->mcnt ) {
+			printf("bad choice: %x\n", choice);
+		} else if ( pp->mons[ac-1] == NULL ) {
+			printf("bad choice: %x\n", choice);
+		} else if ( pp->mons[ac-1]->health <= 0 ) {
+			printf("he dead\n");
+		} else {
+			success = 1;
+		}
+	}
+
+	return pp->mons[ac-1];
+}
+
+void cgc_reset_monsters( pplayer pp )
+{
+	size_t index = 0;
+
+	if ( pp == NULL ) {
+		return;
+	}
+
+	/// Reset the hit points of each monster
+	for ( index = 0; index < pp->mcnt; index++ ) {
+		pp->mons[index]->health = pp->mons[index]->hitpoints;
+	}
+
+
+	return;
+}
+
+void cgc_print_monster( pmonster pm )
+{
+	if ( pm == NULL ) {
+		return;
+	}
+
+	printf("\tType: %s\n", pm->type);
+	printf("\tLevel: %zu\n", pm->level);
+	printf("\tHealth: %d\n", pm->health);
+	printf("\tHit Points: %zu\n", pm->hitpoints);
+	printf("\tPower: %zu\n\n", pm->power);
+
+	return;
+}
+
+int cgc_oneup_monster( pmonster pm )
+{
+	if ( pm == NULL ) {
+		return 0;
+	}
+
+	pm->experience += 1;
+
+	if ( (pm->experience % 15) == 0 ) {
+		printf("%s gained a level\n", pm->type);
+		pm->hitpoints += 1;
+		pm->power += 1;
+		pm->health = pm->hitpoints;
+		pm->level += 1;
+
+		pm->experience = 0;
+	}
+
+	return 1;
+}
+
+pmonster cgc_generate_boss( )
+{
+	pmonster pm = NULL;
+
+	pm = malloc( sizeof(monster) );
+
+	if ( pm == NULL ) {
+		printf("[ERROR] Failed to allocate boss monster structure\n");
+		cgc__terminate(0);
+	}
+
+	bzero( pm, sizeof( monster ) );
+
+	pm->type = cgc_select_name();
+
+	/// Minimum life 4
+	pm->health = (secret_page[ cgc_page_index ] % MAX_MONSTER_LIFE+5) + 4;
+	pm->hitpoints = pm->health;
+	cgc_update_page_index();
+
+	// Minimum power 2
+	pm->power = (secret_page[cgc_page_index] % MAX_MONSTER_POWER+2) + 2;
+	cgc_update_page_index();
+
+	pm->level = 4;
+
+	return pm;
+}
+
+int cgc_change_monster_name( pmonster pm )
+{
+	char new_name[32];
+	size_t index = 0;
+	char *final = NULL;
+
+	bzero( new_name, 32);
+
+	printf("New name: ");
+#ifdef PATCHED_1
+	index = cgc_read_line( new_name, 31 );
+#else
+	index = cgc_read_line_u( new_name );
+#endif
+
+	final = malloc( index + 1 );
+
+	if ( final == NULL ) {
+		printf("[ERROR] Failed to malloc name buffer\n");
+		cgc__terminate(0);
+	}
+
+	bzero( final, index+1);
+	memcpy( final, new_name, index );
+
+	pm->type = final;
+
+	return 1;
+}
+
+int cgc_capture_boss( pmonster pm, pplayer pp )
+{
+	char sel[3];
+	size_t choice = 0;
+
+	if ( pm == NULL || pp == NULL ) {
+		return 0;
+	}
+
+	printf("capture monster? (y\\n): ");
+
+	bzero( sel, 3 );
+
+	cgc_read_line( sel, 2);
+
+	if ( sel[0] != 'y' ) {
+		free(pm);
+		return 0;
+	}
+
+	printf("update boss name? (y\\n): ");
+	bzero( sel, 3 );
+	cgc_read_line( sel, 2 );
+
+	if ( sel[0] == 'y') {
+		cgc_change_monster_name( pm );
+	}
+
+	if ( pp->mcnt < MAX_CAPTURE ) {
+		pp->mons[ pp->mcnt++] = pm;
+		return 1;
+	}
+
+	printf("your cart is full.\n");
+	for ( choice = 0; choice < MAX_CAPTURE; choice++ ) {
+		printf("%zu} \n", choice+1);
+		cgc_print_monster(pp->mons[choice]);
+	}
+
+	printf("*********************************\n");
+	/// Reset the health before printing.
+	pm->health = pm->hitpoints;
+	cgc_print_monster( pm);
+	printf("*********************************\n");
+
+	printf("replace one of yours? (y\\n): ");
+	bzero(sel, 3);
+	cgc_read_line( sel, 2 );
+
+	if ( sel[0] != 'y') {
+		free(pm);
+		return 0;
+	}
+
+	bzero(sel, 3 );
+	printf("which one: ");
+	cgc_read_line( sel, 3);
+
+	choice = atoi( sel );
+
+	if ( choice <= 0 || choice > MAX_CAPTURE ) {
+		printf("invalid\n");
+		free( pm );
+		return 0;
+	}
+
+	free( pp->mons[choice-1]);
+	pp->mons[choice-1] = pm;
+
+	return 1;
+}
+
+int cgc_daboss( pplayer pp )
+{
+	pmonster boss = NULL;
+	pmonster player_current = NULL;
+	size_t player_hit;
+	size_t target_hit;
+
+	if ( pp == NULL ) {
+		return 0;
+	}
+
+	boss = cgc_generate_boss( );
+	cgc_reset_monsters( pp );
+
+	printf("\nDUN DUN DUUUUUUUUUUUUUUN\n");
+	printf("You have reached the boss!!!!!\n\n");
+	cgc_print_monster( boss );
+
+	while ( boss->health > 0 ) {
+		player_current = cgc_select_monster(pp);
+
+		if ( player_current == NULL ) {
+			printf("You have no living monsters. You lose.\n");
+			return 0;
+		}
+
+		player_hit = secret_page[cgc_page_index] % player_current->power;
+		cgc_update_page_index();
+
+		boss->health -= player_hit;
+		printf("You hit for %zu. %d left\n", player_hit, boss->health);
+
+		cgc_oneup_monster( player_current );
+
+		if ( boss->health <= 0 ) {
+			printf("You destroyed the boss!!!!\n");
+			cgc_reset_monsters(pp);
+			cgc_capture_boss( boss, pp);
+			return 1;
+		}
+
+		target_hit = secret_page[cgc_page_index] % boss->power;
+		cgc_update_page_index();
+
+		printf("%s hits %s for %zu\n", boss->type, player_current->type, target_hit);
+
+		player_current->health -= target_hit;
+
+		if ( player_current->health <= 0 ) {
+			printf("%s was knocked out\n", player_current->type);
+		}
+
+	}
+	return 1;
+}
+
+int cgc_capture_monster( pmonster pm, pplayer pp )
+{
+	char sel[3];
+	size_t choice = 0;
+
+	if ( pm == NULL || pp == NULL ) {
+		return 0;
+	}
+
+	printf("capture monster? (y\\n): ");
+
+	bzero( sel, 3 );
+
+	cgc_read_line( sel, 2);
+
+	if ( sel[0] != 'y' ) {
+		free(pm);
+		return 0;
+	}
+
+	if ( pp->mcnt < MAX_CAPTURE ) {
+		pp->mons[ pp->mcnt++] = pm;
+		return 1;
+	}
+
+	printf("your cart is full.\n");
+	for ( choice = 0; choice < MAX_CAPTURE; choice++ ) {
+		printf("%zu} \n", choice+1);
+		cgc_print_monster(pp->mons[choice]);
+	}
+
+	printf("*********************************\n");
+	/// Reset the health before printing.
+	cgc_print_monster( pm);
+	printf("*********************************\n");
+
+	printf("replace one of yours? (y\\n): ");
+	bzero(sel, 3);
+	cgc_read_line( sel, 2 );
+
+	if ( sel[0] != 'y') {
+		free(pm);
+		return 0;
+	}
+
+	bzero(sel, 3 );
+	printf("which one: ");
+	cgc_read_line( sel, 3);
+
+	choice = atoi( sel );
+
+	if ( choice <= 0 || choice > MAX_CAPTURE ) {
+		printf("invalid\n");
+		free( pm );
+		return 0;
+	}
+
+	free( pp->mons[choice-1]);
+	pp->mons[choice-1] = pm;
+
+	return 1;
+}
+
+int cgc_fight ( pplayer pp )
+{
+	pmonster pm = NULL;
+	pmonster player_current = NULL;
+	size_t target_hit = 0;
+	size_t player_hit = 0;
+
+	if ( pp == NULL ) {
+		return 0;
+	}
+
+	cgc_reset_monsters( pp );
+
+	pm = cgc_generate_monster();
+
+	printf("You are being attacked!!!\n");
+	cgc_print_monster( pm );
+
+
+	while ( pm->health > 0 ) {
+		player_current = cgc_select_monster(pp);
+
+		if ( player_current == NULL ) {
+			printf("You have no living monsters. You lose.\n");
+			return 0;
+		}
+
+		player_hit = secret_page[cgc_page_index] % player_current->power;
+		cgc_update_page_index();
+
+		pm->health -= player_hit;
+		printf("You hit for %zu. %d left\n", player_hit, pm->health);
+
+		cgc_oneup_monster( player_current );
+
+		if ( pm->health <= 0 ) {
+			printf("You knocked out %s\n", pm->type);
+			cgc_reset_monsters(pp);
+			cgc_capture_monster( pm, pp);
+			return 1;
+		}
+
+		target_hit = secret_page[cgc_page_index] % pm->power;
+		cgc_update_page_index();
+
+		printf("%s hits %s for %zu\n", pm->type, player_current->type, target_hit);
+
+		player_current->health -= target_hit;
+
+		if ( player_current->health <= 0 ) {
+			printf("%s was knocked out\n", player_current->type);
+		}
+
+	}
+
+	return 1;
+}
+
+int cgc_movement_loop( pmap pm, pplayer pp ) 
+{
+	size_t success = 0;
+	char movement[2];
+	size_t rx_bytes;
+
+	if ( pm == NULL ) {
+		return 0;
+	}
+
+	while ( success == 0 ) {
+		bzero( movement, 2 );
+
+		printf(": ");
+		rx_bytes = cgc_read_line( movement, 2 );
+
+		if ( rx_bytes == 0 ) {
+			printf("[ERROR] Failed to receive movement byte\n");
+			cgc__terminate(-2);
+		}
+
+		cgc_check_egg( pp, movement[0]);
+
+		switch ( movement[0] ) {
+			case 'u':
+				/// Check for the edge of the board
+				if ( pm->current_y == 0 ) {
+					printf("off map\n");
+				} else if ( pm->data[ (pm->width * (pm->current_y-1)) + pm->current_x] == '#') {
+					printf("blocked\n");
+				} else {
+					cgc_set_marker( pm->current_x, pm->current_y, pm, '\0');
+					pm->current_y -= 1;
+					cgc_set_marker( pm->current_x, pm->current_y, pm, PERSON);
+				}
+				break;
+			case 'd':
+				if ( pm->current_y == pm->height-1 ) {
+					printf("off map\n");
+				} else if ( pm->data[ (pm->width * (pm->current_y+1)) + pm->current_x] == '#') {
+					printf("blocked\n");
+				} else {
+					cgc_set_marker( pm->current_x, pm->current_y, pm, '\0');
+					pm->current_y += 1;
+					cgc_set_marker( pm->current_x, pm->current_y, pm, PERSON);
+				}
+				break;
+			case 'l':
+				if ( pm->current_x == 0 ) {
+					printf("off map\n");
+				} else if ( pm->data[ (pm->width * (pm->current_y)) + pm->current_x-1] == '#') {
+					printf("blocked\n");
+				} else {
+					cgc_set_marker( pm->current_x, pm->current_y, pm, '\0');
+					pm->current_x -= 1;
+					cgc_set_marker( pm->current_x, pm->current_y, pm, PERSON);
+				}
+				break;
+			case 'r':
+				if ( pm->current_x == pm->width-1 ) {
+					printf("off map\n");
+				} else if ( pm->data[ (pm->width * (pm->current_y)) + pm->current_x+1] == '#') {
+					printf("blocked\n");
+				} else {
+					cgc_set_marker( pm->current_x, pm->current_y, pm, '\0');
+					pm->current_x += 1;
+					cgc_set_marker( pm->current_x, pm->current_y, pm, PERSON);
+				}
+				break;
+			default:
+				printf("[ERROR] Invalid direction:%d\n", movement[0]);
+				continue;
+		};
+
+		cgc_print_map( pm );
+
+		if ( pm->current_y == pm->end_y && pm->current_x == pm->end_x ) {
+			//// Fight main boss
+			printf("reached the end\n");
+			
+			if ( cgc_daboss( pp ) == 1 ) {
+				printf("You won!!!\n");
+			} else {
+				printf("You failed!!!\n");
+			}
+			
+
+			success = 1;
+		} else {
+			//// Randomly fight monster
+			if ( (secret_page[cgc_page_index] % 100) < 10 ) {
+				cgc_update_page_index();
+				
+				if ( cgc_fight( pp ) == 1 ) {
+					pp->level += 1;
+					printf("player gains a level. now %zu\n", pp->level);
+				}
+				cgc_print_map( pm );
+				
+			} else {
+				cgc_update_page_index();
+			}
+
+		}
+	} 
+
+	return 1;
+}
+
+char *cgc_select_name( )
+{
+	size_t index = 0;
+	size_t value = secret_page[ cgc_page_index ];
+	cgc_update_page_index();
+
+	while ( value ) {
+		index += 1;
+
+		if ( names[index] == NULL ) {
+			index = 0;
+		}
+
+		value -= 1;
+	}
+
+	return names[index];
+}
+
+pmonster cgc_generate_monster( )
+{
+	pmonster pm = NULL;
+
+	pm = malloc( sizeof(monster) );
+
+	if ( pm == NULL ) {
+		printf("[ERROR] Failed to allocate monster structure\n");
+		cgc__terminate(0);
+	}
+
+	bzero( pm, sizeof( monster ) );
+
+	pm->type = cgc_select_name();
+
+	/// Minimum life 4
+	pm->health = (secret_page[ cgc_page_index ] % MAX_MONSTER_LIFE) + 4;
+	pm->hitpoints = pm->health;
+	cgc_update_page_index();
+
+	// Minimum power 2
+	pm->power = (secret_page[cgc_page_index] % MAX_MONSTER_POWER) + 2;
+	cgc_update_page_index();
+
+	pm->level = 1;
+
+	return pm;
+}
+
+pplayer cgc_generate_player( )
+{
+	pplayer np = NULL;
+	char player_one[16];
+	size_t result = 0;
+
+	printf("Enter your name|| ");
+
+	bzero( player_one, 16);
+
+	result = cgc_read_line( player_one, 15);
+
+	/// If they just hit enter then they get a default
+	if ( result == 0 ) {
+		memcpy( player_one, "Player One", 10 );
+	}
+
+	np = malloc( sizeof( player ) );
+
+	if ( np == NULL ) {
+		printf("[ERROR] Failed to malloc player structure\n");
+		cgc__terminate(0);
+	}
+
+	bzero( np, sizeof(player) );
+
+	memcpy( np->name, player_one, 16 );
+
+	/// Generate 3 monsters for the player to fight with
+	for ( result = 0; result < 3; result++ ) {
+		np->mons [ np->mcnt++ ] = cgc_generate_monster();
+	}
+
+	np->level = 1;
+
+	return np;
+}
+
+void cgc_print_player( pplayer pp )
+{
+	size_t index = 0;
+
+	if ( pp == NULL ) {
+		return;
+	}
+
+	printf("Name: %s\n", pp->name);
+	printf("Level: %zu\n", pp->level);
+	printf("Monsters: \n");
+
+	for ( index = 0; index < pp->mcnt; index++ ) {
+		printf("\tType: %s\n", pp->mons[index]->type);
+		printf("\tHealth: %d\n", pp->mons[index]->health);
+		printf("\tPower: %zu\n\n", pp->mons[index]->power);
+	}
+
+	return;
+}
+
+int main(int secret_page_i,  char *unused[]) {
+    secret_page_i = CGC_FLAG_PAGE_ADDRESS;
+
+	pmap pm = NULL;
+	pplayer pp = NULL;
+
+	/// Initialized the secret page stuff
+	secret_page = (unsigned char*)secret_page_i;
+	cgc_page_index = 0;
+	root = NULL;
+	queue_matrix = NULL;
+
+	pp = cgc_generate_player();
+
+	cgc_print_player(pp);
+
+	/// Random value between 5 and 30
+	size_t w = (secret_page[cgc_page_index] % 31) + 5;
+	cgc_update_page_index();
+
+	/// Random height between 5 and 30
+	size_t h = (secret_page[cgc_page_index] % 31) + 5;
+	cgc_update_page_index();
+
+	pm = cgc_generate_map( w, h);
+
+	cgc_movement_loop ( pm, pp );
+
+
+	return 0;
+}