diff --git a/gnugo.py b/gnugo.py index ae81730..8d838ed 100644 --- a/gnugo.py +++ b/gnugo.py @@ -1,4 +1,4 @@ -import string,sys,popen2 +import string,sys,popen2,re import helper,filehandling gnugocommand = "/usr/games/gnugo --mode gtp" @@ -155,10 +155,15 @@ def is_legal(gobandict,coords,req,form): tests wether proposed move is legal. returns True or False. """ - size = gobandict["size"] + """size = gobandict["size"] turn = gobandict["turn_number"] #who's turn is it? color = ["white","black"][turn % 2] #even turn: white plays, else black plays + """ + gamename = gobandict["name"] + color = gobandict["play"] + size = gobandict["size"] + #convert given coordinates gnucoords = " " + helper.dict_coords_to_gnugo_coords(coords,size) #open connection to gnugo: @@ -201,7 +206,10 @@ def make_move_in_sgf(req,form,gobandict,coords,filename = ""): gnucoords = " " + helper.dict_coords_to_gnugo_coords(coords,size) # get current player #even turn: white plays, else its blacks turn + """ color = ["white","black"][turn % 2] + """ + color = gobandict["play"] helper.debug(req,form,"color: %s -- turn: %s " % (color,turn)) #generate tmpfile if filename == "": @@ -221,6 +229,88 @@ def make_move_in_sgf(req,form,gobandict,coords,filename = ""): result = conn.exec_cmd("quit") return sgf +def parse_static_gnugo_sgf(s): + """ + gets a string containing the data saved by the gnugo "printsgf" order. + """ + + + #dicitonary to return + ret = {} + + #removing newlines vom given string + s = s.replace("\r\n","") #windoze + s = s.replace("\n","") #unix + + #getting the board size + # looks like SZ[19] + # the pattern finds a number ([0-9]) with length (1-2) between "SZ[" and "]" + boardsize = re.search("SZ\[([0-9]{1,2})\]",s).groups()[0] + boardsize = int(boardsize) + ret["size"] = boardsize + + #now fill ret with default values (== 0): + for i in range (1,boardsize+1): + for k in range (1,boardsize+1): + ret[(i,k)] = 0 + + #some regexp patterns: + #(?: ...) groups items + stones = "%s((?:\[[a-z][a-z]\])*)" #dont forget to set %s! + whitestones = stones % "AW" + blackstones = stones % "AB" + + + #getting white stones + #looks like AW[bb][cb][cc][cd][de][df] + try: + stonestring = re.search(whitestones,s).groups()[0] + except: + #we could not find anything + stonestring = "" + if stonestring != "": + ret = set_stones(stonestring,1,ret) + + #getting black stones + try: + stonestring = re.search(blackstones,s).groups()[0] + except: + #we could not find anything + stonestring = "" + if stonestring != "": + ret = set_stones(stonestring,2,ret) + + #who's turn is it? + if string.find(s,"PL[B]")>0: + ret["play"] = "black" + else: + ret["play"] = "white" + + return ret + +def set_stones(stonestring,value,ret): + """ + gets: + - string from sgf file with stone postitions in brackets: '[ab][ac]...' + - value to set + - dictionary to transform + does: + returns: + - dicionary + """ + #create a list of letters + letters = [" "] + letters.extend(list(string.letters)[0:26]) + + #regexp + stonestolist = "\[([a-z][a-z])\]" + + rawlist = re.findall(stonestolist,stonestring) + for item in rawlist: + #fill in specific values + ret[(letters.index(item[1]),letters.index(item[0]))] = value + return ret + if __name__ == '__main__': #showboard_to_goban_dict(showboard) @@ -245,3 +335,21 @@ if __name__ == '__main__': #is_legal black F2 #dict_coords_to_gnugo_coords(coords) translates (6,6) to "F2" + #sample output + + + s = """(; +GM[1] +FF[4] +SZ[19] +GN[GNU Go 3.7.4 load and print] +DT[2005-10-09] +KM[5.5] +RU[Japanese] +AP[GNU Go:3.7.4] +AW[bb][cb][cc][cd][de][df] +[ag][cg][ah][ch][dh][ai][bi][ci] +AB[ba][ab][ac][bc][bd][be][ce][af][cf][bg][bh] +PL[B] +)""" + print parse_static_gnugo_sgf(s) \ No newline at end of file diff --git a/goban.py b/goban.py index dcb9506..714d912 100755 --- a/goban.py +++ b/goban.py @@ -30,6 +30,10 @@ def display_goban(goban,req,form): """ % (form["sessionid"],form["username"],form["game"]) + sgf = psql.get_sgf(form["game"]) + helper.debug(req,form,sgf) + gobandict = gnugo.parse_static_gnugo_sgf(sgf) + try: size = goban["size"] except: @@ -39,9 +43,9 @@ def display_goban(goban,req,form): for x in range(1,size+1): for y in range(1,size+1): # check for white or black stone - if goban[(x,y)] == 1: + if gobandict[(x,y)] == 1: stone = "_white" - elif goban[(x,y)] == 2: + elif gobandict[(x,y)] == 2: stone = "_black" else: stone = "" @@ -67,9 +71,9 @@ def display_goban(goban,req,form): else: # hoshi or empty inner field defaultfield = '' #too lazy to make special images for hoshi fields with stones: - if goban[(x,y)] == 1: + if gobandict[(x,y)] == 1: hoshifield = '' - elif goban[(x,y)] == 2: + elif gobandict[(x,y)] == 2: hoshifield = '' else: #empty hoshi hoshifield = '' @@ -130,19 +134,7 @@ def set_stone(gobandict, position,req,form): new_sgf = gnugo.make_move_in_sgf(req,form,gobandict,position) #write new sgf file into database psql.update_goban_table_field(name,"x1","sgf",new_sgf) - #...and in current gobandict - gobandict["sgf"] = new_sgf - #now convert sgf to gobandict coordinates. - gobanlite = gnugo.sgf_to_goban_dict(gobandict) - #merge new coordinates with gobandict and update database where necessary - (new_gobandict, something_changed) = update_goban_dict_and_table(gobandict,gobanlite) - #and finally: - if something_changed: - psql.update_turn_number(name,turn+1) - helper.debug(req,form,"updated turn b/c gobandict has changed") - else: - helper.debug(req,form,"gobandict has not been changed, leaving turn_number untouched") - helper.debug(req,form,"set_stone:game name: %s, turn: %s, value at position: %s" % (name,turn,new_gobandict[position])) + psql.update_turn_number(name,turn+1) return "" else: #move not ok return "This is not a legal move (says Gnugo)." @@ -165,7 +157,8 @@ def update_goban_dict_and_table(gobandict,gobanlite): psql.update_goban_field(gobandict["name"],key[0],key[1],gobandict[key]) tf = True return gobandict,tf - + + ############################################################################### diff --git a/helper.py b/helper.py index 556fb04..063a607 100644 --- a/helper.py +++ b/helper.py @@ -101,83 +101,13 @@ def dict_coords_to_gnugo_coords(coords,size): return letter+str(digit) -def parse_static_gnugo_sgf(s): - """ - gets a string containing the data saved by the gnugo "printsgf" order. - """ - #create a list of letters - letters = [" "] - letters.extend(list(string.letters)[0:26]) - - #dicitonary to return - ret = {} - - #removing newlines vom given string - s = s.replace("\r\n","") #windoze - s = s.replace("\n","") #unix - - #getting the board size - # looks like SZ[19] - # the pattern finds a number ([0-9]) with length (1-2) between "SZ[" and "]" - boardsize = re.search("SZ\[([0-9]{1,2})\]",s).groups()[0] - boardsize = int(boardsize) - ret["size"] = boardsize - #some regexp patterns: - #(?: ...) groups items - stones = "%s((?:\[[a-z][a-z]\])*)" #dont forget to set %s! - whitestones = stones % "AW" - blackstones = stones % "AB" - stonestolist = "\[([a-z][a-z])\]" - - #getting white stones - #looks like AW[bb][cb][cc][cd][de][df] - - stonestring = re.search(whitestones,s).groups()[0] - rawlist = re.findall(stonestolist,stonestring) - for item in rawlist: - #fill in specific values - ret[(letters.index(item[0]),letters.index(item[1]))] = 1 - - - #getting black stones - stonestring = re.search(blackstones,s).groups()[0] - rawlist = re.findall(stonestolist,stonestring) - for item in rawlist: - #fill in specific values - ret[(letters.index(item[0]),letters.index(item[1]))] = 2 - - #who's turn is it? - if string.find(s,"PL[B]")>0: - ret["player"] = "black" - else: - ret["player"] = "white" - - return ret - - - def test(): print dict_coords_to_gnugo_coords((6,5),7) - #sample output - s = """(; -GM[1] -FF[4] -SZ[19] -GN[GNU Go 3.7.4 load and print] -DT[2005-10-09] -KM[5.5] -RU[Japanese] -AP[GNU Go:3.7.4] -AW[bb][cb][cc][cd][de][df] -[ag][cg][ah][ch][dh][ai][bi][ci] -AB[ba][ab][ac][bc][bd][be][ce][af][cf][bg][bh] -PL[B] -)""" - print parse_static_gnugo_sgf(s) + if __name__ == "__main__": test() diff --git a/playgame.py b/playgame.py index 4599630..3957db0 100644 --- a/playgame.py +++ b/playgame.py @@ -1,4 +1,4 @@ -import goban,helper,psql,login +import goban,helper,psql,login,gnugo import string DEBUG = 1 @@ -9,31 +9,32 @@ def is_my_turn(req,form,gobandict): check wether or not the current this is the players turn. return true or false. """ - #INFO: player1 is black,player2 is white. black starts the game. me = form["username"] player1 = gobandict["player1"] player2 = gobandict["player2"] - #get turn_number. - turn_number = gobandict["turn_number"] - #if player 2 can play: are we player two? - # yes:return True, else return False - if turn_number % 2 == 0: - if me == player2: - return True - else: - return False - #else:are we player1? - # yes:return True, else return False - else: - if me == player1: - return True - else: - return False + play = gobandict["play"] + if ((player1 == me) and (play == "white")) or ((player2 == me) and (play == "black")): + return True + else: + return false - - +def create_gobandict(req,form,gamename): + """ + gets a gamename + loads sgf, transforms it to dict, writes stuff like player names to dict + returns dict + """ + #read goban table from database + tmplist = psql.read_table(gamename) + #make a dictionary out of the list + tmpdict = psql.fetchall_list_to_goban_dict(tmplist) + sgf = psql.get_sgf(gamename) + gobandict = gnugo.parse_static_gnugo_sgf(sgf) + for key in ["player1","player2","turn_number","name","sgf"]: + gobandict[key] = tmpdict[key] + return gobandict def main(req,form): """ @@ -48,10 +49,7 @@ def main(req,form): data = "" req.write(helper.header()) #helper.debug(req,form,str(form.keys())) - #read goban table from database - tmplist = psql.read_table(gamename) - #make a dictionary out of the list - gobandict = psql.fetchall_list_to_goban_dict(tmplist) + gobandict = create_gobandict(req,form,gamename) #check if user has already clicked onto a field: click_on_field = False for item in form.keys(): @@ -66,11 +64,12 @@ def main(req,form): helper.debug(req,form,"playgame.main says: "+str(retstring)) else: #reload gobandict, it has been changed. - gobandict = psql.fetchall_list_to_goban_dict(psql.read_table(gamename)) + gobandict = create_gobandict(req,form,gamename) + else: helper.debug(req,form,"its not my turn.") data += """
Turn number: %s. %s plays.\n - """ % (str(gobandict["turn_number"]), ["White","Black"][int(gobandict["turn_number"] % 2)]) + """ % (str(gobandict["turn_number"]), (string.capitalize(gobandict["play"]))) #check whether its our turn #if yes: print 'your move' and display goban and process move diff --git a/psql.py b/psql.py index 00dfc3b..c4bbafe 100755 --- a/psql.py +++ b/psql.py @@ -39,12 +39,7 @@ def create_goban_table(player1,player2,size): returns: name of created table. the table looks like this: - line x1 x2 x3 x4 ... x(size) - y1 - y2 - y3 - ... - y(size) + line x1 turn_number size name @@ -53,7 +48,6 @@ def create_goban_table(player1,player2,size): sgf and the meaning of these fields: - (xn,yn) is a field of the goban, (turn_number,x1) is the current turn, (size,x1) is the length of a side of the goban, (name,x1) is the name of this goban. @@ -63,19 +57,8 @@ def create_goban_table(player1,player2,size): """ tablename = helper.generate_game_name() data="line text" - for i in range(1,size+1): - if data != "": - data += ", " - data += "x"+str(i) + ' text' + data = "x1 text" create_table(tablename,data) - #table created, now fill the table - for i in range(1,size+1): - tmplist=[] - tmplist.append("y"+str(i)) - for k in range(1,size+1): - tmplist.append(0) - insert_into_table(tablename,str(tuple(tmplist))) - #ok, goban itself has been created and filled, #now insert additional variables tmplist=[] tmplist.append("turn_number")