[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: checking in
On Thursday, 21 Sep 2000, Galen Johnson <gjohnson@totalsports.net> said:
> If we can get the new AI a little more user friendly (I haven't
>won a single battle since I installed Mike and Rob's patch) I'd like to
>include that as well since it does seem to play better.
I had a closer look at the way skill is managed, and I discovered that it's even messier than I thought. The #defines for FIELD_SKILL_HARD etc were unused, and so were many fields in computer_data. I have changed these all around to work with the new AI. Some fields are still unused and there is room for improvement, e.g. skill_level may need to be revisited for cell-style movement.)
skill_level, as defined in FIELD_SKILL_HARD etc, is the average number of frames for the computer to skip. I probably should have written better comments. Anyway, here's how it works: Each frame, FIELD_SKILL is applied to a simplified random number test that decides whether to skip this frame. If the computer skips a frame, that means it does the same thing it did last frame instead of recalculating its action.
Despite repeated (but brief) attempts, I haven't been able to get SSH working so I can use the CVS archive. Instead, I've included a patch below.
Galen, try the patch out and change the value for FIELD_SKILL_EASY until you think it's the right difficulty. Change the other values as you see fit.
- Mike
--- xarchon-mike.rob/src/computer.c Thu Aug 24 15:34:45 2000
+++ xarchon-working/src/computer.c Wed Oct 4 14:42:57 2000
@@ -23,14 +23,20 @@
#define DATA(x) (computer_data[configs[computer_side]->data_num].x)
#define FIELD_SKILL DATA(skill_level)
-#define SHOOT_DISTANCE DATA(shoot_distance)
-#define ACTOR_DISTANCE DATA(actor_distance)
+#define TIME_TOLERANCE DATA(time_tolerance)
+#define DIST_TOLERANCE DATA(dist_tolerance)
#define ACTOR_RECHARGE DATA(actor_recharge)
#define NUM_GOOD_MOVES DATA(num_good_moves)
-#define FIELD_SKILL_HARD 0
-#define FIELD_SKILL_MEDIUM 10
-#define FIELD_SKILL_EASY 20
+/* these field_skill values are the number of frames to skip between actions */
+#define FIELD_SKILL_HARD 4
+#define FIELD_SKILL_MEDIUM 9
+#define FIELD_SKILL_EASY 13
+
+/* dist_tolerance is the range between max and min distances from enemy */
+#define DIST_TOLERANCE_EASY CELL_XSIZE * 3
+#define DIST_TOLERANCE_MEDIUM CELL_XSIZE * 2
+#define DIST_TOLERANCE_HARD CELL_XSIZE
/*--------------------------------------------------------------------------*/
/* enums */
@@ -66,11 +72,10 @@
typedef struct {
/* field */
- int skill_level; /* how easy should the computer be */
- /* the following three are unused in computer.c. Get rid of them? - mhc */
- int shoot_distance; /* escape missiles this close */
- int actor_distance; /* escape actors this close, who */
- int actor_recharge; /* are at this recharge level */
+ int skill_level; /* how many frames to skip on field */
+ int time_tolerance; /* (unused) when to dodge missile */
+ int dist_tolerance; /* range between min & max dist */
+ int actor_recharge; /* (unused) min enemy recharge level */
/* board */
int num_good_moves; /* good moves to consider (max 32) */
} COMPUTER_DATA;
@@ -162,9 +167,9 @@
};
static COMPUTER_DATA computer_data[3] = {
- { 45, 2, 7, FPS * 0.5, 6 },
- { 9, 2, 7, FPS * 0.5, 4 },
- { 4, 5, 5, FPS * 0.3, 1 }
+ { FIELD_SKILL_EASY, 2, DIST_TOLERANCE_EASY, FPS * 0.5, 6 },
+ { FIELD_SKILL_MEDIUM, 2, DIST_TOLERANCE_MEDIUM, FPS * 0.5, 4 },
+ { FIELD_SKILL_HARD, 5, DIST_TOLERANCE_HARD, FPS * 0.3, 1 }
};
static DAMAGE computer_damage[ACTOR_NUM_LIGHT + 1][ACTOR_NUM_DARK + 1];
@@ -630,41 +635,45 @@
void computer_field_compute_stats(FIELD_STATS *stats, FIELD_ACTOR *fa,
FIELD_ACTOR *enemy)
{
- int safe_distance, max_unsafe_distance, min_unsafe_distance;
+ int safe_distance, max_safe_distance;
+ int max_unsafe_distance, min_unsafe_distance;
- /* compute the minimum distance fa can be and still dodge a dead-on */
- /* shot from enemy */
+ /* compute the minimum distance fa can be and still dodge a dead-on */
+ /* shot from enemy */
if ((enemy->weapon->actor->type & ACTOR_WEAPON_HAND) == ACTOR_WEAPON_HAND) {
- safe_distance = 3*CELL_XSIZE/2 + enemy->actor->speed;
- max_unsafe_distance = safe_distance;
+ safe_distance = 3*CELL_XSIZE/2 + enemy->actor->speed;
+ max_unsafe_distance = safe_distance;
+ min_unsafe_distance = CELL_XSIZE/2;
+ }
+ else if ((enemy->weapon->actor->type & ACTOR_WEAPON_CLOUD) ==
+ ACTOR_WEAPON_CLOUD) {
+ if ((enemy->weapon->actor->type & ACTOR_FREEZE_USER) ==
+ ACTOR_FREEZE_USER) {
+ safe_distance = 7*CELL_XSIZE/2 + enemy->actor->speed;
+ max_unsafe_distance = 3*CELL_XSIZE/2;
+ min_unsafe_distance = 0;
+ }
+ else {
+ safe_distance = 7*CELL_XSIZE/2 + 2*enemy->actor->speed;
+ max_unsafe_distance = 3*CELL_XSIZE/2;
min_unsafe_distance = CELL_XSIZE/2;
+ }
+ } else {
+ safe_distance = enemy->weapon->actor->speed *
+ (1 + 2*CELL_XSIZE / (3*fa->actor->speed)) + CELL_XSIZE;
+ max_unsafe_distance = safe_distance;
+ min_unsafe_distance = safe_distance - DIST_TOLERANCE;
}
- else if ((enemy->weapon->actor->type & ACTOR_WEAPON_CLOUD) ==
- ACTOR_WEAPON_CLOUD) {
- if ((enemy->weapon->actor->type & ACTOR_FREEZE_USER) ==
- ACTOR_FREEZE_USER) {
- safe_distance = 7*CELL_XSIZE/2 + enemy->actor->speed;
- max_unsafe_distance = 3*CELL_XSIZE/2;
- min_unsafe_distance = 0;
- }
- else {
- safe_distance = 7*CELL_XSIZE/2 + 2*enemy->actor->speed;
- max_unsafe_distance = 3*CELL_XSIZE/2;
- min_unsafe_distance = CELL_XSIZE/2;
- }
- } else {
- safe_distance = enemy->weapon->actor->speed*(1 + 2*CELL_XSIZE/
- (3*fa->actor->speed)) + CELL_XSIZE;
- max_unsafe_distance = safe_distance;
- min_unsafe_distance = safe_distance - CELL_XSIZE;
- }
- /* store the squares of the distances */
- stats->min_safe_dist_2 = safe_distance*safe_distance;
- stats->max_safe_dist_2 = (safe_distance+CELL_XSIZE)*(safe_distance+CELL_XSIZE);
- stats->max_unsafe_dist_2 = max_unsafe_distance*max_unsafe_distance;
- stats->min_unsafe_dist_2 = min_unsafe_distance*min_unsafe_distance;
- stats->dodge_dir = 0;
- stats->last_dir = 0;
+
+ max_safe_distance = safe_distance + DIST_TOLERANCE;
+
+ /* store the squares of the distances */
+ stats->min_safe_dist_2 = safe_distance*safe_distance;
+ stats->max_safe_dist_2 = max_safe_distance*max_safe_distance;
+ stats->max_unsafe_dist_2 = max_unsafe_distance*max_unsafe_distance;
+ stats->min_unsafe_dist_2 = min_unsafe_distance*min_unsafe_distance;
+ stats->dodge_dir = 0;
+ stats->last_dir = 0;
}
/*--------------------------------------------------------------------------*/
@@ -687,7 +696,7 @@
their_stats = &light_stats;
}
- if (field_frame_time % (random() % (FIELD_SKILL / 5 +1) + 5) != 0) {
+ if (random() % (FIELD_SKILL + 1) != 0) {
cmd->f.dir = my_stats->last_dir;
cmd->f.fire = 0;
return;