“完全自动化” Cookie Clicker


目的

我已经筋疲力尽了。我试图完全自动化我以前玩过的名为Cookie Clicker的游戏,因为我可以对其进行编程。

什么是"全自动"在这里

如果可以的话我会很高兴

python CookieClicker.py
→Cookie Clicker启动
→保存并从文件中读取
→自动单击大Cookie和金曲奇
→适当升级并购买
→适当保存

首先是Cookie Clicker是什么?

Baba是一个饼干烘烤游戏。就这样。
对于那些想玩

的人,请点击这里

我做了什么

基本上,当使用python(硒)远程运行Firefox时,让javascript在硒上运行。
自动单击部分的源代码是从Cookie Cliker Wiki借来的。

文件结构

Cookie Clicker /
├Building.py
├AutoCookieClicker.py
└保存(git)/
└savedata

源代码

Gabber设计,这只是移动的问题,所以它处于可怕的状态。
单击此处获取github:https://github.com/RyuSA/CookieClicker

CookieClicker.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import sys
import git
import csv
import time
from selenium import webdriver
from time import sleep
from datetime import datetime
from buildings import Building
from configparser import SafeConfigParser

URL_CookieClicker = "http://orteil.dashnet.org/cookieclicker/"
EXECUTE_CLICK_BIGCOOKIE = "setInterval(function() {Game.ClickCookie(); Game.lastClick=0; }, 1000/1000);"
EXECUTE_CLICK_GOLDENCOOKIE = "setInterval(function(){for (var i in Game.shimmers) { Game.shimmers[i].pop(); }}, 500);"

def git_commit():
    repository = git.Repo("save")
    repository.git.add(".")
    commit_meessage = datetime.now().isoformat()
    repository.index.commit(commit_meessage)

class CookieCliker(object):
    Path = "save/savedata"
    WINDOW_WIDTH = 1200
    WINDOW_HEIGHT = 500
    SAVE_INTERVAL = 30
    NUMBER_OF_BUY = 1000
    INTERVAL = 30
    PRODUCTS_LIST = ("Cursor", "Grandma", "Farm", "Mine", "Factory", "Bank", "Temple", "Tower", "Shipment", "Lab", "Portal", "Time_Machine", "Condefsor", "Prism", "Chansemaker")
    def __init__(self, url):
        self.driver = webdriver.Firefox()
        self.driver.set_window_size(CookieCliker.WINDOW_WIDTH, CookieCliker.WINDOW_HEIGHT)        
        self.driver.get(url)
        # 2秒待てば、ブラウザの読み込みが間に合う
        sleep(2)
        # クリック用の大クッキー取得
        self.BigCookie = self.driver.find_element_by_id("bigCookie")
        self.products = []
        for id, name in enumerate(CookieCliker.PRODUCTS_LIST):
            self.products.append(Building(name = name, id = id, driver = self.driver))
        print("Cookie Clicker has been initialized")

# セーブデータをブラウザからコピぺして保存
    def Export_Savedata(self):
        OpenTextAreaScript = "Game.ExportSave();"
        self.driver.execute_script(OpenTextAreaScript)
        savedata = self.driver.find_element_by_id("textareaPrompt").text
        f = open(CookieCliker.Path, 'w')
        f.write(savedata)
        f.close()
        self.driver.execute_script("Game.ClosePrompt();")
        git_commit()

    def Import_Savedata(self):
        OpenTextAreaScript = "Game.ImportSave();"
        ImportScript = "Game.ImportSaveCode(l('textareaPrompt').value);"
        LoadScript = "Game.ClosePrompt();"

        # Importを開く
        self.driver.execute_script(OpenTextAreaScript)

        # 注意:savefileの中には1行しか記述されていないはず
        f = open(CookieCliker.Path, 'r')
        # savedataが読み込めないことがあったら、空のセーブデータでプレイ
        savefile = ""
        for a in f:
            savefile = a
        f.close()

        self.driver.find_element_by_id("textareaPrompt").send_keys(savefile)
        self.driver.execute_script(ImportScript)
        self.driver.execute_script(LoadScript)
        for p in self.products:
            p.Update(self.driver)

        print("/////////////////////////////////////")
        print("/           Load done               /")
        print("/////////////////////////////////////")

    def Auto_Clicker(self):
        print("set auto click")
        global EXECUTE_CLICK_BIGCOOKIE, EXECUTE_CLICK_GOLDENCOOKIE
        self.driver.execute_script(EXECUTE_CLICK_BIGCOOKIE)
        self.driver.execute_script(EXECUTE_CLICK_GOLDENCOOKIE)

    def Buy_allUpgrades(self):
        print("Buy all upgrades")
        while True:
            try:
                upgrade = self.driver.find_element_by_id("upgrade0")
                if "enabled" in upgrade.get_attribute("class"):
                    upgrade.click()
                else:
                    return
            except:
                # print(something happened : at buyallupgrades)
                return

    def Standard_Strategy(self):
        # productsの中で、Cps_per_priceの高いもの順に並び替え
        temp = sorted(self.products, key=lambda p:-p.Cps_per_price)
        count = 0
        max_count = 3
        buythem = []
        # Cps_per_priceの高い順に、unlockされているものを4つ持ってくる
        for p in temp:
            if p.is_unlocked:
                buythem.append(p)
                count += 1
                if count > max_count:
                    break
        print("Standard Strategy begin")
        for p in buythem:
            if p.is_active(self.driver):
                # NUMBER_OF_BUYだけ購入
                p.Buy(CookieCliker.NUMBER_OF_BUY, self.driver)
        print("Standard Strategy end")

    def Run(self):
        print("#####################################")
        print("#        Running CookieCliker       #")
        print("#####################################")
        self.Import_Savedata()
        self.Auto_Clicker()
        fieldnames = ("time","Cookies", "Cps")          
        save_point = 0
        data = [0, 0, 0]
        start = time.time()
        while True:
            self.Buy_allUpgrades()
            self.Standard_Strategy()
            print("wait" + str(CookieCliker.INTERVAL) + "sec")
            sleep(CookieCliker.INTERVAL)
            save_point += 1
            if save_point > 10:
                self.Export_Savedata()
                data = {}
                data["time"] = time.time() - start
                data["Cookies"] = self.driver.execute_script("return Game.cookies")
                data["Cps"] = self.driver.execute_script("return Game.cookiesPs")
                save_point = 0
                with open("log.csv", "a", newline="") as log:
                    temp = csv.DictWriter(log, fieldnames=fieldnames)
                    temp.writerow(data)
            print("--------------------------------------")

