Author Topic: Algorythem for chosing random AI's with consistant difficulty?  (Read 1239 times)

Offline Buttons840

  • Hero Member
  • *****
  • Posts: 559
I've been working on a little script to pick my random AI's for me.  My goal is for the script to accept a approximate difficulty between 1 and 10, and then equalize the difficulty [or challenge] based on the AI personalities chosen and the difficulty.  For example, choosing a pair of easy AI types might be assigned a difficulty of 8 because they are easy AI types, where as technologist AI's might receive a difficulty of 6.  I'd also like the difficulties to fluctuate a bit; ie. a set of AI's may both be given difficulty 7 or one might be given difficulty 8 while the other is given difficulty 5 or 6 - still averaging to about difficulty 7.

I have a few questions I've been thinking about and I'd like input from other players.

1) How much harder is a hard AI type than an easy AI type?
Consider something like a turtle vs a raid engine.  I would say the raid engine is probably 3 or 4 times more difficult.

2) How does the difficulty scale?
Consider a difficulty 10 AI vs a difficulty 5.  The difficulty 10 is not just twice as hard, it's probably about 10 times harder if not more.  I would probably model these using a exponential of some kind.

3) How much effect on difficulty [or challenge] does the AI type have vs the difficulty level?
I would rather face a difficulty 8 turtle than a difficulty 7 raid engine.

Code: [Select]
import random
import time

diff_points = int(raw_input('Difficulty: '))

ais = []
ais.append(('Entrenched Homeworld', 1))
ais.append(('Fortress Baron', 1))
ais.append(('Grav Driller', 1))
ais.append(('Mine Enthusiast', 1))
ais.append(('One-Way Doormaster', 1))
ais.append(('Shield Ninny', 1))
ais.append(('Sledge Hammer', 1))
ais.append(('The Tank', 1))
ais.append(('Train Master', 1))
ais.append(('Turtle', 1))
ais.append(('Zenith Descendant', 1))
ais.append(('Assassin', 2))
ais.append(('Backdoor Hacker', 2))
ais.append(('Bully', 2))
ais.append(('Camouflager', 2))
ais.append(('Counter Spy', 2))
ais.append(('Experimentalist', 2))
ais.append(('Feeding Parasite', 2))
ais.append(('Mad Bomber', 2))
ais.append(('Peacemaker', 2))
ais.append(('Speed Racer', 2))
ais.append(('Starfleet Commander', 2))
ais.append(('Stealth Master', 2))
ais.append(('Tag Teamer', 2))
ais.append(('Teleporter Turtle', 2))
ais.append(('Vicious Raider', 2))
ais.append(('Alarmist', 3))
ais.append(('Attritioner', 3))
ais.append(('Golemite', 3))
ais.append(('Radar Jammer', 3))
ais.append(('Scorched Earth', 3))
ais.append(('Shadow Master', 3))
ais.append(('Special Forces Captain', 3))
ais.append(('Raid Engine', 3))
ais.append(('Technologist Homeworld', 3))
ais.append(('Technologist Parasite', 3))
ais.append(('Technologist Raider', 3))
ais.append(('Technologist Sledge', 3))
ais.append(('Technologist Turtle', 3))
ais.append(('The Core', 3))

diffs = [1, 2, 3, 4, 5, 6, 7, 7.3, 7.6,
8, 8.3, 8.6, 9, 9.3, 9.6, 9.8, 10]

while True:
ai1 = random.choice(ais)
ai2 = random.choice(ais)
diff1 = random.choice(diffs)
diff2 = random.choice(diffs)
if abs(ai1[1] + ai2[1] + diff1 + diff2 - diff_points*2.5) <= 2.5: break

print 'AI1: %s (%s)' % (ai1[0], diff1)
print 'AI2: %s (%s)' % (ai2[0], diff2)

time.sleep(120)

This is what I currently have.  Sometimes I am wanting a difficulty 7 and a difficulty 10 AI is produced, but the other AI difficulty is greatly reduced to make up for it.  The problem is that no amount of reduction to the other AI can compensate for the impenetrable difficulty 10 AI.  I have tried multiplicative, polynomial, and exponential equations, but haven't produced any better results; for this reason I've posted the simplest equation and anyone interested can experiment further on their own.

I would also be interested in having such a feature build into AI war itself.

Thanks for your thoughts.

Offline Buttons840

  • Hero Member
  • *****
  • Posts: 559
Re: Algorythem for chosing random AI's with consistant difficulty?
« Reply #1 on: May 15, 2010, 05:11:03 pm »
Code: [Select]
import random
import time

target_diff = float(raw_input('Enter difficulty between .6 and 10.3: '))

