ref: fcdcc0d9929f461f09f35bf901e3344c89b4efc5
parent: 2f7ec64f856564b48d3ae7493fae937afe29c794
author: sirjofri <sirjofri@sirjofri.de>
date: Fri Feb 13 19:12:13 EST 2026
first working gameplay
--- a/dat.h
+++ b/dat.h
@@ -16,4 +16,6 @@
int running;
int canskip;
+
+ int hadpotion;
};
\ No newline at end of file
--- a/game.c
+++ b/game.c
@@ -8,10 +8,138 @@
struct Card {Color col;
int value;
+ Card *next;
};
State state;
+Card possible[4*9 + 2*4];
+
+Card *deck = nil;
+Card *last = nil;
+int ncards = 0;
+
+static void
+addcard(int c, Color col)
+{+ Card *card;
+ card = mallocz(sizeof(Card), 1);
+ if (!card)
+ sysfatal("mallocz: %r");+ card->col = col;
+ card->value = c;
+
+ if (!deck) {+ deck = last = card;
+ state.deckcards++;
+ return;
+ }
+
+ last->next = card;
+ last = card;
+ state.deckcards++;
+}
+
+static Card
+drawcard(void)
+{+ Card *c, card;
+ if (!deck)
+ return (Card){-1, -1, nil};+ c = deck;
+ deck = deck->next;
+ card = *c;
+ free(c);
+ state.deckcards--;
+ return card;
+}
+
+static int
+cardexists(int c, Color col)
+{+ Card *cd;
+
+ for (cd = deck; cd; cd = cd->next) {+ if (cd->col == col && cd->value == c)
+ return 1;
+ }
+ return 0;
+}
+
+static void
+cleardeck(void)
+{+ Card *c, *d;
+
+ for (c = deck; c; c = d) {+ d = c->next;
+ free(c);
+ }
+ deck = last = nil;
+ state.deckcards = 0;
+}
+
+static int
+validcard(int c, Color col)
+{+ int range;
+
+ if (c < 2)
+ return 0;
+
+ switch (col) {+ case Diamonds:
+ case Hearts:
+ range = 10;
+ break;
+ case Clubs:
+ case Spades:
+ range = 14;
+ break;
+ default:
+ return 0;
+ }
+ return c <= range;
+}
+
+static void
+gendeck(void)
+{+ int c, col;
+ int expected = 4*9 + 2*4;
+ cleardeck();
+
+ while (state.deckcards < expected) {+ c = nrand(13) + 2;
+ col = nrand(4);
+ if (!validcard(c, col))
+ continue;
+ if (cardexists(c, col))
+ continue;
+ addcard(c, col);
+ }
+}
+
+static void
+fillroom(void)
+{+ int i;
+ Card c;
+
+ for (i = 0; i < 4; i++) {+ if (state.room[i] > 0)
+ continue;
+ c = drawcard();
+ if (c.value < 0) {+ fprint(2, "error: drawcard. Empty deck?\n");
+ continue;
+ }
+ state.room[i] = c2n(c.value, c.col);
+ }
+
+ state.hadpotion = 0;
+}
+
int
c2n(int c, Color col)
{@@ -18,6 +146,15 @@
return c + col*15;
}
+static Card
+n2c(int n)
+{+ Card c;
+ c.col = n/15;
+ c.value = n%15;
+ return c;
+}
+
State*
getstate()
{@@ -27,16 +164,54 @@
int
roomaction(int c, int useweapon)
{- int card;
+ int cd, i, n;
+ Card card, weapon;
if (!state.running)
return 0;
- card = state.room[c];
- if (card < 0)
+ cd = state.room[c];
+ if (cd < 0)
return 0;
- // TODO: manage card: fight if enemy, heal if potion, change weapon if weapon card
- fprint(2, "card pressed: %d\n", c);
+
+ card = n2c(cd);
+ weapon = n2c(state.weapon);
+
+ switch (card.col) {+ case Diamonds:
+ state.lastweaponkill = -1;
+ state.weapon = cd;
+ state.room[c] = -1;
+ break;
+ case Hearts:
+ state.room[c] = -1;
+ if (state.hadpotion)
+ break;
+ state.hp += card.value;
+ if (state.hp > 20) state.hp = 20;
+ state.hadpotion = 1;
+ break;
+ case Spades:
+ case Clubs:
+ state.room[c] = -1;
+ state.hp -= useweapon && weapon.value > 0 ? card.value - weapon.value : card.value;
+ if (useweapon)
+ state.lastweaponkill = cd;
+ break;
+ }
+
+ state.canskip = 0;
+
+ n = 0;
+ for (i = 0; i < 4; i++) {+ if (state.room[i] < 0)
+ n++;
+ }
+ if (n >= 3) {+ state.canskip = 1;
+ fillroom();
+ }
+
return 1;
}
@@ -43,6 +218,7 @@
int
startgame(void)
{+ int i;
if (state.running)
return 0;
@@ -50,17 +226,14 @@
state.canskip = 1;
state.hp = 20;
- // TODO: mix cards, update state
+ state.weapon = -1;
+ state.lastweaponkill = -1;
- // fake display
+ gendeck();
- state.room[0] = c2n(2, Spades);
- state.room[1] = c2n(11, Diamonds);
- state.room[2] = c2n(14, Clubs);
- state.room[3] = c2n(4, Hearts);
- state.deckcards = 5;
- state.weapon = c2n(6, Diamonds);
- state.lastweaponkill = c2n(4, Spades);
+ for (i = 0; i < 4; i++)
+ state.room[i] = -1;
+ fillroom();
return 1;
}
@@ -67,12 +240,27 @@
int
nextround(void)
{+ int i;
+ Card c;
if (!state.running)
return 0;
if (!state.canskip)
return 0;
+ /* skipped this round, another skip is invalid! */
state.canskip = 0;
- // TODO: skip round: move cards to end of deck
+
+ for (i = 0; i < 4; i++) {+ if (state.room[i] < 0) {+ fprint(2, "skip room with empty slot. Invalid!\n");
+ continue;
+ }
+ c = n2c(state.room[i]);
+ addcard(c.value, c.col);
+ state.room[i] = -1;
+ }
+
+ fillroom();
+
return 1;
}
\ No newline at end of file
--- a/main.c
+++ b/main.c
@@ -192,6 +192,7 @@
sysfatal("initdraw: %r");einit(Emouse|Ekeyboard);
+ srand(time(0));
loadimages("img");--
⑨