clicker = CookieCliker(URL_CookieClicker)

clicker.Run()

print("cookie Clicker end")

建筑.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Building(object):
    product = "product"

    def __init__(self, name ,id , driver):
        self.id = id
        self.productid = "product" + str(id)
        self.name = name
        self.execute_ThisBuilding = "Game.ObjectsById[" + str(id) + "]"
        self.Cps = driver.execute_script("return " + self.execute_ThisBuilding + ".storedCps;")
        self.price =  driver.execute_script("return " + self.execute_ThisBuilding + ".price;")
        self.Cps_per_price = self.Cps / self.price

    def Buy(self, bought_number, driver):
        # クリックさせるよりも高速
        driver.execute_script(self.execute_ThisBuilding + ".buy(" + str(bought_number) + ");")
        self.Cps = driver.execute_script("return " + self.execute_ThisBuilding + ".storedCps;")
        self.price =  driver.execute_script("return " + self.execute_ThisBuilding + ".price;")
        self.Cps_per_price = self.Cps / self.price

    def Sell(self, sold_number, driver):
        driver.execute_script(self.execute_ThisBuilding + ".sell(" + str(bought_number) + ");")
        self.Cps = driver.execute_script("return " + self.execute_ThisBuilding + ".storedCps;")
        self.price =  driver.execute_script("return " + self.execute_ThisBuilding + ".price;")
        self.Cps_per_price = self.Cps / self.price

    def is_active(self, driver):
        return "enabled" in driver.find_element_by_id(self.productid).get_attribute("class")

    def is_unlocked(self, driver):
        return "unlocked" in driver.find_element_by_id(self.productid).get_attribute("class")

    def Update(self, driver):
        self.Cps = driver.execute_script("return " + self.execute_ThisBuilding + ".storedCps;")
        self.price =  driver.execute_script("return " + self.execute_ThisBuilding + ".price;")
        self.Cps_per_price = self.Cps / self.price

一点评论。

git_commit

使用Gitpython从python提交保存存储库的函数。
如果您在自动化时分别保存保存数据,则会生成大量保存数据,因此这次我决定使用git管理保存数据部分。

我提到了使用GitPython。

建造

基本上,我们只有随时间变化的信息(Cps,价格)
其余的,我适当地运行javascript进行检查。
……在程序设计方面我该怎么办? ??

CookieClicker

到目前为止,还没有那么复杂,所以我只是启动Firefox并运行javascript。
javascript是通过阅读CookieClicker的源代码而带来的。

保存数据管理(Import / Export_Savedata)

我本可以采用单击Cookie Clicker的选项的简单方法,但是当我阅读javascript时,发现可以通过执行以下操作来加载数据。

firefox_console

1
2
3
4
5
6
7
8
9
Game.ImportSave();
// id = textareaPrompt のテキストエリアが出現
// id = textareaPrompt のテキストエリアにセーブデータを入力する

Game.ImportSaveCode(l('textareaPrompt').value);
//セーブデータがロードされる

Game.ClosePrompt();
// テキストエリアを閉じる

同样,我发现导出应按以下步骤进行。

firefox_console

1
2
3
4
5
6
Game.ExportSave();
// id = textareaPrompt のテキストエリアが出現
// id = textareaPrompt のテキストエリアのセーブデータを保存

Game.ClosePrompt();
// テキストエリアを閉じる

购买自动升级(Buy_allUpgrades)

升级的ID为" id = upgradeX"(X是大于或等于0的整数)
将"已启用类别"分配给可以购买的商品。因此,当" id = upgrade0"的升级具有" class enabled"时,我尝试尽可能多地购买。

自动购买建筑物(Standard_Strategy)

我最担心的是,但是最后,我采取了一种简单的方法:"以最高Cps /价格(在不限时的价格中)在前四名中购买尽可能多的建筑物"。
但是,此方法

  • 升级订单注意事项0
  • 考虑协同作用0
  • 神秘的新元素(龙蛋和糖块)
  • 在下半年,Cps根本不会增加(因为购买建筑物需要时间)

由于

...(包括购买时间)

之类的问题,它根本没有效率。

印象数

Cookie Clicker Fun