Just reporting on my progress
I made a tic tac toe program where you have a menu as 1st screen.
You can choose to
- play with 2 humans
- play AI vs. Human
- two AI’s play against each other.
In the third type, two AI’s play against each other, I made it so that YOUR AI (AI #1) plays a random AI (AI #2) (it chooses randomly an empty cell). Now it automatically plays 10.000 games and reports the result. Now you can change things in your code (regarding AI #1) and check out if it still plays perfect.
So this is a great way to test AI #1!
Explanation
The AI #2 is very bad, but with 10.000 games even it finds randomly a way to win.
When AI #1 plays perfect though AI #2 never wins.
When there’s minor flaw in AI #1, AI #2 wins about 20 Games of 10.000.
There is test data below.
Some of my code
I did not optimize the code in terms of OOP or speed
Here is some code for the board:
// The Board
// x coordinates of all 9 fields [all same in one column]
int[] xPosition =
{
110, 300, 490,
110, 300, 490,
110, 300, 490
};
// y coordinates of all 9 fields [all same in one row]
int[] yPosition =
{
150, 150, 150,
300, 300, 300,
450, 450, 450
};
// The status of all 9 fields: empty, or player X or player 0 (record the progress of the Game) // THE BOARD
char[] clicked =
{
' ', ' ', ' ',
' ', ' ', ' ',
' ', ' ', ' '
};
Internal board for the AI
Here is the internal board for the AI to add up the scores from your rules:
It must have initially values like 1,3,4 (since I didn’t implement your rule “5.BETTER THAN NOTHING is a line empty.” correctly. When I implement this, the initial scores can all be 0 obviously, so thank you)
// AI: The scores for all 9 fields: intial Score for each field. In each move fields get a score, the field with the best score is the field for the next AI move.
int[] pointsOfFieldForAI = new int[9]; // THE BOARD with AI scores
final int[] pointsOfFieldForAIEmpty =
{
3, 1, 3,
1, 4, 1,
3, 1, 3
};
Data for the lines
And here is the data for the lines that are checked by the AI:
String[] winnings = {
"012", // the horizontals lines // this is actually how the field is enumerated in the arrays above
"345",
"678",
"036", // vertical lines
"147",
"258",
"048", // diagonal lines
"246"
};
I use the numbers from each String as indexes for the board and the AI Score Board.
Report
Here is a report that I generated from the 10.000 Games test,
to test which initial values for the AI Score Table are best:
**Protokoll: X and O Game**
*Analysis of the necessary initial values for the internal AI-Score-Board to calculate the scores for the AI-Moves.*
final int[] pointsOfFieldForAIEmpty =
{
1, 1, 1,
1, 4, 1,
1, 1, 1
}
29.11.2020 12:52
10000 games with: 9904 wins and 170 draws; 9884 vs. 20 [AI #1 looses 20 Games, it’s not perfect]
--------------------------------
final int[] pointsOfFieldForAIEmpty =
{
3, 1, 3,
1, 1, 1,
3, 1, 3
};
29.11.2020 12:57
10000 games with: 9884 wins and 231 draws; 9884 vs. 0 [AI #1 looses 0 Games, it’s perfect]
--------------------------------
This is the best array for the 9 fields:
final int[] pointsOfFieldForAIEmpty =
{
3, 1, 3,
1, 4, 1,
3, 1, 3
};
29.11.2020 13:13
10000 games with: 9892 wins and 214 draws; 9892 vs. 0 [AI #1 looses 0 Games, it’s perfect]
--------------------------------
final int[] pointsOfFieldForAIEmpty =
{
0, 0, 0,
0, 0, 0, // 1 4 1
0, 0, 0
};
29.11.2020 13:15
10000 games with: 9829 wins and 317 draws; 9739 vs. 90 [AI #1 looses 90 Games, it’s NOT perfect]
--------------------------------
pretty much Nonsense values:
final int[] pointsOfFieldForAIEmpty =
{
1, 4, 1,
4, 0, 4, // 1 4 1
1, 4, 1
};
29.11.2020 15:26
10000 games with: 9708 wins and 514 draws; 9486 vs. 222 [AI #1 looses 222 Games, it’s NOT perfect]
So, a cool way to test your AI.
Again, thank you for your great ideas!
Warm regards,
Chrisir