From 01d411a870580e368d6530a2eaacd9c828a258ce Mon Sep 17 00:00:00 2001 From: Nathan Vance Date: Tue, 24 Mar 2015 12:34:19 -0400 Subject: Implemented ai trading (buggy) --- ai.c | 22 ++++++++++++++++++++-- ai_trade.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- data.c | 13 +++++++++++-- trade.c | 2 +- 4 files changed, 87 insertions(+), 8 deletions(-) diff --git a/ai.c b/ai.c index 1eb8c11..e166585 100644 --- a/ai.c +++ b/ai.c @@ -5,6 +5,7 @@ int* data_gethand(int p); int data_numcards(int p); int data_getera(); int data_getnext(int p); //next recipient of the hand +int data_getdir(int dir, int p); int data_getwonderstages(int p); void data_discard(int p, int card); void data_build(int p, int card); @@ -16,22 +17,34 @@ int weight_buildwonder(int player); int* cards_getproduction(int era, int card); int* cards_getcost(int era, int card); int data_hasbuiltname(int p, int era, int card); +int* get_intarray(int size); +int* ai_trade(int player, int era, int card); int* ai_bestcard(int *hand, int player) //return card { int i, temp; int max = 0; int card = 0; + int *trade = get_intarray(3); + static int ret[5]; for(i = 0; hand[i] != -1 && i < 7; i++) { + trade[0] = trade[1] = trade[2] = 0; temp = weight_buildcard(data_getera(), hand[i], player); - if(! data_canafford(player, data_getera(), hand[i]) || data_hasbuiltname(player, data_getera(), hand[i])) + if(data_hasbuiltname(player, data_getera(), hand[i])) temp = 0; + else if(! data_canafford(player, data_getera(), hand[i])) { + trade = ai_trade(player, data_getera(), hand[i]); + if(trade[2]) temp -= trade[2] / 3; + else temp = 0; + } if(temp > max) { max = temp; card = hand[i]; + ret[2] = trade[0]; + ret[3] = trade[1]; + ret[4] = trade[2]; } } - static int ret[2]; ret[0] = max; ret[1] = card; return ret; @@ -42,11 +55,16 @@ void ai_turn(int player) int *bestcard; int *hand = data_gethand(player); int wonder = 0; + int i; if(data_getwonderstages(player) < wonder_numstages(player)) wonder = weight_buildwonder(player); bestcard = ai_bestcard(hand, player); if(bestcard[0] > wonder && bestcard[0] > 0) { data_build(player, bestcard[1]); + for(i = 0; i < 2; i++) { + data_addgold(bestcard[2+i], data_getdir(i, player)); + } + data_addgold(bestcard[4] * -1, player); return; } bestcard = ai_bestcard(hand, data_getnext(player)); diff --git a/ai_trade.c b/ai_trade.c index e5aef1e..e45272e 100644 --- a/ai_trade.c +++ b/ai_trade.c @@ -1,13 +1,65 @@ #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_clear(int player); +void trade_set(int player, int trade[3][GOLD]); +int* trade_gettradables(int player, int direction); + +void ai_cleartrade(int trade[3][GOLD]) +{ + int i, j; + for(i = 0; i < 3; i++) + for(j = 0; j < GOLD; j++) + trade[i][j] = 0; +} -int ai_trade(int player, int *cost) +void recurse(int ret[], int cost, int trade[3][GOLD], int player, int era, int card) { - while(data_getgold(player) > 1) { - //finish trade_set and this + int i, j; + 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; //if we can afford it, don't bother recursing further. } + for(i = 0; i < 2; i++) { + 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]+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); + ai_cleartrade(trade); + trade_set(player, trade); + return ret; } diff --git a/data.c b/data.c index 6ad09f2..81bfe56 100644 --- a/data.c +++ b/data.c @@ -288,9 +288,8 @@ int data_productiontype(int e, int card) int* data_getdefinites(int p) { int *ret = get_intarray(GOLD); - int *trade = trade_buffer(); int i, j, k, *prod; - for(i = 0; i < GOLD; i++) ret[i] = trade[i]; + for(i = 0; i < GOLD; i++) ret[i] = 0; for(i = 0; i < 3; i++) { for(j = 0; j < 7; j++) { if(data_productiontype(i, player[p][i][j]) == 1) { @@ -315,6 +314,15 @@ void data_removedefinites(int p, int *cost) } } +void data_removetraded(int p, int *cost) +{ + int *trade = trade_buffer(); + int i; + for(i = 0; i < GOLD; i++) { + cost[i] -= trade[i]; + if(cost[i] < 0) cost[i] = 0; + } +} int** data_getindefinites(int p) { @@ -455,6 +463,7 @@ int data_canafford(int p, int era, int card) if(cost[GOLD] > data_getgold(p)) return 0; int i, j, k; data_removedefinites(p, cost); + data_removetraded(p, cost); if(data_iszerocost(cost)) return 1; return recurse(cost, data_getindefinites(p), 0); } diff --git a/trade.c b/trade.c index 4299bb8..8c7cb98 100644 --- a/trade.c +++ b/trade.c @@ -51,7 +51,7 @@ void trade_clear(int player) tradebuffer[i][j] = 0; } -void trade_set(int player, int **trade) +void trade_set(int player, int trade[3][GOLD]) { trade_clear(player); int i, j; -- cgit