def benchmark(maxdepth=6): """ Times a search of a static list of positions. """ suite_time = time() suite_nodes = lsearch.nodes lsearch.endtime = sys.maxsize lsearch.searching = True for i, fen in enumerate(benchmarkPositions): lsearch.table.clear() clearPawnTable() board = LBoard(NORMALCHESS) board.applyFen(fen) pos_start_time = time() pos_start_nodes = lsearch.nodes for depth in range(1, maxdepth): mvs, scr = lsearch.alphaBeta(board, depth) pos_time = time() - pos_start_time pos_nodes = lsearch.nodes - pos_start_nodes pv = " ".join(listToSan(board, mvs)) time_cs = int(100 * pos_time) print(depth, scr, time_cs, pos_nodes, pv) print("Searched position", i, "at", int(pos_nodes / pos_time) if pos_time > 0 else pos_nodes, "n/s") suite_time = time() - suite_time suite_nodes = lsearch.nodes - suite_nodes print("Total:", suite_nodes, "nodes in", suite_time, "s: ", suite_nodes / suite_time, "n/s") lsearch.nodes = 0
def benchmark(maxdepth=6): """ Times a search of a static list of positions. """ suite_time = time() suite_nodes = lsearch.nodes lsearch.endtime = sys.maxsize lsearch.searching = True for i, fen in enumerate(benchmarkPositions): lsearch.table.clear() clearPawnTable() board = LBoard(NORMALCHESS) board.applyFen(fen) pos_start_time = time() pos_start_nodes = lsearch.nodes for depth in range(1, maxdepth): mvs, scr = lsearch.alphaBeta(board, depth) pos_time = time() - pos_start_time pos_nodes = lsearch.nodes - pos_start_nodes pv = " ".join(listToSan(board, mvs)) time_cs = int(100 * pos_time) print(depth, scr, time_cs, pos_nodes, pv) print("Searched position", i, "at", int(pos_nodes / pos_time) if pos_time > 0 else pos_nodes, "n/s") suite_time = time() - suite_time suite_nodes = lsearch.nodes - suite_nodes print("Total:", suite_nodes, "nodes in", suite_time, "s: ", suite_nodes / suite_time, "n/s") lsearch.nodes = 0
def __analyze (self, worker): """ Searches, and prints info from, the position as stated in the cecp protocol """ start = time() lsearch.endtime = sys.maxint lsearch.searching = True for depth in xrange (1, 10): if not lsearch.searching: break t = time() mvs, scr = alphaBeta (self.board, depth) # Analyze strings are given in the following format: # depth in plies, evaluation, time used, nodes searched, p/v movstrs = " ".join(listToSan(self.board, mvs)) worker.publish("\t".join(("%d","%d","%0.2f","%d","%s")) % (depth, scr, time()-start, lsearch.nodes, movstrs)) if lsearch.movesearches: mvs_pos = lsearch.nodes/float(lsearch.movesearches) mvs_tim = lsearch.nodes/(time()-t) worker.publish("%0.1f moves/position; %0.1f n/s" % (mvs_pos, mvs_tim)) lsearch.nodes = 0 lsearch.movesearches = 0
def test1(self): """Testing lsearch.alphaBeta() Losers variant""" board = LosersBoard(setup=FEN0) lsearch.searching = True lsearch.timecheck_counter = lsearch.TIMECHECK_FREQ lsearch.endtime = time() + 1 mvs, scr = lsearch.alphaBeta(board.board, 1) self.assertNotEqual(mvs, [])
def __analyze(self): """ Searches, and prints info from, the position as stated in the cecp protocol """ start = time() lsearch.endtime = sys.maxsize lsearch.searching = True for depth in range(1, self.sd): if not lsearch.searching: break board = self.board.clone() mvs, scr = alphaBeta(board, depth) pv1 = " ".join(listToSan(board, mvs)) time_cs = int(100 * (time() - start)) print("%s %s %s %s %s" % (depth, scr, time_cs, lsearch.nodes, pv1)) lsearch.nodes = 0
def __analyze(self): """ Searches, and prints info from, the position as stated in the cecp protocol """ start = time() lsearch.endtime = sys.maxsize lsearch.searching = True for depth in range(1, self.sd): if not lsearch.searching: break board = self.board.clone() mvs, scr = alphaBeta(board, depth) pv1 = " ".join(listToSan(board, mvs)) time_cs = int(100 * (time() - start)) self.print("%s %s %s %s %s" % (depth, scr, time_cs, lsearch.nodes, pv1)) lsearch.nodes = 0
def __go(self, ondone=None): """ Finds and prints the best move from the current position """ mv = False if self.outOfBook else self.__getBestOpening() if mv: mvs = [mv] if not mv: lsearch.skipPruneChance = self.skipPruneChance lsearch.searching = True timed = self.basetime > 0 if self.searchtime > 0: usetime = self.searchtime else: usetime = self.clock[self.playingAs] / self.__remainingMovesA() if self.clock[self.playingAs] > 10: # If we have time, we assume 40 moves rather than 80 usetime *= 2 # The increment is a constant. We'll use this always usetime += self.increment[self.playingAs] prevtime = 0 starttime = time() lsearch.endtime = starttime + usetime if timed else sys.maxsize if self.debug: if timed: print("# Time left: %3.2f s; Planing to think for %3.2f s" % (self.clock[self.playingAs], usetime)) else: print("# Searching to depth %d without timelimit" % self.sd) for depth in range(1, self.sd + 1): # Heuristic time saving # Don't waste time, if the estimated isn't enough to complete # next depth if timed and usetime <= prevtime * 4 and usetime > 1: break lsearch.timecheck_counter = lsearch.TIMECHECK_FREQ search_result = alphaBeta(self.board, depth) if lsearch.searching: mvs, self.scr = search_result if time() > lsearch.endtime: break if self.post: pv1 = " ".join(listToSan(self.board, mvs)) time_cs = int(100 * (time() - starttime)) print("%s %s %s %s %s" % ( depth, self.scr, time_cs, lsearch.nodes, pv1)) else: # We were interrupted if depth == 1: mvs, self.scr = search_result break prevtime = time() - starttime - prevtime self.clock[self.playingAs] -= time( ) - starttime - self.increment[self.playingAs] if not mvs: if not lsearch.searching: # We were interupted lsearch.nodes = 0 return # This should only happen in terminal mode if self.scr == 0: print("result %s" % reprResult[DRAW]) elif self.scr < 0: if self.board.color == WHITE: print("result %s" % reprResult[BLACKWON]) else: print("result %s" % reprResult[WHITEWON]) else: if self.board.color == WHITE: print("result %s" % reprResult[WHITEWON]) else: print("result %s" % reprResult[BLACKWON]) return lsearch.nodes = 0 lsearch.searching = False move = mvs[0] sanmove = toSAN(self.board, move) if ondone: ondone(sanmove) return sanmove
def __go (self, ondone=None): """ Finds and prints the best move from the current position """ mv = self.__getBestOpening() if mv: mvs = [mv] if not mv: lsearch.skipPruneChance = self.skipPruneChance lsearch.searching = True timed = self.basetime > 0 if self.searchtime > 0: usetime = self.searchtime else: usetime = self.clock[self.playingAs] / self.__remainingMovesA() if self.clock[self.playingAs] < 6*60+self.increment[self.playingAs]*40: # If game is blitz, we assume 40 moves rather than 80 usetime *= 2 # The increment is a constant. We'll use this always usetime += self.increment[self.playingAs] if usetime < 0.5: # We don't wan't to search for e.g. 0 secs usetime = 0.5 prevtime = 0 starttime = time() lsearch.endtime = starttime + usetime if timed else sys.maxint if self.debug: if timed: print "# Time left: %3.2f s; Planing to think for %3.2f s" % (self.clock[self.playingAs], usetime) else: print "# Searching to depth %d without timelimit" % self.sd for depth in range(1, self.sd+1): # Heuristic time saving # Don't waste time, if the estimated isn't enough to complete next depth if timed and usetime <= prevtime*4 and usetime > 1: break lsearch.timecheck_counter = lsearch.TIMECHECK_FREQ search_result = alphaBeta(self.board, depth) if lsearch.searching: mvs, self.scr = search_result if time() > lsearch.endtime: break if self.post: pv = " ".join(listToSan(self.board, mvs)) time_cs = int(100 * (time()-starttime)) print depth, self.scr, time_cs, lsearch.nodes, pv else: # We were interrupted if depth == 1: mvs, self.scr = search_result break prevtime = time()-starttime - prevtime self.clock[self.playingAs] -= time() - starttime - self.increment[self.playingAs] if not mvs: if not lsearch.searching: # We were interupted lsearch.nodes = 0 return # This should only happen in terminal mode if self.scr == 0: print "result %s" % reprResult[DRAW] elif self.scr < 0: if self.board.color == WHITE: print "result %s" % reprResult[BLACKWON] else: print "result %s" % reprResult[WHITEWON] else: if self.board.color == WHITE: print "result %s" % reprResult[WHITEWON] else: print "result %s" % reprResult[BLACKWON] return lsearch.nodes = 0 lsearch.searching = False move = mvs[0] sanmove = toSAN(self.board, move) if ondone: ondone(sanmove) return sanmove
def __go (self, worker): """ Finds and prints the best move from the current position """ # TODO: Length info should be put in the book. # Btw. 10 is not enough. Try 20 #if len(self.board.history) < 14: movestr = self.__getBestOpening() if movestr: mvs = [parseSAN(self.board, movestr)] #if len(self.board.history) >= 14 or not movestr: if not movestr: lsearch.skipPruneChance = self.skipPruneChance lsearch.useegtb = self.useegtb lsearch.searching = True if self.mytime == None: lsearch.endtime = sys.maxint worker.publish("Searching to depth %d without timelimit" % self.sd) mvs, self.scr = alphaBeta (self.board, self.sd) else: usetime = self.mytime / self.__remainingMovesA() if self.mytime < 6*60+self.increment*40: # If game is blitz, we assume 40 moves rather than 80 usetime *= 2 # The increment is a constant. We'll use this allways usetime += self.increment if usetime < 0.5: # We don't wan't to search for e.g. 0 secs usetime = 0.5 starttime = time() lsearch.endtime = starttime + usetime prevtime = 0 worker.publish("Time left: %3.2f seconds; Planing to thinking for %3.2f seconds" % (self.mytime, usetime)) for depth in range(1, self.sd+1): # Heuristic time saving # Don't waste time, if the estimated isn't enough to complete next depth if usetime > prevtime*4 or usetime <= 1: lsearch.timecheck_counter = lsearch.TIMECHECK_FREQ search_result = alphaBeta(self.board, depth) if lsearch.searching: mvs, self.scr = search_result if time() > lsearch.endtime: # Endtime occured after depth worker.publish("Endtime occured after depth") break worker.publish("got moves %s from depth %d" % (" ".join(listToSan(self.board, mvs)), depth)) else: # We were interrupted worker.publish("I was interrupted (%d) while searching depth %d" % (lsearch.last, depth)) if depth == 1: worker.publish("I've got to have some move, so I use what we got") mvs, self.scr = search_result break prevtime = time()-starttime - prevtime else: worker.publish("I don't have enough time to go into depth %d" % depth) # Not enough time for depth break else: worker.publish("I searched through depths [1, %d]" % (self.sd+1)) self.mytime -= time() - starttime self.mytime += self.increment if not mvs: if not lsearch.searching: # We were interupted lsearch.movesearches = 0 lsearch.nodes = 0 return # This should only happen in terminal mode #if lsearch.last == 4: # print "resign" #else: if self.scr == 0: worker.publish("result %s" % reprResult[DRAW]) elif self.scr < 0: if self.board.color == WHITE: worker.publish("result %s" % reprResult[BLACKWON]) else: worker.publish("result %s" % reprResult[WHITEWON]) else: if self.board.color == WHITE: worker.publish("result %s" % reprResult[WHITEWON]) else: worker.publish("result %s" % reprResult[BLACKWON]) worker.publish("last: %d %d" % (lsearch.last, self.scr)) return worker.publish("moves were: %s %d" % (" ".join(listToSan(self.board, mvs)), self.scr)) lsearch.movesearches = 0 lsearch.nodes = 0 lsearch.searching = False move = mvs[0] sanmove = toSAN(self.board, move) return sanmove