瀏覽代碼

Changed chapter numbers...

master
父節點
當前提交
82238afbdc
共有 9 個文件被更改,包括 666 次插入613 次删除
  1. +0
    -320
      chapter/chapter_5.c
  2. +1
    -139
      chapter/chapter_5.h
  3. +0
    -149
      chapter/chapter_6.c
  4. +1
    -2
      chapter/chapter_6.h
  5. +334
    -0
      chapter/chapter_x.c
  6. +156
    -0
      chapter/chapter_x.h
  7. +152
    -0
      chapter/chapter_y.c
  8. +20
    -0
      chapter/chapter_y.h
  9. +2
    -3
      xhartae.c

+ 0
- 320
chapter/chapter_5.c 查看文件

@@ -11,324 +11,4 @@ It is distributed in the hope that it will be useful or harmful, it really depen

#include "chapter_5.h"

/*
So, what are actually getters and setters, and why you should never use them? Lets explain.
*/

#define MEMORY_LIMIT (1024 * 1024)

static number_t game_memory_length = 0;
static memory_t * game_memory = NULL;

static procedure_t game_free_memory (memory_t memory) {
++game_memory_length;

game_memory = reallocate (game_memory, game_memory_length * (number_t) sizeof (* game_memory));

game_memory [game_memory_length - 1] = memory;
}

procedure_t game_clean_up (procedure_t) {
for (number_t pointer = 0; pointer < game_memory_length; ++pointer) {
game_memory [pointer] = deallocate (game_memory [pointer]);
}

game_memory = deallocate (game_memory);
}

number_t randomize (number_t lower, number_t upper) {
return ((number_t) rand () % (upper - lower + 1) + lower);
}

bundle_t * game_bundle (number_t minimum, number_t maximum, number_t current) {
bundle_t * bundle = allocate ((number_t) sizeof (* bundle));

bundle->minimum = minimum;
bundle->maximum = maximum;
bundle->current = current;

game_free_memory (bundle);

return (bundle);
}

symbol_t * game_symbol (number_t character, number_t colour, number_t effect) {
symbol_t * symbol = allocate ((number_t) sizeof (* symbol));

symbol->character = character;
symbol->colour = colour;
symbol->effect = effect;

game_free_memory (symbol);

return (symbol);
}

sprite_t * game_sprite (number_t width, number_t height, memory_t data) {
sprite_t * sprite = allocate ((number_t) sizeof (* sprite));

sprite->width = width;
sprite->height = height;
sprite->data = data;

game_free_memory (sprite);

return (sprite);
}

generator_t * game_generator (generate_t function) {
generator_t * generator = allocate ((number_t) sizeof (* generator));

generator->generate = function;

game_free_memory (generator);

return (generator);
}

attribute_t * game_attribute (string_t name, bundle_t * points, ...) {
va_list list;

attribute_t * attribute = allocate ((number_t) sizeof (* attribute));

string_copy ((attribute->name = allocate (string_length (name) + 1)), name);

memory_copy ((attribute->points = allocate ((number_t) sizeof (* attribute->points))), points, (number_t) sizeof (* points));

va_start (list, points);

for (;;) {
number_t action = (number_t) va_arg (list, int);

if (action > 0) {
attribute->positive_count += 1;
attribute->positive = reallocate (attribute->positive, attribute->positive_count * (number_t) sizeof (action));
attribute->positive [attribute->positive_count - 1] = (action_t) action;
} else if (action < 0) {
attribute->negative_count += 1;
attribute->negative = reallocate (attribute->negative, attribute->negative_count * (number_t) sizeof (action));
attribute->negative [attribute->negative_count - 1] = (action_t) -action;
} else break;
}

va_end (list);

game_free_memory (attribute->name);
game_free_memory (attribute->points);
game_free_memory (attribute->positive);
game_free_memory (attribute->negative);
game_free_memory (attribute);

return (attribute);
}

skill_t * game_skill (string_t name, bundle_t * points, ...) {
va_list list;

skill_t * skill = allocate ((number_t) sizeof (* skill));

string_copy ((skill->name = allocate (string_length (name) + 1)), name);

memory_copy ((skill->points = allocate ((number_t) sizeof (* skill->points))), points, (number_t) sizeof (* points));

va_start (list, points);

for (;;) {
action_t action = (action_t) va_arg (list, int);

if (action > 0) {
skill->positive_count += 1;
skill->positive = reallocate (skill->positive, skill->positive_count * (number_t) sizeof (action));
skill->positive [skill->positive_count - 1] = action;
} else break;
}

va_end (list);

game_free_memory (skill->name);
game_free_memory (skill->points);
game_free_memory (skill->positive);
game_free_memory (skill);

return (skill);
}

bot_t * game_bot (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina) {
bot_t * bot = allocate ((number_t) sizeof (* bot));

string_copy ((bot->name = allocate (string_length (name) + 1)), name);

bot->x = 0;
bot->y = 0;

memory_copy ((bot->symbol = allocate ((number_t) sizeof (* bot->symbol))), symbol, (number_t) sizeof (* symbol));
memory_copy ((bot->sprite = allocate ((number_t) sizeof (* bot->sprite))), sprite, (number_t) sizeof (* sprite));
memory_copy ((bot->health = allocate ((number_t) sizeof (* bot->health))), health, (number_t) sizeof (* health));
memory_copy ((bot->mana = allocate ((number_t) sizeof (* bot->mana))), mana, (number_t) sizeof (* mana));
memory_copy ((bot->stamina = allocate ((number_t) sizeof (* bot->stamina))), stamina, (number_t) sizeof (* stamina));

game_free_memory (bot->name);
game_free_memory (bot->symbol);
game_free_memory (bot->sprite);
game_free_memory (bot->health);
game_free_memory (bot->mana);
game_free_memory (bot->stamina);
game_free_memory (bot);

return (bot);
}

