[WIP] Superdom: game improvements

- macro-ify board dimensions, surrender thresholds
 - make AI skill level adjustable
 - let AI buy nukes in hard mode (still can't use them yet)
 - make nukes persistent (stay after an invasion)
 - make AI treat nukes with priority

Change-Id: I1add6250766810787080624bd9e36026df449509
Reviewed-on: http://gerrit.rockbox.org/940
Reviewed-by: Michael Giacomelli <giac2000@hotmail.com>
This commit is contained in:
Franklin Wei 2014-08-28 19:19:08 -04:00 committed by Michael Giacomelli
parent a231754af9
commit bc00d38987

View file

@ -33,9 +33,55 @@
char buf[255]; char buf[255];
/* key mappings */
#define SUPERDOM_OK PLA_SELECT
#define SUPERDOM_CANCEL PLA_CANCEL
#define SUPERDOM_RIGHT PLA_RIGHT
#define SUPERDOM_LEFT PLA_LEFT
#define SUPERDOM_UP PLA_UP
#define SUPERDOM_DOWN PLA_DOWN
#define SUPERDOM_RIGHT_REPEAT PLA_RIGHT_REPEAT
#define SUPERDOM_LEFT_REPEAT PLA_LEFT_REPEAT
#define SUPERDOM_UP_REPEAT PLA_UP_REPEAT
#define SUPERDOM_DOWN_REPEAT PLA_DOWN_REPEAT
/***** game settings *****/
/* Some defines for the prices */
#define PRICE_MEN 1
#define PRICE_MOVE 100
#define PRICE_TANK 300
#define PRICE_PLANE 600
#define PRICE_FARM 1150
#define PRICE_FACTORY 1300
#define PRICE_NUKE 2000
#define STRINGIZE_2(X) #X
#define STRINGIZE(X) STRINGIZE_2(X)
#define PRICE_MEN_STR STRINGIZE(PRICE_MEN)
#define PRICE_MOVE_STR STRINGIZE(PRICE_MOVE)
#define PRICE_TANK_STR STRINGIZE(PRICE_TANK)
#define PRICE_PLANE_STR STRINGIZE(PRICE_PLANE)
#define PRICE_FARM_STR STRINGIZE(PRICE_FARM)
#define PRICE_FACTORY_STR STRINGIZE(PRICE_FACTORY)
#define PRICE_NUKE_STR STRINGIZE(PRICE_NUKE)
/* surrender thresholds */
#define HUMAN_SURRENDER_THRESHOLD 15
#define COMPUTER_SURRENDER_THRESHOLD 15
#define COMPUTER_HARD_SURRENDER_THRESHOLD 25
/* board size */
#define BOARD_SIZE 10
#define NUM_SPACES (BOARD_SIZE*BOARD_SIZE)
#define COLOUR_DARK 0 #define COLOUR_DARK 0
#define COLOUR_LIGHT 1 #define COLOUR_LIGHT 1
/* drawing presets */
#define MARGIN 5 #define MARGIN 5
#if (LCD_DEPTH >= 16) #if (LCD_DEPTH >= 16)
@ -45,11 +91,11 @@ char buf[255];
#endif #endif
#if LCD_WIDTH > LCD_HEIGHT #if LCD_WIDTH > LCD_HEIGHT
#define BOX_WIDTH ((LCD_WIDTH-(MARGIN*2))/10) #define BOX_WIDTH ((LCD_WIDTH-(MARGIN*2))/BOARD_SIZE)
#define BOX_HEIGHT ((BOX_WIDTH*2)/3) #define BOX_HEIGHT ((BOX_WIDTH*2)/3)
#else #else
#define BOX_HEIGHT ((LCD_HEIGHT-(MARGIN*2)-15)/10) #define BOX_HEIGHT ((LCD_HEIGHT-(MARGIN*2)-15)/BOARD_SIZE)
#define BOX_WIDTH ((BOX_HEIGHT*2)/3) #define BOX_WIDTH ((BOX_HEIGHT*2)/3)
#endif #endif
@ -72,38 +118,6 @@ char buf[255];
#define ICON_HEIGHT (BMPHEIGHT_superdom_boarditems/6) #define ICON_HEIGHT (BMPHEIGHT_superdom_boarditems/6)
#define ICON_WIDTH (BMPWIDTH_superdom_boarditems/2) #define ICON_WIDTH (BMPWIDTH_superdom_boarditems/2)
#define SUPERDOM_OK PLA_SELECT
#define SUPERDOM_CANCEL PLA_CANCEL
#define SUPERDOM_RIGHT PLA_RIGHT
#define SUPERDOM_LEFT PLA_LEFT
#define SUPERDOM_UP PLA_UP
#define SUPERDOM_DOWN PLA_DOWN
#define SUPERDOM_RIGHT_REPEAT PLA_RIGHT_REPEAT
#define SUPERDOM_LEFT_REPEAT PLA_LEFT_REPEAT
#define SUPERDOM_UP_REPEAT PLA_UP_REPEAT
#define SUPERDOM_DOWN_REPEAT PLA_DOWN_REPEAT
/* Some defines for the prices */
#define PRICE_MEN 1
#define PRICE_MOVE 100
#define PRICE_TANK 300
#define PRICE_PLANE 600
#define PRICE_FARM 1150
#define PRICE_FACTORY 1300
#define PRICE_NUKE 2000
#define STRINGIZE_2(X) #X
#define STRINGIZE(X) STRINGIZE_2(X)
#define PRICE_MEN_STR STRINGIZE(PRICE_MEN)
#define PRICE_MOVE_STR STRINGIZE(PRICE_MOVE)
#define PRICE_TANK_STR STRINGIZE(PRICE_TANK)
#define PRICE_PLANE_STR STRINGIZE(PRICE_PLANE)
#define PRICE_FARM_STR STRINGIZE(PRICE_FARM)
#define PRICE_FACTORY_STR STRINGIZE(PRICE_FACTORY)
#define PRICE_NUKE_STR STRINGIZE(PRICE_NUKE)
enum { enum {
RET_VAL_OK, RET_VAL_OK,
RET_VAL_USB, RET_VAL_USB,
@ -149,6 +163,21 @@ static struct settings {
int startcash; int startcash;
int startfood; int startfood;
int movesperturn; int movesperturn;
/* 1=easy 2=medium 3=hard */
/* AI difficulty works like this:
easy:
- no movement
- no investing
medium:
- movement
- investing
- can build factories/farms
hard:
- nuclear war
- harder to surrender
*/
int compdiff;
bool spoil_enabled;
} superdom_settings; } superdom_settings;
static struct resources humanres; static struct resources humanres;
@ -161,7 +190,7 @@ static struct cursor {
int y; int y;
} cursor; } cursor;
static struct tile board[12][12]; static struct tile board[BOARD_SIZE+2][BOARD_SIZE+2];
static const struct button_mapping *plugin_contexts[] = { pla_main_ctx }; static const struct button_mapping *plugin_contexts[] = { pla_main_ctx };
@ -171,9 +200,9 @@ static void init_board(void)
rb->srand(*rb->current_tick); rb->srand(*rb->current_tick);
for(i=0;i<12;i++) for(i=0;i<12;i++)
{ /* Hopefully about 50% each colour */ { /* Hopefully about 50% each colour */
for(j=0;j<12;j++) for(j=0;j<BOARD_SIZE+2;j++)
{ {
if((i<1)||(j<1)||(i>10)||(j>10)) if((i<1)||(j<1)||(i>BOARD_SIZE)||(j>BOARD_SIZE))
board[i][j].colour = -1; /* Unset */ board[i][j].colour = -1; /* Unset */
else else
board[i][j].colour = rb->rand()%2; board[i][j].colour = rb->rand()%2;
@ -188,8 +217,8 @@ static void init_board(void)
while(compres.farms < superdom_settings.compstartfarms) while(compres.farms < superdom_settings.compstartfarms)
{ {
i = rb->rand()%10 + 1; i = rb->rand()%BOARD_SIZE + 1;
j = rb->rand()%10 + 1; j = rb->rand()%BOARD_SIZE + 1;
if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false)) if((board[i][j].colour == COLOUR_DARK) && (board[i][j].farm == false))
{ {
board[i][j].farm = true; board[i][j].farm = true;
@ -198,8 +227,8 @@ static void init_board(void)
} }
while(compres.inds < superdom_settings.compstartinds) while(compres.inds < superdom_settings.compstartinds)
{ {
i = rb->rand()%10 + 1; i = rb->rand()%BOARD_SIZE + 1;
j = rb->rand()%10 + 1; j = rb->rand()%BOARD_SIZE + 1;
if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false)) if((board[i][j].colour == COLOUR_DARK) && (board[i][j].ind == false))
{ {
board[i][j].ind = true; board[i][j].ind = true;
@ -208,8 +237,8 @@ static void init_board(void)
} }
while(humanres.farms < superdom_settings.humanstartfarms) while(humanres.farms < superdom_settings.humanstartfarms)
{ {
i = rb->rand()%10 + 1; i = rb->rand()%BOARD_SIZE + 1;
j = rb->rand()%10 + 1; j = rb->rand()%BOARD_SIZE + 1;
if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false)) if((board[i][j].colour == COLOUR_LIGHT)&&(board[i][j].farm == false))
{ {
board[i][j].farm = true; board[i][j].farm = true;
@ -218,8 +247,8 @@ static void init_board(void)
} }
while(humanres.inds < superdom_settings.humanstartinds) while(humanres.inds < superdom_settings.humanstartinds)
{ {
i = rb->rand()%10 + 1; i = rb->rand()%BOARD_SIZE + 1;
j = rb->rand()%10 + 1; j = rb->rand()%BOARD_SIZE + 1;
if((board[i][j].colour == COLOUR_LIGHT) && (board[i][j].ind == false)) if((board[i][j].colour == COLOUR_LIGHT) && (board[i][j].ind == false))
{ {
board[i][j].ind = true; board[i][j].ind = true;
@ -232,9 +261,9 @@ void draw_board(void)
{ {
int i,j; int i,j;
rb->lcd_clear_display(); rb->lcd_clear_display();
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if(board[i][j].colour == COLOUR_DARK) if(board[i][j].colour == COLOUR_DARK)
{ {
@ -325,14 +354,14 @@ void draw_board(void)
} }
rb->lcd_set_foreground(LCD_BLACK); rb->lcd_set_foreground(LCD_BLACK);
/* Draw Horizontal lines */ /* Draw Horizontal lines */
for(i=0;i<=10;i++) for(i=0;i<=BOARD_SIZE;i++)
{ {
rb->lcd_hline(MARGIN, MARGIN+(BOX_WIDTH*10), MARGIN+(BOX_HEIGHT*i)); rb->lcd_hline(MARGIN, MARGIN+(BOX_WIDTH*BOARD_SIZE), MARGIN+(BOX_HEIGHT*i));
} }
/* Draw Vertical lines */ /* Draw Vertical lines */
for(i=0;i<=10;i++) for(i=0;i<=BOARD_SIZE;i++)
{ {
rb->lcd_vline(MARGIN+(BOX_WIDTH*i), MARGIN, MARGIN+(BOX_HEIGHT*10)); rb->lcd_vline(MARGIN+(BOX_WIDTH*i), MARGIN, MARGIN+(BOX_HEIGHT*BOARD_SIZE));
} }
rb->lcd_update(); rb->lcd_update();
} }
@ -346,15 +375,30 @@ static int calc_strength(int colour, int x, int y)
{ {
if(board[x+a][y+b].colour==colour) if(board[x+a][y+b].colour==colour)
{ {
score += 10; if(a && b) /* diagonally adjacent, give less influence */
if(board[x + a][y + b].tank || board[x + a][y + b].farm) {
score += 30; score += 5;
if(board[x + a][y + b].plane || board[x + a][y + b].ind) if(board[x + a][y + b].tank || board[x + a][y + b].farm)
score += 40; score += 15;
if(board[x + a][y + b].nuke) if(board[x + a][y + b].plane || board[x + a][y + b].ind)
score += 20; score += 20;
if(board[x + a][y + b].men) if(board[x + a][y + b].nuke)
score += (board[x + a][y + b].men*133/1000); score += 10;
if(board[x + a][y + b].men)
score += (board[x + a][y + b].men*133/1000);
}
else
{
score += 10;
if(board[x + a][y + b].tank || board[x + a][y + b].farm)
score += 30;
if(board[x + a][y + b].plane || board[x + a][y + b].ind)
score += 40;
if(board[x + a][y + b].nuke)
score += 20;
if(board[x + a][y + b].men)
score += (board[x + a][y + b].men*133/1000);
}
} }
} }
} }
@ -468,6 +512,7 @@ void gen_resources(void)
static void update_score(void) static void update_score(void)
{ {
int strength; int strength;
rb->lcd_setfont(FONT_SYSFIXED); rb->lcd_setfont(FONT_SYSFIXED);
rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID); rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20); rb->lcd_fillrect(5,LCD_HEIGHT-20,105,20);
@ -486,7 +531,7 @@ static int settings_menu(void)
MENUITEM_STRINGLIST(menu, "Super Domination Settings", NULL, MENUITEM_STRINGLIST(menu, "Super Domination Settings", NULL,
"Computer starting farms", "Computer starting factories", "Computer starting farms", "Computer starting factories",
"Human starting farms", "Human starting factories", "Human starting farms", "Human starting factories",
"Starting cash", "Starting food", "Moves per turn"); "Starting cash", "Starting food", "Computer difficulty","Food spoilage", "Moves per turn");
while(1) while(1)
{ {
@ -523,6 +568,22 @@ static int settings_menu(void)
250, 0, 5000, NULL); 250, 0, 5000, NULL);
break; break;
case 6: case 6:
{
static const struct opt_items difficulty_options[3]={
{"Easy", 1},
{"Intermediate", 2},
{"Hard", 3}
};
rb->set_option("Computer difficulty", &superdom_settings.compdiff,
INT, difficulty_options, 3, NULL);
superdom_settings.compdiff++;
break;
}
case 7:
rb->set_bool_options("Food spoilage", &superdom_settings.spoil_enabled, "Enabled",
0, "Disabled", 0, NULL);
break;
case 8:
rb->set_int("Moves per turn", "", UNIT_INT, rb->set_int("Moves per turn", "", UNIT_INT,
&superdom_settings.movesperturn, NULL, &superdom_settings.movesperturn, NULL,
1, 1, 5, NULL); 1, 1, 5, NULL);
@ -1499,7 +1560,7 @@ static int select_square(void)
} }
else else
{ {
cursor.x = 10; cursor.x = BOARD_SIZE;
} }
update_score(); update_score();
draw_cursor(); draw_cursor();
@ -1507,7 +1568,7 @@ static int select_square(void)
case SUPERDOM_RIGHT: case SUPERDOM_RIGHT:
case SUPERDOM_RIGHT_REPEAT: case SUPERDOM_RIGHT_REPEAT:
draw_cursor(); /* Deselect the current tile */ draw_cursor(); /* Deselect the current tile */
if(cursor.x<10) if(cursor.x<BOARD_SIZE)
{ {
cursor.x++; cursor.x++;
} }
@ -1531,9 +1592,9 @@ static int select_square(void)
if(cursor.x > 1) if(cursor.x > 1)
cursor.x--; cursor.x--;
else else
cursor.x = 10; cursor.x = BOARD_SIZE;
#endif #endif
cursor.y = 10; cursor.y = BOARD_SIZE;
} }
update_score(); update_score();
draw_cursor(); draw_cursor();
@ -1541,14 +1602,14 @@ static int select_square(void)
case SUPERDOM_DOWN: case SUPERDOM_DOWN:
case SUPERDOM_DOWN_REPEAT: case SUPERDOM_DOWN_REPEAT:
draw_cursor(); /* Deselect the current tile */ draw_cursor(); /* Deselect the current tile */
if(cursor.y<10) if(cursor.y<BOARD_SIZE)
{ {
cursor.y++; cursor.y++;
} }
else else
{ {
#if CONFIG_KEYPAD == IRIVER_H10_PAD #if CONFIG_KEYPAD == IRIVER_H10_PAD
if(cursor.x < 10) if(cursor.x < BOARD_SIZE)
cursor.x++; cursor.x++;
else else
cursor.x = 1; cursor.x = 1;
@ -1583,9 +1644,9 @@ static int killmen(int colour)
compres.food = 0; compres.food = 0;
} }
menkilled = 0; menkilled = 0;
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if(board[i][j].colour == colour) if(board[i][j].colour == colour)
{ {
@ -1642,11 +1703,11 @@ static int attack_territory(int colour, int x, int y)
defres->inds -= board[x][y].ind; defres->inds -= board[x][y].ind;
offres->farms += board[x][y].farm; offres->farms += board[x][y].farm;
offres->inds += board[x][y].ind; offres->inds += board[x][y].ind;
offres->nukes += board[x][y].nuke;
board[x][y].colour = colour; board[x][y].colour = colour;
board[x][y].men = 0; board[x][y].men = 0;
board[x][y].tank = false; board[x][y].tank = false;
board[x][y].plane = false; board[x][y].plane = false;
board[x][y].nuke = false;
draw_board(); draw_board();
if(human) if(human)
rb->sleep(HZ*2); rb->sleep(HZ*2);
@ -1668,6 +1729,19 @@ static int attack_territory(int colour, int x, int y)
return 0; return 0;
} }
static void spoil_food(void)
{
/* spoil 0-10% of food, different amounts for computer/player */
int spoil_amount=humanres.food*(0.1*rb->rand()/RAND_MAX);
if(spoil_amount)
rb->splashf(2*HZ, "Spoilage claims %d units of food", spoil_amount);
humanres.food-=spoil_amount;
/* now for computer */
spoil_amount=compres.food*(0.1*rb->rand()/RAND_MAX);
compres.food-=spoil_amount;
}
static int war_menu(void) static int war_menu(void)
{ {
int selection = 0, temp; int selection = 0, temp;
@ -1782,7 +1856,7 @@ static void computer_allocate(void)
{ {
/* Firstly, decide whether to go offensive or defensive. /* Firstly, decide whether to go offensive or defensive.
* This is primarily decided by the human player posing a threat to either * This is primarily decided by the human player posing a threat to either
* the computer's farms or factories */ * the computer's farms, factories or nukes */
int i, j, k; int i, j, k;
bool offensive = true; bool offensive = true;
struct threat threats[4]; struct threat threats[4];
@ -1797,17 +1871,18 @@ static void computer_allocate(void)
compres.cash += compres.bank; compres.cash += compres.bank;
compres.bank = 0; compres.bank = 0;
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if(board[i][j].colour == COLOUR_DARK) if(board[i][j].colour == COLOUR_DARK)
{ {
numterritory++; numterritory++;
str_diff = calc_strength(COLOUR_LIGHT,i,j) - str_diff = calc_strength(COLOUR_LIGHT,i,j) -
calc_strength(COLOUR_DARK,i,j); calc_strength(COLOUR_DARK,i,j);
if(str_diff > 0 && (board[i][j].ind || board[i][j].farm)) if(str_diff > 0 && (board[i][j].ind || board[i][j].farm || board[i][j].nuke))
{ {
/* computer's farm/factory/nuke is being threatened */
if(numthreats < 3) if(numthreats < 3)
{ {
offensive = false; offensive = false;
@ -1821,10 +1896,24 @@ static void computer_allocate(void)
rb->yield(); rb->yield();
} }
} }
/* AI player will buy nukes if possible first */
if(compres.cash > PRICE_NUKE + PRICE_TANK && superdom_settings.compdiff>=3)
{
while(compres.cash >= PRICE_NUKE && compres.nukes < numterritory)
{
i = rb->rand()%BOARD_SIZE + 1;
j = rb->rand()%BOARD_SIZE + 1;
if(board[i][j].colour == COLOUR_DARK)
{
buy_resources(COLOUR_DARK, 5, i, j, 0);
}
rb->yield();
}
}
if(offensive) if(offensive)
{ {
/* The AI is going to go straight for the throat here and attack /* The AI is going to go straight for the throat here and attack
* the player's farms and factories. The amount of cash * the player's farms, nukes, and factories. The amount of cash
* the AI has to spend will determine how many targets there are */ * the AI has to spend will determine how many targets there are */
if(compres.cash > 1200) if(compres.cash > 1200)
{ {
@ -1839,12 +1928,12 @@ static void computer_allocate(void)
* owned by the computer. If none are found just place troops in * owned by the computer. If none are found just place troops in
* random places around the map until we run out of money */ * random places around the map until we run out of money */
k = 0; k = 0;
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if(has_adjacent(i,j) && if(has_adjacent(i,j) &&
(board[i][j].ind || board[i][j].farm)) (board[i][j].ind || board[i][j].farm || board[i][j].nuke))
{ {
if(k<numtargets) if(k<numtargets)
{ {
@ -1863,10 +1952,12 @@ static void computer_allocate(void)
{ {
/* No targets found! Randomly pick squares and if they're owned /* No targets found! Randomly pick squares and if they're owned
* by the computer then stick a tank on it. */ * by the computer then stick a tank on it. */
while(compres.cash >= 300 && compres.tanks < numterritory) { while(compres.cash >= 300 && compres.tanks < numterritory)
i = rb->rand()%10 + 1; {
j = rb->rand()%10 + 1; i = rb->rand()%BOARD_SIZE + 1;
if(board[i][j].colour == COLOUR_DARK) { j = rb->rand()%BOARD_SIZE + 1;
if(board[i][j].colour == COLOUR_DARK)
{
buy_resources(COLOUR_DARK, 1, i, j, 0); buy_resources(COLOUR_DARK, 1, i, j, 0);
} }
rb->yield(); rb->yield();
@ -1962,8 +2053,12 @@ static void computer_allocate(void)
} }
} }
} }
compres.bank += compres.cash; /* no investing in easy mode */
compres.cash = 0; if(superdom_settings.compdiff>=2)
{
compres.bank += compres.cash;
compres.cash = 0;
}
} }
static int find_adj_target(int x, int y, struct cursor* adj) static int find_adj_target(int x, int y, struct cursor* adj)
@ -2001,9 +2096,14 @@ static int find_adj_target(int x, int y, struct cursor* adj)
return 0; return 0;
} }
static void computer_movement(void)
{
}
static void computer_war(void) static void computer_war(void)
{ {
/* Work out where to attack - prioritise the defence of buildings */ /* Work out where to attack - prioritise the defence of buildings and nukes */
int i, j; int i, j;
bool found_target = true; bool found_target = true;
struct cursor adj; struct cursor adj;
@ -2011,12 +2111,12 @@ static void computer_war(void)
while(found_target) while(found_target)
{ {
found_target = false; found_target = false;
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if((board[i][j].colour == COLOUR_DARK) && if((board[i][j].colour == COLOUR_DARK) &&
(board[i][j].farm || board[i][j].ind) && (board[i][j].farm || board[i][j].ind || board[i][j].nuke) &&
find_adj_target(i, j, &adj)) find_adj_target(i, j, &adj))
{ {
found_target = true; found_target = true;
@ -2036,12 +2136,12 @@ static void computer_war(void)
while(found_target) while(found_target)
{ {
found_target = false; found_target = false;
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if(board[i][j].colour == COLOUR_LIGHT && if(board[i][j].colour == COLOUR_LIGHT &&
(board[i][j].ind || board[i][j].farm) && (board[i][j].ind || board[i][j].farm || board[i][j].nuke) &&
(calc_strength(COLOUR_DARK, i, j) >= calc_strength(COLOUR_LIGHT, i, j))) (calc_strength(COLOUR_DARK, i, j) >= calc_strength(COLOUR_LIGHT, i, j)))
{ {
found_target = true; found_target = true;
@ -2061,9 +2161,9 @@ static void computer_war(void)
while(found_target) while(found_target)
{ {
found_target = false; found_target = false;
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if(board[i][j].colour == COLOUR_LIGHT && if(board[i][j].colour == COLOUR_LIGHT &&
(calc_strength(COLOUR_DARK, i, j) >= (calc_strength(COLOUR_DARK, i, j) >=
@ -2141,6 +2241,8 @@ static void default_settings(void)
superdom_settings.startcash = 0; superdom_settings.startcash = 0;
superdom_settings.startfood = 0; superdom_settings.startfood = 0;
superdom_settings.movesperturn = 2; superdom_settings.movesperturn = 2;
superdom_settings.compdiff=2;
superdom_settings.spoil_enabled=false;
} }
static int average_strength(int colour) static int average_strength(int colour)
@ -2149,9 +2251,9 @@ static int average_strength(int colour)
* used to determine when the computer wins or loses. */ * used to determine when the computer wins or loses. */
int i,j; int i,j;
int totalpower = 0; int totalpower = 0;
for(i=1;i<11;i++) for(i=1;i<=BOARD_SIZE;i++)
{ {
for(j=1;j<11;j++) for(j=1;j<=BOARD_SIZE;j++)
{ {
if(board[i][j].colour != -1) if(board[i][j].colour != -1)
{ {
@ -2159,7 +2261,7 @@ static int average_strength(int colour)
} }
} }
} }
return totalpower/100; return totalpower/NUM_SPACES;
} }
enum plugin_status plugin_start(const void* parameter) enum plugin_status plugin_start(const void* parameter)
@ -2220,12 +2322,15 @@ startyear:
{ {
int avg_str_diff = (average_strength(COLOUR_LIGHT) - int avg_str_diff = (average_strength(COLOUR_LIGHT) -
average_strength(COLOUR_DARK)); average_strength(COLOUR_DARK));
if(avg_str_diff > 15) /* computer will hold out longer in hard mode */
if(avg_str_diff > (superdom_settings.compdiff>=3 ?
COMPUTER_HARD_SURRENDER_THRESHOLD :
COMPUTER_SURRENDER_THRESHOLD))
{ {
rb->splash(HZ*4, "The computer has surrendered. You win."); rb->splash(HZ*4, "The computer has surrendered. You win.");
return PLUGIN_OK; return PLUGIN_OK;
} }
if(-avg_str_diff > 15) if(-avg_str_diff > HUMAN_SURRENDER_THRESHOLD)
{ {
rb->splash(HZ*4, "Your army have suffered terrible morale from" rb->splash(HZ*4, "Your army have suffered terrible morale from"
" the bleak prospects of winning. You lose."); " the bleak prospects of winning. You lose.");
@ -2259,6 +2364,15 @@ startyear:
return PLUGIN_OK; return PLUGIN_OK;
break; break;
} }
/* computer movement */
computer_movement();
/* spoil food */
if(superdom_settings.spoil_enabled)
{
spoil_food();
}
/* feed men */ /* feed men */
if(humanres.men) if(humanres.men)
{ {