Session 13 (02.02.24) - RUB-INI-Theory-of-Machine-Learning/Info1_WS23-24 GitHub Wiki

In der dreizehnten Session vervollständigen wir den Bot, in dem wir die Fitnessfunktion ausformulieren. Diese kann aus vielen Unterfunktionen bestehen, die gegeneinander gewichtet werden um dann zu einem finalen Score verrechnet zu werden. Beispielhaft werden drei Unterfunktionen gezeigt: Höhe des Spielbilds, Anzahl der Löcher und Roughness der Oberfläche.

Ziele

  • Gewichtsvektor
  • Höhe des Spielbilds
  • Anzahl der Löcher
  • Roughness der Oberfläche

Gewichtsvektor

function find_optimal_position(tetromino, playfield){

    ...
    
    positions.push(
        {
            "score": math.random(),
            "column": tetromino.column,
            "rotation": tetromino.rotation
        }
    );
    
    ...
    
}
function score(playfield){
    var weights = {
        "height": 1,
        "holes": 2,
        "roughness": 1
    };
    
    return (
        this.height(playfield.bitmap) * weights["height"] + 
        this.holes(playfield.bitmap) * weights["holes"] + 
        this.roughness(playfield.bitmap) * weights["roughness"]
    );
}

Höhe des Spielbilds

function height(bitmap){
    var zones = [
        {"boundaries": [0,12], "value": 0},
        {"boundaries": [13,16], "value": 3},
        {"boundaries": [16, bitmap.size()], "value": 10}
    ];
    
    var height = bitmap.size();
    for var row_idx in 0:bitmap.size() do {
        var empty = true;
        
        for var block in bitmap[row_idx] do {
        
            if block != 0 and block != "f" then {

                empty = false;
                break;
            }
        }
        
        if empty == false then {
            height = bitmap.size() - row_idx;
            break;
        }
        
    
        
        
    }
    for var zone in zones do {
            if height >= zone["boundaries"][0] and height <= zone["boundaries"][1] then
                return zone["value"];
        }
}

Anzahl der Löcher

function holes(playfield){
    var holes = 0;
    
    for var col_idx in 1:playfield[0].size()-1 do {
        var flag = false;
        for var row_idx in 1:playfield.size()-1 do {
            if playfield[row_idx][col_idx] != 0 then flag = true;
            if flag and playfield[row_idx][col_idx] == 0 then holes +=1;
        }
    }
    
    return holes;
}

Roughness der Oberfläche

function roughness(playfield){
    var playfield_heights = [];
    
    for var col_idx in 1:playfield[0].size()-1 do {
        for var row_idx in 1:playfield.size()-1 do {
            if playfield[row_idx][col_idx] != 0 then {
                playfield_heights.push(row_idx);
                break;
            }
        }
    }

    var score = 0;
    
    for var height_idx in 0:playfield_heights.size()-1 do {
        score += math.abs(playfield_heights[height_idx] - playfield_heights[height_idx+1]);
    }
    
    return score;
}