I am writing a connect four game in c++ but am having trouble adding depth to my current AI to add multiple levels of difficulty. I was hoping to add at least 2 more levels. I have seen a few other questions similar to this although I am a student and am having following the code in some cases. Does anyone know how I could approach this in a simple way or even leave a commented function? I am using eclipse on Mac but coding in the character set ASCII. Here is what I have at this point in time:
int summ :: AI()
{
string ax;
cout << "What's Your Name? ";
cin >> ax;
for (int a = 0; a <= 5; a++)
{
for (int b = 0; b <= 6; b++)
place[a][b] = ' ';
}
display();
int hold;
int hold2 = 0;
int charsPlaced = 0;
bool gamewon = false;
char player = 15;
string r;
while (!gamewon)
{
if (hold2 != -1)
{
if (player == 15)
{
cout << ax << " what column would you like to drop in?";
player = 254;
}
else
{
player = 15;
}
}
while (true)
{
if (charsPlaced == 42)
break;
if (player == 15)
{
cin >> hold;
hold--;
}
else
{
hold = (1 + (rand() % 7));
srand(time(NULL));
hold--;
}
if (hold <= 6 && hold >= 0)
break;
else cout << "nEnter a value between 1 and 7: ";
if (cin.fail())
{
cin.clear();
char c;
cin >> c;
}
}
if (charsPlaced == 42)
break;
hold2 = drop(hold, player);
if (hold2 == -1)
cout << "Column is fullnEnter another number between 1 and 7: ";
else
{
gamewon = check(hold2, hold);
charsPlaced++;
system("CLS");
display();
}
}
system("cls");
if (charsPlaced == 42)
{
cout << "Draw!n";
system ("pause");
return 0;
}
if (player == 15)
{
cout << ax << " has won!" << endl;
}
else
{
cout << "AI" << " has won!" << endl;
}
system ("pause");
return 0;
}
2
Answers
One of the standard ways to do game AI levels is to configure how many moves the AI will look ahead.
CHeckout http://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning and http://en.wikipedia.org/wiki/A*_search_algorithm
You can utilize alpha beta pruning (or just A* search) and limit how far each level of AI can look into the future to determine what its best course of action will be. This is essentially how many chess AI systems work. They will look X moves ahead to determine their possible move.
To solve this problem, you need better structure. That is to say, you need a better function structure (
summ :: AI()
does WAY too much) and you need a better datastructure.In particular, you need a board class. It should have a
move(int col, bool who)
function which returns a copy of the original board. Don’t change the original, your AI must be able to try out moves before committing itself.You can now generate a list of all possible boards after the AI moved N times (with N-1 intermediate moves from the player). This forms a tree of boards, with the original board at the root, some leaves halfway that represent final positions, and some boards that are still active because you didn’t finish the whole tree. Almost there, really….
The final step is figuring out the best sequence of moves. As a simple first attempt, the sequence you want is one that wins regardless of opposing moves, and failing that avoids losses. You’ll have to work backwards for this. For each possible board after N-1 player moves, calculate the best possible AI result. The player can foresee this, so he’ll prefer the move that wins directly, and failing that avoid all that allows the AI to win. Having calculated all these, the N-1’th move for the AI can now be calculated by leaving the opponent in the worst possible position (again, a direct winning move is good, but a move that the player cannot counter is equally good).