aboutsummaryrefslogtreecommitdiff
path: root/ai_trade.c
blob: bf6aaf8dadce276380a680dc17f23908e5137c08 (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
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;
}
bgstack15