108 lines
2.4 KiB
Python
108 lines
2.4 KiB
Python
import time
|
|
import httpx
|
|
import random
|
|
import sqlite3
|
|
import logging
|
|
from dataclasses import dataclass
|
|
|
|
@dataclass
|
|
class Scores:
|
|
productivity : int
|
|
rank : int
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
log = logging.getLogger(__name__)
|
|
|
|
http = httpx.Client(headers={
|
|
'Referer': 'https://neal.fun/infinite-craft/',
|
|
})
|
|
|
|
db = sqlite3.connect('words.sqlite3')
|
|
db.execute('pragma foreign_keys = on')
|
|
|
|
r = db.execute('''
|
|
select x.word, x.rank, y.word, y.rank
|
|
from words x, words y
|
|
where not exists (
|
|
select *
|
|
from combos c
|
|
where c.x = x.word and c.y = y.word
|
|
)
|
|
''')
|
|
|
|
while True:
|
|
r = db.execute('''
|
|
select
|
|
w.word,
|
|
w.rank,
|
|
count(distinct c.z) as productivity
|
|
from combos c
|
|
join words w on w.word = c.x
|
|
where w.word != 'Nothing'
|
|
group by w.word
|
|
''')
|
|
scores = {
|
|
w: Scores(productivity=p, rank=r)
|
|
for w, r, p in r.fetchall()
|
|
}
|
|
|
|
pop = [(
|
|
(x,y),
|
|
xs.productivity*ys.productivity,
|
|
) for x, xs in scores.items()
|
|
for y, ys in scores.items()
|
|
]
|
|
|
|
while True:
|
|
(x, y), = random.sample(
|
|
k=1,
|
|
population=[xy for xy,_ in pop],
|
|
counts=[score for _,score in pop],
|
|
)
|
|
|
|
r = db.execute('''
|
|
select exists (
|
|
select *
|
|
from combos
|
|
where x = ? and y = ?
|
|
)
|
|
''', (x, y))
|
|
if r.fetchall()[0][0]:
|
|
# we already know the answer
|
|
log.info('already got %s + %s', x, y)
|
|
continue
|
|
else:
|
|
break
|
|
|
|
resp = http.get(
|
|
'https://neal.fun/api/infinite-craft/pair',
|
|
params={
|
|
'first': x,
|
|
'second': y,
|
|
},
|
|
)
|
|
resp.raise_for_status()
|
|
|
|
response = resp.json()
|
|
z = response['result']
|
|
is_new = response['isNew']
|
|
log.info(
|
|
'%s (%s) + %s (%s) -> %s%s',
|
|
x, scores[x], y, scores[y], z,
|
|
' [NEW!]' if is_new else ''
|
|
)
|
|
|
|
z_rank = 1+max(scores[x].rank, scores[y].rank)
|
|
db.execute('''
|
|
insert into words (word, rank, is_new) values (?, ?, ?)
|
|
on conflict(word) do update set rank = ? where rank > ?
|
|
''', (z, z_rank, is_new, z_rank, z_rank))
|
|
|
|
db.executemany(
|
|
'insert or ignore into combos (x, y, z) values (?, ?, ?)',
|
|
[(x, y, z), (y, x, z)],
|
|
)
|
|
db.commit()
|
|
|
|
time.sleep(5)
|