Skip to content

Instantly share code, notes, and snippets.

@KTakahiro1729
Created January 21, 2017 15:02
Show Gist options
  • Save KTakahiro1729/a6ad893ce60498c8f43f5bc80ac29cd3 to your computer and use it in GitHub Desktop.
Save KTakahiro1729/a6ad893ce60498c8f43f5bc80ac29cd3 to your computer and use it in GitHub Desktop.
import datetime, re,collections
logTemplate = collections.namedtuple('template','chunkName logREString')
logDict = collections.OrderedDict({ #ログの種類の辞書です。chunkNameにはそのログが出てくるようなログの塊で実行されたコマンドの種類、logREStringにはログの書かれた内容を正規表現で書いてあります。
'ログヘッダー':logTemplate(
'ログヘッダー',r'■ターン\d+ - \d+/\d+ \d+:\d+'),
#開発コマンド
'整地':logTemplate('整地',
r''), #未完成
'埋め立て':logTemplate('埋め立て',
r'\(\d+,\d+\)で埋め立てが行われました。'),
'伐採':logTemplate('伐採',
r'\(\d+,\d+\)で伐採が行われました。'),
'植林':logTemplate('植林',
r''), #未完成
'農場整備':logTemplate('農場整備',
r'\(\d+,\d+\)で農場整備が行われました。'),
'工場建設':logTemplate('工場建設',
r'\(\d+,\d+\)で工場建設が行われました。'),
'採掘場整備':logTemplate('採掘場整備',
r'\(\d+,\d+\)で採掘場整備が行われました。'),
'ミサイル基地建設':logTemplate('ミサイル基地建設',
r''), #未完成
'防衛施設建設':logTemplate('防衛施設建設',
r'\(\d+,\d+\)で防衛施設建設が行われました。'),
'地ならし':logTemplate('地ならし',
r''), #未完成
'一括地ならし':logTemplate('一括地ならし',
r'\(\d+,\d+\)で一括地ならしが行われました。'),
'海底基地建設':logTemplate('海底基地建設',
r''), #未完成
'記念碑建造':logTemplate('記念碑建造',
r''), #未完成
'ハリボテ設置':logTemplate('ハリボテ設置',
r''), #未完成
'誘致活動':logTemplate('誘致活動',
r'誘致活動が行われました。'),
'掘削':logTemplate('掘削',
r''), #未完成
'油田掘削':logTemplate('油田掘削',
r''), #未完成
#内政・外交コマンド
'資金繰り':logTemplate('資金繰り',
r'資金繰りが行われました。'),
'食料輸出':logTemplate('食糧輸出',
r'\d+㌧の食料輸出を行いました。'),
'資金繰り':logTemplate('資金繰り',
r'資金繰りが行われました。'),
'資金援助':logTemplate('資金援助',
r'.+島へ\d+億円の資金援助を行いました。'),
'被資金援助':logTemplate('被資金援助',
r'.+島から\d+億円の資金援助が行われました。'),
'食料援助':logTemplate('食料援助',
r''), #未完成
'被食料援助':logTemplate('被食料援助',
r''), #未完成
#銀行コマンド
'出金':logTemplate('出金',
r'銀行から\d+億円を出金しました。'),
'自島入金':logTemplate('自島入金',
r''), #未完成
'他島へ送金':logTemplate('他島へ送金',
r'.+島の銀行口座へ\d+億円の送金を行いました。'),
'他島から入金':logTemplate('他島から入金',
r'.+島の銀行口座から\d+億円の入金がありました。'),
#攻撃コマンド
##通常ミサイル
'被通常ミサイル被害なし':logTemplate('被通常ミサイル',
r'.+島が.+島\(\d+,\d+\)地点に向けてミサイル発射を行いましたが、\(\d+,\d+\)の海に落ちたので被害がありませんでした。'),
'被通常ミサイル領域外':logTemplate('被通常ミサイル',
r'.+島が.+島\(\d+,\d+\)地点に向けてミサイル発射を行いましたが、領域外の海に落ちた模様です。'),
'被通常ミサイル被害あり':logTemplate('被通常ミサイル',
r'.+島が.+島\(\d+,\d\)地点に向けてミサイル発射を行い、.+。'),
'被通常ミサイル空中爆発':logTemplate('被通常ミサイル',
r'.+島\(\d+,\d+\)地点に向けてミサイル発射を行いましたが、\(\d+,\d+\)地点上空にて力場に捉えられ、空中爆発しました。'),
'通常ミサイル成果なし':logTemplate('通常ミサイル',
r'.+島\(\d+,\d+\)地点に向けてミサイル発射を行いましたが、\(\d+,\d+\)の海に落ちたので被害がありませんでした。'),
'通常ミサイル領域外':logTemplate('通常ミサイル',
r'.+島\(\d+,\d+\)地点に向けてミサイル発射を行いましたが、領域外の海に落ちた模様です。'),
'通常ミサイル成果あり':logTemplate('通常ミサイル',
r'.+島\(\d+,\d+\)地点に向けてミサイル発射を行い、.+。'),
'通常ミサイル空中爆発':logTemplate('PP',
r'.+島\(\d+,\d+\)地点に向けてミサイル発射を行い、.+。'),
##PPミサイル
'被PP被害なし':logTemplate('被PP',
r'.+島が.+島\(\d+,\d+\)地点に向けてPPミサイル発射を行いましたが、\(\d+,\d+\)の海に落ちたので被害がありませんでした。'),
'被PP領域外':logTemplate('被PP',
r'.+島が.+島\(\d+,\d+\)地点に向けてPPミサイル発射を行いましたが、領域外の海に落ちた模様です。'),
'被PP被害あり':logTemplate('被PP',
r'.+島が.+島\(\d+,\d\)地点に向けてPPミサイル発射を行い、.+。'),
'被PP空中爆発':logTemplate('被PP',
r'.+島\(\d+,\d+\)地点に向けてPPミサイル発射を行いましたが、\(\d+,\d+\)地点上空にて力場に捉えられ、空中爆発しました。'),
'PP成果なし':logTemplate('PP',
r'.+島\(\d+,\d+\)地点に向けてPPミサイル発射を行いましたが、\(\d+,\d+\)の海に落ちたので被害がありませんでした。'),
'PP領域外':logTemplate('PP',
r'.+島\(\d+,\d+\)地点に向けてPPミサイル発射を行いましたが、領域外の海に落ちた模様です。'),
'PP成果あり':logTemplate('PP',
r'.+島\(\d+,\d+\)地点に向けてPPミサイル発射を行い、.+。'),
'PP空中爆発':logTemplate('PP',
r'.+島\(\d+,\d+\)地点に向けてPPミサイル発射を行い、.+。'),
##陸地破壊弾
'被陸破被害なし':logTemplate('被陸破',
r'.+島が.+島\(\d+,\d+\)地点に向けて陸地破壊弾発射を行いましたが、\(\d+,\d+\)の海に落ちたので被害がありませんでした。'),
'被陸破領域外':logTemplate('被陸破',
r'.+島が.+島\(\d+,\d+\)地点に向けて陸地破壊弾発射を行いましたが、領域外の海に落ちた模様です。'),
'被陸破被害あり':logTemplate('被陸破',
r'.+島が.+島\(\d+,\d\)地点に向けて陸地破壊弾発射を行い、.+。'),
'被陸破空中爆発':logTemplate('被陸破',
r'.+島\(\d+,\d+\)地点に向けて陸地破壊弾発射を行いましたが、\(\d+,\d+\)地点上空にて力場に捉えられ、空中爆発しました。'),
'陸破成果なし':logTemplate('陸破',
r'.+島\(\d+,\d+\)地点に向けて陸地破壊弾発射を行いましたが、\(\d+,\d+\)の海に落ちたので被害がありませんでした。'),
'陸破領域外':logTemplate('陸破',
r'.+島\(\d+,\d+\)地点に向けて陸地破壊弾発射を行いましたが、領域外の海に落ちた模様です。'),
'陸破成果あり':logTemplate('陸破',
r'.+島\(\d+,\d+\)地点に向けて陸地破壊弾発射を行い、.+。'),
'陸破空中爆発':logTemplate('陸破',
r'.+島\(\d+,\d+\)地点に向けて陸地破壊弾発射を行い、.+。'),
##怪獣派遣 #未完成
#他島コマンド #未完成
'植林/ミサイル基地建設':logTemplate('植林/ミサイル基地建設',
r'こころなしか森が増えたようです。'),
#災害コマンド #未完成
})
class Log():
'''
Logクラスは各ログをまとめたものです。
海戦の戦闘ログのように複数行のログは一つとして扱います。
'''
def __init__(self,log):
self.log = log
def judgeType(self):
'''
判断の根拠はlogDict中のテンプレートですが、攻撃時のコマンドに関しては「「A島がB」島(○,○)地点」と「A島が「B」島」の区別ができていません。
したがって、攻撃と判断されても被攻撃である可能性はあります。
'''
for action in logDict:
if re.fullmatch(logDict[action].logREString,self.log):
return logDict[action].chunkName
class LogChunk():
'''
LogChunkクラスは近況ログを、ログのヘッダー(「■ターン~」)を区切りに格納しています。
Logs(logChunk,year)のように二つの初期値を与えて下さい。
logChunkはリスト型であることを想定しています。
このリストの最初の要素はログのヘッダー、残りの各ログです。
yearはログの年を入力してください。デフォルトではプログラム実行時の年を入れます。ログが年をまたいだ場合に関してはまだ対応していません。
Logsのクラス属性にはheader,contents,yearがあります。
headerにはログのヘッダーが文字列として格納されています。
contentsにはログの中身が配列として格納されています。
yearには初期値のyearが格納されています。
turnにはログが実行されたときのターン数が格納されています。
yearには初期値のyearが格納されています。
'''
def __init__(self,logChunk,year = datetime.datetime.today().year):
def extractTime():
'''
ヘッダーから日付を抽出し、datetime.datetime型に格納しています。
'''
date = self.header.log.split()[2]
time = self.header.log.split()[3]
result = datetime.datetime(
year = year,
month = int(date.split('/')[0]),
day = int(date.split('/')[1]),
hour = int(time.split(':')[0]),
minute = int(time.split(':')[1]),
)
return result
self.header = logChunk[0]
self.contents = logChunk[1:]
self.year = year
def judgeType(self):
'''
ログチャンク中の最初のログをもとに実行されたコマンドを推定しています。
'''
return self.contents[0].judgeType()
def extractTime():
'''
ヘッダーから日付を抽出し、datetime.datetime型に格納しています。
'''
date = self.header.log.split()[2]
time = self.header.log.split()[3]
result = datetime.datetime(
year = self.year,
month = int(date.split('/')[0]),
day = int(date.split('/')[1]),
hour = int(time.split(':')[0]),
minute = int(time.split(':')[1]),
)
return result
def extractTurn(self):
'''ヘッダーからターン数を抽出する'''
return int(self.header.log.split()[0][4:])
class Logs():
'''
Logsクラスはマイページの近況ログのように、ターン数とその実行ログが改行されているものを、行単位でリストに収めたものです。
Logs(logs,year)のように二つの初期値を与えて下さい。
logsはリスト型であることを想定しています。
通常、各行、一インデックスを与えられますが、複数行のログ(海戦の戦闘ログなど)はまとめます。
yearはログの年を入力してください。デフォルトではプログラム実行時の年を入れます。ログが年をまたいだ場合に関してはまだ対応していません。
Logsのクラス属性にはlogs,year,logChunksがあります。
logsには実際のログが配列として格納されています。
yearには初期値のyearが格納されています。
logChunksにはlogに格納されたログに関して、すべてのログのまとまりがLogChunk型として格納されています。
ログのまとまりとは、同時に実行されたログのことで、ログのヘッダー(「■ターン~」)を区切りに格納しています。
'''
def __init__(self, list, year = datetime.datetime.today().year):
def makeLogChunks():
'''
logChunk型を作ります。ログのヘッダーを基準にしています。
'''
result = []
oneLogChunk = [self.logs[0]]
i = 1
while i < len(self.logs):
if re.fullmatch(logDict['ログヘッダー'].logREString,self.logs[i].log):
result.append(LogChunk(oneLogChunk,year))
oneLogChunk = [self.logs[i]]
i += 1
continue
else:
oneLogChunk.append(self.logs[i])
i += 1
result.append(LogChunk(oneLogChunk,year))
return result
def readLogs(list):
'''
配列で渡されたログをまとめます。
基本的にはそのまま格納しますが、groupDict中に記述されているログに関しては、辞書の値の分だけ後ろの行も同じログの中の行とみなして、同じ要素としてまとめて格納します。
'''
logs = []
groupDict= {
'於:.+島':4, #海戦戦闘ログ
'対戦終了':4 #道場対戦終了
}
i = 0
while i < len(list):
log = list[i]
for template in groupDict:
if re.match(template,log):
withinLog = [list[i + j] for j in range(1,groupDict[template])]
log = log + '\n' + '\n'.join(withinLog)
i += groupDict[template] - 1
logs.append(Log(log))
i += 1
return logs
self.logs = readLogs(list)
self.year = year
self.logChunks = makeLogChunks()
def readLogFile(fileName,encoding='utf-8'):
'''与えられたファイル名からログを抽出し、Log型で返す'''
txt = open(fileName, 'rt', encoding = encoding)
fullLog = Logs([line[:-1] for line in txt.readlines()])
return fullLog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment