Friday, September 24, 2010

Rushing Medium AI in Starcraft II

So here I am, having fun, wondering how to quickly end a match versus the AI.  Against a medium AI to be precise.  Well; it doesn't require much effort:

Terran:
Build around 3 SCV's per mineral field and 3 per Vespene Geyser.  While that is happening, build 3 barracks (each upgraded to build 2 marines at once) and sources of food (upgraded through the upgraded command center).  Now; build marines.  That means 6 marines produced simultaneously once everything is set up.  Send them into the opponents base.  They won't know what hit them.

Zerg:
Classic zerg rush.  Focus drones on harvesting minerals only (about 3 per mineral field), and build as many zerglings as possible using the Hive Queen to augment the number or larvae.  Don't forget to build overlords.  After the first attack, or when you have a good 20+ zerglings, send them off into the enemy base.  Game over, you win!

Protoss:
Rush with Zealots.  Build 3 zealot-producing buildings.  Focus all effort on minerals.  Build an expansion if you can!  Send into the enemy base about 20 zealots - watch them die off rather quickly...

I think I need to play on hard mode now...

Sunday, September 19, 2010

Starcraft II: First Impression of All Races

I've spent some quality time with Starcraft II today; and have a few notes on the individual races when playing against medium AIs.

Terran
The easiest to use - keep on upgrading weapons and units.  Make sure there is a constant cash flow and all will go well.  Build bunkers at choke points, a few towers to detect invisible units, missile turrets, and then it's just finding out how to destroy your enemy.  I like siege tanks.

Zerg
The Zerg have the early-on advantage.  Get to the Hydralisks as fast as possible and move on to Infestors when possible.  The infestors can remain hidden underneath the ground all the time and spit out infested marines.  It's an easy, disposable, army.  Focus on taking out any units that can detect the burrowed units.  Be sure to dedicate one Queen to your Hive to maximize the number of Larvae through which units are born.

In the second-half of the game, use the burrowing capability to pick out units from the end of the line.  Normally siege-tanks are behind so to not get damaged.  Use Zerglings on them.

I enjoy the Zerg force me to think up of bizarre attack strategies - that is rather than upfront powerful units, units creep up onto the enemy and destroy them in surprise attacks.

Protoss
The most powerful, however micromanagement is necessary.  Getting Carriers early can mean an early demise for opponents that have not prepared themselves for an aerial attack.

Sending a mass of Zerglings to attack some location on their own is usually a safe bet.  I found myself constantly watching battles and making sure units had shields, pulling weaker units out, etc.

Overall
Despite what I say here - the best way is to flank the AI.  That is, once the AI tries to attack the base, send in a heavy army into their base.  Raze a few buildings; and you're off to success!

The only problem I had was that the "VS. AI" button on the single player screen does not affect achievements, but playing versus the AI on the multiplayer screen gives me my achievements...  that's an interesting bug...

Also, randomly Battle.net decides to log me out and prevent me from getting an achievement once a level completes...  Quite annoying, especially when I've already spent a few hours...  fortunately the game is fun on its own.


Sunday, September 12, 2010

Starcraft II: A Zerg Strategy (medium, Zerg vs. Terran)

Today I started playing as Zerg against Terran on medium difficulty.  And I've found a very interesting strategy which the AI doesn't react to well against.

First, send your initial drones to the mineral field, and create up to 10 drones and those will go to the mineral field.

Now, build a second Overlord (send the Overlords somewhere "safe" either the corner of the map or over your hatchery).

Good - build 2 more drones, and send them mining.  You want a continuous stream of income!

Your next drones, make them relay somewhere safe, and build a Spawning Pool and an Extractor.  The Spawning Pool allows you to get Zerglings, the Extractor you need for Vespene Gas.

Get 3 Drones working on each of your geysers.  If you have 2, build 6 Drones, and another Extractor.

By now, the Spawning Pool must be built; build a Queen and upgrade your Hatchery to a Hive.  Your income ought to be stable enough by now to forget about resources for a bit (your units should be 13 Drones on minerals, 6 Drones maximum on Vespene gas, and one Queen).