player_t * game_player (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina, ...) {
va_list list;

player_t * player = allocate ((number_t) sizeof (* player));

string_copy ((player->name = allocate (string_length (name) + 1)), name);

player->x = 3;
player->y = 3;

memory_copy ((player->symbol = allocate ((number_t) sizeof (* player->symbol))), symbol, (number_t) sizeof (* symbol));
memory_copy ((player->sprite = allocate ((number_t) sizeof (* player->sprite))), sprite, (number_t) sizeof (* sprite));
memory_copy ((player->health = allocate ((number_t) sizeof (* player->health))), health, (number_t) sizeof (* health));
memory_copy ((player->mana = allocate ((number_t) sizeof (* player->mana))), mana, (number_t) sizeof (* mana));
memory_copy ((player->stamina = allocate ((number_t) sizeof (* player->stamina))), stamina, (number_t) sizeof (* stamina));

player->attribute_count = 0;
player->skill_count = 0;

va_start (list, stamina);

for (;;) {
attribute_t * attribute = (attribute_t *) va_arg (list, void *);

if (attribute != NULL) {
player->attribute_count += 1;
player->attributes = reallocate (player->attributes, player->attribute_count * (number_t) sizeof (* player->attributes));
player->attributes [player->attribute_count - 1] = attribute;
} else break;
}

for (;;) {
skill_t * skill = (skill_t *) va_arg (list, void *);

if (skill != NULL) {
player->skill_count += 1;
player->skills = reallocate (player->skills, player->skill_count * (number_t) sizeof (* player->skills));
player->skills [player->skill_count - 1] = skill;
} else break;
}

va_end (list);

game_free_memory (player->name);
game_free_memory (player->symbol);
game_free_memory (player->sprite);
game_free_memory (player->health);
game_free_memory (player->mana);
game_free_memory (player->stamina);
game_free_memory (player->attributes);
game_free_memory (player->skills);
game_free_memory (player);

return (player);
}

block_t * game_block (string_t name, symbol_t * symbol, sprite_t * sprite, number_t collision, number_t override) {
block_t * block = allocate ((number_t) sizeof (* block));

string_copy ((block->name = allocate (string_length (name) + 1)), name);

memory_copy ((block->symbol = allocate ((number_t) sizeof (* block->symbol))), symbol, (number_t) sizeof (* symbol));
memory_copy ((block->sprite = allocate ((number_t) sizeof (* block->sprite))), sprite, (number_t) sizeof (* sprite));

block->collision = collision;
block->override = override;

game_free_memory (block->name);
game_free_memory (block->symbol);
game_free_memory (block->sprite);
game_free_memory (block);

return (block);
}

world_t * game_world (number_t width, number_t height, ...) {
va_list list;

world_t * world = allocate ((number_t) sizeof (* world));

world->width = width;
world->height = height;

world->block = allocate (width * height * (number_t) sizeof (* world->block));

va_start (list, height);

for (;;) {
generator_t * generator = (generator_t *) va_arg (list, void *);

if (generator != NULL) {
memory_t data = (memory_t) va_arg (list, void *);
number_t w = (number_t) va_arg (list, int);
number_t h = (number_t) va_arg (list, int);
number_t x = (number_t) va_arg (list, int);
number_t y = (number_t) va_arg (list, int);

generator->generate (world, data, w, h, x, y);
} else break;
}

va_end (list);

game_free_memory (world->bots);
game_free_memory (world->block);
game_free_memory (world);

return (world);
}

procedure_t game_render_attribute (attribute_t * attribute, number_t x, number_t y) {
curses_render_string (attribute->name, COLOUR_CYAN, EFFECT_NORMAL, x + 0, y);
curses_render_string ("[ ", COLOUR_GREY, EFFECT_BOLD, x + 18, y);
curses_render_string (format_to_string (attribute->points->minimum, 0, 10, 4, ' '), COLOUR_RED, EFFECT_NORMAL, x + 20, y);
curses_render_string (format_to_string (attribute->points->current, 0, 10, 4, ' '), COLOUR_WHITE, EFFECT_NORMAL, x + 24, y);
curses_render_string (format_to_string (attribute->points->maximum, 0, 10, 4, ' '), COLOUR_GREEN, EFFECT_NORMAL, x + 28, y);
curses_render_string (" ]", COLOUR_GREY, EFFECT_BOLD, x + 32, y);
}

procedure_t game_render_skill (skill_t * skill, number_t x, number_t y) {
curses_render_string (skill->name, COLOUR_CYAN, EFFECT_NORMAL, x + 0, y);
curses_render_string ("[ ", COLOUR_GREY, EFFECT_BOLD, x + 18, y);
curses_render_string (format_to_string (skill->points->minimum, 0, 10, 4, ' '), COLOUR_RED, EFFECT_NORMAL, x + 20, y);
curses_render_string (format_to_string (skill->points->current, 0, 10, 4, ' '), COLOUR_WHITE, EFFECT_NORMAL, x + 24, y);
curses_render_string (format_to_string (skill->points->maximum, 0, 10, 4, ' '), COLOUR_GREEN, EFFECT_NORMAL, x + 28, y);
curses_render_string (" ]", COLOUR_GREY, EFFECT_BOLD, x + 32, y);

}

procedure_t game_render_bot (bot_t * bot) {
curses_render_character ((char) bot->symbol->character, bot->symbol->colour, bot->symbol->effect, bot->x, bot->y);
}

procedure_t game_render_player (player_t * player) {
curses_render_character ((char) player->symbol->character, player->symbol->colour, player->symbol->effect, player->x, player->y);
}

procedure_t game_render_block (block_t * block, number_t x, number_t y) {
curses_render_character ((char) block->symbol->character, block->symbol->colour, block->symbol->effect, x, y);
}

procedure_t game_render_world (world_t * world, number_t x, number_t y, number_t width, number_t height) {
for (number_t j = 0; (j < height) && (j < world->height); ++j) {
for (number_t i = 0; (i < width) && (i < world->width); ++i) {
game_render_block (world->block [j * world->width + i], i + x, j + y);
}
}

for (number_t index = 0; index < world->bot_count; ++index) {
game_render_bot (& world->bots [index]);
}
}

#endif

+ 1
- 139
chapter/chapter_5.h 查看文件

@@ -13,144 +13,6 @@ It is distributed in the hope that it will be useful or harmful, it really depen
#include "chapter_1.h"
#include "chapter_2.h"
#include "chapter_3.h"

/*
Okay, we're finally on chapter five, and now we'll write something fun, not serious and boring. Before the Great Flood, when our ancestors were riding dinosaurs, building
pyramids, killing African men and mating with Asian women, people didn't have dedicated nor integrated graphical processing units, called GPUs. They only had their terminals,
built inside some of their spaceships. And what did they do with them? They played terminal rogue-like games, similar to those that archeologists discovered in ancient Egypt,
Syria, Sumeria, Greece and Atlantis. They were reconstructed around 50 years ago by some guy that made the game Rogue. So, all those myths, sagas and legends about Anubis,
Gilgamesh, Achilles, Inana, Gaea, they were just playable characters or main characters in those games, with different statistics, skills, attributes and back-story. Now, lets
make a simple terminal rogue-like game using what we wrote in previous chapters.

First of all, lets talk briefly about keyword 'typedef' and why I hate to use it.
*/

