def alpha_beta_timed(self,c4_orig,depth): stime = time.time() c4temp = c4() self.c4h = c4h() c4temp.board = c4_orig.copy_board() c4temp.mode = c4_orig.mode c4temp.turn = c4_orig.turn c4temp.potgames = [] turn = c4temp.turn mode = c4temp.mode for i in range(0,c4temp.xmax): #x = [i for i in range(c4temp.xmax)] #random.shuffle(x) #for i2 in x: c4temp.potgames.append(c4()) i = len(c4temp.potgames) - 1 c4temp.potgames[i].board = c4temp.copy_board() c4temp.potgames[i].turn = turn c4temp.potgames[i].mode = mode c4temp.potgames[i].sim = True if c4temp.potgames[i].play_piece(i): c4temp.potgames[i].turn = (turn + 1) % 2 self.run_time = time.time() - self.start_time #if depth < self.maxd and not c4temp.potgames[i].is_winner(): #run_time gets a little ahead, this comparison works if (not self.times_up(depth,c4temp.xmax) #and depth < self.maxd and not c4temp.potgames[i].is_winner()): c4temp.potgames[i].hval = self.alpha_beta_timed(c4temp.potgames[i],depth + 1)[0] else: c4temp.potgames[i].hval = self.c4h.h2(c4temp.potgames[i],i,(turn + 1) == c4temp.red) if depth == 0: print "Board %d, depth %d, turn: %d, time: %f".rjust(37 + depth + 1) % (i,depth, c4temp.potgames[i].turn + 1,self.run_time) print " hval: %d".rjust(9 + depth) % (c4temp.potgames[i].hval) #c4temp.potgames[i].print_board() #pruning if (c4temp.potgames[i].hval == 1 and (turn + 1) == c4temp.black): #my move return (1,i) if (c4temp.potgames[i].hval == -1 and (turn + 1) == c4temp.red): #opp move return (-1,i) #end pruning else: #if not potgame[i].play_piece(i) if (turn + 1) == c4temp.black: c4temp.potgames[i].hval = -2 elif (turn + 1) == c4temp.red: c4temp.potgames[i].hval = 2 etime = time.time() rtime = etime - stime #print "Depth %d" % (depth) #print "run time: %f" % (rtime) if (turn + 1) == c4temp.black: pass #print "My move, max: %d" % self.max_h(c4temp.potgames)[1] return(self.max_h(c4temp.potgames)) elif (turn + 1) == c4temp.red: pass #print "Opp move, max: %d" % self.max_h(c4temp.potgames)[1] return(self.min_h(c4temp.potgames))
def alpha_beta(self,c4_orig,depth): stime = time.time() c4temp = c4() self.c4h = c4h() c4temp.board = c4_orig.copy_board() c4temp.mode = c4_orig.mode c4temp.turn = c4_orig.turn c4temp.potgames = [] turn = c4temp.turn mode = c4temp.mode for i in range(0,c4temp.xmax): c4temp.potgames.append(c4()) c4temp.potgames[i].board = c4temp.copy_board() c4temp.potgames[i].turn = turn c4temp.potgames[i].mode = mode c4temp.potgames[i].sim = True if c4temp.potgames[i].play_piece(i): c4temp.potgames[i].turn = (turn + 1) % 2 if depth < self.maxd and not c4temp.potgames[i].is_winner(): c4temp.potgames[i].hval = self.alpha_beta(c4temp.potgames[i],depth + 1)[0] else: c4temp.potgames[i].hval = self.c4h.h2(c4temp.potgames[i],i,(turn + 1) == c4temp.red) if depth == 0: print "Board %d, depth %d, turn: %d".rjust(27 + depth + 1) % (i,depth, c4temp.potgames[i].turn + 1) print " hval: %d".rjust(9 + depth) % (c4temp.potgames[i].hval) #c4temp.potgames[i].print_board() #pruning if (c4temp.potgames[i].hval == 1 and (turn + 1) == c4temp.black): #my move return (1,i) if (c4temp.potgames[i].hval == -1 and (turn + 1) == c4temp.red): #opp move return (-1,i) #end pruning else: #if not potgame[i].play_piece(i) if (turn + 1) == c4temp.black: c4temp.potgames[i].hval = -2 elif (turn + 1) == c4temp.red: c4temp.potgames[i].hval = 2 etime = time.time() rtime = etime - stime #print "Depth %d" % (depth) #print "run time: %f" % (rtime) if (turn + 1) == c4temp.black: pass #print "My move, max: %d" % self.max_h(c4temp.potgames)[1] return(self.max_h(c4temp.potgames)) elif (turn + 1) == c4temp.red: pass #print "Opp move, max: %d" % self.max_h(c4temp.potgames)[1] return(self.min_h(c4temp.potgames))
def __init__(self): self.c4temp = c4() self.c4h = c4h() #seconds self.maxd = 4 # 0 - n #for alpha_beta_timed self.time_limit = 30 self.total_turns = 1
def ai_test(self,depth): self.c4temp.potgames = [] #set turn ahead to current player turn = (self.c4temp.turn + 1) % 2 mode = self.c4temp.mode for i in range(0,self.c4temp.xmax): stime = time.time() self.c4temp.potgames.append(c4()) self.c4temp.potgames[i].board = self.c4temp.copy_board() self.c4temp.potgames[i].turn = turn self.c4temp.potgames[i].mode = mode self.c4temp.potgames[i].hval = self.c4h.h1(self.c4temp.potgames[i],i) etime = time.time() rtime = etime - stime print " Board col %d, rtime = %f" % (i,rtime) #self.c4temp.potgames[i].print_board() #print " hval = %d" % (self.c4temp.potgames[i].hval) #print ".", print print "Best col %d" % self.max_h(self.c4temp.potgames)[1] return(self.max_h(self.c4temp.potgames))
def h1(self,potgame_orig,x): potgame = c4() potgame.board = potgame_orig.copy_board() potgame.turn = potgame_orig.turn potgame.mode = potgame_orig.mode #make parallel copy for block detection potgame_block = c4() potgame_block.board = potgame.copy_board() potgame_block.turn = potgame.turn #win detection #potgame.turn = (potgame.turn + 1) % 2 if not potgame.play_piece(x): return -1 if potgame.is_winner(): return 300 potgame.turn = (potgame.turn + 1) % 2 #end win detection #block detection potgame_block.turn = (potgame.turn + 1) % 2 if not potgame_block.play_piece(x): return -1 if potgame_block.is_winner(): return 300 #otherwise, we need to do some stats totalScore = 0 #total probability of game win emptyScore = 1 pieceScore = 3 piece = potgame.turn + 1 empty = potgame.empty opp = ((potgame.turn + 1) % 2) + 1 #find y - pos of played piece for y in range(0,potgame.ymax): if potgame.board[x][y] == piece: break if potgame.board[x][y] == opp: y = y - 1 break #get vert. score # y2 - bottom-most, not-seperated piece y2 = y while(y2 < potgame.ymax and potgame.board[x][y2] == piece): y2 = y2 - 1 if (y2 - 1 >= 0 and y2 - 2 >= 0 and y2 - 3 >= 0 ): if potgame.board[x][y2 - 1] == empty: totalScore = totalScore + emptyScore elif potgame.board[x][y2 - 1] == piece: totalScore = totalScore + pieceScore if potgame.board[x][y2 - 2] == empty: totalScore = totalScore + emptyScore elif potgame.board[x][y2 - 2] == piece: totalScore = totalScore + pieceScore if potgame.board[x][y2 - 3] == empty: totalScore = totalScore + emptyScore elif potgame.board[x][y2 - 3] == piece: totalScore = totalScore + pieceScore #get hor. score #left score if x < 3: pass else: if (potgame.board[x-1][y] == opp or potgame.board[x-2][y] == opp or potgame.board[x-3][y] == opp ): pass else: if potgame.board[x-1][y] == piece: totalScore = totalScore + pieceScore elif potgame.board[x-1][y] == empty: totalScore = totalScore + emptyScore if potgame.board[x-2][y] == piece: totalScore = totalScore + pieceScore elif potgame.board[x-2][y] == empty: totalScore = totalScore + emptyScore if potgame.board[x-3][y] == piece: totalScore = totalScore + pieceScore elif potgame.board[x-3][y] == empty: totalScore = totalScore + emptyScore #right score if x > potgame.xmax - 4 : pass else: if (potgame.board[x-1][y] == opp or potgame.board[x-2][y] == opp or potgame.board[x-3][y] == opp ): pass else: if potgame.board[x-1][y] == piece: totalScore = totalScore + pieceScore elif potgame.board[x-1][y] == empty: totalScore = totalScore + emptyScore if potgame.board[x-2][y] == piece: totalScore = totalScore + pieceScore elif potgame.board[x-2][y] == empty: totalScore = totalScore + emptyScore if potgame.board[x-3][y] == piece: totalScore = totalScore + pieceScore elif potgame.board[x-3][y] == empty: totalScore = totalScore + emptyScore #return(random.randint(0,6)) return(totalScore)
def eval_func(chromosome): try: old_best_comp = compile(pickle.load(open('best.c4', 'rb')), "<string>", "eval") except: old_best_comp = None code_comp = chromosome.getCompiledCode() win = lose = tie = 0.0 for rnd in range(ROUNDS): c = c4(rows=ROWS,cols=COLS) if rnd % 2 == 0: other_player = dumb.url(1,'http://dl.no.de/ai/twostep/move') else: other_player = dumb.url(2,'http://dl.no.de/ai/twostep/move') winner = 0 turns = 0 total_turns = c.rows * c.cols for i in range(total_turns): winner = c.isWinner() if winner <> 0: break board = c.getBoard(is_json=False) player = (i % 2) + 1 # Train if we're not the genetic player if other_player.getPlayer() == player: json_state = json.dumps( { "rows":ROWS, "cols":COLS, "board":board, "currentTurn":player, "moveNumber":i} ) column = other_player.getMoveJSON(json_state) else: # Otherwise let's eval and see what we get col_scores = [] for col in utils.getFreeCols(board): const, aps, apo, nlts, nlto, nr = utils.getStats(board,player,col) score = eval(code_comp) col_scores.append((score, col)) random.shuffle(col_scores) sc = sorted(col_scores, key=itemgetter(0), reverse=True) #print 'Col Scores', str(sc) column = sc[0][1] c.move(player, column) # This is to compete against self, to do later #if False: #old_best_comp is not None: # col_scores = [] # for col in utils.getFreeCols(board): # aps, apo, nlts, nlto, nr = utils.getStats(board,player,col) # score = eval(old_best_comp) # col_scores.append((score, col)) # random.shuffle(col_scores) # sc = sorted(col_scores, key=itemgetter(0), reverse=True) # #print 'Col Scores', str(sc) # column = sc[0][1] turns += 1 if winner == 0: tie += 1.0 elif winner == other_player.getPlayer(): lose += 1.0 else: win += 1.0 return (win + tie * 0.5)/ROUNDS