paia-hw5/ml/collect2.py

188 lines
5.0 KiB
Python

"""
The template of the main script of the machine learning process
"""
from ctypes import *
import pygame
class Player(Structure):
_fields_ = [
("x", c_int32),
("y", c_int32),
("speed", c_int32),
("score", c_int32),
("power", c_int32),
("oil", c_float),
("lives", c_int32),
("angle", c_int32),
("gun_angle", c_int32),
("cooldown", c_int32),
]
def from_dict(self, d: dict):
self.x = d["x"]
self.y = d["y"]
self.speed = d["speed"]
self.score = d["score"]
self.power = d["power"]
self.oil = d["oil"]
self.lives = d["lives"]
self.angle = d["angle"]
self.gun_angle = d["gun_angle"]
self.cooldown = d["cooldown"]
return self
class Bullet(Structure):
_fields_ = [("x", c_int32), ("y", c_int32)]
def from_dict(self, d: dict):
self.x = d["x"]
self.y = d["y"]
return self
class Station(Structure):
_fields_ = [
("x", c_int32),
("y", c_int32),
("power", c_int32),
]
def from_dict(self, d: dict):
self.x = d["x"]
self.y = d["y"]
self.power = d["power"]
return self
class Wall(Structure):
_fields_ = [
("x", c_int32),
("y", c_int32),
("lives", c_int32),
]
def from_dict(self, d: dict):
self.x = d["x"]
self.y = d["y"]
self.lives = d["lives"]
return self
class Info(Structure):
_fields_ = [
("player", POINTER(Player)),
("teammates", POINTER(Player)),
("teammates_len", c_uint32),
("enemies", POINTER(Player)),
("enemies_len", c_uint32),
("bullets", POINTER(Bullet)),
("bullet_len", c_uint32),
("bullet_stations", POINTER(Station)),
("bullet_stations_len", c_uint32),
("oil_stations", POINTER(Station)),
("oil_stations_len", c_uint32),
("walls", POINTER(Wall)),
("walls_len", c_uint32),
]
def from_dict(self, d: dict):
self.player = pointer(Player().from_dict(d))
self.teammates = (Player * len(d["teammate_info"]))()
for i, t in enumerate(d["teammate_info"]):
self.teammates[i] = Player().from_dict(t)
self.teammates_len = len(d["teammate_info"])
self.enemies = (Player * len(d["competitor_info"]))()
for i, e in enumerate(d["competitor_info"]):
self.enemies[i] = Player().from_dict(e)
self.enemies_len = len(d["competitor_info"])
self.bullets = (Bullet * len(d["bullets_info"]))()
for i, b in enumerate(d["bullets_info"]):
self.bullets[i] = Bullet().from_dict(b)
self.bullet_len = len(d["bullets_info"])
self.bullet_stations = (Station * len(d["bullet_stations_info"]))()
for i, b in enumerate(d["bullet_stations_info"]):
self.bullet_stations[i] = Station().from_dict(b)
self.bullet_stations_len = len(d["bullet_stations_info"])
self.oil_stations = (Station * len(d["oil_stations_info"]))()
for i, o in enumerate(d["oil_stations_info"]):
self.oil_stations[i] = Station().from_dict(o)
self.oil_stations_len = len(d["oil_stations_info"])
self.walls = (Wall * len(d["walls_info"]))()
for i, w in enumerate(d["walls_info"]):
self.walls[i] = Wall().from_dict(w)
self.walls_len = len(d["walls_info"])
return self
tank_rs = cdll.LoadLibrary("../libtank_rust.so")
tank_rs.init.argtypes = [c_char_p, c_int32]
tank_rs.init.restype = c_void_p
tank_rs.tick.argtypes = [c_void_p, POINTER(Info)]
tank_rs.tick.restype = c_int32
tank_rs.flush.argtypes = [c_void_p]
app = tank_rs.init(c_char_p("../output2".encode()), 10)
class MLPlay:
def __init__(self, ai_name, *args, **kwargs):
"""
Constructor
@param ai_name A string "1P" or "2P" indicates that the `MLPlay` is used by
which side.
"""
self.side = ai_name
print(f"Initial Game {ai_name} ml script")
self.time = 0
def update(self, scene_info: dict, keyboard=[], *args, **kwargs):
"""
Generate the command according to the received scene information
"""
if scene_info["status"] != "GAME_ALIVE":
tank_rs.flush(app)
info = Info().from_dict(scene_info)
action = tank_rs.tick(app, info)
command = ""
if action == 0:
command = "FORWARD"
elif action == 1:
command = "BACKWARD"
elif action == 2:
command = "TURN_RIGHT"
elif action == 3:
command = "TURN_LEFT"
elif action == 4:
command = "AIM_RIGHT"
elif action == 5:
command = "AIM_LEFT"
elif action == 6:
command = "SHOOT"
elif action == 7:
command = "NONE"
info
return [command]
def reset(self):
"""
Reset the status
"""
print(f"reset Game {self.side}")