2006-05-07

Mu Torere AI II

Step 15.

Two new steps and a modification for the Move Generator class and a new function and a modification for the Game class.

The modification is for the CMoveGenerator's getMove function;
int CMoveGenerator::getMove(const int& aiL)
Pre-Condition:
That aiL is between 0% and 100%, inclusive.
If a random value (mod 100) is greater than aiL, use the randomMove(COwner::playC) function.
Otherwise use the aiMove(COwner::playC) function.

(The move returned should NOT equal CBoard::OFF_BOARD.)

Return the move.
Instead of constructing the class instance with the value to use for the AI effort, we are just going to submit the value when getting the Computer's move. No need to store anything that way.

The 'AI';
int CMoveGenerator::aiMove(const COwner::Player& tag)
Pre-Condition:
That tag is either COwner::playC or COwner::playU.
Create two COwner::NUM_PIECES-sized integer arrays.

Initialize both arrays with the MoveGenerator's thisGame's buildMove() for player tag.
(The returned caount should be within limits.)

Use evaluateMoves() to assign values.
(The returned array should NOT equal NULL.)

Return a move given that;
If any move was assigned a 1 (the player tag won) has the highest priority.
Otherwise, pick a random move with the value of 0 (no-one won).
Any moves assigned -1 are to be ignored.
And, yes, only one array to store the moves could be used here. The thought in my so-called mind was that the issue was where the next move needs to be considered as well, needing a spare array.

Evaluating the move;
void CMoveGenerator::evaluateMoves(const COwner::Player& forTag, const CGame& startG, int* moves)
Pre-Condition:
That tag is either COwner::playC or COwner::playU.
That moves is NOT NULL.
Create an integer array with COwner::NUM_PIECES with elements.
Assign a COwner::Player variable to the opposing player.

For each move in moves;
{
If move equals CBoard::OFF_BOARD,
Re-assign element to and go to next element.

Create a temporary CGame variable with thisGame's values.
Apply this move to the temporary CGame.

Did forTag win?
{
Assign +1 to the element.
}
Else,
{
Use the created move array to store the opponent's moves given the applied move. (The program has already tested the applied move to see if forTag won, now check the opposing side.)

If any of the opposing move is a winner,
{
Assign -1 to this moves element.
}
Else,
{
Assign 0 to this moves element.
}
}
}
Creating the move array before the loop gets the possible error condition out of the way.

The new function in CGame is;
bool CGame::applyMove(const COwner::Player& tag, const int& moveFrom)
Pre-Condition:
That tag is either COwner::playC or COwner::playU.
That moveFrom is with CBoard bounds.
That moveFrom is NOT equals emptyLoc.

Pre-Condition:
Apply Move(tag,moveTag)


The modification in CGame is in the computerMove() function, one just needs to give the CMoveGenerator's getMove() function the specified AI level.

No comments: