1. Programmer: How does the new AI work?

EAI Programmers description,

In reference to code in JPortal.

Code can be found in package csa.jportal.ai.enhancedAI;

In each Phase the AI does following

Match calls the MatchComputer and asks him toDo something (Method: waitingForYou() in MatchComputerplayer)
This wakes up the waiting AI Thread. The woken up Thread calls handleMessage() in MatchComputerplayer. Here it is checked what kind of call it was, and whose turn it is etc. Here the calls are distributed to specialized subroutines for each phase, like: untapCards(), drawLibraryCard() etc.

Each of these routines return a boolean. If true, than the computer is completely finished with the phase, if not he still wants to do something, but must pass (for now) the lead to the game (perhaps some communication with other player is pendening).

Within each of these specialized MatchComputerPlayer methods it is checked, whether the AI is an interanl AI - or an external (external = the old behaviour).

Internal AI's must implement the interface: AISituationHandler, which consists of more or less exactly the same specialized methods that are called above:

public interface AISituationHandler
{
    public void setComputerPlayer(MatchComputerPlayer p);
    public void init();
    public void initRound(boolean isPlayer);
    public void deinit();
    public boolean wantToStart();
    public boolean wantMulligan();
    public boolean declareAttackers();
    public boolean declareBlockers();
    public boolean untapCards();
    public boolean doMainPhase();
    public boolean handleStack();
    public boolean drawLibraryCard();
    public Card dropOneExcessCard();
    public void handleCommunicationRequest(Communication c);
}

If an internal AI is detected - than the corresponding interface method is called.

The first implmentation of an internal AI is the class AbstractEnhancedAI. Dispite the name - it can be instantiated. If it is not further derived it behaves at the moment exactly like the old alround AI (but all computing is still internal - no scripts are called).

Any other internal AI should be inherited from that AbstractEnhancedAI class. If so it is already a working AI and you can finetune the one to your likings.

The new AI I am at right now is found in the class: EnhancedAI Which does inherit from the above - but in the end it will most likely be able to stand up alone :-).

Each of the above interface methods is handled by the same scheme e.g.:

public boolean doMainPhase()
{
        initEnvironment();
        generatePlan();
        return executePlan();
}

generatePlan()

This little darling does all the work. Mainly here the class EAIPlan is constructed with the current match as the current situation.

EAIPlan

Here mainly the static method createSchedules() is called which now really really starts of generating some AI results :-). This first EAIPlan is the starting point of all further EAIPlans

Again - some gerneral statements on what is done further. The current Match is "converted" to a VirtualMatch - which holds (more or less) all relevant information about the current in game situation. For each phase beginning with the currently CURRENT phase, all meaningfull "Actions" (playing a card, activating a card, attacking...) are generated and collected. One "complete" set of actions, meaning all actions for phase CURRENT to PHASE END CLEANUP are collected in one EAIPlan. One EAIPlan has one EAIScedule for each phase. One EAISchedule has none, one or more EAIActions for one phase.

I know this sounds highly confusing - but the differntation makes sense and one can handle the complete thing more or less well.

The generation of EAIPlans is more or less iterativ. We start of with the current game situation. Build a meaningfull schedule for the current phase. EAIActions can be "executed" on the match - which are in fact the AITurns - or (now it gets interesting :-

can likewise be executed on the VirtualMatch. After execution on the VirtualMatch, the situation of the VrtualMatch has all the effects of the action taken into account. So In fact the effect of the card can be evaluated more or less exactly the same as playing it out for real.

This is what actually happens. The collected actions for the above generated phase are executed on the VirtualMatch. The resulting VirtualMatch (situation) is taken as the input for the Action generation of the next phase - and so on.

After doing this for all phases (each phase with its possibly variations). We have:

  1. Many many EAIPlans for the current "real" Match situation

  2. The plans can AS THEY are be executed on the real Match

  3. only thing left to do is - decide what EAIPlan we wish to take

Weighting

Here we come to the Weighting process, each Match and each VirtualMatch can be weighted. Each player gets a score for the current situation. Winner will be the plan, where the difference in the score (positiv difference) is greatest. Weighting / Scoring is implemented - but probably must be fine tuned.

executePlan()

Here the above worked out plan is executed.

It is looked if for the current phase any actions are scheduled. Actions from the schedule are placed on an ActionStack, which is executed - well - stack wise. Some actions can put subActions on the stack (like play a card has subactions for all paying mana...).

The Actions we built above are executed by another method executeAction(), which executes them on the real match (like the method in VirtualMatch for the - VirtualMatch) - this is - once the actions are known - quite straight forward.

If all is done - true is returned - false otherwise.

The whole structure described above is implemented and working.