Tetris game automata

Time:2020-11-25

Making Tetris with electronFollow up article, intelligent program to play Tetris game.

background

Not long ago, I completed the basic Tetris game with ES6. Today, I have completed a preliminary intelligent algorithm. I can play Tetris automatically, which makes my idea closer to the realization.

design sketch

The first run, eliminate 1398 lines, steal joy! The highest record was 3676 lines.

Tetris game automata

Program structure

It mainly focuses on intelligent algorithm, and its structure is simplified index.js Medium.

Using timers to drive games

function autoPlayClick(){
    isAutoPlay = document.getElementById('autoPlay').checked;
    if(isAutoPlay){
        clearInterval(interval)
        Interval = setinterval (autotick, 1); // automatic algorithm entry
    }else{
        clearInterval(interval)
        Interval = setinterval (tick, tickval); // Auto drop entry
    }
    document.getElementById('speedShow').focus();
}

Variable definition

Simulating manual operation, a square is divided into three steps: rotating, moving left or right, and falling to the bottom.

Const moveops = ['moveleft ','moveright'] // definition of left and right movement
Var oplist = [], besteva; // queue to be operated

Class operation {// operation details
    constructor(op,num){                    
        this.op  =OP; // operation method
        this.num  =Num; // number of operations
    }
}

Class evaluation {// result definition of situation evaluation function
    constructor(r,x,eva){
        This. R = R; // number of rotations
        This. X = x; // horizontal position of square
        this.eva  =EVA; // evaluation results
    }
}

Intelligent algorithm scheduling

function autoTick(){
    If ( opList.length  ==0) {// the previous block has been processed
        Getstrategy(); // policy algorithm to generate the operation method strategy sequence of the next block
    }else{
        let op =  opList.shift (); // get the operation method
        for(let i=0; i< op.num ; I + +) {// execute the established policy
            tetris[op.op]();
            If ( op.op  =='movedown ') // it is a drop operation. It takes a block
                generateNext();
        }
    }
}

Strategy algorithm

This is the core of the algorithm to determine the operation method of each block.

function getStrategy(){
    Let max = 0; // the optimal evaluation value exists
    tetris.erase();
    let tmp = new Tetris( tetris.shape , tetris.ctx , Tetris. X, Tetris. Y, 'RGB (1,1,1,1)','rgb (111111111) '// generate blocks for testing
    For (let I = 0; I < 4; I + +) {// keep the test squares consistent with the real ones, because each of my squares is generated with random number of rotations
        for(let j = 0; j < 4; j++){
            tmp.data[i][j] = tetris.data[i][j];  
        }
    }
    For (let r = 0; R < 4; R + +) {// each square is rotated four times to evaluate the situation respectively
        tmp.erase();
        tmp.x = tetris.x;
        tmp.y = tetris.y;
        if(r > 0)
            tmp.rotate();
        while( tmp.moveLeft ()); // test from leftmost to right
        while( tmp.moveDown ()); // fall to the bottom
        While (rightover (TMP)) {// ends the evaluation of this form to the right
            Let score = evaluate (TMP); // situation assessment
            If (score > max) {// save the best result
                max = score;
                bestEva = new Evaluation(r,tmp.x,max)
            }
            if(! tmp.moveRight ()) {// right shift failed
                if(! tmp.moveUp ()) {// move up to bypass the obstacle
                    Max = 1000; // if the move up fails, it means that the hole is filled and the square is put here
                    bestEva = new Evaluation(r,tmp.x,max)
                    break;
                }
            }else{
                while( tmp.moveDown ()); // fall to the bottom after moving right successfully
            }
        }
        Let score = evaluate (TMP); // last position
        if(score > max){
            max = score;
            bestEva = new Evaluation(r,tmp.x,max)
        }
    }
    tmp.erase();
    // console.log(max)

    opList.push (New opration ('rotate ', besteva. R)); // rotation operation
    Let moveact = besteva. X - Tetris. X > 0? 1:0; // the horizontal position difference is converted into a left or right shift operation
    let actNum = Math.abs(bestEva.x - tetris.x)
    opList.push New (opmove); or move right
    opList.push (New opration ('movedown ', 1)); // drop operation

}

Evaluation function

Now only a few basic parameters have been evaluated and need to be optimized. A more in-depth approach is to add machine learning algorithm for autonomous feedback learning.

function evaluate(t){
    Let CT = T.Y; // the larger the debugging, the better
    For (let I = 0; I < 4; I + +) {// check the four neighbors of each square
        for(let j = 0; j < 4; j++){
            if(t.data[i][j]){
                If (t.cansee (t.x + I, T.Y + j + 1)) // there is a void below
                    ct -= 5;
                for(let k=0; k<4; k++){
                    switch(k){
                        Case 0: CT + = t.cansee (t.x + I + 1, T.Y + J)? 0:1; // right
                        break;
                        Case 1: CT + = t.cansee (t.x + I - 1, T.Y + J)? 0:1; // left
                        break;
                        Case 2: CT + = t.cansee (t.x + I, T.Y + j + 1)? 0:1; // below
                        break;
                        Case 3: CT + = t.cansee (t.x + I, T.Y + J - 1)? 0:1; // top
                        break;
                    }
                }
            }
        }
    }
    return ct;
}

source code

git clone https://git.oschina.net/zhoutk/Tetris.git

Or:

git clone https://github.com/zhoutk/Tetris

Summary

Opened my intelligent algorithm learning road, this is only a simplest automatic program, can not talk about any intelligence, but for me, it is the beginning of a new direction, come on!