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
|
#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 commiting to any. Therefore, such handy methods as trade_commit are not used.
*/
int data_getgold(int p);
int get_trade(int player, int type, int direction);
int data_canafford(int p, int era, int card);
void trade_set(int player, int trade[3][GOLD]);
int* trade_gettradables(int player, int direction);
int data_gettotvps(int p);
int data_getdir(int dir, int p);
static int bestCost[3];
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;
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++) {
for(k = 0; k < 1; k++) {
i = bestNeighbor(player, j);
if(k) i = (i-1)*-1;
if(data_getgold(player) - cost - get_trade(player, j, i) >= 0 && trade_gettradables(player, i)[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)
{
static int ret[3]; //east gold, west gold, player gold
int trade[3][GOLD];
int i;
for(i = 0; i < 3; i++)
ret[i] = 0;
ai_cleartrade(trade);
int gold = data_getgold(player);
recurse(ret, 0, trade, player, era, card);
restoreCost(ret);
ai_cleartrade(trade);
trade_set(player, trade);
return ret;
}
|