Session 11 (19.01.24) - RUB-INI-Theory-of-Machine-Learning/Info1_WS23-24 GitHub Wiki
In der elften Session starten wir mit der Programmierung eines Tetrisbots. Dazu müssen wir uns entscheiden wie solch eine Klasse in das Programm integriert wird. Danach muss der Bot lernen Spielzüge auszuführen. Schlussendlich bringen wir dem Bot bei eine zufällige Position gezielt anzusteuern.
Ziele
- Botklasse in das Programm integrieren (mit Interface)
- Spielzüge ausführen
- Zufällige Position berechnen und dann gezielt ansteuern
Botklasse in das Programm integrieren (mit Interface)
class Bot {
public:
var current_time, speed;
var optimal_position, current_tetromino, next_tetromino;
var game;
constructor(game, speed=100){
this.game = game;
this.speed = speed;
this.current_time = time() + speed/2;
}
function step(){
this.game.step();
}
function keyup(e){}
function keydown(e){}
function get_incoming_lines(){
return this.game.get_incoming_lines();
}
function add_incoming_lines(lines){
this.game.add_incoming_lines(lines);
}
function get_outgoing_lines(){
return this.game.get_outgoing_lines();
}
function set_outgoing_lines(lines){
this.game.set_outgoing_lines(lines);
}
}
class Game {
...
function get_incoming_lines(){
return this.incoming_lines;
}
function add_incoming_lines(lines){
this.incoming_lines += lines;
}
function get_outgoing_lines(){
return this.outgoing_lines;
}
function set_outgoing_lines(lines){
this.set_outgoing_lines = lines;
}
}
setEventHandler("timer", function(event) {
for var game_idx in 0:games.size() do {
var game = games[game_idx];
if game.get_outgoing_lines() > 0 then {
games[(game_idx + 1) % games.size()].add_incoming_lines(game.outgoing_lines());
game.set_outgoing_lines(0);
}
...
}
}
Zufällige Spielzüge ausführen
function step() {
this.game.step();
if time() - this.current_time > this.speed then {
this.current_time = time();
var key = this.game.bindings[Integer(math.random() * 4)];
this.game.keydown(key);
}
}
Zufällige Position gezielt ansteuern
function step(){
this.game.step();
if time() - this.current_time > this.speed then {
this.current_time = time();
if this.optimal_position == null or
(
this.current_tetromino != this.game.tetromino.type or
this.next_tetromino != this.game.pool.next()
)
then {
this.current_tetromino = this.game.tetromino.type;
this.next_tetromino = this.game.pool.next();
this.optimal_position = {
"column": math.floor(math.random() * playfield.width + 1),
"rotation": math.floor(math.random() * tetromino.max_rotations))
};
}
if this.game.tetromino.rotation < this.optimal_position["rotation"] then this.game.keydown(this.game.bindings[0]);
else if this.game.tetromino.rotation > this.optimal_position["rotation"] then this.game.keydown(this.game.bindings[1]);
else if this.game.tetromino.column > this.optimal_position["column"] then this.game.keydown(this.game.bindings[2]);
else if this.game.tetromino.column < this.optimal_position["column"] then this.game.keydown(this.game.bindings[3]);
}
}