diff --git a/w/w.c b/w/w.c index a2ca0b2..dddb71a 100644 --- a/w/w.c +++ b/w/w.c @@ -5,13 +5,18 @@ #define CMD_LEN 10 #define NAME_LEN 10 +#define SUMMARY_LEN 255 #define POV_3D_SIZE 10 #define POV_SIZE 3 -#define CMD_NULL "-" -#define CMD_FWD 's' -#define CMD_ATTACK 'a' -#define CMD_FLEE 'f' +#define CMD_NULL "-" +#define CMD_FWD 's' +#define CMD_ATTACK 'a' +#define CMD_FLEE 'f' +#define CMD_RIGHT 'x' +#define CMD_LEFT 'w' +#define CMD_BACKTOSTATION 'r' +#define CMD_GOTOMAZE 'v' #define SC_TITLE 0 #define SC_SETNAME 1 @@ -19,6 +24,7 @@ #define SC_MAP 3 #define SC_MONSTER 4 #define SC_GAMEOVER 5 +#define SC_WON 6 #define NORTH 0 #define EAST 1 @@ -49,6 +55,7 @@ typedef struct { Character monster; Position position; char screen; + char summary[SUMMARY_LEN]; } Gamestate; const char* statepath = "w.state"; @@ -64,8 +71,8 @@ char map[15][15] = { "w w w d w w w", "w w w w w w w", "w w w w w w", - "wdwwwwwdw w", - "w w w wwwwwdw", + "wdwwwwwdwwwwwdw", + "w w w w w", "w www w w", "ws w w w", "wwwwwww w w", @@ -76,7 +83,7 @@ char map[15][15] = { }; Character monsters[1] = { - { "Alien", 1, 2, 1, 1 } + { "Alien", 2, 2, 1, 1 } }; int dice() @@ -84,6 +91,16 @@ int dice() return 1 + (rand() % 6); } +int dices(int count) +{ + int result = 0; + for (int i = 0; i < count; i++) + { + result += dice(); + } + return result; +} + char charatpos(int x, int y) { if (x < 0 || y < 0 || x >= mapsize || y >= mapsize) @@ -395,10 +412,45 @@ void init() else { state.screen = SC_TITLE; + strcpy(state.summary, ""); } } -void update(char command[CMD_LEN]) +void attack(Character* attacker, Character* defender) +{ + char tmp[50]; + + int a = dices(attacker->atk) ; + int d = dices(defender->def) ; + + if (a > d) + { + int dmg = a - d; + + // todo: store fight sequence history instead, and write things in draw()? + // and disable 'q' during fight, to avoid having serializing this? + sprintf(tmp, "%s inflige %d à %s.\n", attacker->name, dmg, defender->name); + strcat(state.summary, tmp); + + defender->hp -= dmg; + } + else + { + sprintf(tmp, "%s parre le coup de %s.\n", defender->name, attacker->name); + strcat(state.summary, tmp); + } +} + +void createhero(char* name) +{ + strcpy(state.hero.name, name); + state.hero.hp = 10; + state.hero.gold = 0; + state.hero.atk = 1; + state.hero.def = 1; +} + +void update(char* command) { char c = command[0]; if (state.screen == SC_MAP) @@ -407,20 +459,22 @@ void update(char command[CMD_LEN]) { case CMD_FWD: case '\0': + int x = state.position.x; + int y = state.position.y; forward(); - if (dice() == 1) + if ( (x != state.position.x || y != state.position.y) && dice() > 4) { memcpy(&state.monster, &(monsters[0]), sizeof(Character)); state.screen = SC_MONSTER; } break; - case 'x': + case CMD_RIGHT: right(); break; - case 'w': + case CMD_LEFT: left(); break; - case 'r': + case CMD_BACKTOSTATION: if (currentchar() == TILE_START) { state.screen = SC_STATION; @@ -442,56 +496,70 @@ void update(char command[CMD_LEN]) { if (strlen(command) > 0) { - strcpy(state.hero.name, command); - state.hero.hp = 10; - state.hero.gold = 0; - state.hero.atk = 1; - state.hero.def = 1; + createhero(command); state.screen = SC_STATION; } } else if (state.screen == SC_STATION) { - if (c == 'n') + if (c == CMD_GOTOMAZE) { state.screen = SC_MAP; state.position.x = 1; - state.position.y = 5; + state.position.y = 9; state.position.orientation = NORTH; updatepov(); } } else if (state.screen == SC_MONSTER) { + int fleefails = 0; if (c == CMD_FLEE) { - state.screen = SC_MAP; - } - else if (c == CMD_ATTACK) - { - // hero then monster turn. - // possible outcomes: hero dead, monster dead, or still fight - - // hero attacks - state.monster.hp--; - - if (state.monster.hp <= 0) + if (dice() > 3) { - state.hero.gold += state.monster.gold; + strcpy(state.summary, ""); state.screen = SC_MAP; } else + { + char tmp[50]; + sprintf(tmp, "%s ne parvient pas à fuir.\n", state.hero.name); + strcat(state.summary, tmp); + fleefails = 1; + } + } + + if (c == CMD_ATTACK || fleefails) + { + // hero attacks + if (!fleefails) + { + attack(&state.hero, &state.monster); + } + + if (state.monster.hp <= 0) + { + state.hero.gold += state.monster.gold; + state.screen = SC_WON; + } + else { // monster attacks - state.hero.hp--; + attack(&state.monster, &state.hero); if (state.hero.hp <= 0) { + state.hero.hp = 0; state.screen = SC_GAMEOVER; } } - } } + else if (state.screen == SC_GAMEOVER) + { + state.hero.hp = 10; + state.screen = SC_STATION; + } } void debugoutput() @@ -567,35 +635,43 @@ void draw() } else if (state.screen == SC_STATION) { - printf("\n"); - printf(" STATION SPACIALE\n"); - printf(" INTERGALACTIQUE\n"); + printf("%s est à la station\nspatiale intergalactique.\n", state.hero.name); printf("\n"); - printf("n: Prendre la navette\n"); + printf("v: Partir en vaisseau\n"); } else if (state.screen == SC_MONSTER) { - printf("Rencontre avec un %s\n", state.monster.name); - printf("f: Tenter de fuir\n"); + printf("Rencontre avec %s.\n\n", state.monster.name); + + if (strlen(state.summary) > 0) + { + printf("%s\n", state.summary); + } + printf("a: Attaquer\n"); + printf("f: Tenter de fuir\n"); + } + else if (state.screen == SC_WON) + { + printf("Rencontre avec %s.\n\n", state.monster.name); + printf("%s\n", state.summary); + printf("%s est vaincu.\n", state.monster.name); + printf("%s gagne %d crédits galactiques.\n", state.hero.name, state.monster.gold); + strcpy(state.summary, ""); + state.screen = SC_MAP; } else if (state.screen == SC_GAMEOVER) { - printf("%s est fatiguée\n"); - state.hero.hp = 10; - state.screen = SC_STATION; + printf("%s est fatigué.e.\nIel retourne à la station.\n", state.hero.name); } - if (state.screen == SC_MONSTER - || state.screen == SC_STATION - || state.screen == SC_MAP) + if (state.screen != SC_TITLE && state.screen != SC_SETNAME) { printf("\n"); for (int i = 0; i < screenwidth; i++) printf("-"); printf("\n"); printf("%s | P.V. : %d | C.G. : %d", state.hero.name, state.hero.hp, state.hero.gold); - } debugoutput(); @@ -647,6 +723,7 @@ int main() draw(); getcommand(command); } + savestate(); return 0; }