예제 #1
0
 def __init__(self, tileset, canvas, label, max_scale):
     self.tileset = tileset
     self.canvas = canvas
     self.label = label
     self.max_scale = max_scale
     self.challenge = None
     scale = min(max_scale, DEFAULT_SCALE)
     self.screen = PliTk(canvas, 0, 0, 0, 0, self.tileset, scale)
예제 #2
0
 def __init__(self, game, canvas, label):
     self.game = game
     self.canvas = canvas
     self.label = label
     self.tileset = load_tileset(game["tileset"])
     self.screen = PliTk(canvas, 0, 0, 0, 0, self.tileset, SCALE)
     self.load_players()
     self.level_index = 0
     self.load_level()
예제 #3
0
class Board:
    def __init__(self, tileset, canvas, label, max_scale):
        self.tileset = tileset
        self.canvas = canvas
        self.label = label
        self.max_scale = max_scale
        self.challenge = None
        scale = min(max_scale, DEFAULT_SCALE)
        self.screen = PliTk(canvas, 0, 0, 0, 0, self.tileset, scale)

    def set_max_scale(self, new_scale):
        self.max_scale = new_scale
        map_scale = min(self.map_scale, new_scale)
        print(self.map_scale, new_scale, map_scale)
        if map_scale != self.screen.scale:
            self.screen.rescale(map_scale)
            self.update(self.grid, self.players)

    def load(self, map):
        self.map_scale = map.get("scale") or DEFAULT_SCALE
        scale = min(self.map_scale, self.max_scale)
        print(f"map scale = {scale}")
        self.screen.rescale(scale)
        cols, rows = len(map["grid"][0]), len(map["grid"])
        self.screen.resize(cols, rows)
        self.tiles = dict(DEFAULT_TILES)
        if map.get("tiles"): self.tiles.update(map["tiles"])
        self.map_title = map.get("title") or "unknown"
        self.update(map["grid"], [])

    def update(self, grid, players):
        self.grid, self.players = grid, players
        for y in range(len(grid)):
            for x in range(len(grid[0])):
                self.screen.set_tile(x, y, self.tiles[grid[y][x]])
        for p in players:
            self.screen.set_tile(p.x, p.y, p.tile)
        lines = []
        if self.challenge:
            lines.append(
                "Chal: %s\nLevels total: %4d" %
                (self.challenge.get("title"), len(self.challenge["levels"])))
        lines.append("Level: %3s" % (self.map_title))
        for p in sorted(players, key=lambda x: x.gold, reverse=True):
            lines.append("%s: %3d" % (p.name, p.gold))
        self.label["text"] = "\n".join(lines)

    def set_challenge(self, chal):
        self.challenge = chal
예제 #4
0
    def __init__(self):
        #################### Init settings ####################
        sets = (SETTINGS
                if SETTINGS.exists() else DEFAULT_SETTINGS).read_text()
        self.settings = json.loads(sets)

        self.mp = None
        self.game = None

        #################### Init window ####################
        self.root = root = tk.Tk()
        root.configure(background="black")
        root.title("DandyBot")
        canvas = tk.Canvas(root, bg="black", highlightthickness=0)
        canvas.pack(side=tk.LEFT)
        self.m_frame = frame = tk.Frame(root,
                                        bg="black",
                                        width=MENU_WIDTH,
                                        height=MENU_HEIGHT)
        frame.pack_propagate(0)
        frame.pack(side=tk.RIGHT, anchor="n", fill="x")
        label = tk.Label(frame,
                         font=("TkFixedFont", ),
                         justify=tk.RIGHT,
                         fg="white",
                         bg="gray15")
        label.pack(side=tk.TOP, fill="x", anchor="n")
        tileset = json.loads(DATA_DIR.joinpath("tileset.json").read_text())
        tileset["data"] = DATA_DIR.joinpath(tileset["file"]).read_bytes()
        self.board = Board(tileset, canvas, label, self.settings["max_scale"])

        #################### Bot label ####################
        self.bot_label = tk.Label(frame,
                                  font=("TkFixedFont", ),
                                  justify=tk.RIGHT,
                                  bg="gray15")
        self.bot_label.pack(side=tk.TOP, anchor="n", fill="x", pady=5)
        self.bot_label[
            "text"] = f"Bot: {self.settings.get('bot') or 'undefined'}"
        self.bot_label["fg"] = GREEN if self.settings.get('bot') else "red"

        #################### Tile selector ####################
        tile_frame = tk.Frame(frame, bg="black")
        tile_frame.pack(side=tk.TOP)
        btn_left = tk.Button(tile_frame,
                             text="<",
                             fg="gray1",
                             bg="gray30",
                             highlightthickness=0)
        btn_right = tk.Button(tile_frame,
                              text=">",
                              fg="gray1",
                              bg="gray30",
                              highlightthickness=0)
        tile_canvas = tk.Canvas(tile_frame, bg="black", highlightthickness=0)
        tile_canvas.config(width=tileset["tile_width"],
                           height=tileset["tile_height"])
        btn_left.pack(side=tk.LEFT, padx=3, pady=3)
        tile_canvas.pack(side=tk.LEFT)
        btn_right.pack(side=tk.LEFT, padx=3, pady=3)
        tile_plitk = PliTk(tile_canvas, 0, 0, 1, 1, tileset, 1)
        tile_label = tk.Label(frame,
                              font=("TkFixedFont", 7),
                              text="tile: " + str(self.settings["tile"]),
                              justify=tk.RIGHT,
                              fg="gray50",
                              bg="black")
        tile_label.pack(side=tk.TOP)

        def switch_tile(n):
            # TODO: restrict choice
            tile_plitk.set_tile(0, 0, n)
            tile_label["text"] = f"tile: {n}"
            self.settings["tile"] = n
            self.save_settings(0)

        tile_plitk.set_tile(0, 0, self.settings["tile"])
        btn_left.config(command=lambda: switch_tile(self.settings["tile"] - 1))
        btn_right.config(
            command=lambda: switch_tile(self.settings["tile"] + 1))
        ########################   Menu   ########################
        menu_frame = tk.Frame(frame, bg="black")
        menu_frame.pack(side=tk.TOP, fill="x")
        self.menu = Menu(self, menu_frame)
        self.menu.show("main")
        self.init_level()
        root.mainloop()
