Tetris AI
Interrupt the AI at any time. It will resume playing after a few seconds.
Metrics
The demo is also available in python as Tetris.py and can be played in any terminal.
The AI uses a set of metrics that are computed from the tetris board. These metrics are each given a weight and added together to give a board its fitness score. The final set I used is shown below.
Metric | Description |
sum holes | The count of all holes on the grid. A cell is a hole if it is empty and a filled cell is above it. |
sum height | The sum of the column heights. |
row flip | The number of times neighboring cells flip between empty and filled along a row. |
column flip | The number of times neighboring cells flip between empty and filled along a column. |
piece height | The height of the top cell of the most recently placed piece. Do not take into account line clears. |
sum well | The sum of squared well heights. A well is an opening 1 cell wide, which happens to function as a chokepoint. |
The AI maps out all possible moves it can make (with the option to add human-like lag), and records the final board states with their scores. The AI then backtracks from these final states to generate a map of the most optimal move to make given any position on the board.
If a new piece is spawned, or the board changes, then a new move map is generated. At each frame, the AI looks at the current piece position, looks at the map it has made, and can immediately see what move to make next.
I used Colin Fahey's metrics as a starting point and created a bunch of my own. I then set about finding the minimum set of metrics that yielded good performance.
Finding the set of optimal weights was difficult, mostly because their performance couldn't be predicted or approximated. The AI had to play several games with the weights to get their average performance. The performance of weights was also very jagged and full of local minima. For that reason, I used particle swarm optimization and added the ability for a particle to randomly reset itself if it became stuck.
When I had settled on the final set of metrics and weights, the AI was able to clear 19,032,064 lines before I forced it to terminate. During that time, it totally cleared the board 23,588 times.