def numverse(self,srdiff = 1): """Seeks relevant geometric series connected uniquely in the graph. Gives 2 scores, one for longevity (clearing deep cursed tiles) and one for max score with extra gold tiles. Observe the score formula - a single gold tile outweighs pretty much any chain length. Queue format: Chain (list of ids), current graph node.""" logger.debug("Start numverse") uti.St_Timer("numverse") vque = deque() # Start from any letter and no match. for k in self.root.keys(): if k is not None: nnode = self.root[k] vque.append(([k],nnode)) # In a dfs loop, check if any adjacent gns have trie depth, # and any valid results along the way are stored for later. # Do not repeat routes - skip neighbour if on the chain. # Numverse actually has many more options; # Optimisation involves finding the least connected nodes # for starting points in every subgraph (all of them), # but I'm not sure that's a perfect cover. # Relying on past chains is difficult due to uniqueness cond. # Mayhap the best method is filtering all irrelevant cons prematurely. stopme = 1000000 cntstop = 0 lres = [] while vque: (lchain,cnode) = vque.pop() if len(lchain) > MINCHAIN: lres.append(lchain) for k in cnode.refs.keys(): if not k in lchain: nnode = cnode.refs[k] nchain = lchain[:] nchain.append(k) if abs(int(nnode.value[0]) - int(cnode.value[0])) == srdiff: vque.append((nchain,nnode)) cntstop = cntstop + 1 if cntstop % (stopme // 10) == 0: tdiff = uti.Ed_Timer("numverse") Deb_Prtlog(LOGMSG["numvrprog"].format( cntstop // (stopme // 100),tdiff),logging.DEBUG) if cntstop >= stopme: vque = None tdiff = uti.Ed_Timer("numverse") Deb_Prtlog(LOGMSG["numvrok"].format(len(lres),tdiff),logging.DEBUG) return lres
def Convert_Dict(indfrc = False,indsave = True): """Builds counter arr from raw dict, all saved to file. If forced, will not negate "bad" dict. With saving, takes 1.5s for 50k words.""" Deb_Prtlog("Start convert dict",logging.DEBUG) uti.St_Timer("TConvert") from inpdict import goodd1, goodd2, badd1, badd2 # v tri1 = BNtrie() tri2 = BNtrie() tri1.build_dict(goodd1,True) tri2.build_dict(goodd2,True) if not indfrc: tri1.build_dict(badd1,False) tri2.build_dict(badd2,False) if indsave: with open(BRANCH + BCKSLS + "tri1.pkl","wb") as flw: pickle.dump(tri1,flw) with open(BRANCH + BCKSLS + "tri2.pkl","wb") as flw: pickle.dump(tri2,flw) tdiff = uti.Ed_Timer("TConvert") Deb_Prtlog(LOGMSG["dconvok"].format(tdiff),logging.DEBUG) return (tri1,tri2)
def Word_Score(self,lres): """Grades word combos based on danger and value. See score formula above. As for danger, whilst removing 2+ tiles below cursed is bad, it's most important to rank depth exponentially (game over at bottom). Don't actually measure depth precisely, but the exp should suffice.""" uti.St_Timer("wordscore") lsort = [] lres = self.Cull_Chains(lres) for lchain in lres: vscore1 = 0 vscore2 = 0 gcnt = 0 for cid in lchain: try: (cchr,ctyp) = self.root[cid].value except Exception as err: print(err) raise if ctyp == TILECURSE2: # Cursed penalty is heavier by row. vscore2 = vscore2 + 100 * (4 ** cid[1]) elif ctyp == TILEGOLD2: gcnt = gcnt + 1 # Letter value check. Dict should be equivalent. for chksc in SCLET: if str(cchr) in chksc[0]: cmod = chksc[1] vscore1 = vscore1 + cmod vscore2 = vscore2 + cmod vscore1 = vscore1 * (1 + gcnt * 3) vscore2 = vscore2 * (1 + gcnt * 3) lsort.append((lchain,vscore1,vscore2)) if len(lres) >= MAXCHAIN: tdiff = uti.Ed_Timer("wordscore") if len(lsort) % (MAXCHAIN // 10) == 0: Deb_Prtlog(LOGMSG["wordscprog"].format( len(lsort) // (MAXCHAIN // 100),tdiff),logging.DEBUG) lsort1 = sorted(lsort,key=lambda x:x[1],reverse = True) lsort2 = sorted(lsort,key=lambda x:x[2],reverse = True) tdiff = uti.Ed_Timer("wordscore") Deb_Prtlog(LOGMSG["wordscok"].format(tdiff),logging.DEBUG) return (lsort1,lsort2)
def Load_Dict(): """Loads dictionaries from respective folders - files. Pick el pickle pickle.""" Deb_Prtlog("Start load dict",logging.DEBUG) uti.St_Timer("TDload") with open(BRANCH + BCKSLS + "tri1.pkl","rb") as flr: tri1 = pickle.load(flr) with open(BRANCH + BCKSLS + "tri2.pkl","rb") as flr: tri2 = pickle.load(flr) tdiff = uti.Ed_Timer("TDload") Deb_Prtlog(LOGMSG["dloadok"].format(tdiff),logging.DEBUG) return (tri1,tri2)
def Main(): """Activates function calls. Main.""" global mgui Deb_Prtlog("Start main",logging.DEBUG) uti.St_Timer("Main") verr = 0 # dbrefs = Init_Parms() if FMAIN == 1: Convert_Dict() if FMAIN == 2: (tri1,tri2) = Load_Dict() while True: groot = BNgraph(None) gi = Graph_Input() gi = Hexify(gi) groot.build_hex(gi) potword = groot.trieverse(tri1,tri2) (optim,dang) = groot.Word_Score(potword) print("Topmost score:") groot.Print_Scores(optim) print("Topmost danger:") groot.Print_Scores(dang) print("---------------------") Print_Format(gi) verr = 0 elif FMAIN == 8: # verr = Mine_List(dbrefs) verr = 0 elif FMAIN == 11: # verr = Review_Dbs(dbrefs,QUERYLIST) # (tri1,tri2) = Load_Dict() # Not always needed, form will summon it once as needed. mgui.Start_Form() verr = 0 tdiff = uti.Ed_Timer("Main") print("\nFin.") # Remember that timestamp is automatic in logger. logger.debug("End main {}".format(tdiff)) if verr == 0: uti.Msgbox(LOGMSG["mainok"],"Good morning chrono") else: uti.Msgbox(LOGMSG["mainer"],"Wake up") return verr
def trieverse(self,tri1,tri2): """Seeks dictionary words connected uniquely in the graph. Gives 2 scores, one for longevity (clearing deep cursed tiles) and one for max score with extra gold tiles. Observe the score formula - a single gold tile outweighs pretty much any chain length. Queue format: Chain (list of ids),current graph node, current tri1 / tri2 nodes (separate checks).""" logger.debug("Start trieverse") uti.St_Timer("trieverse") vque = deque() # Start from any letter and no match. for k in self.root.keys(): if k is not None: nnode = self.root[k] vque.append(([k],nnode, tri1.refs[nnode.value[0]])) vque.append(([k],nnode, tri2.refs[nnode.value[0]])) # In a dfs loop, check if any adjacent gns have trie depth, # and any valid results along the way are stored for later. # Do not repeat routes - skip neighbour if on the chain. stopme = 1000000 # 10000 in 0.021s, so speed is no issue at all. cntstop = 0 lres = [] while vque: (lchain,cnode,ctri) = vque.pop() if ctri.indvalid: lres.append(lchain) for k in cnode.refs.keys(): if not k in lchain: nnode = cnode.refs[k] nchain = lchain[:] nchain.append(k) if nnode.value[0] in ctri.refs: vque.append((nchain,nnode, ctri.refs[nnode.value[0]])) cntstop = cntstop + 1 if cntstop >= stopme: vque = None tdiff = uti.Ed_Timer("trieverse") Deb_Prtlog(LOGMSG["trievrok"].format(tdiff),logging.DEBUG) return lres
def DebP_Select(seldb,ftc = 1000): """Fetches in iterations, prints to console with timers in log. Spam.""" scur = "DO" pwid = None i = 0 while scur is not None: # Make sure scur is sent back, otherwise generating inf loop. uti.St_Timer("Dbprint") if len(scur) == 2: # Comparison is bothersome. scur = None (lrecs,scur,heads) = seldb.Select_Recs(ftc,oldrun = scur) if pwid is not None: # Start indicator. heads = None edind = scur is None # No need for additional ind. pwid = seldb.Print_Sel(lrecs,heads,edind,pstwid = pwid) i = i + 1 tdiff = uti.Ed_Timer("Dbprint") logger.debug("Batch {} time: {}".format(i,tdiff))
def Cull_Chains(self,lres,ncull = MAXCHAIN): """When there are too many chains, removes a percentage by len. Creep: Counting the gold / curse prematurely may improve or obviate this, wordscore would be O(1) and score based culling. Bit extra memory though.""" uti.St_Timer("cullchain") if len(lres) <= ncull: return lres dlen = dict() for lchain in lres: len1 = len(lchain) dlen[len1] = dlen.get(len1,0) + 1 tcnt = 0 maxcull = None for len1 in sorted(dlen.keys(),reverse = True): tcnt = tcnt + dlen[len1] if tcnt > ncull and maxcull is None: maxcull = len1 lres = [lchain for lchain in lres if len(lchain) >= maxcull] tdiff = uti.Ed_Timer("cullchain") Deb_Prtlog(LOGMSG["cullchok"].format(len(lres),tdiff),logging.DEBUG) return lres
def Main_Test(): """Short activation. Spam.""" global galena global mgui Deb_Prtlog("Start main TEST",logging.DEBUG) uti.St_Timer("Main") # dbrefs = Init_Parms() # (cmpdb,infdb,dbini) = dbrefs indstop = False verr = 0 btc = 1000 # dbini["Main"][INIBTC] # ddl = ldb.Date_Conv(dbini["Main"][INIDDL]) # from Rawdt_LDL import lwin # lfail = [("Crystal_Babyface-2000-11-27.jpg","19-Sep-2001 19:44 ","7.9K"), # ("Crystal_Babyface.jpg","19-Sep-2001 19:44 ","7.9K"), # ("abreik_meerca-.jpg","01-Apr-2018 22:43 ","65K")] # tstdl = "http://upload.neopets.com/beauty/images/winners/silkmon-2012-05-11.jpg" while not indstop: if 1 != 0: # Trie. # tstrie = BNtrie() # tstrie.build_dict(np.array(("ziggy","wino"))) # Convert_Dict() # (tri1,tri2) = Load_Dict() # print(list(tri1.refs["a"].refs["a"].refs["h"].refs["s"].refs.keys())) # print(tri1.search("aardvark")) # Graph. groot = BNgraph(None) # groot.build_hex([[10,20,30],[11,21,31,41],[12,22,32]]) # gi = Graph_Input() # smpl = """k,u,l,i,n,o, # t,l,s,o,j,o,u, # a,r,a,a,a,n, # n,d,u,a,s,o,z, # i,a,i,g,a,a, # d,i,a,l,t,f,s, # t,t,o,a,y,l, # u,n,a,i,a,r,i, # n,q,n,l,t,v""" # gi = [(v,0) for v in gi if len(v) > 0] # gi = Graph_Input(smpl) # Form activation. mgui.Start_Form() smpl = """2,3,5,5-,5,5, 3,1,2,3,3,2,4, 4,2,1,4-,1,3, 3,4,2,5,5,3,3, 3,5,2-,2,4,2, 3,2,2,2,1,1,5, 5,2,3,1,5-,4, 3,4,1,1,1,4,3, 4,4,5,5,4,1""" gi = Graph_Input(smpl) # gi = re.split(REDELIM,smpl) # gi = [(int(v),0) for v in gi if len(v) > 0] gi[10] = gi[10][0],1 gi[20] = gi[20][0],2 gi[30] = gi[30][0],1 gi[40] = gi[40][0],2 Print_Hexagrid(gi) gi = Hexify(gi) groot.build_hex(gi) # Print_Hexagrid([["a",1],["b",0],["c",2],["d",0]] * 30) # Pathing. #potword = groot.trieverse(tri1,tri2) potword = groot.numverse() (optim,dang) = groot.Word_Score(potword) print("Topmost score:") groot.Print_Scores(optim) print("Topmost danger:") groot.Print_Scores(dang) # Clearing mechanism. groot.Tile_Move([(0,3),(0,4),(1,3)]) # Print_Format(groot) # Don't have one for graphs. print(verr) indstop = True # TEST else: indstop = True # All done. tdiff = uti.Ed_Timer("Main") print("\nFin.") # Remember that timestamp is automatic in logger. logger.debug("End main {}".format(tdiff)) return verr