예제 #5
0
class Board:
    def __init__(self, game, canvas, label):
        self.game = game
        self.canvas = canvas
        self.label = label
        self.tileset = load_tileset(game["tileset"])
        self.screen = PliTk(canvas, 0, 0, 0, 0, self.tileset, SCALE)
        self.load_players()
        self.level_index = 0
        self.load_level()

    def load_players(self):
        self.players = []
        for i, name in enumerate(self.game["players"]):
            script = import_module(name).script
            tile = self.game["tiles"]["@"][i]
            self.players.append(Player(name, script, self, tile))
        shuffle(self.players)

    def load_level(self):
        self.gold = 0
        self.steps = 0
        self.level = self.game["levels"][self.level_index]
        data = self.game["maps"][self.level["map"]]
        cols, rows = len(data[0]), len(data)
        self.map = [[data[y][x] for y in range(rows)] for x in range(cols)]
        self.has_player = [[None for y in range(rows)] for x in range(cols)]
        self.canvas.config(width=cols * self.tileset["tile_width"] * SCALE,
                           height=rows * self.tileset["tile_height"] * SCALE)
        self.screen.resize(cols, rows)
        for y in range(rows):
            for x in range(cols):
                self.update(x, y)
        for p in self.players:
            self.add_player(p, *self.level["start"])
        self.update_score()

    def get(self, x, y):
        if x < 0 or y < 0 or x >= self.screen.cols or y >= self.screen.rows:
            return "#"
        return self.map[x][y]

    def update(self, x, y):
        if self.has_player[x][y]:
            self.screen.set_tile(x, y, self.has_player[x][y].tile)
        else:
            self.screen.set_tile(x, y, self.game["tiles"][self.map[x][y]])

    def remove_player(self, player):
        self.has_player[player.x][player.y] = None
        self.update(player.x, player.y)

    def add_player(self, player, x, y):
        player.x, player.y = x, y
        self.has_player[x][y] = player
        self.update(x, y)

    def take_gold(self, x, y):
        self.gold += self.check("gold", x, y)
        self.map[x][y] = " "
        self.update(x, y)
        self.update_score()

    def check(self, cmd, *args):
        if cmd == "level":
            return self.level_index + 1
        x, y = args
        item = self.get(x, y)
        if cmd == "wall":
            return item == "#"
        if cmd == "gold":
            return int(item) if item.isdigit() else 0
        if cmd == "player":
            return item != "#" and self.has_player[x][y]

    def play(self):
        for p in self.players:
            p.act(p.script(self.check, p.x, p.y))
        if self.gold >= self.level["gold"]:
            return self.next_level()
        self.steps += 1
        return self.steps < self.level["steps"]

    def update_score(self):
        lines = [("Level:%4d\n" % (self.level_index + 1))]
        players = sorted(self.players, key=lambda x: x.gold, reverse=True)
        for p in players:
            lines.append("%s:%4d" % (p.name, p.gold))
        self.label["text"] = "\n".join(lines)

    def next_level(self):
        self.level_index += 1
        if self.level_index < len(self.game["levels"]):
            self.load_level()
            return True
        return False