ais = []
ais.append(('Entrenched Homeworld', 1))
ais.append(('Fortress Baron', 1))
ais.append(('Grav Driller', 1))
ais.append(('Mine Enthusiast', 1))
ais.append(('One-Way Doormaster', 1))
ais.append(('Shield Ninny', 1))
ais.append(('Sledge Hammer', 1))
ais.append(('The Tank', 1))
ais.append(('Train Master', 1))
ais.append(('Turtle', 1))
ais.append(('Zenith Descendant', 1))
ais.append(('Assassin', 2))
ais.append(('Backdoor Hacker', 2))
ais.append(('Bully', 2))
ais.append(('Camouflager', 2))
ais.append(('Counter Spy', 2))
ais.append(('Experimentalist', 2))
ais.append(('Feeding Parasite', 2))
ais.append(('Mad Bomber', 2))
ais.append(('Peacemaker', 2))
ais.append(('Speed Racer', 2))
ais.append(('Starfleet Commander', 2))
ais.append(('Stealth Master', 2))
ais.append(('Tag Teamer', 2))
ais.append(('Teleporter Turtle', 2))
ais.append(('Vicious Raider', 2))
ais.append(('Alarmist', 3))
ais.append(('Attritioner', 3))
ais.append(('Golemite', 3))
ais.append(('Radar Jammer', 3))
ais.append(('Scorched Earth', 3))
ais.append(('Shadow Master', 3))
ais.append(('Special Forces Captain', 3))
ais.append(('Raid Engine', 3))
ais.append(('Technologist Homeworld', 3))
ais.append(('Technologist Parasite', 3))
ais.append(('Technologist Raider', 3))
ais.append(('Technologist Sledge', 3))
ais.append(('Technologist Turtle', 3))
ais.append(('The Core', 3))

diffs = [1, 2, 3, 4, 5, 6, 7, 7.3, 7.6,
8, 8.3, 8.6, 9, 9.3, 9.6, 9.8, 10]

def challenge(ai1_type, ai2_type, ai1_diff, ai2_diff):
ai1_type += 2
ai2_type += 2
return ai1_type * 2**ai1_diff + ai2_type * 2**ai2_diff

target_challenge = challenge(2, 2, target_diff, target_diff)
while True:
ai1 = random.choice(ais)
ai2 = random.choice(ais)
diff1 = random.choice(diffs)
diff2 = random.choice(diffs)
if abs(challenge(ai1[1], ai2[1], diff1, diff2) - target_challenge) <= target_challenge / 20.: break

print 'AI1: %s (%s)' % (ai1[0], diff1)
print 'AI2: %s (%s)' % (ai2[0], diff2)

time.sleep(12)

I'm happy with how this performs.  The most interesting part is that function called "challenge" which quantifies challenge.
It's based on the fallowing assumptions:
1) Going up one difficulty level (IE, from difficulty 7 to difficulty 8 ) results in twice the challenge.
2) The AI types provide challenges proportional to 3, 4, and 5 respectively.  Meaning a harder AI type provides 5/3 (just under double) the challenge of a easier AI type.

What it means:  If you enter difficulty 7, it means you will get 2 "moderate" AI types at difficulty 7 or the equivalent thereof.  You may receive harder AI types and the difficulty would be lowered, or you may receive an easier AI type and the difficulty will be raised.  One AI may take a lower difficulty to raise the difficulty of the other.

Script is written in python.  Either download and install the python interpreter or port it to your preferred language; both options should be equally easy. :)
« Last Edit: May 15, 2010, 05:12:34 pm by Buttons840 »

Offline superking

  • Hero Member Mark III
  • *****
  • Posts: 1,205
Re: Algorythem for chosing random AI's with consistant difficulty?
« Reply #2 on: May 15, 2010, 06:21:16 pm »
Your concept of difficulty seems pretty arbitary, which makes the output of said Algorythem fairly meaningless as far as I can see. If you could access the raw details of each AI, such as wave size scaling etc then you might be able to do somthing with it, but I dont see how you can quantify the difference in difficulty between, for example, the turtle and the sledgehammer, which perform very differently yet are both given a difficulty of 1.

Offline Buttons840

  • Hero Member
  • *****
  • Posts: 559
Re: Algorythem for chosing random AI's with consistant difficulty?
« Reply #3 on: May 15, 2010, 07:27:04 pm »
Your concept of difficulty seems pretty arbitary, which makes the output of said Algorythem fairly meaningless as far as I can see. If you could access the raw details of each AI, such as wave size scaling etc then you might be able to do somthing with it, but I dont see how you can quantify the difference in difficulty between, for example, the turtle and the sledgehammer, which perform very differently yet are both given a difficulty of 1.