typedef int number_t;
typedef void procedure_t;
typedef char * string_t;
typedef void * memory_t;

typedef enum action_t {
GAME_ACTION_NONE,
GAME_ACTION_WAIT, GAME_ACTION_WALK, GAME_ACTION_REST, GAME_ACTION_CAMP,
GAME_ACTION_SWING_BLADE, GAME_ACTION_SWING_AXE, GAME_ACTION_SHOOT_ARROW, GAME_ACTION_THROW_SPEAR,
GAME_ACTION_SUMMON_PUPPET, GAME_ACTION_CALL_NATURE, GAME_ACTION_CITE_RUNE, GAME_ACTION_CAST_CHARM,
GAME_ACTION_COUNT
} action_t;

typedef struct bundle_t {
number_t minimum;
number_t maximum;
number_t current;
} bundle_t;

typedef struct symbol_t {
number_t character;
number_t colour;
number_t effect;
} symbol_t;

typedef struct sprite_t {
number_t width;
number_t height;
memory_t data;
} sprite_t;

typedef struct attribute_t {
string_t name;
number_t positive_count;
number_t negative_count;
bundle_t * points;
action_t * positive;
action_t * negative;
} attribute_t;

typedef struct skill_t {
string_t name;
number_t positive_count;
number_t learning_rate;
bundle_t * points;
action_t * positive;
} skill_t;

typedef struct bot_t {
string_t name;
number_t x;
number_t y;
symbol_t * symbol;
sprite_t * sprite;
bundle_t * health;
bundle_t * mana;
bundle_t * stamina;
} bot_t;

typedef struct player_t {
string_t name;
number_t x;
number_t y;
symbol_t * symbol;
sprite_t * sprite;
bundle_t * health;
bundle_t * mana;
bundle_t * stamina;
number_t attribute_count;
number_t skill_count;
attribute_t * * attributes;
skill_t * * skills;
} player_t;

typedef struct block_t {
string_t name;
number_t collision;
number_t override;
symbol_t * symbol;
sprite_t * sprite;
} block_t;

typedef struct world_t {
number_t width;
number_t height;
number_t item_count;
number_t bot_count;
block_t * * block;
bot_t * bots;
player_t * player;
} world_t;

typedef procedure_t (* generate_t) (world_t *, memory_t, number_t, number_t, number_t, number_t);

typedef struct generator_t {
generate_t generate;
} generator_t;

extern procedure_t game_clean_up (procedure_t);

extern number_t randomize (number_t lower, number_t upper);

extern bundle_t * game_bundle (number_t minimum, number_t maximum, number_t current);
extern symbol_t * game_symbol (number_t character, number_t colour, number_t effect);
extern sprite_t * game_sprite (number_t width, number_t height, memory_t data);

extern generator_t * game_generator (generate_t generator);

extern attribute_t * game_attribute (string_t name, bundle_t * points, ...);
extern skill_t * game_skill (string_t name, bundle_t * points, ...);

extern bot_t * game_bot (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina);
extern player_t * game_player (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina, ...);

extern block_t * game_block (string_t name, symbol_t * symbol, sprite_t * sprite, number_t collision, number_t override);

extern world_t * game_world (number_t width, number_t height, ...);

extern procedure_t game_render_attribute (attribute_t * attribute, number_t x, number_t y);
extern procedure_t game_render_skill (skill_t * skill, number_t x, number_t y);

extern procedure_t game_render_bot (bot_t * bot);
extern procedure_t game_render_player (player_t * player);

extern procedure_t game_render_block (block_t * block, number_t x, number_t y);

extern procedure_t game_render_world (world_t * world, number_t x, number_t y, number_t width, number_t height);
#include "chapter_4.h"

#endif

+ 0
- 149
chapter/chapter_6.c 查看文件

@@ -11,153 +11,4 @@ It is distributed in the hope that it will be useful or harmful, it really depen

#include "chapter_6.h"

#define UNUSED(variable) (void) variable

static procedure_t generate_full_fill_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
UNUSED (width); UNUSED (height); UNUSED (x); UNUSED (y);

for (number_t j = 0; j < world->height; ++j) {
for (number_t i = 0; i < world->width; ++i) {
world->block [j * world->width + i] = (block_t *) data;
}
}
}

static procedure_t generate_rectangle_fill_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
for (number_t j = 0; j < height; ++j) {
for (number_t i = 0; i < width; ++i) {
world->block [(j + y) * world->width + (i + x)] = (block_t *) data;
}
}
}

static procedure_t generate_rectangle_line_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
for (number_t offset = 0; offset < width; ++offset) {
world->block [world->width * y + offset + x] = (block_t *) data;
world->block [world->width * (height - 1 + y) + offset + x] = (block_t *) data;
}

for (number_t offset = 0; offset < height; ++offset) {
world->block [world->width * (y + offset) + x] = (block_t *) data;
world->block [world->width * (y + offset) + width - 1 + x] = (block_t *) data;
}
}

static procedure_t generate_create_bots_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
UNUSED (height); UNUSED (x); UNUSED (y);

bot_t * bot = (bot_t *) data;
number_t count = width;

for (number_t index = 0; index < count; ++index) {
world->bot_count += 1;
world->bots = reallocate (world->bots, world->bot_count * (number_t) sizeof (* world->bots));
memory_copy (& world->bots [world->bot_count - 1], game_bot (bot->name, bot->symbol, NULL, bot->health, bot->mana, bot->stamina), (number_t) sizeof (* world->bots));
world->bots [world->bot_count - 1].x = randomize (1, 40);
world->bots [world->bot_count - 1].y = randomize (1, 40);
}
}

