#!/usr/bin/python #mport os import sys import time import getopt #mport gtp import ishi import goban import player def usage(): sys.stderr.write(sys.argv[0]+'\n') sys.stderr.write('\t-h (gives help)\n') sys.stderr.write('\t-w {human|gtp} (default gtp)\n') sys.stderr.write('\t-b {human|gtp} (default gtp)\n') sys.stderr.write('\t-B boardsize (default 9)\n') sys.stderr.write('\t-k komi (default 6.5 for a handicap 0, 0.5 for others)\n') sys.stderr.write('\t-H handicap (default 0)\n') sys.stderr.write('\t-x white program (default "gnugo --mode gtp")\n') sys.stderr.write('\t-y black program (default "gnugo --mode gtp")\n') sys.stderr.write('\t-t (gives a text mode)\n') sys.stderr.write('\t-W (uses weak illegal move checking)\n') sys.exit(1) def main(): #x,y = 0,0 # while 1: # #Draw Everything # screen.blit(background, (0, 0)) # (x,y) = pygame.mouse.get_pos() # pygame.event.pump() # #pygame.mouse.set_visible(0) # #x += 1 # #y += 1 # #print x,y # screen.blit(black_image, (x, y)) # pygame.display.flip() # clock.tick(60) prog_black='gnugo --mode gtp' prog_white='gnugo --mode gtp' boardsize = 9 #komi = 6.5 komi_given = False handicap = 0 pause_time = 2 Player = ['gtp','gtp'] try: optlist, args = getopt.getopt(sys.argv[1:], 'w:b:B:k:h:tx:y:WH:') except: sys.stderr.write('Unrecognized option\n') usage() #white_done = 0 #black_done = 0 human = 0 text_mode = 0 weak_validity_check = 0 for opt in optlist: if opt[0] == '-t': text_mode = 1 elif opt[0] == '-H': handicap = int(opt[1]) elif opt[0] == '-w': if opt[1] == 'human' or opt[1] == 'h': Player[ishi.white] = 'human' human += 1 elif opt[1] == 'gtp': Player[ishi.white] = 'gtp' else: usage() elif opt[0] == '-b': if opt[1] == 'human' or opt[1] == 'h': Player[ishi.black] = 'human' human += 1 elif opt[1] == 'gtp': Player[ishi.black] = 'gtp' else: usage() elif opt[0] == '-B': try: boardsize = int(opt[1]) except: usage() elif opt[0] == '-k': try: komi = float(opt[1]) komi_given = True except: usage() elif opt[0] == '-h': usage() elif opt[0] == '-x': prog_white = opt[1] elif opt[0] == '-y': prog_black = opt[1] elif opt[0] == '-W': weak_validity_check = 1 if human > 1: sys.stderr.write('Only one human player allowed\n') sys.exit(1) if not komi_given: if handicap == 0: komi = 6.5 else: komi = 0.5 if not text_mode: # with these import's, we're making an effort to make it so # text mode users don't have to have pygame installed # however, this independence is untested. A threaded python # interpreter shouldn't be required for the text mode either import pygame import pygamehelper import pygame.sprite import pygame.transform import pygame.image import pygame.draw import pygame.locals import pygame.font #import pygamehelper import pe import guigoban #Initialize Everything GUI-related pygame.init() # hoping this is just smaller than a 1024x768 screen, with window # borders screen = pygame.display.set_mode((1004, 748)) pygame.display.set_caption('Pygame Go') #pygame.mouse.set_visible(0) def pump(): if pygame.event is not None: pygame.event.pump() PE = pe.PeriodicExecutor(0.02, pump) PE.start() # amount by which to displace text relative to the board spacing = 20 background_color = (128, 128, 128) # some sounds. There's more in the board stuff for stone clicks error_sound = pygamehelper.load_sound('error.wav') pass_sound = pygamehelper.load_sound('pass.wav') # font stuff. More below. font = pygame.font.Font(None, 36) pass_text = font.render("Pass", 1, (128, 10, 10)) quit_text = font.render("Quit", 1, (128, 10, 10)) #Create The Backgound background = pygame.Surface(screen.get_size()) background.fill(background_color) #Put Text On The Background, Centered # text = font.render("White vs. Black", 1, (10, 10, 10)) # text_pos = text.get_rect() # text_pos.centerx = background.get_rect().centerx # background.blit(text,text_pos) #Display The Background screen.blit(background, (0, 0)) pygame.display.flip() #Prepare Game Objects #clock = pygame.time.Clock() black_image, black_rect = pygamehelper.load_image('white.png', -1) #print 'prog_white is',prog_white #print 'prog_black is',prog_black # initialize players if Player[ishi.black] == 'gtp': Player[ishi.black] = \ player.player(1,0,prog_black,boardsize,komi,handicap,text_mode) elif Player[ishi.black] == 'human': Player[ishi.black] = \ player.player(0,1,'human',boardsize,komi,handicap,text_mode) else: raise 'bad thing in player initialization 1' if Player[ishi.white] == 'gtp': Player[ishi.white] = \ player.player(1,0,prog_white,boardsize,komi,handicap,text_mode) elif Player[ishi.white] == 'human': Player[ishi.white] = \ player.player(0,1,'human',boardsize,komi,handicap,text_mode) else: raise 'bad thing in player initialization 2' if text_mode: board = goban.board(boardsize,handicap) else: board = guigoban.guiboard(boardsize,handicap) # add handicap stones. # no attempt is made to get two gtp clients to agree on this # yet. Humans ignore it, and we pick the first gtp client # that gives us this info for color in [ishi.black,ishi.white]: if Player[color].gtp_flag: for pos in Player[color].stuff.hcap_list: board.move(pos,ishi.black) break passcount = 0 first_time = 1 if handicap < 2: move_order = [ishi.black,ishi.white] else: move_order = [ishi.white,ishi.black] #Main Loop white_caps_text = None black_caps_text = None komi_text = None handicap_text = None white_caps_text_pos = None black_caps_text_pos = None komi_text_pos = None handicap_text_pos = None while True: for state in move_order: if text_mode: print print board else: stones_pos = board.gen_rect() stones_pos.center = screen.get_rect().center stones_offset = stones_pos.topleft stones = board.gen_surface(stones_offset) #stones_pos.topleft = stones_offset #print stones screen.blit(stones,stones_pos) #print board #print pass_text_pos = pass_text.get_rect() pass_text_pos.topleft = stones_pos.topright pass_text_pos.move_ip(spacing,0) board.pass_text_pos = pass_text_pos screen.blit(pass_text, pass_text_pos) quit_text_pos = quit_text.get_rect() quit_text_pos.topleft = pass_text_pos.bottomleft board.quit_text_pos = quit_text_pos screen.blit(quit_text, quit_text_pos) if first_time: first_time = 0 else: # erase what was there before white_caps_text.fill(background_color) screen.blit(white_caps_text, white_caps_text_pos) black_caps_text.fill(background_color) screen.blit(black_caps_text, black_caps_text_pos) komi_text.fill(background_color) screen.blit(komi_text, komi_text_pos) handicap_text.fill(background_color) screen.blit(handicap_text, handicap_text_pos) if text_mode: print print 'White caps',Player[ishi.white].caps print 'Black caps',Player[ishi.black].caps print 'Komi',komi print 'Handicap',handicap else: white_caps_text = font.render( \ 'White caps: '+str(Player[ishi.white].caps), 1, \ (250, 250, 250)) white_caps_text_pos = white_caps_text.get_rect() white_caps_text_pos.topright = stones_pos.topleft white_caps_text_pos.move_ip(-spacing,0) screen.blit(white_caps_text, white_caps_text_pos) black_caps_text = font.render( \ 'Black caps: '+str(Player[ishi.black].caps), 1, \ (5, 5, 5)) black_caps_text_pos = black_caps_text.get_rect() black_caps_text_pos.topright = white_caps_text_pos.bottomright screen.blit(black_caps_text, black_caps_text_pos) komi_text = font.render( \ 'Komi: '+str(komi), 1, (10, 128, 10)) komi_text_pos = komi_text.get_rect() komi_text_pos.topright = black_caps_text_pos.bottomright screen.blit(komi_text, komi_text_pos) handicap_text = font.render( \ 'Handicap: '+str(handicap), 1, \ (10, 128, 10)) handicap_text_pos = handicap_text.get_rect() handicap_text_pos.topright = komi_text_pos.bottomright screen.blit(handicap_text, handicap_text_pos) pygame.display.flip() time.sleep(pause_time) while True: position = Player[state].get_input(state,board) if position == 'QUIT': PE.func = None PE.active = False sys.exit(0) if position != 'PASS': # ask the other player if this is a legal move if weak_validity_check: valid = not board.taken(position) else: valid = \ Player[ishi.invert(state)].is_legal(board,state,position) if valid: break else: if text_mode: sys.stdout.write(chr(7)+'Illegal move\n') else: error_sound.play() #time.sleep(pause_time) else: break if position == 'PASS': if text_mode: print 'Pass' else: pass_sound.play() #time.sleep(pause_time) passcount += 1 else: (current_caps,opponent_caps) = board.move(position,state) Player[state].caps += current_caps Player[ishi.invert(state)].caps += opponent_caps #print Player[ishi.white].caps,Player[ishi.black].caps if not text_mode: board.stone_sound.play() passcount = 0 Player[ishi.invert(state)].feed_move(state,position) if passcount == 2: break # this slows things down of course, but it deters multiple mouseclicks # (which feel like a single click to the user) on the same spot making # more than one sound if not text_mode: pass #time.sleep(pause_time) if passcount == 2: break estimate = 'no estimate' for state in [ishi.black,ishi.white]: t = Player[state].get_result() if t != 'no estimate': estimate = t # print ishi.description(state),'estimates',\ # Player[state].get_result() # while 1: # screen.blit(stones,stones_pos) # pygame.display.flip() if text_mode: print 'Result:',estimate sys.exit(0) else: result_text = font.render('Result: '+estimate, 1, (10, 128, 10)) result_text_pos = result_text.get_rect() result_text_pos.midbottom = stones_pos.midtop ##result_text_pos.topleft = screen.get_rect().topleft result_text_pos.move_ip(0,-spacing) screen.blit(result_text,result_text_pos) pygame.display.flip() while 1: (b1,b2,b3) = pygame.mouse.get_pressed() pygame.event.pump() if b1: (mx,my) = pygame.mouse.get_pos() pygame.event.pump() if quit_text_pos.collidepoint(mx,my): sys.exit(0) time.sleep(0.05) #Game Over #def text_main(): # board = goban.board(9) # print board #this calls the 'main' function when this script is executed if __name__ == '__main__': main()