aboutsummaryrefslogtreecommitdiff
path: root/ai_trade.c
blob: d20d05dc0194dd71beb09639b48aadc05fd1b204 (plain)
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
#include "7w.h"

/*
 A brief note on why we have separated the functionality of trade.c and ai_trade.c in regards to gold transfer:
 This class is designed for the sole purpose of analyzing potential transactions without committing to any. Therefore, such handy methods as trade_commit are not used.
 */

static int bestCost[3];
static int baseCost[NUMRESOURCES];

void ai_cleartrade(int trade[3][GOLD]) {
	int i, j;
	for (i = 0; i < 3; i++) {
		bestCost[i] = 0;
		for (j = 0; j < GOLD; j++)
			trade[i][j] = 0;
	}
}

int saveCost(int trade[3][GOLD], int player) {
	int buffer[3] = { 0 };
	int i, j;
	for (i = 0; i < 2; i++) {
		for (j = 0; j < GOLD; j++) {
			buffer[i] += get_trade(player, j, i) * trade[i][j];
		}
		buffer[2] += buffer[i];
	}
	if (buffer[2] < bestCost[2] || bestCost[2] == 0) {
		for (i = 0; i < 3; i++)
			bestCost[i] = buffer[i];
	}
	return buffer[2];
}

void restoreCost(int ret[3]) {
	int i;
	for (i = 0; i < 3; i++)
		ret[i] = bestCost[i];
}

int bestNeighbor(int player, int res) {
	int best = 0;
	if (get_trade(player, res, 0) != get_trade(player, res, 1)) {
		best = (get_trade(player, res, 0) < get_trade(player, res, 1)) ? 0 : 1;
	} else if (data_gettotvps(data_getdir(0, player))
			> data_gettotvps(data_getdir(1, player)))
		best = 0;
	else
		best = 1;
	return best;
}

void recurse(int ret[], int cost, int trade[3][GOLD], int player, int era,
		int card) {
	int i, j, k;
	int tradables[GOLD + 1];
	data_gettradables(player, tradables);
	if (data_canafford(player, era, card)) {
		saveCost(trade, player);
		return; //if we can afford it, don't bother recursing further.
	}
	for (j = 0; j < GOLD; j++) {
		if (baseCost[j] - trade[0][j] - trade[1][j] - tradables[j] <= 0)
			continue;
		for (k = 0; k < 1; k++) {
			i = bestNeighbor(player, j);
			if (k)
				i = (i - 1) * -1;
			int temp[GOLD + 1];
			if (data_getgold(player) - cost - get_trade(player, j, i) >= 0
					&& trade_gettradables(player, i, temp)[j] >= 1) {
				trade[i][j]++;
				trade[2][j]++;
				trade_set(player, trade);
				recurse(ret, cost + get_trade(player, j, i), trade, player, era,
						card);
				trade[i][j]--;
				trade[2][j]--;
			}
		}
	}
}

int* ai_trade(int player, int era, int card, int ret[3]) {
	int trade[3][GOLD];
	int i;
	for (i = 0; i < 3; i++)
		ret[i] = 0;
	ai_cleartrade(trade);
	cards_getcost(era, card, baseCost);
	recurse(ret, 0, trade, player, era, card);
	restoreCost(ret);
	ai_cleartrade(trade);
	trade_set(player, trade);
	return ret;
}
bgstack15