procedure_t play_game (procedure_t) {
generator_t * full_fill = game_generator (generate_full_fill_function);
generator_t * rectangle_fill = game_generator (generate_rectangle_fill_function);
generator_t * rectangle_line = game_generator (generate_rectangle_line_function);
generator_t * create_bots = game_generator (generate_create_bots_function);

bot_t * goblin = game_bot ("Goblin", game_symbol ('g', COLOUR_RED, EFFECT_NORMAL), NULL, game_bundle (0, 11, 11), game_bundle (0, 3, 3), game_bundle (0, 23, 23));
bot_t * hob_goblin = game_bot ("Hob Goblin", game_symbol ('g', COLOUR_RED, EFFECT_BOLD), NULL, game_bundle (0, 17, 17), game_bundle (0, 7, 7), game_bundle (0, 31, 31));
bot_t * orc = game_bot ("Orc", game_symbol ('G', COLOUR_RED, EFFECT_NORMAL), NULL, game_bundle (0, 23, 23), game_bundle (0, 5, 5), game_bundle (0, 47, 47));
bot_t * ogre = game_bot ("Ogre", game_symbol ('G', COLOUR_RED, EFFECT_BOLD), NULL, game_bundle (0, 37, 37), game_bundle (0, 2, 2), game_bundle (0, 83, 83));

player_t * player = game_player ("Riri", game_symbol ('@', COLOUR_CYAN, EFFECT_BOLD), NULL, game_bundle (0, 29, 29), game_bundle (0, 3, 3), game_bundle (0, 37, 37),
game_attribute ("Strength", game_bundle (1, 12, 0), GAME_ACTION_SWING_BLADE, GAME_ACTION_SWING_AXE, -GAME_ACTION_CAMP, 0),
game_attribute ("Edurance", game_bundle (1, 12, 0), GAME_ACTION_WALK, GAME_ACTION_CAMP, -GAME_ACTION_REST, 0),
game_attribute ("Wisdom", game_bundle (1, 12, 0), GAME_ACTION_CITE_RUNE, GAME_ACTION_CAST_CHARM, -GAME_ACTION_WALK, 0),
game_attribute ("Agility", game_bundle (1, 12, 0), GAME_ACTION_SHOOT_ARROW, GAME_ACTION_THROW_SPEAR, -GAME_ACTION_WAIT, 0),
NULL,
game_skill ("Blades", game_bundle (10, 120, 0), GAME_ACTION_SWING_BLADE, 0),
game_skill ("Axes", game_bundle (10, 120, 0), GAME_ACTION_SWING_AXE, 0),
game_skill ("Bows", game_bundle (10, 120, 0), GAME_ACTION_SHOOT_ARROW, 0),
game_skill ("Spears", game_bundle (10, 120, 0), GAME_ACTION_THROW_SPEAR, 0),
game_skill ("Puppet Magic", game_bundle (10, 120, 0), GAME_ACTION_SUMMON_PUPPET, 0),
game_skill ("Nature Magic", game_bundle (10, 120, 0), GAME_ACTION_CALL_NATURE, 0),
game_skill ("Rune Magic", game_bundle (10, 120, 0), GAME_ACTION_CITE_RUNE, 0),
game_skill ("Charm Magic", game_bundle (10, 120, 0), GAME_ACTION_CAST_CHARM, 0),
NULL);

block_t * grass = game_block ("Grass", game_symbol (',', COLOUR_GREEN, EFFECT_BOLD), NULL, FALSE, FALSE);
block_t * stone_floor = game_block ("Stone Floor", game_symbol ('.', COLOUR_GREY, EFFECT_BOLD), NULL, FALSE, FALSE);
block_t * stone_wall = game_block ("Stone Wall", game_symbol ('#', COLOUR_GREY, EFFECT_BOLD), NULL, TRUE, FALSE);

//~world_t * world = game_world (300, 100,
//~full_fill, game_block ("Grass", game_symbol (',', COLOUR_GREEN, EFFECT_BOLD), NULL, FALSE, FALSE), 0, 0, 0, 0,
//~rectangle_fill, game_block ("Stone Floor", game_symbol ('.', COLOUR_GREY, EFFECT_BOLD), NULL, FALSE, FALSE), 5, 9, 2, 4,
//~rectangle_line, game_block ("Stone Wall", game_symbol ('#', COLOUR_GREY, EFFECT_BOLD), NULL, TRUE, FALSE), 5, 9, 2, 4,
//~create_bots, game_bot ("Goblin", game_symbol ('g', COLOUR_RED, EFFECT_NORMAL), NULL, game_bundle (0, 11, 11), game_bundle (0, 3, 3), game_bundle (0, 23, 23)), 3, 0, 0, 0,
//~create_bots, game_bot ("Hob Goblin", game_symbol ('g', COLOUR_RED, EFFECT_BOLD), NULL, game_bundle (0, 17, 17), game_bundle (0, 7, 7), game_bundle (0, 31, 31)), 3, 0, 0, 0,
//~create_bots, game_bot ("Orc", game_symbol ('G', COLOUR_RED, EFFECT_NORMAL), NULL, game_bundle (0, 23, 23), game_bundle (0, 5, 5), game_bundle (0, 47, 47)), 3, 0, 0, 0,
//~create_bots, game_bot ("Ogre", game_symbol ('G', COLOUR_RED, EFFECT_BOLD), NULL, game_bundle (0, 37, 37), game_bundle (0, 2, 2), game_bundle (0, 83, 83)), 3, 0, 0, 0,
//~NULL
//~);

world_t * world = game_world (300, 100, full_fill, grass, 0, 0, 0, 0,
rectangle_fill, stone_floor, 5, 9, 2, 4,
rectangle_line, stone_wall, 5, 9, 2, 4,
create_bots, goblin, 3, 0, 0, 0,
create_bots, hob_goblin, 3, 0, 0, 0,
create_bots, orc, 3, 0, 0, 0,
create_bots, ogre, 3, 0, 0, 0,
NULL);

player->attributes [0]->points->current = 7;
player->attributes [1]->points->current = 3;
player->attributes [2]->points->current = 5;
player->attributes [3]->points->current = 3;

player->skills [0]->points->current = randomize (1, 10);
player->skills [1]->points->current = randomize (1, 10);
player->skills [2]->points->current = randomize (1, 10);
player->skills [3]->points->current = randomize (1, 10);
player->skills [4]->points->current = randomize (1, 10);
player->skills [5]->points->current = randomize (1, 10);
player->skills [6]->points->current = randomize (1, 10);
player->skills [7]->points->current = randomize (1, 10);

curses_configure ();

terminal_show_cursor (FALSE);

while (curses_active) {
number_t game_screen_offset = curses_screen_width - 40;

curses_render_background (' ', COLOUR_WHITE, EFFECT_NORMAL);

game_render_world (world, 0, 0, game_screen_offset, curses_screen_height);

game_render_player (player);

for (number_t attribute = 0; attribute < player->attribute_count; ++attribute) {
game_render_attribute (player->attributes [attribute], game_screen_offset, 1 + attribute);
}

for (number_t skill = 0; skill < player->skill_count; ++skill) {
game_render_skill (player->skills [skill], game_screen_offset, 6 + skill);
}

switch (curses_character) {
case SIGNAL_ARROW_UP: player->y -= 1; limit (& player->y, 0, world->height - 1); break;
case SIGNAL_ARROW_DOWN: player->y += 1; limit (& player->y, 0, world->height - 1); break;
case SIGNAL_ARROW_LEFT: player->x -= 1; limit (& player->x, 0, world->width - 1); break;
case SIGNAL_ARROW_RIGHT: player->x += 1; limit (& player->x, 0, world->width - 1); break;
default: break;
}

curses_synchronize ();
}

terminal_show_cursor (TRUE);

game_clean_up ();
}

