diff options
-rw-r--r-- | ai_trade.c | 71 | ||||
-rw-r--r-- | data.c | 5 | ||||
-rw-r--r-- | trade.c | 9 |
3 files changed, 58 insertions, 27 deletions
@@ -13,46 +13,74 @@ 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++) + 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]; } -int recurse(int ret[], int cost, int trade[3][GOLD], int player, int era, int card) +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)) { - if(cost < ret[2] || ret[2] == 0) { - ret[2] = cost; - ret[0] = ret[1] = 0; - for(i = 0; i < 2; i++) { - for(j = 0; j < GOLD; j++) { - ret[i] += get_trade(player, j, i) * trade[i][j]; - } - } - } - return 1; //if we can afford it, don't bother recursing further. + saveCost(trade, player); + return; //if we can afford it, don't bother recursing further. } - for(k = 0; k < 2; k++) { - if(data_gettotvps(data_getdir(0, player)) > data_gettotvps(data_getdir(1, player))) - i = 0; - else i = 1; - if(k) i = (i-1)*-1; //The preceeding block selects the weaker neighbor for trade preference. - for(j = 0; j < GOLD; j++) { - if(data_getgold(player) - cost - get_trade(player, j, i) >= 0 && trade_gettradables(player, i)[j] - trade[i][j] >= trade[i][j]+1) { + 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); - if(recurse(ret, cost+get_trade(player, j, i), trade, player, era, card)) return 1; + recurse(ret, cost+get_trade(player, j, i), trade, player, era, card); trade[i][j]--; trade[2][j]--; } } } - return 0; } int* ai_trade(int player, int era, int card) @@ -65,6 +93,7 @@ int* ai_trade(int player, int era, int card) 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; @@ -570,15 +570,14 @@ int data_iscouponed(int p, int era, int card) int data_canafford(int p, int era, int card) { - int ret; if(data_iscouponed(p, era, card)) return 1; int *cost = cards_getcost(era, card); + if(cost[GOLD] > data_getgold(p) && p != hasfreebuild) return 0; int i, j, k; data_removedefinites(p, cost); data_removetraded(p, cost); if(data_iszerocost(cost)) return 1; - ret = recurse(cost, data_getindefinites(p), 0) && (cost[GOLD] <= data_getgold(p)); - if(ret) return 1; + if(recurse(cost, data_getindefinites(p), 0)) return 1; if(p == hasfreebuild) return 2; return 0; } @@ -54,12 +54,15 @@ void trade_clear(int player) void trade_set(int player, int trade[3][GOLD]) { int i, j; - for(i = 0; i < 3; i++) { + for(i = 0; i < 3; i++) + tradebuffer[i][GOLD] = 0; //we deal with gold in the method that calls this + for(i = 0; i < 2; i++) { for(j = 0; j < GOLD; j++) { - tradebuffer[i][j] = trade[i][j]; + tradebuffer[i][j] = trade[i][j] * -1; } - tradebuffer[i][GOLD] = 0; //we deal with gold in the method that calls this } + for(j = 0; j < GOLD; j++) + tradebuffer[2][j] = trade[2][j]; } //gold amounts relative to player |