summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-21 16:36:36 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-21 16:36:36 -0700
commitc4c7913d5c48958732f645c8a3edb57c9004dd30 (patch)
tree9f1a04efa3fa1e95793bd710bfb583b8469ae2c0
parente7a2e5e24bf0523fb49a3ce07e3eb96d1fd5aea2 (diff)
downloaddartboat-multi.tar.gz
dartboat-multi.tar.xz
web: add support for custom matchesmulti
-rw-r--r--match.c3
-rw-r--r--web/web_match.c18
-rw-r--r--web/web_match.h1
-rw-r--r--web/web_prompt.c106
4 files changed, 96 insertions, 32 deletions
diff --git a/match.c b/match.c
index d8f8a23..1e131f0 100644
--- a/match.c
+++ b/match.c
@@ -6,7 +6,7 @@
struct leg *leg_init(int points, char *name)
{
struct leg *l = calloc(1, sizeof(*l));
- l->name = name;
+ l->name = strdup(name);
l->start = l->rem = points;
l->size_visits = 16;
l->visits = calloc(l->size_visits, sizeof(*(l->visits)));
@@ -23,6 +23,7 @@ void leg_free(struct leg *l)
free(l->visits[i].ccoords);
}
free(l->visits);
+ free(l->name);
free(l);
}
diff --git a/web/web_match.c b/web/web_match.c
index cd87c5a..58b0aca 100644
--- a/web/web_match.c
+++ b/web/web_match.c
@@ -5,6 +5,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
+#include <string.h>
struct match_state *state;
struct match_opts *match_opts;
@@ -83,7 +84,20 @@ void match_opts_add_player(enum player_type type, char *name)
match_opts->throws_first = pn;
match_opts->players[pn - 1].type = type;
- match_opts->players[pn - 1].name = name;
+ match_opts->players[pn - 1].name = strdup(name);
+}
+
+void match_opts_remove_player(int pn)
+{
+ if (match_opts->throws_first == pn)
+ match_opts->throws_first = match_opts->num_players > 1 ? 1 : 0;
+ else if (match_opts->throws_first > pn)
+ --match_opts->throws_first;
+
+ free(match_opts->players[pn - 1].name);
+ for (int i = pn; i < match_opts->num_players; ++i)
+ match_opts->players[i - 1] = match_opts->players[i];
+ --match_opts->num_players;
}
void match_opts_free()
@@ -91,6 +105,8 @@ void match_opts_free()
if (!match_opts)
return;
+ for (int i = 0; i < match_opts->num_players; ++i)
+ free(match_opts->players[i].name);
free(match_opts->players);
free(match_opts);
match_opts = NULL;
diff --git a/web/web_match.h b/web/web_match.h
index 0a5a71d..8fb2056 100644
--- a/web/web_match.h
+++ b/web/web_match.h
@@ -40,6 +40,7 @@ void match_add_player(int start_pts, enum player_type type, char *name);
void free_state();
void match_opts_new();
void match_opts_add_player(enum player_type type, char *name);
+void match_opts_remove_player(int pn);
void match_opts_free();
struct leg *state_active_leg();
diff --git a/web/web_prompt.c b/web/web_prompt.c
index 17383db..5c5659c 100644
--- a/web/web_prompt.c
+++ b/web/web_prompt.c
@@ -25,6 +25,7 @@ enum prompt_mode pm;
enum menu {
MENU_MAIN,
MENU_MATCH_OPTS,
+ MENU_CUSTOM_MATCH_OPTS,
MENU_START_PTS,
MENU_THROWS_FIRST
};
@@ -37,7 +38,7 @@ struct menu_opt {
int arg;
bool takes_arg;
};
-static struct menu_opt menu_optv[10];
+static struct menu_opt menu_optv[20];
static int menu_optc;
static struct {
@@ -170,8 +171,6 @@ enum match_mode {
MM_1P,
MM_2P,
MM_2C,
- MM_3P,
- MM_1P3C,
MM_8C
};
@@ -179,14 +178,13 @@ void select_match_mode(int mode)
{
match_opts_new();
- // names need to be freed if we stop using string literals
switch((enum match_mode)mode) {
case MM_1P1C:
- match_opts_add_player(PT_USER, "User");
+ match_opts_add_player(PT_USER, "Player");
match_opts_add_player(PT_COMP, "Computer");
break;
case MM_1P:
- match_opts_add_player(PT_USER, "Player 1");
+ match_opts_add_player(PT_USER, "Player");
break;
case MM_2P:
match_opts_add_player(PT_USER, "Player 1");
@@ -196,32 +194,26 @@ void select_match_mode(int mode)
match_opts_add_player(PT_COMP, "Computer 1");
match_opts_add_player(PT_COMP, "Computer 2");
break;
- case MM_3P:
- match_opts_add_player(PT_USER, "Player 1");
- match_opts_add_player(PT_USER, "Player 2");
- match_opts_add_player(PT_USER, "Player 3");
- break;
- case MM_1P3C:
- match_opts_add_player(PT_USER, "Player 1");
- match_opts_add_player(PT_COMP, "Computer 1");
- match_opts_add_player(PT_COMP, "Computer 2");
- match_opts_add_player(PT_COMP, "Computer 3");
- break;
- case MM_8C:
- match_opts_add_player(PT_COMP, "Computer 1");
- match_opts_add_player(PT_COMP, "Computer 2");
- match_opts_add_player(PT_COMP, "Computer 3");
- match_opts_add_player(PT_COMP, "Computer 4");
- match_opts_add_player(PT_COMP, "Computer 5");
- match_opts_add_player(PT_COMP, "Computer 6");
- match_opts_add_player(PT_COMP, "Computer 7");
- match_opts_add_player(PT_COMP, "Computer 8");
+ case MM_8C:;
+ char buf[32];
+ for (int i = 1; i <= 8; ++i) {
+ sprintf(buf, "Computer %d", i);
+ match_opts_add_player(PT_COMP, buf);
+ }
break;
}
menu_push(MENU_MATCH_OPTS);
}
+static int custom_users_added, custom_comps_added;
+void select_custom_match()
+{
+ match_opts_new();
+ custom_users_added = custom_comps_added = 0;
+ menu_push(MENU_CUSTOM_MATCH_OPTS);
+}
+
void menu_display_main()
{
prompt_set_msgl("Select match mode:");
@@ -234,12 +226,9 @@ void menu_display_main()
select_match_mode, MM_2P);
add_menu_opti("Computer vs computer",
select_match_mode, MM_2C);
- add_menu_opti("Three-player scoreboard",
- select_match_mode, MM_3P);
- add_menu_opti("Play against three computers",
- select_match_mode, MM_1P3C);
add_menu_opti("Battle of the computers",
select_match_mode, MM_8C);
+ add_menu_opt("Custom", select_custom_match);
}
void menu_display_match_opts()
@@ -258,6 +247,60 @@ void menu_display_match_opts()
add_menu_opt("Back", menu_pop);
}
+static void custom_start_match()
+{
+ if (match_opts->throws_first)
+ start_match();
+ else
+ oi();
+}
+void menu_display();
+static void custom_add_player(int type)
+{
+ if (match_opts->num_players >= 10) {
+ oi();
+ return;
+ }
+
+ char buf[64];
+ sprintf(buf, type == PT_USER ? "Player %d" : "Computer %d",
+ type == PT_USER ? ++custom_users_added : ++custom_comps_added);
+
+ match_opts_add_player(type, buf);
+ menu_display();
+}
+static void custom_remove_player(int pn)
+{
+ match_opts_remove_player(pn);
+ menu_display();
+}
+
+static void menu_display_custom_match_opts()
+{
+ prompt_set_msgl("Match options:");
+
+ add_menu_opt("Start match", custom_start_match);
+
+ char buf[64];
+ sprintf(buf, "Starting points: %d", match_opts->start_pts);
+ add_menu_opti(buf, menu_push_int, MENU_START_PTS);
+ sprintf(buf, "Throws first: %s",
+ match_opts->throws_first ?
+ match_opts->players[
+ match_opts->throws_first - 1].name :
+ "(no players added)");
+ add_menu_opti(buf, menu_push_int, MENU_THROWS_FIRST);
+ add_menu_opti("Add user player", custom_add_player, PT_USER);
+ add_menu_opti("Add computer player", custom_add_player, PT_COMP);
+
+ for (int i = 0; i < match_opts->num_players; ++i) {
+ sprintf(buf, "Remove player: %s", match_opts->players[i].name);
+ add_menu_opti(buf, custom_remove_player, i + 1);
+ }
+
+ add_menu_opt("Back", menu_pop);
+}
+
static void set_start_pts(int pts)
{
match_opts->start_pts = pts;
@@ -309,6 +352,9 @@ void menu_display()
case MENU_MATCH_OPTS:
menu_display_match_opts();
break;
+ case MENU_CUSTOM_MATCH_OPTS:
+ menu_display_custom_match_opts();
+ break;
case MENU_START_PTS:
menu_display_start_pts();
break;