#endif

+ 1
- 2
chapter/chapter_6.h 查看文件

@@ -13,8 +13,7 @@ It is distributed in the hope that it will be useful or harmful, it really depen
#include "chapter_1.h"
#include "chapter_2.h"
#include "chapter_3.h"
#include "chapter_4.h"
#include "chapter_5.h"

extern procedure_t play_game (procedure_t);

#endif

+ 334
- 0
chapter/chapter_x.c 查看文件

@@ -0,0 +1,334 @@
/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic

Xhartae is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/

#ifndef CHAPTER_5_SOURCE
#define CHAPTER_5_SOURCE

#include "chapter_5.h"

/*
So, what are actually getters and setters, and why you should never use them? Lets explain.
*/

#define MEMORY_LIMIT (1024 * 1024)

static number_t game_memory_length = 0;
static memory_t * game_memory = NULL;

static procedure_t game_free_memory (memory_t memory) {
++game_memory_length;

game_memory = reallocate (game_memory, game_memory_length * (number_t) sizeof (* game_memory));

game_memory [game_memory_length - 1] = memory;
}

procedure_t game_clean_up (procedure_t) {
for (number_t pointer = 0; pointer < game_memory_length; ++pointer) {
game_memory [pointer] = deallocate (game_memory [pointer]);
}

game_memory = deallocate (game_memory);
}

number_t randomize (number_t lower, number_t upper) {
return ((number_t) rand () % (upper - lower + 1) + lower);
}

bundle_t * game_bundle (number_t minimum, number_t maximum, number_t current) {
bundle_t * bundle = allocate ((number_t) sizeof (* bundle));

bundle->minimum = minimum;
bundle->maximum = maximum;
bundle->current = current;

game_free_memory (bundle);

return (bundle);
}

symbol_t * game_symbol (number_t character, number_t colour, number_t effect) {
symbol_t * symbol = allocate ((number_t) sizeof (* symbol));

symbol->character = character;
symbol->colour = colour;
symbol->effect = effect;

game_free_memory (symbol);

return (symbol);
}

sprite_t * game_sprite (number_t width, number_t height, memory_t data) {
sprite_t * sprite = allocate ((number_t) sizeof (* sprite));

sprite->width = width;
sprite->height = height;
sprite->data = data;

game_free_memory (sprite);

return (sprite);
}

generator_t * game_generator (generate_t function) {
generator_t * generator = allocate ((number_t) sizeof (* generator));

generator->generate = function;

game_free_memory (generator);

return (generator);
}

attribute_t * game_attribute (string_t name, bundle_t * points, ...) {
va_list list;

attribute_t * attribute = allocate ((number_t) sizeof (* attribute));

string_copy ((attribute->name = allocate (string_length (name) + 1)), name);

memory_copy ((attribute->points = allocate ((number_t) sizeof (* attribute->points))), points, (number_t) sizeof (* points));

va_start (list, points);

for (;;) {
number_t action = (number_t) va_arg (list, int);

if (action > 0) {
attribute->positive_count += 1;
attribute->positive = reallocate (attribute->positive, attribute->positive_count * (number_t) sizeof (action));
attribute->positive [attribute->positive_count - 1] = (action_t) action;
} else if (action < 0) {
attribute->negative_count += 1;
attribute->negative = reallocate (attribute->negative, attribute->negative_count * (number_t) sizeof (action));
attribute->negative [attribute->negative_count - 1] = (action_t) -action;
} else break;
}

va_end (list);

game_free_memory (attribute->name);
game_free_memory (attribute->points);
game_free_memory (attribute->positive);
game_free_memory (attribute->negative);
game_free_memory (attribute);

return (attribute);
}

skill_t * game_skill (string_t name, bundle_t * points, ...) {
va_list list;

skill_t * skill = allocate ((number_t) sizeof (* skill));

string_copy ((skill->name = allocate (string_length (name) + 1)), name);

memory_copy ((skill->points = allocate ((number_t) sizeof (* skill->points))), points, (number_t) sizeof (* points));

va_start (list, points);

for (;;) {
action_t action = (action_t) va_arg (list, int);

if (action > 0) {
skill->positive_count += 1;
skill->positive = reallocate (skill->positive, skill->positive_count * (number_t) sizeof (action));
skill->positive [skill->positive_count - 1] = action;
} else break;
}

va_end (list);

game_free_memory (skill->name);
game_free_memory (skill->points);
game_free_memory (skill->positive);
game_free_memory (skill);

return (skill);
}

bot_t * game_bot (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina) {
bot_t * bot = allocate ((number_t) sizeof (* bot));

string_copy ((bot->name = allocate (string_length (name) + 1)), name);

bot->x = 0;
bot->y = 0;

memory_copy ((bot->symbol = allocate ((number_t) sizeof (* bot->symbol))), symbol, (number_t) sizeof (* symbol));
memory_copy ((bot->sprite = allocate ((number_t) sizeof (* bot->sprite))), sprite, (number_t) sizeof (* sprite));
memory_copy ((bot->health = allocate ((number_t) sizeof (* bot->health))), health, (number_t) sizeof (* health));
memory_copy ((bot->mana = allocate ((number_t) sizeof (* bot->mana))), mana, (number_t) sizeof (* mana));
memory_copy ((bot->stamina = allocate ((number_t) sizeof (* bot->stamina))), stamina, (number_t) sizeof (* stamina));

game_free_memory (bot->name);
game_free_memory (bot->symbol);
game_free_memory (bot->sprite);
game_free_memory (bot->health);
game_free_memory (bot->mana);
game_free_memory (bot->stamina);
game_free_memory (bot);

return (bot);
}

