from UserDict import UserDict import gopatterns,drawboard #import random #IN=open('c:\\projects\\sgf\\2.sgf','r') #lines=IN.readlines() #print repr(lines) def getorthogonals(loc,size): x,y=loc orth=[] if x>1: orth.append((x-1,y)) if x1: orth.append((x,y-1)) if y0: continue break self.addpoint(p) for o in getorthogonals(p,size): if o in tocheck: continue if o in checked: continue tocheck.append(o) if len(tocheck)==0: break def addpoint(self,point): self.points.append(point) self.libs=self.countlibs() def delpoint(self,point): self.points.remove(point) self.libs=self.countlibs() def countlibs(self): nextdoor=[] for p in self.points: near=getorthogonals(p,self.size) for n in near: if n not in nextdoor: nextdoor.append(n) empty=[] libs=0 for p in nextdoor: if self.parent.getcolor(p)=="e": libs+=1 self.libs=libs def getlibs(self): return self.libs class BoardPosition(object): def __init__(self,size,seq='',movenumber=10000): #print seq self.size=size self.points={} self.lastmove='' self.bdead=0 self.wdead=0 self.lastplayedcolor='w' i=0 for move in seq: if i>movenumber: break i=i+1 self.playmove(move) self.switchlastplayedcolor() def switchlastplayedcolor(self): self.lastplayedcolor=oppositecolor(self.lastplayedcolor) def show(self): """show board position data""" print "points",self.points print "lastmove",self.lastmove print "bdead",self.bdead print "wdead",self.wdead print "size",self.size def isoffboard(self,point): x,y=point if x<1 or x>self.size or y<1 or y>self.size: return True return False def pattern_to_pos(self,c): """for a given pattern character, what on the board is ok there?""" if c in ["."]: return "e" now=self.lastplayedcolor if c in ["X","S"]: return now if c=="O": return oppositecolor(now) if c=="Z": return [now,'e','offboard'] if c=="Y": return [oppositecolor(now),'e','offboard'] def isedge(self,point): if self.iscorner(point): return False if point[0]==1 or point[0]==self.size or point[1]==1 or point[1]==self.size: return True return False def iscorner(self,point): if (point[0]==1 or point[0]==self.size) and (point[1]==1 or point[1]==self.size): return True return False def matchpattern(self,pattern,checkonepattern=''): """tries to match the last move played into a pattern patterns can have from 1-8 symmetries pattern codes are found at the top of the file gopatterns.py used to make them""" patternname=pattern.name for sym in pattern.data: matched=1 sp=sym.split("\n") for y,l in enumerate(sp): loc=l.find("X") if loc != -1: xloc=(loc,y) break for y,l in enumerate(sp): for x,c in enumerate(l): #check every spot in the pattern against the corresponding point on the board. #c is the pattern character we're checking now if c=="\n": continue if c=="A": continue try: #the corresponding point is the board's last move plus where we are in the pattern #minus where the last move is in the pattern checkloc=(self.lastmove[0]+x-xloc[0],self.lastmove[1]+y-xloc[1]) except: print "getting checkloc failed" print "lastmove",self.lastmove print "sym",sym print "sp",sp print "xloc:",xloc print "C",c print "x",x print "y",y if c=="E": if self.isedge(checkloc): continue else: matched=0 break if c=="C": if self.iscorner(checkloc): continue else: matched=0 break #easy part is over - done with newlines in pattern, anything-ok, edges, and corners target=self.pattern_to_pos(c) if "offboard" in target and self.isoffboard(checkloc): continue checkval="e" if checkloc in self.points: checkval=self.points[checkloc] if patternname==checkonepattern: print "this c is",c print "sym is",sym print "match if checkloc",checkloc,checkval,"is in target",target if not checkval in target: if patternname==checkonepattern: print "checkval not in target" matched=0 if matched==0: if patternname==checkonepattern: print "no" break if patternname==checkonepattern: print "ok" if matched==0: #print "failed on",working,workingsym break if matched: return 1 else: #print "that sym bad; going to next one" continue #print "didn't match",working return 0 def ischainliving(self,xy): """ just looks for a connected empty""" tocheck=[xy] color=self.getcolor(xy) done=[] while 1: if not len(tocheck): return False neighbor=tocheck.pop() done.append(neighbor) if self.getcolor(neighbor)=='e': return True for new in getorthogonals(neighbor,self.size): if new not in tocheck: if new not in done: ncolor=self.getcolor(new) if ncolor=='e': return True if ncolor==color: tocheck.append(new) def getchain(self,loc,debug=0): return Chain(self,loc,debug,size=self.size) def playmove(self,move): color=oppositecolor(self.lastplayedcolor) #print "playing",move cur=self.getstone(move) self.points[move]=color self.lastmove=move tocheck=getorthogonals(move,self.size) tocheck.append(move) for xy in tocheck: if self.getcolor(xy) not in ["b","w"]: continue if self.getcolor(xy) == color: continue res=self.ischainliving(xy) if not res: self.killchain(xy) checked=[] res=self.ischainliving(move) if not res: self.killchain(move) def killchain(self,move): todie=self.getchain(move) orig=todie color=self.getcolor(move) name=color+"dead" for p in todie.points: setattr(self,name,getattr(self,name)+1) del self.points[p] def getstone(self,xy): x,y=xy stone=self.getcolor(xy) if stone in ["b","w"]: if self.lastmove==xy: return stone+"sel" return stone elif x==1: if y==1: stone="ul" elif y==self.size: stone="ll" else: stone="l" elif x==self.size: if y==1: stone="ur" elif y==self.size: stone="lr" else: stone="r" elif y==1:stone="u" elif y==self.size:stone="d" elif ((x+2)%6==0) and ((y+2)%6==0): stone="star" else: stone="m" return stone def getimage(self,stone): return stone+".png" def getchar(self,stone): if stone in ["ul","ur","ll","lr"]: return "X" elif stone in ["l","r"]: return "|" elif stone in ["u","d"]: return "-" elif stone=="star": return "+" elif stone=="b": return chr(149) elif stone=="w": return chr(176) elif stone=="bsel": return "B" elif stone=="wsel":return "W" return ". " def asciidraw(self): print "abcdefghijklmnopqrs" for y in range(1,self.size+1): for x in range(1,self.size+1): print self.getchar(self.getstone((x,y))), print "" def gethtml(self): html="" topline="\n" for j in range(65,65+self.size+1): if j==73: continue topline=topline+"" topline=topline+"\n" html=html+topline for y in range(1,self.size+1): html=html+"\n" for x in range(1,self.size+1): line='' html=html+line html=html+"" html=html+"\n" html=html+"
"+chr(j)+"
" html=html+"move number:"+str(len(self["points"]))+"
b dead: "+str(self.bdead)+"
w dead: "+str(self.wdead)+"
" return html def getcolor(self,xy): if xy in self.points.keys(): return self.points[xy] return "e" def getopen(self): """ return empty points """ open=[] for x in range(1,self.size+1): for y in range(1,self.size+1): if self.getcolor((x,y))=='e': open.append((x,y)) return open def getniceopen(self,color): """ return empty points which aren't fully surrounded by your own color""" niceopen=[] neighbors=[] allopen=self.getopen() for a in allopen: for p in getorthogonals(a,size): thisp=self.getcolor(p) if thisp !=color: niceopen.append(a) return niceopen class SGF(object): def __init__(self,file=''): if not file: print "no sgf file;" self.sgfcontent=open(file,'r').readlines() self.vals=self.sgf_read_meta() self.seq=self.sgf_read_moves() def print_raw(self): for l in self.sgfcontent: print l def show_data(self): for x in dir(self): if not callable(x): print x,self.__getattribute__(x) def sgf_read_meta(self): print "read meta" vals={} for var in ["SZ","HA","PB","PW","KM","RE"]: done=0 v='' for l in self.sgfcontent: loc=l.find(var) if loc != -1: v="" reading=loc+3 while l[reading] != "]": v=v+l[reading] reading+=1 done=1 break if not done: vals[var]='' continue if var in ["SZ","HA"]: v=int(v) if var in ["KM"]: v=float(v) vals[var]=v return vals def sgf_read_moves(self): seq=[] for l in self.sgfcontent: if l.startswith(";W") or l.startswith(";B"): x,y=ord(l[3])-96,ord(l[4])-96 if (1<=x<=self.vals["SZ"]) and (1<=y<=self.vals["SZ"]): seq.append((x,y)) return seq class GoGame(object): """ main game object. board, ko, dead info is in self.boardposition """ def __init__(self,file='',movesequence='',size=''): print "opened with file",file self.sgf=SGF(file) self.movenumber=0 self.foundpositions={} def show(self): print self.sgf.vals #print self.contents def boardposition(self,movenumber=0): return BoardPosition(seq=self.sgf.seq,size=self.sgf.vals["SZ"],movenumber=movenumber) def asciidraw(self,movenumber=0): if movenumber in self.foundpositions.keys(): self.foundpositions[movenumber].draw() return self.foundpositions[movenumber]=BoardPosition(seq=self.sgf.seq,size=self.sgf.vals["SZ"],movenumber=movenumber) self.foundpositions[movenumber].asciidraw() def tohtml(self,movenumber=0): B=BoardPosition(seq=self.sgf.seq,size=self.sgf.vals["SZ"],movenumber=movenumber) B.tohtml() def play_and_look(self,patterns,movenumber): typecount={} colors=["b","w"] for c in colors: typecount[c]={} for p in patterns: n=p.name typecount[c][n]=0 out=open("out.html",'w') out.write("\n") for v in self.sgf.vals: out.write(v+":"+str(self.sgf.vals[v])+"\n") out.write("\n\n") loadedtiles=drawboard.loadtiles() for i in range(movenumber): if i>len(self.sgf.seq): print "game over" break B=self.boardposition(movenumber=i) color=B.lastplayedcolor out.write("\n\n") #print "after,B show is:" #B.show() for c in ["b","w"]: print "\nfor",c for key in typecount[c].keys(): if typecount[c][key]>0: print key,typecount[c][key] out.write(key+str(typecount[c][key])+"
") out.close() if __name__=="__main__": opened=0 G=GoGame(file=r"data\10k\acd-kgs2006.sgf") G.show() #print G.boardposition() #for x in range(20): #G.tohtml(x) #G.tohtml(movenumber=75) patterns=gopatterns.readpatterns() G.play_and_look(patterns,movenumber=500)
") print "move #",i fullpath="test\\"+str(i)+".png" #B.asciidraw() drawboard.drawpngboard(B,fullpath,loadedtiles=loadedtiles) out.write("") out.write("") for p in patterns: if B.matchpattern(p): typecount[color][p.name]+=1 print p.name,"HIT!!!" out.write(p.name+"\n
") out.write("