This web app follows Project: Tic Tac Toe from The Odin Project, including the AI extension criteria.
This app wasn't designed with mobile in mind.
Six different AI players are implemented:
- Hard: Perfect gameplay algorithm that goes through a priority rule list.
- Implemented using the expert system algorithm outlined in Flexible Strategy Use in Young Children's Tic-Tac-Toe by Kevin Crowley and Robert S. Siegler.
- The algorithm follows a priority rule list:
- Rule 1: The AI checks if it can win on the current turn. If so, it takes the win. If not, it tries the next rule.
- Rule 2: The AI checks if its opponent can win on the current turn. If so, it blocks the opponent from winning. If not, it tries the next rule.
- Rule 3: The AI checks if it can set up a fork. If so, then it will do so. If not, it tries the next rule.
- A fork is a situation where the "forking player" can guarantee a win the turn after the fork situation was create.
- Rule 4: The AI checks if its opponent can set up a fork on its turn. If so, then it will block it. If not, it tries the next rule.
- To block its opponent's fork, the AI will first attempt to create a "line-of-two" to force its opponent to block it, taking care so when its opponent blocks, it doesn't inadvertently let the opponent create a fork.
- If creating a valid "line-of-two" isn't possible, then the AI will simply place its marker on a square such that its opponent can no longer set up a fork.
- Rule 5: The AI will attempt to place its marker at the center. If it can't, it tries the next rule.
- Rule 6: The AI will attempt to place its marker at the opposite corner of an opponent's corner marker, if such a position exists. If it can't, it tries the next rule.
- Rule 7: The AI will attempt to place its marker at an empty corner. If it can't, then it moves to the final rule.
- Rule 8: The AI will attempt to place its marker at an empty side.
- Medium: An intelligent but flawed AI whose weakness is that it only looks one step ahead.
- Also implemented using an expert system algorithm that goes through a simple priority rule list:
- Rule 1: The AI checks if it can win on the current turn. If so, it takes the win. If not, it tries the next rule.
- Rule 2: The AI checks if its opponent can win on the current turn. If so, it blocks at least one of its opponent's possible winning moves (even if it's a fork). If not, it tries the next rule.
- Rule 3: The AI checks if there's any possible path to victory. If so, then it will try to "win as fast as possible", favouring lines that already contain its own marker. If there are no possible lines to victory, then it moves to the final rule.
- Rule 4: The AI picks any random empty square.
- Easy: Picks any empty square at random. All empty squares have equal probabilities of being chosen.
- Minimax: Cannot lose. Takes advantage of guaranteed wins, or forces a draw if it can't.
- Implemented using the minimax algorithm.
- This AI may sometimes choose not to take a win on the next turn, but (I believe) it will only do so if it can guarantee a win in subsequent turns anyway.
- Although the AI plays very well, this implementation still has room for improvement. Currently, if it can't guarantee a win, it will randomly pick between moves that can guarantee a draw, rather than trying to pick the "best" move between them like the Hard AI does.
- Loser: Tries to lose. Also implemented using the minimax algorithm, so it behaves like Hard, but for a different goal.
- Sabotaged: A sabotaged version of Hard that has a chance of playing poorly on each turn.
- During each turn, there's a 60% chance of playing like Hard, and a 40% chance of playing like Easy.
Honestly, this project has become a lot more interesting than I expected because of all the different AI's that can be implemented. As a result, the codebase has become increasingly complex to accomodate the new ideas. Also, I'm interested in presenting these ideas with a much nicer UI.
So maybe I'll spin this project off into something more serious? idk, not gonna make any promises though.