player_t * game_player (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina, ...) {
va_list list;

player_t * player = allocate ((number_t) sizeof (* player));

string_copy ((player->name = allocate (string_length (name) + 1)), name);

player->x = 3;
player->y = 3;

memory_copy ((player->symbol = allocate ((number_t) sizeof (* player->symbol))), symbol, (number_t) sizeof (* symbol));
memory_copy ((player->sprite = allocate ((number_t) sizeof (* player->sprite))), sprite, (number_t) sizeof (* sprite));
memory_copy ((player->health = allocate ((number_t) sizeof (* player->health))), health, (number_t) sizeof (* health));
memory_copy ((player->mana = allocate ((number_t) sizeof (* player->mana))), mana, (number_t) sizeof (* mana));
memory_copy ((player->stamina = allocate ((number_t) sizeof (* player->stamina))), stamina, (number_t) sizeof (* stamina));

player->attribute_count = 0;
player->skill_count = 0;

va_start (list, stamina);

for (;;) {
attribute_t * attribute = (attribute_t *) va_arg (list, void *);

if (attribute != NULL) {
player->attribute_count += 1;
player->attributes = reallocate (player->attributes, player->attribute_count * (number_t) sizeof (* player->attributes));
player->attributes [player->attribute_count - 1] = attribute;
} else break;
}

for (;;) {
skill_t * skill = (skill_t *) va_arg (list, void *);

if (skill != NULL) {
player->skill_count += 1;
player->skills = reallocate (player->skills, player->skill_count * (number_t) sizeof (* player->skills));
player->skills [player->skill_count - 1] = skill;
} else break;
}

va_end (list);

game_free_memory (player->name);
game_free_memory (player->symbol);
game_free_memory (player->sprite);
game_free_memory (player->health);
game_free_memory (player->mana);
game_free_memory (player->stamina);
game_free_memory (player->attributes);
game_free_memory (player->skills);
game_free_memory (player);

return (player);
}

block_t * game_block (string_t name, symbol_t * symbol, sprite_t * sprite, number_t collision, number_t override) {
block_t * block = allocate ((number_t) sizeof (* block));

string_copy ((block->name = allocate (string_length (name) + 1)), name);

memory_copy ((block->symbol = allocate ((number_t) sizeof (* block->symbol))), symbol, (number_t) sizeof (* symbol));
memory_copy ((block->sprite = allocate ((number_t) sizeof (* block->sprite))), sprite, (number_t) sizeof (* sprite));

block->collision = collision;
block->override = override;

game_free_memory (block->name);
game_free_memory (block->symbol);
game_free_memory (block->sprite);
game_free_memory (block);

return (block);
}

world_t * game_world (number_t width, number_t height, ...) {
va_list list;

world_t * world = allocate ((number_t) sizeof (* world));

world->width = width;
world->height = height;

world->block = allocate (width * height * (number_t) sizeof (* world->block));

va_start (list, height);

for (;;) {
generator_t * generator = (generator_t *) va_arg (list, void *);

if (generator != NULL) {
memory_t data = (memory_t) va_arg (list, void *);
number_t w = (number_t) va_arg (list, int);
number_t h = (number_t) va_arg (list, int);
number_t x = (number_t) va_arg (list, int);
number_t y = (number_t) va_arg (list, int);

generator->generate (world, data, w, h, x, y);
} else break;
}

va_end (list);

game_free_memory (world->bots);
game_free_memory (world->block);
game_free_memory (world);

return (world);
}

procedure_t game_render_attribute (attribute_t * attribute, number_t x, number_t y) {
curses_render_string (attribute->name, COLOUR_CYAN, EFFECT_NORMAL, x + 0, y);
curses_render_string ("[ ", COLOUR_GREY, EFFECT_BOLD, x + 18, y);
curses_render_string (format_to_string (attribute->points->minimum, 0, 10, 4, ' '), COLOUR_RED, EFFECT_NORMAL, x + 20, y);
curses_render_string (format_to_string (attribute->points->current, 0, 10, 4, ' '), COLOUR_WHITE, EFFECT_NORMAL, x + 24, y);
curses_render_string (format_to_string (attribute->points->maximum, 0, 10, 4, ' '), COLOUR_GREEN, EFFECT_NORMAL, x + 28, y);
curses_render_string (" ]", COLOUR_GREY, EFFECT_BOLD, x + 32, y);
}

procedure_t game_render_skill (skill_t * skill, number_t x, number_t y) {
curses_render_string (skill->name, COLOUR_CYAN, EFFECT_NORMAL, x + 0, y);
curses_render_string ("[ ", COLOUR_GREY, EFFECT_BOLD, x + 18, y);
curses_render_string (format_to_string (skill->points->minimum, 0, 10, 4, ' '), COLOUR_RED, EFFECT_NORMAL, x + 20, y);
curses_render_string (format_to_string (skill->points->current, 0, 10, 4, ' '), COLOUR_WHITE, EFFECT_NORMAL, x + 24, y);
curses_render_string (format_to_string (skill->points->maximum, 0, 10, 4, ' '), COLOUR_GREEN, EFFECT_NORMAL, x + 28, y);
curses_render_string (" ]", COLOUR_GREY, EFFECT_BOLD, x + 32, y);

}

procedure_t game_render_bot (bot_t * bot) {
curses_render_character ((char) bot->symbol->character, bot->symbol->colour, bot->symbol->effect, bot->x, bot->y);
}

procedure_t game_render_player (player_t * player) {
curses_render_character ((char) player->symbol->character, player->symbol->colour, player->symbol->effect, player->x, player->y);
}

procedure_t game_render_block (block_t * block, number_t x, number_t y) {
curses_render_character ((char) block->symbol->character, block->symbol->colour, block->symbol->effect, x, y);
}

procedure_t game_render_world (world_t * world, number_t x, number_t y, number_t width, number_t height) {
for (number_t j = 0; (j < height) && (j < world->height); ++j) {
for (number_t i = 0; (i < width) && (i < world->width); ++i) {
game_render_block (world->block [j * world->width + i], i + x, j + y);
}
}

for (number_t index = 0; index < world->bot_count; ++index) {
game_render_bot (& world->bots [index]);
}
}

#endif

+ 156
- 0
chapter/chapter_x.h 查看文件

@@ -0,0 +1,156 @@
/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic

Xhartae is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/

#ifndef CHAPTER_5_HEADER
#define CHAPTER_5_HEADER

#include "chapter_0.h"
#include "chapter_1.h"
#include "chapter_2.h"
#include "chapter_3.h"

/*
Okay, we're finally on chapter five, and now we'll write something fun, not serious and boring. Before the Great Flood, when our ancestors were riding dinosaurs, building
pyramids, killing African men and mating with Asian women, people didn't have dedicated nor integrated graphical processing units, called GPUs. They only had their terminals,
built inside some of their spaceships. And what did they do with them? They played terminal rogue-like games, similar to those that archeologists discovered in ancient Egypt,
Syria, Sumeria, Greece and Atlantis. They were reconstructed around 50 years ago by some guy that made the game Rogue. So, all those myths, sagas and legends about Anubis,
Gilgamesh, Achilles, Inana, Gaea, they were just playable characters or main characters in those games, with different statistics, skills, attributes and back-story. Now, lets
make a simple terminal rogue-like game using what we wrote in previous chapters.

First of all, lets talk briefly about keyword 'typedef' and why I hate to use it.
*/