Well, I can't inspect the AIs.  What I can do is rely on the opinion of the game and AI creator who says that sledge hammer and turtle are both "easier" AIs; versus "moderate" and "harder" AIs.  Also, I don't quantify any difference in difficulty between sledge and turtle, they're both given the same values.

Without such a formula, there is no way to chose random AIs of uniform difficulty.  Sure, you can set the difficulty to 7 and set "Random All" but you may end up with a Turtle or a Raid Engine.  I agree that this is "arbitrary", a matter of opinion, and thus there are no right or wrong answers.  I'm open to suggestions, discussion, and other approaches to solving this problem.

You can't perfectly randomize based on a set difficulty, because difficulty is a matter of opinion, but I think this does pretty good.  How would you go about picking random opponents of similar difficulty?  Please feel free to share your opinions, or simply criticize mine.
« Last Edit: May 15, 2010, 07:31:57 pm by Buttons840 »

Offline Hellheart

  • Newbie Mark II
  • *
  • Posts: 14
Re: Algorythem for chosing random AI's with consistant difficulty?
« Reply #4 on: May 15, 2010, 08:42:07 pm »
I think you should go beyond the easy/moderate/hard difficulty provided by Arcen in order to streamline the algorithm and make better choices for some AI types.

For example, it's been argued that the Backdoor Hacker should be an easy AI type, because yes you can get waves on your homeworld but that's the only extra point to defend. The Shield Ninny might be given an even lower difficulty modifier, but I think with the new Border Aggression mechanic the Turtle actually got quite a bit more lethal (at high AI difficulties and AI progress, his frequent heavy reinforcements might result in a steady stream of ships in pretty large numbers from full planets if you don't neuter). Train Master maybe should be a moderate AI type, or that should at least be an option, and should not be there at all if Astro Trains are disabled (many, many people hate astro trains, me included). The Peacemaker should probably be an Easy AI type (although if paired with certain AI types, those anti-everythings can be a headache), while the Mad Bomber should probably get a 2.2 or 2.3 rating because at high difficulties he becomes much harder than most AI types. Golemite should probably have a special modifier that automatically selects an Easy AI type for the other, or perhaps excludes AI types with heavy defenses, because unless they fixed it his golems will result in massive AI reinforcements every time you enter an enemy planet.

You might also want to exclude certain combinations, such as the Special Forces Captain and Alarmist. That's a pain on any difficulty - I don't see the fun in constant reloading because if I get a bad roll on an SF alarm post I'm going to get creamed by 10k+ ships. Attritioner and One-Way Doormaster is also pretty nasty. Shadow Master paired with certain AI types also becomes a total pain. I would also like to see some sort of tag for people who don't want, say, Vicious Raider and Mad Bomber as their 2 AI's because they can't handle those waves yet, or Turtle and Teleporting Turtle because it would take 20+ hours to finish the game.

Offline Trezamere

  • Jr. Member
  • **
  • Posts: 60
Re: Algorythem for chosing random AI's with consistant difficulty?
« Reply #5 on: May 15, 2010, 10:24:17 pm »
Unless I'm mistaken it's just printing suggestions to the screen; if you don't like the particular AI types you can run it again.  Maybe have it run off a file and then the user can adjust the AI types he doesn't want to see or difficulties, since really difficulty is always a matter of opinion.  Could also get rid of always having to punch in a difficulty when it's read, since it's likely that we play on the same difficulty generally speaking from game to game.

rubikscube

  • Guest
Re: Algorythem for chosing random AI's with consistant difficulty?
« Reply #6 on: May 16, 2010, 02:19:42 am »
everyone sounds all developerish

Offline Hellheart

  • Newbie Mark II
  • *
  • Posts: 14
Re: Algorythem for chosing random AI's with consistant difficulty?
« Reply #7 on: May 16, 2010, 09:53:44 am »
Well, yeah, hopefully it doesn't force things into the code, but I would just like to see options for a slicker program I suppose. If it's easy enough to tweak individual settings (and I suppose it is, since he's basically giving us the base numbers and we could certainly change them before encoding), his changes wouldn't matter, but he clearly wants to get things as close as possible to the way it should be. New players also wouldn't know what changes to make, and they could run into problems where they don't realize how broken certain AI combos would be. And the Golemite second-AI exclusion, at least, is probably necessary, otherwise you'll have to reroll when you get one a huge amount of the time. I wouldn't know how to code that. I suppose the other issue with printing them out instead is that you know what AI's your dealing with going in, which I suppose is okay, but some people like not having that knowledge because it can dictate early strategy for you.

Technologist AI's also might be given a higher multiplier by, well, pretty much everyone since they can be so hard to handle.