summaryrefslogtreecommitdiff
path: root/web/web_match.c
blob: d4dac50b67757eb8812e23f3618e53862709ab19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "web_match.h"

#include "match.h"

#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

struct match_state *state;
struct match_opts *match_opts;
static int curr_id = 0;

void match_new()
{
	if (state) free_state();

	state = calloc(1, sizeof(*state));
	state->id = ++curr_id;
	state->m = match_init();
}

void free_state()
{
	free(state->m);
	free(state);
	state = NULL;
}

void match_opts_new()
{
	if (match_opts) match_opts_free();

	match_opts = calloc(1, sizeof(*match_opts));
	match_opts->start_pts = 501;

	match_opts->size_players = 2;
	match_opts->players = malloc(
		match_opts->size_players * sizeof(*(match_opts->players)));
}

void match_opts_add_player(enum player_type type, char *name)
{
	if (match_opts->num_players == match_opts->size_players) {
		match_opts->size_players +=
			match_opts->size_players ?
				match_opts->size_players : 1;
		match_opts->players = realloc(match_opts->players,
			match_opts->size_players *
				sizeof(*(match_opts->players)));
	}

	int pn = ++match_opts->num_players;
	if (!match_opts->throws_first)
		match_opts->throws_first = pn;

	match_opts->players[pn - 1].type = type;
	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()
{
	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;
}

struct leg *state_active_leg()
{
	return state->m->legs[state->m->active_player - 1];
}

bool match_player_is_comp(int pn)
{
	return state->m->players[pn - 1].type == PT_COMP;
}

bool match_first_user_has_thrown()
{
	for (int i = 0, np = state->m->n_players; i < np; ++i) {
		int pn = match_opts->throws_first + i;
		if (pn > np)
			pn -= np;

		if (!match_player_is_comp(pn))
			return !!state->m->legs[pn - 1]->n_visits;
	}

	return false;
}