Here's the bad news - all this time spent building up for resources left us a bit vulnerable.  Quickly, build some Zerglings (you may want to build them earlier).  2 suffice!  These two will venture and explore the map.

While you take in the bad news, build a Lair and an Evolution Chamber.  When building units, build 2 Roach and 1 Drone or 1 Roach 1, Drone and 1 Overlord.  The Zerglings are useless against Terran, we want Roaches to have a bit of defence, and we want the Zerglings to reveal the Terran base.

As you build units, make your Queen build Creep Tumors all over the place.  Preferably towards a choke point.  At the choke-point, build Spine Crawlers.  Expect to lose your Spine Crawlers.  Also - research Burrowing at the Hive.

Quick Recap: By now you should have a Hive, discovered the Terran base, or the location of their army (avoid it if you can).  Have a few (3 maybe?) roaches, plenty of defence, and your upgrade to Burrow is being worked on.  Ideally, you know where the Terran base is thanks to your Zerglings.  We know that the Terran are overpowering us.  

Quickly, get the Roaches out of your base in a spot outside of the Terran field of interest (that is - where they most likely won't be...) - ideally near the entrance of their base.  Burrow the roaches.

At the base, build (as soon as possible) a Hydralisk Den and build hydralisks.

Expect to be attacked.  When the Terrans attack - they will have sent their entire army.  Their base is now empty.  You have units waiting there...


Attack the base with your units.  If you can do enough damage - the Terrans will retreat and your base will be in good shape (minimal damage - except for the loss of the Queen and some Spine Crawlers.  If you manage to take out some SCVs, Supply Depots, etc. in the Terran base; they are done for.  While they head back to their base you have time to inflict quite a bit of damage.

You can sacrifice your Roaches.  By now, you should have plenty of Hydralisks.  With the enemy back at their base, bring the Hydralisks to their entrance, and Burrow.  Rebuild your minimal defences and try to get an expansion going.  With an expansion, the number of Hydralisks built will easily double.

Repeat the tactic of squatting in front of the Terran base and attack when your cheap defences get attacked.  Be sure to have a few Hydralisks and Spine Crawlers to keep thing from wanting to stay and get past the cheap defences.  Doing a lot of damage to their base also has the same effect!

And now, it's rinse-wash-repeat.

To recap: the overall strategy is to Burrow near the entrance of the base and to go in and destroy when the offence (also acting as defence against medium Terran difficulty) as busy destroying a cheap entrance to your base that can easily be rebuilt.  Without stopping, keep on sending reinforcements to your crew waiting to ambush the enemy.  Once they leave their base, keep your new units with you as defence.  Once they reach your base and start attacking, inflict as much damage as possible.


Happily - this works very well.  However, don't expect to win the first time.  The AI does make the mistake of leaving its base undefended - but that doesn't mean it is completely stupid.  The building must be done as fast as possible.  Go too slow and the first wave from the Terrans will destroy your base.

Is the "New Digg" that bad?

<rant>
Each time a new version of iTunes comes out; people line up to complain about the UI.  There's something about change that people fear and don't like.

Now that I've spent a bit more time with the "New Digg" - let me say it isn't that bad.  You can still submit links.  That erases most of the arguments that I had against it.  The crux of Digg is finding new stuff.

For the auto-submission?  I think it's a good thing.  Normally - if I wanted to submit something I wrote, I'd log into Digg, submit it, and see it remain ranked with 1 Digg (mine).  Now, what I do gets auto-submitted, and automatically gets a single Digg (mine, again).

For the enhanced algorithm?  Using multiple sources, but weighing the number of Diggs as having more of an effect.  Good idea, actually.  Ok, sit back and let's see how this works out: you want to find new stuff.  Stuff that a lot of people like.  Do you want a closed community of Diggers or a bigger community of people who may in the future be lured to Digg?  At the end of the day - I don't think this will make much of a difference.

For those quoting http://www.alexa.com/siteinfo/digg.com, let me say that is a considerable dip (in the month of August 2010, pageviews and time on site have nearly halved!).  Is this the end of the world?  Let's dig deeper.  Page views probably went down since articles don't seem change as often.  Can't complain there.  That would also describe why the time on the site went down.  And would explain why the reach has remained somewhat constant.  I call the evidence inconclusive that Digg shed most of it's users.

Lastly, for those complaining about not seeing how many Diggs a comment, just click your profile icon.

Yes, Digg did shed some users - there are the emotional bunch that have trouble whenever the iTunes UI changes...

Here's the only downside.  I lost my entire history.  Either it's in the process of being ported, or lost forever.  From reading the comments on Digg, I see things are probably being tweaked.

Like any new machine; Digg will take some time.  Play around with it, and you might even find that going forward it's going to be much better.  It looks more like a problem with deployment rather than a problem with the system.  If they slowly deployed it to certain users rather than the whole - things might have gone more smoothly.  A bit more communication, and maybe Reddit wouldn't have flooded the front page (if deployment of the new version took considerable time and people were complaining about real issues at the time - notifying the users might have been better).

But all in all.  It's not that bad.  And to say this, I forced myself to spend a bit of time to use it (rather than my previous version of this post that was completely inaccurate - a bit of research goes a long way - although let's say I still did no research for the fun of it!)...

Edit1: Mashable has a nicely researched piece at http://mashable.com/2010/09/15/what-digg-must-do-to-survive/
</rant>

Case for Objective-C++

Forget Objective-C. I mean it. For iOS development, the ideal language is Objective-C++.

I expect plenty of pitch-fork bearing purists who tend to align themselves with the crowd of goto is bad, and overloaded operators are bad to not like what I'm about to suggest. But; as with goto and overloaded operators, like certain medicines, too much can be fatal. I believe programmers can make reasonable decisions to the use of these constructs.

With Objective-C 2.0 came properties. These allowed for easy integration with key-value coding; but there's one problem with it - all properties are public. All methods are public as well. I believe this is bad programming style.

Here's a key to my solution; simple and elegant:
template<class T>
class Auto
{
private:
T m_o;
public:
inlineoperator=(T in_o)
{
if (in_o) [in_o retain];
if (m_o) [m_o release];
m_o = in_o;
return m_o;
}
inline T noRetain(T in_o)
{
if (m_o) [m_o release];
m_o = in_o;
return m_o;
}
inlineoperator()() const
{
return m_o;
}
inline Auto(T in_o = NULL)
: m_o(NULL)
{ (*this) = in_o; }
inline Auto(const TNS<T> &in_cpy)
: m_o(NULL)
{
(*this) = in_cpy();
}
inline ~Auto()
{
if (m_o) [m_o release];
}
};

Consider how this code nicely takes an an Objective-C object and wraps it in a smart-pointer.  Ensuring that objects get retained and released becomes much more trivial - and a lot less typing.  No need to define a parameter, synthesize, and double-check that it exists in the dealloc.  Why?  Objective-C++ automagically calls the destructor for C++ objects.

Using this is quite simple: Auto<NSString*> m_something; creates your string.  Assign an auto-release string to it (or use the noRetain method) and off you go forgetting about this object.  Assign a new string?  The old one gets automatically released.  Need to call a method?  [m_something() UTF8String]; is a good example.

The good thing?  minimal overhead - the compiler should inline out most, if not all, of the Auto object.  What you're left with are the retains and releases that you'd have normally put in.

A note of caution: only use this object in places where you'd normally ensure an object gets a retain or release.  Do not enthusiastically put it everywhere.  Recall: good things in great quantities might not be that good.  They can even be fatal!

On the up-side, if you want properties, you'll need to actually write the methods behind to translate from the C++ wrapper.  This is good, you'll see, since it makes it harder to make objects publicly accessible, always a good design decision.

Before I wrap up this post; for private methods, I suggest using C static functions in your implementation files.  Can't get more private than that!

For protected functions - useful with polymorphism - I'd avoid them.  Once a function is declared, it can easily be reflected and used.  No matter how hidden/private it is (unfortunately).  I believe that this poses interesting software design constraints though.