typedef int number_t;
typedef void procedure_t;
typedef char * string_t;
typedef void * memory_t;

typedef enum action_t {
GAME_ACTION_NONE,
GAME_ACTION_WAIT, GAME_ACTION_WALK, GAME_ACTION_REST, GAME_ACTION_CAMP,
GAME_ACTION_SWING_BLADE, GAME_ACTION_SWING_AXE, GAME_ACTION_SHOOT_ARROW, GAME_ACTION_THROW_SPEAR,
GAME_ACTION_SUMMON_PUPPET, GAME_ACTION_CALL_NATURE, GAME_ACTION_CITE_RUNE, GAME_ACTION_CAST_CHARM,
GAME_ACTION_COUNT
} action_t;

typedef struct bundle_t {
number_t minimum;
number_t maximum;
number_t current;
} bundle_t;

typedef struct symbol_t {
number_t character;
number_t colour;
number_t effect;
} symbol_t;

typedef struct sprite_t {
number_t width;
number_t height;
memory_t data;
} sprite_t;

typedef struct attribute_t {
string_t name;
number_t positive_count;
number_t negative_count;
bundle_t * points;
action_t * positive;
action_t * negative;
} attribute_t;

typedef struct skill_t {
string_t name;
number_t positive_count;
number_t learning_rate;
bundle_t * points;
action_t * positive;
} skill_t;

typedef struct bot_t {
string_t name;
number_t x;
number_t y;
symbol_t * symbol;
sprite_t * sprite;
bundle_t * health;
bundle_t * mana;
bundle_t * stamina;
} bot_t;

typedef struct player_t {
string_t name;
number_t x;
number_t y;
symbol_t * symbol;
sprite_t * sprite;
bundle_t * health;
bundle_t * mana;
bundle_t * stamina;
number_t attribute_count;
number_t skill_count;
attribute_t * * attributes;
skill_t * * skills;
} player_t;

typedef struct block_t {
string_t name;
number_t collision;
number_t override;
symbol_t * symbol;
sprite_t * sprite;
} block_t;

typedef struct world_t {
number_t width;
number_t height;
number_t item_count;
number_t bot_count;
block_t * * block;
bot_t * bots;
player_t * player;
} world_t;

typedef procedure_t (* generate_t) (world_t *, memory_t, number_t, number_t, number_t, number_t);

typedef struct generator_t {
generate_t generate;
} generator_t;

extern procedure_t game_clean_up (procedure_t);

extern number_t randomize (number_t lower, number_t upper);

extern bundle_t * game_bundle (number_t minimum, number_t maximum, number_t current);
extern symbol_t * game_symbol (number_t character, number_t colour, number_t effect);
extern sprite_t * game_sprite (number_t width, number_t height, memory_t data);

extern generator_t * game_generator (generate_t generator);

extern attribute_t * game_attribute (string_t name, bundle_t * points, ...);
extern skill_t * game_skill (string_t name, bundle_t * points, ...);

extern bot_t * game_bot (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina);
extern player_t * game_player (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina, ...);

extern block_t * game_block (string_t name, symbol_t * symbol, sprite_t * sprite, number_t collision, number_t override);

extern world_t * game_world (number_t width, number_t height, ...);

extern procedure_t game_render_attribute (attribute_t * attribute, number_t x, number_t y);
extern procedure_t game_render_skill (skill_t * skill, number_t x, number_t y);

extern procedure_t game_render_bot (bot_t * bot);
extern procedure_t game_render_player (player_t * player);

extern procedure_t game_render_block (block_t * block, number_t x, number_t y);

extern procedure_t game_render_world (world_t * world, number_t x, number_t y, number_t width, number_t height);

#endif

+ 152
- 0
chapter/chapter_y.c 查看文件

@@ -0,0 +1,152 @@
/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic

Xhartae is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/

#ifndef CHAPTER_6_SOURCE
#define CHAPTER_6_SOURCE

#include "chapter_6.h"

#define UNUSED(variable) (void) variable

static procedure_t generate_full_fill_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
UNUSED (width); UNUSED (height); UNUSED (x); UNUSED (y);

for (number_t j = 0; j < world->height; ++j) {
for (number_t i = 0; i < world->width; ++i) {
world->block [j * world->width + i] = (block_t *) data;
}
}
}

static procedure_t generate_rectangle_fill_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
for (number_t j = 0; j < height; ++j) {
for (number_t i = 0; i < width; ++i) {
world->block [(j + y) * world->width + (i + x)] = (block_t *) data;
}
}
}

static procedure_t generate_rectangle_line_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
for (number_t offset = 0; offset < width; ++offset) {
world->block [world->width * y + offset + x] = (block_t *) data;
world->block [world->width * (height - 1 + y) + offset + x] = (block_t *) data;
}

for (number_t offset = 0; offset < height; ++offset) {
world->block [world->width * (y + offset) + x] = (block_t *) data;
world->block [world->width * (y + offset) + width - 1 + x] = (block_t *) data;
}
}

static procedure_t generate_create_bots_function (world_t * world, memory_t data, number_t width, number_t height, number_t x, number_t y) {
UNUSED (height); UNUSED (x); UNUSED (y);

bot_t * bot = (bot_t *) data;
number_t count = width;

for (number_t index = 0; index < count; ++index) {
world->bot_count += 1;
world->bots = reallocate (world->bots, world->bot_count * (number_t) sizeof (* world->bots));
memory_copy (& world->bots [world->bot_count - 1], game_bot (bot->name, bot->symbol, NULL, bot->health, bot->mana, bot->stamina), (number_t) sizeof (* world->bots));
world->bots [world->bot_count - 1].x = randomize (1, 40);
world->bots [world->bot_count - 1].y = randomize (1, 40);
}
}

