あけましておめでとうございます。
どうもdaigoroです。
かなり始めるの遅いのですが、クラッシュオブクランを最近始めました。
いまTHレベル8ですかね~。2021年1月現在でTHレベルは13までリリースされてますね。
で、レベルカンストするのに無課金でどれだけのコスト(時間)がかかるのか気になったのでPythonで計算してみました。
Windows10、メモリ8GB、CPUはCorei5、使用言語はPython3.9の環境でやってます
下記にソースコードを記載しまーす
import os, csv, re, math
#init_cost_list()は、コスト(建築時間(秒))のリストを取得する関数
def init_cost_list():
file_name = os.listdir(path='./csvs')
cost_list = []
#file_nameにはcsvsディレクトリ下の全ファイル名がリスト型として保存
#csvsはパスを含むファイル名
#devsは各csvファイル内のテキストデータがリスト型で保存
for i in file_name:
csvs = os.getcwd() + '\\csvs\\' + i
with open(csvs ,'r') as f:
devs = csv.reader(f)
for dev in devs:
dev_tmp = []
#すべてのタブをスペースに変換
dev = str(dev).replace('\\t', ' ')
#重複するスペースをひとつにまとめる
dev = re.sub(r" +", " ", dev)
#余分な角括弧等の文字列を消去し、スペースで区切る
cost_list.append(str(dev).replace('[', '').replace(']', '').replace("'", "").split(' '))
return cost_list
#extract_TH_costはタウンホールレベルに応じたコストのリストを返す関数
def extract_TH_cost(TH_level, cost_list):
target_TH_dev_list = []
for i in range(len(cost_list)):
if cost_list[i][2] == str(TH_level):
target_TH_dev_list.append(cost_list[i])
return target_TH_dev_list
#target_TH_dev_listの中身をint型に変更し、建設物のレベルをキーに昇順にソートする関数
def sort_dev(target_TH_dev_list):
for i in range(len(target_TH_dev_list)):
for j in range(3):
target_TH_dev_list[i][j] = int(target_TH_dev_list[i][j])
target_TH_dev_list.sort( key=lambda x: x[0] )
return target_TH_dev_list
def daiku_assignner(target_TH_dev_list, daiku, daiku_num, TH_level):
if target_TH_dev_list != []:
for i in range(len(daiku)):
if daiku[i] == 0:
daiku[i] = target_TH_dev_list[0][1]
del target_TH_dev_list[0]
return target_TH_dev_list, daiku
def total_cost(target_TH_dev_list):
target_TH_total_cost = 0
for i in range(len(target_TH_dev_list)):
target_TH_total_cost = target_TH_total_cost + int(target_TH_dev_list[i][1])
return target_TH_total_cost
def past_time(time):
mons = math.floor((time % 77760000 ) / 2592000 ) #要した月数
ds = math.floor((time % 2592000 ) / 86400 ) #要した日数
hrs = math.floor((time % 86400 ) /3600) #要した時間数
minute = math.floor(( time % 3600 ) / 60 ) #要した分数
sec = time % 60 #要した秒数
return mons, ds, hrs, minute, sec
def main():
#パラメータの初期化
TH_level, daiku_num, time_steps = 1, 5, 100000000000000000000000000000000000
TH_updating_flag = False #FalseならTHは未アップデート TrueならTHのアップデート中
TH_update_cost_list = [0, 10, 7200, 28800, 57600, 86400, 172800, 259200, 345600, 518400, 864000, 1209600, 1555200]
daiku = [] #daiku_num分だけ領域を確保し、それぞれの要素に建設コスト値を代入
#daikuの初期化
for i in range(daiku_num):
daiku.append(0)
#コスト値の初期化
cost_list = init_cost_list()
#cost_listからTHレベル1に対応する建設コストのリストを算出
target_TH_dev_list = extract_TH_cost(TH_level, cost_list)
target_TH_total_cost = total_cost(target_TH_dev_list)
#THレベル1に対応した建設コストのリストを建設物のレベルをキーとして昇順にソート
target_TH_dev_list = sort_dev(target_TH_dev_list)
#時間経過とともにdaiku[]の各要素のコスト値を減算するfor文
for time in range(time_steps):
mons, ds, hrs, minute, sec = past_time(time)
#現THの建造物の総コストが次THの建設コストより小さく、かつ空きの大工がいる場合、THの建設をアサイン
try:
if ((target_TH_total_cost - (time * daiku_num )) > TH_update_cost_list[TH_level]):
if daiku.count(0) > 0 and TH_updating_flag == False:
#空いてる大工が誰かを記録
TH_daiku = daiku.index(0)
#当該大工にTHの建設をアサイン
daiku[daiku.index(0)] = TH_update_cost_list[TH_level]
#TH建設中のフラグをTrueに切り替え
TH_updating_flag = True
except:
pass
#THを建設中であれば、THの建設が完了したかどうかを確認し、完了していたらフラグをFalseに戻す処理
if TH_updating_flag == True and daiku[TH_daiku] == 0 and TH_level < 14:
#TH建設中フラグをFalseに切り替え
TH_updating_flag = False
#THレベルを上げる
TH_level = TH_level + 1
print("\nTHレベル:" + str(TH_level))
#レベル上げ後のコストリストを取得
next_level_cost_list = extract_TH_cost(TH_level, cost_list)
#取得したリストを挿入
for j in range(len(next_level_cost_list)):
target_TH_dev_list.append(next_level_cost_list[j])
#更新したコストリストをソート
target_TH_dev_list = sort_dev(target_TH_dev_list)
#更新したコストリストをもとに、総コストを計算
target_TH_total_cost = total_cost(target_TH_dev_list)
#daikuにコストを割り当て
target_TH_dev_list, daiku = daiku_assignner(target_TH_dev_list, daiku, daiku_num, TH_level)
#時間経過とともにdaikuリストの各要素から減算
for j in range(len(daiku)):
if daiku[j] > 0:
daiku[j] = daiku[j] - 1
if daiku_num == 5:
print("\r" + "大工1" + ": " + str(daiku[0]) + "\t大工2" + ": " + str(daiku[1]) + "\t大工3" + ": " + str(daiku[2])+ "\t大工4" + ": " + str(daiku[3])+ "\t大工5" + ": " + str(daiku[4]) + "\t" + "time step:" + str(time) + " " + str(mons) + " カ月 " + str(ds) + "日 " + str(hrs) + "時間 " + str(minute) + "分 " + str(sec) + "秒 ",end="")
#目標とするTHのレベルを達成した場合の処理
if TH_level == 13 and daiku == [0,0,0,0,0]:
# print("大工" + str(daiku_num) + " 名")
# print("TH" + str(TH_level) + "までの完了所要時間:\t" + str(mons) + "カ月" + str(ds) + "日" + str(hrs) + "時間" + str(minute) + "分" + str(sec) + "秒" )
break
if __name__ == '__main__':
main()
おおまかなアルゴリズムについて解説します
防衛装備、軍事装備、資源、トラップ等の情報をまとめたCSVファイルを各装備で作成します。
CSVファイルの中身のデータは次の通りです。
darkeric.csv
1 28800 7
2 57600 7
3 86400 8
4 129600 8
5 172800 9
6 259200 9
7 432000 12
8 864000 13
1行目は当該装備のレベル、2行目をコスト(秒)、3行目を装備レベルに対応するTHレベルとしています。
本プログラムでは、TH1から開始し、5名いる大工に建築タスクをそれぞれ割り当てます。
①割り当てる建築タスクは現在のTHレベルに対応するレベルの建築物を割り当てます。
②タイムスタンプは1秒ずつ進行し、各大工のタスクを1ずつ減算します。
③次レベルのTHの建築を大工に割り当てるタイミングは次式の不等式を初めて満たしたタイミングで考えてます。
④現THで建築可能な建築物の総コスト - タイムスタンプ×大工数 > 次THの建築コスト
こうすることで、一人の大工が次THの建築が完了するタイミングが概ね他の大工が建築が終了するタイミングが一致します。
まぁ、次THの建築を開始できるタイミングで次THの建築を開始したほうがロスがないので時間的には早いのですが、そこまでやるのは面倒実際は早くTHを成長させてしまうと他アカウントへの進行時にかかるお金が増えるので今回はこういうアルゴリズムにしてみました。
⓹THがレベルアップしたタイムスタンプを記録します。
⑥①に戻り、TH13が完了するまでループします。
結果として、大工5名、無課金の条件下でTH13までレベルを上げ、建築可能な建造物をすべてレベルカンストさせるのにかかる時間は
29 カ月 26日 8時間 29分 50秒
でした。睡眠時間を一切考慮せずプレイしても、無課金だと2年と5カ月かかります笑
改めて課金ありきのゲームなんだな~と感じました。