what's up everybody and welcome to part
14 of our AI in starcraft 2 with Python
tutorials series in the previous video
we talked about all the changes that
we're gonna be working on and in this
video we're gonna be working
specifically on improving the scouting
so the scouting that we had been doing
was pretty stupid and we're gonna make
it a little better not perfect but a
little better so with that let's get
into it this one's gonna take a minute
or two so let's go so first of all we're
gonna do self in the init method self
not Scouts and spots and that's going to
be a dictionary that tracks the ID so
all the units have this attribute of a
dot tag and that is a sort of unique ID
to that to that unit so we're gonna use
that and say and store into Scouts and
spots that ID tag and the location of
that unit so we can kind of keep track
of where our Scouts are and then when
they died or whatever we can iterate
through things and remove the Scouts
that no longer exist and then we can
have new Scouts fill their spots and
stuff like that and then also we want to
scout again you know you want to send
the first scout to the enemy base and
then you want to send subsequent Scouts
to the expansions of that base so I'm
just gonna go to expansion zones that
are by distance you know closest to the
expansion or closest to the enemy start
location so we are going to be rewriting
our scout method here I don't think
we're going to be using anything here
except for maybe this code but we'll put
that in a different method entirely so
I'm gonna go ahead and just delete it
all ok let's get started so first of all
we want to have an ex self dot expand
dis der and that'll just be an empty
directory and the what this would be
quicker the the setup of this will be
the
is the distance to the enemy start and
the value is the actual location object
itself and now what we want to do is to
begin iterating over expansion locations
which are a something that are it's
located in our actual you know object so
for il expansion location in self dot
expansion underscore locations what do
we want to do well we want to calculate
the distance why is that already oh it's
because it's a tradition er that's like
how does it already know that distance
to enemy start is equal to L dot
distance actually its distance
underscore two so this so so L recall is
an expansion location object right and
it has a method of distance to and now
we can figure out what's the distance to
whatever we pass here so we're gonna say
self dot enemy start location zero and
yeah so starts self dot enemy start
location zero so wherever that first
enemy started and we only have one so
we're gonna use that guy so now we've
got the distance now we want to add that
to our expand this dirt so self dot
expand this der and then the key is the
distance to enemy start and the value is
L so now what we want to do is once
we've got all those in there the keys
are the actual distances so self dot
ordered expansion distances is going to
be the sorted list of K for K in self
dot expand dis der so all we're doing is
just sorting the keys and then we can
start iterating through that's those
sorted keys
to figure out the next one to go with
now as of Python 37 you can Juro trust a
trust and rely on dictionary orders
unfortunately we can't use Python 37 yet
with Python se 2 due to some WebSockets
thing so I can't rely on that yet so
this is the kind of hacky way that we're
gonna go about it I'm sure somebody can
come up with a way better method for
scout here and feel free to share it
okay mmm so now that we have that sorted
the next thing we want to do is check
all of our current unit IDs so I'm gonna
say existing IDs is equal to unit dot
tag for unit in self dot units so we're
gonna grab the tag of everything so the
way that we're gonna learn how or we're
gonna figure out who we need to remove
from self dot Scouts and spots is again
Scouts and spots is gonna be a
dictionary of the unit unit tag unit tag
in the location that that units at so
all we need to do is iterate over the
tags and scouts and spots and then find
out if any of the IDs or tags in Scouts
and spots don't exist and our self dot
units if they don't well that on that
unit unfortunately has moved to a better
place
so so those are the so now that we have
the existing IDs we're gonna say two
flips to be removed for now is an empty
list but it's gonna be populated so for
noted Scout in self dot Scouts and spots
so that's you know for the ones that we
know about and these noted Scout is the
Scout ID if noted Scout not in existing
IDs then we need to to be removed dot
append that noted Scout
finally for Scout in to be removed we
want to del self dot Scouts and spots
that Scout because now we want some
other Scout to be able to take that
Scouts position at wherever he was where
she was manned now he or she man anyways
okay so if Len of self dot units
robotics facility dot ready is equal to
zero so if we don't have any then our
unit type I'm gonna say unit type equals
probe otherwise under case that their
unit type equals probe and we're going
to say unit limit equals one we don't
want to send all of our probes to scout
so like we have observers we want all of
the observers scouting well we have
probes we don't want all of them
scouting we want just one just one so
yeah so else unit type equals observer
and then I'm just gonna I really don't
know what to think about this limit so
I'm just gonna say 15 I don't know
okay so now we're gonna set a little
flag here assign Scout is equal to true
if unit type equals probe what we need
to do is grab one of them too
we only want one to be the Scout so what
I'm going to say is for unit in self dot
units probe if unit dot tag in self dot
Scouts and spots assign Scout is going
to be false
now what we're gonna say is if a sign
scout we're gonna begin a unfortunate
string of events so if Len self dot
units of the unit type whatever they
happen to be dot idle is greater than
zero so again this is only gonna apply
for scouts I'm sorry observers as Scouts
well or one probe anyways for Hobbes
this is usually gonna be observers
though self dot units unit type dot idle
up to whatever the unit unit limit is
why for arms in done thanks editor you
know an idle I would have been like
running this and been like wait what
okay for arms I'm sorry it's not for us
if Bob's dot tag not in self dot Scouts
and spots Wow now we got something now
what we want to do is take that list of
distances and then so it's that list of
distances and when we wheel in it what
we want to do is start iterating through
them so those distances are in order of
closest to furthest from the enemy start
location and we want to iterate over
those checking the expansion location
that is that distance and seeing do we
have a scout there yea or nay
if nay well let's put one there so the
way that we're going to do that is for
dist
in self dot ordered expedition TSA's
we're going to engage in a try
exception as e-print a stringy
if you want to be decent otherwise you
can just pass and what we're going to
say is location is equal to next value
for key value in self dot expand distr
dot idem and that's if key is equal to
the distance so this is the way that
we're going to find the value which
recall expand as dirt the key is the
distance the value is the actual
expansion location so this is how I'm
searching a dictionary for a value pause
can I not hold on I'm about to be really
angry at myself it's late today I'm
gonna take a little bit of credit for it
being late but this would be how you
would look up for a key by value but I'm
looking for a value location next value
for key value why would you ever do this
I'm pretty sure I'm gonna be so angry if
I go down this road but the location
really should just be expand dis der and
you're looking it up by the distance
that should be acceptable that should
give you the location
okay the show must go on
active locations is equal to self dot
Scouts and spots K for K in self dot
self dot Scouts and spots man this is
still bothering me how did I make that
mistake when I went through this the
first time I mean that code works but as
I started saying why I was doing it I'm
like oh no okay anyways too much okay so
if location not in active locations if
units type equals probe check it over
this four units in self dot units probe
whoops
if unit tag in self dot Scouts and spots
continue then a wait self dot do ABS dot
move to that location then we're gonna
update self dot Scouts and spots ops dot
tag equals that location and then we are
done with this little loop here and we
want to break whoo okay so something is
is gravely wrong here
and I don't want to talk about it mm-hmm
so okay so now what we want to do is let
me scroll down here make sure I don't
mess up anything more I'm still I'm
still reeling over that code there
there's got it
I also feel like something's going wrong
here but not gonna try to live fixed
that one at the moment
so finally the last thing I want us to
do in this method is going to be in line
here so two tabs over so after we're
done with assigning Scout what we want
to do is for arms in self dot units
units type if odds dot tag in self dot
Scouts and spots if Bob's in probe for
probe in self dot units probe await self
dot do and this really is the exact same
code that we had before so actually we
do save that I'm gonna just paste that
in so stuff to do Bob's don't move self
dot random location variance and then
it's that that random location variance
function which I think I kept and in
this case instead I'm just going to say
x and y is plus equals a random dot R
and range of negative 5 to positive five
and cool I think that's really all we
need there and then finally build so we
don't have the build Scout so the last
thing I want to add is a build Scout
method and so this is what we're gonna
do to actually Scout and at least for
the time being I'm gonna use this
temporary function you can go to the
text-based version of the tutorial but
this right now we're just going to build
a scout for every three minutes that has
elapsed so if it's nine minutes into the
game we're going to expect to have three
Scouts so I'm gonna take build scout and
I'm gonna throw that
right before the Scout method the way
itself not build scout and I think we're
done I still can't get over that code oh
boy someone's gonna someone's gonna have
a fit many people will have fits if
you're right perfect code on your first
pass let me know but if I don't think
anybody's had that problem so at least
the way that I came across that was at
first I had this that dictionary was
kind of structured a little different
I'll we do hidden error okay we need to
import math that's an easy bug I don't
mind that bug import math anyway at
first it was a it was a differently
structured dictionary so I was actually
searching for a key by value and then
later I flipped them and then I needed I
just all I had to do was go down into
that method and just change the words
around because and then I was looking
for the value by the key and yeah that's
that's how I how that resulted that's
right that's pretty funny as I'm running
through that I'm like wait but this is
what a dictionary does I should edit
this out and never share this with
anybody and just not talk about it ever
again but that's okay so we can see here
this is our little worker and he is
heading into enemy territory doing his
job quite quite well so I think he's
hanging out I can't tell anymore I don't
even know if he's there how would I tell
I don't even know is this our guy I
think this is our guy right here you
just you just be bopping around I wish
they would kill him Sarge
so we'd send another one but I don't
think they're gonna anyway I'm pretty
sure that's our unit yeah okay they just
killed him and we'll see so this guy
looks like he's setting up another base
and then how long are we so we're three
minutes in so here we go we're
yet another worker unit great
everything's working as we would expect
I still can't I'm just well I think he
was destroyed immediately and we're just
we're gonna send another one in that's
all right
what I'm really waiting on is the
observer unit to come in and I want to
see how that how that goes
make sure the observers start coming in
and going into where they need to be why
is the game time so slow we must have
some some crappy logic going on here a
game time is just not going very fast
maybe once we produce an observer
that'll be fixed it almost looks like it
has been fixed although there goes
another that was it so we've got our
first observer coming out things are
going faster but interestingly enough it
happened before the observer anyway I'm
sure there's something wrong with that
code you can clearly tell I was having a
mental breakdown as that code was coming
up so we got one Scout up
well hype right okay here comes a second
scout so we'll see where this guy cause
he's already has his orders and I don't
think that other Scout will be even seen
I'm not even sure that they'll be
expanded to the location yet let me
we're really angry if you okay good
that's like because of that base so yeah
so he's posted up at the first
reasonable expansion but they just
simply haven't expanded but we would
catch it if they did so you can even see
we're right here at the mineral spot
that would probably be the next place
although actually it looks like this is
the next place and to be honest like
looking at the map this looks closer so
that's probably also unfortunate and I
think if you look at the pathing that
you could take like this expansion is
the safest next expansion to take this
one because I think this one only still
has like one or two areas that you can
get in this one has like three or four
and then as you go out it's like you
just totally open to attack in a lot of
spots but anyway this guy's gonna cover
that next spot no problem and the AI has
already been defeated all right
so okay we at least are scouting how we
wanted to wow we really did just totally
dominate we got 19 his 16 void rays now
17 void its wow that was like how many
minutes was that that was not very long
before we wow that was a good game
anyway I think that's it someone feel
free to comment below I still feel like
something is wrong like I'm throwing
flags here someone help me out I think
this will be the last tutorial for the
day but yeah that's interesting and
nobody speak of this ever again I'm
gonna delete all comments that reference
that I think okay anyways
that's all for now questions comments
suggestions for improvement whatever
feel free to leave them below otherwise
I will see you guys in another video