procedure_t play_game (procedure_t) {
generator_t * full_fill = game_generator (generate_full_fill_function);
generator_t * rectangle_fill = game_generator (generate_rectangle_fill_function);
generator_t * rectangle_line = game_generator (generate_rectangle_line_function);
generator_t * create_bots = game_generator (generate_create_bots_function);

bot_t * goblin = game_bot ("Goblin", game_symbol ('g', COLOUR_RED, EFFECT_NORMAL), NULL, game_bundle (0, 11, 11), game_bundle (0, 3, 3), game_bundle (0, 23, 23));
bot_t * hob_goblin = game_bot ("Hob Goblin", game_symbol ('g', COLOUR_RED, EFFECT_BOLD), NULL, game_bundle (0, 17, 17), game_bundle (0, 7, 7), game_bundle (0, 31, 31));
bot_t * orc = game_bot ("Orc", game_symbol ('G', COLOUR_RED, EFFECT_NORMAL), NULL, game_bundle (0, 23, 23), game_bundle (0, 5, 5), game_bundle (0, 47, 47));
bot_t * ogre = game_bot ("Ogre", game_symbol ('G', COLOUR_RED, EFFECT_BOLD), NULL, game_bundle (0, 37, 37), game_bundle (0, 2, 2), game_bundle (0, 83, 83));

player_t * player = game_player ("Riri", game_symbol ('@', COLOUR_CYAN, EFFECT_BOLD), NULL, game_bundle (0, 29, 29), game_bundle (0, 3, 3), game_bundle (0, 37, 37),
game_attribute ("Strength", game_bundle (1, 12, 0), GAME_ACTION_SWING_BLADE, GAME_ACTION_SWING_AXE, -GAME_ACTION_CAMP, 0),
game_attribute ("Edurance", game_bundle (1, 12, 0), GAME_ACTION_WALK, GAME_ACTION_CAMP, -GAME_ACTION_REST, 0),
game_attribute ("Wisdom", game_bundle (1, 12, 0), GAME_ACTION_CITE_RUNE, GAME_ACTION_CAST_CHARM, -GAME_ACTION_WALK, 0),
game_attribute ("Agility", game_bundle (1, 12, 0), GAME_ACTION_SHOOT_ARROW, GAME_ACTION_THROW_SPEAR, -GAME_ACTION_WAIT, 0),
NULL,
game_skill ("Blades", game_bundle (10, 120, 0), GAME_ACTION_SWING_BLADE, 0),
game_skill ("Axes", game_bundle (10, 120, 0), GAME_ACTION_SWING_AXE, 0),
game_skill ("Bows", game_bundle (10, 120, 0), GAME_ACTION_SHOOT_ARROW, 0),
game_skill ("Spears", game_bundle (10, 120, 0), GAME_ACTION_THROW_SPEAR, 0),
game_skill ("Puppet Magic", game_bundle (10, 120, 0), GAME_ACTION_SUMMON_PUPPET, 0),
game_skill ("Nature Magic", game_bundle (10, 120, 0), GAME_ACTION_CALL_NATURE, 0),
game_skill ("Rune Magic", game_bundle (10, 120, 0), GAME_ACTION_CITE_RUNE, 0),
game_skill ("Charm Magic", game_bundle (10, 120, 0), GAME_ACTION_CAST_CHARM, 0),
NULL);

block_t * grass = game_block ("Grass", game_symbol (',', COLOUR_GREEN, EFFECT_BOLD), NULL, FALSE, FALSE);
block_t * stone_floor = game_block ("Stone Floor", game_symbol ('.', COLOUR_GREY, EFFECT_BOLD), NULL, FALSE, FALSE);
block_t * stone_wall = game_block ("Stone Wall", game_symbol ('#', COLOUR_GREY, EFFECT_BOLD), NULL, TRUE, FALSE);

world_t * world = game_world (300, 100, full_fill, grass, 0, 0, 0, 0,
rectangle_fill, stone_floor, 5, 9, 2, 4,
rectangle_line, stone_wall, 5, 9, 2, 4,
create_bots, goblin, 3, 0, 0, 0,
create_bots, hob_goblin, 3, 0, 0, 0,
create_bots, orc, 3, 0, 0, 0,
create_bots, ogre, 3, 0, 0, 0,
NULL);

player->attributes [0]->points->current = 7;
player->attributes [1]->points->current = 3;
player->attributes [2]->points->current = 5;
player->attributes [3]->points->current = 3;

player->skills [0]->points->current = randomize (1, 10);
player->skills [1]->points->current = randomize (1, 10);
player->skills [2]->points->current = randomize (1, 10);
player->skills [3]->points->current = randomize (1, 10);
player->skills [4]->points->current = randomize (1, 10);
player->skills [5]->points->current = randomize (1, 10);
player->skills [6]->points->current = randomize (1, 10);
player->skills [7]->points->current = randomize (1, 10);

curses_configure ();

terminal_show_cursor (FALSE);

while (curses_active) {
number_t game_screen_offset = curses_screen_width - 40;

curses_render_background (' ', COLOUR_WHITE, EFFECT_NORMAL);

game_render_world (world, 0, 0, game_screen_offset, curses_screen_height);

game_render_player (player);

for (number_t attribute = 0; attribute < player->attribute_count; ++attribute) {
game_render_attribute (player->attributes [attribute], game_screen_offset, 1 + attribute);
}

for (number_t skill = 0; skill < player->skill_count; ++skill) {
game_render_skill (player->skills [skill], game_screen_offset, 6 + skill);
}

switch (curses_character) {
case SIGNAL_ARROW_UP: player->y -= 1; limit (& player->y, 0, world->height - 1); break;
case SIGNAL_ARROW_DOWN: player->y += 1; limit (& player->y, 0, world->height - 1); break;
case SIGNAL_ARROW_LEFT: player->x -= 1; limit (& player->x, 0, world->width - 1); break;
case SIGNAL_ARROW_RIGHT: player->x += 1; limit (& player->x, 0, world->width - 1); break;
default: break;
}

curses_synchronize ();
}

terminal_show_cursor (TRUE);

game_clean_up ();
}

#endif

+ 20
- 0
chapter/chapter_y.h 查看文件

@@ -0,0 +1,20 @@
/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic

Xhartae is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/

#ifndef CHAPTER_6_HEADER
#define CHAPTER_6_HEADER

#include "chapter_0.h"
#include "chapter_1.h"
#include "chapter_2.h"
#include "chapter_3.h"
#include "chapter_5.h"

extern procedure_t play_game (procedure_t);

#endif

+ 2
- 3
xhartae.c 查看文件

@@ -132,9 +132,8 @@ int main (int argc, char * * argv) {
(void) argc;
(void) argv;

preview_c_file ("program/example.c", 5, 1);

play_game ();
//~preview_c_file ("program/example.c", 5, 1);
preview_c_file ("chapter/chapter_0.c", 0, 0);

return (EXIT_SUCCESS);
}

Loading…
取消
儲存