def play_game(self): self.squares = {} for x in range(self.cols): for y in range(self.rows): color = zero_sq self.squares[(x,y)]=self.canvas.create_rectangle(x*self.scale+10,y*self.scale+10,\ (x+1)*self.scale+10,(y+1)*self.scale+10,fill=color,outline=color) self.s = getattr(self.module,self.strategy_name.split('.')[1])() self.m = minemap.MineMap(self.mines,self.rows,self.cols) self.s.play1(self.m) self.display_game() numCleared = self.m.cleared numTotal = self.cols*self.rows - self.mines print 'Playing on',self.rows,'by',self.cols,'board -' if self.m.won(): print " Game was won:",'uncovered',numCleared,'of',numTotal,'tiles' else: print " Game was lost:",'uncovered',numCleared,'of',numTotal,'tiles'
def main(args): m = None strategy_name = "cspstrategy.CSPStrategy" game_name = 'intermediate' mines = 40 rows = 16 cols = 16 hinted = False realrules = True tries = 1 sets = 1 module = __import__(strategy_name.split('.')[0]) cont = False for i in range(len(args)): if cont: cont = False continue if args[i] == '-H': hinted = True elif args[i] == '-R': realrules = True elif args[i] == '-i': game_name = 'intermediate' mines = 40 rows = 16 cols = 16 elif args[i] == '-e': game_name = 'expert' mines = 99 rows = 16 cols = 30 elif args[i] == '-b': game_name = 'beginner' mines = 10 rows = 8 cols = 8 elif args[i] == '-r': if i + 1 >= len(args): raise Exception("Wrong input") else: rows = int(args[i + 1]) cont = True elif args[i] == '-c': if i + 1 >= len(args): raise Exception("Wrong input") else: cols = int(args[i + 1]) cont = True elif args[i] == '-m': if i + 1 >= len(args): raise Exception("Wrong input") else: mines = int(args[i + 1]) cont = True elif args[i] == '-s': if i + 1 >= len(args): raise Exception("Wrong input") else: strategy_name = args[i + 1] cont = True elif args[i] == '-n': if i + 1 >= len(args): raise Exception("Wrong input") else: tries = int(args[i + 1]) cont = True elif args[i] == '-S': if i + 1 >= len(args): raise Exception("Wrong input") else: sets = int(args[i + 1]) cont = True elif args[i] == '-v': module.VERBOSE = True elif args[i] == '-noreal': realrules = False else: raise Exception("Wrong input") if rows < 1 or cols < 1 or mines < 1 or mines >= rows * cols: raise Exception("Wrong input") sumN = 0.0 sumsqr = 0.0 numCleared = 0.0 numTotal = 0.0 game_count = 0 for seti in range(1, sets + 1): wins = 0 for n in range(1, tries + 1): s = getattr(module, strategy_name.split('.')[1])() m = minemap.MineMap(mines, rows, cols, realrules) if not hinted: s.play1(m) else: hint = m.hint() s.play2(m, hint[0], hint[1]) game_count += 1 if m.won(): wins += 1 numCleared += m.cleared numTotal += cols * rows - mines sumN += wins sumsqr += wins**2 print str(rows), "by", str(cols), "board with", str(mines), "mines" print "In %s sets of %s tries (%s) games total:" % (sets, tries, sets * tries) mean = sumN / sets print " Mean wins: %s/%s (%s%%)" % (int(mean), tries, 100.0 * mean / tries) print " Mean %% of board cleared: %s/%s (%s%%)" % ( int(numCleared), int(numTotal), 100 * numCleared / numTotal)
def play2(self, m, hint_column, hint_row, not_first): self.map = m # initialize SolutionSet statics solutionset.largest_neqns = 0 solutionset.largest_nvars = 0 solutionset.largest_nsols = 0 # initialize board cspboard = csp.CSPBoard() cspboard.CreateBoard(self.map) if VERBOSE: print("================ NEW GAME ================") # use hint if cspboard.board[hint_column][hint_row].probe( self.map) == minemap.BOOM and m.realrules: map2 = minemap.MineMap(m.mines, m.rows, m.cols, m.realrules, True) self.play2(map2, hint_column, hint_row) m.cleared = map2.cleared m.victory = map2.victory return # initialize constraints for x in range(self.map.cols): for y in range(self.map.rows): self.addConstraint(cspboard.board[x][y].newConstraint()) # main loop while not self.map.done(): # Simplify constraints by combining with each other and # marking or probing _obvious_ mines and cleared areas. self.simplifyConstraints() if self.map.done(): break # At this point the constraints are as simple as possible and # the choice of next move is _not_ obvious. All solutions to # the CSP must be found to determine if there are any _safe_ # moves. # Seperate the constraints into coupled subsets, each represented # by a SolutionSet object. subsets = self.seperateConstraints() nsubsets = len(subsets) if nsubsets <= 0: # This happens when all remaining (unknown) clear positions # are seperated (by mines) from the known clear positions. if VERBOSE: print("No problems to solve!") else: solving_msg = False if VERBOSE: # determine number of variables in largest subproblem nvars = subsets[0].getVariableCount() ncnts = subsets[0].getConstraintCount() for i in range(1, nsubsets): if (subsets[i].getVariableCount() - subsets[i].getConstraintCount() ) > nvars - ncnts: nvars = subsets[i].getVariableCount() ncnts = subsets[i].getConstraintCount() if nvars - ncnts >= SOLVE_THRESHOLD: solving_msg = True if nsubsets == 1: print("Solving " + str(ncnts) + " constraint " + str(nvars) + " variable system...") else: print("Solving " + str(nsubsets) + " systems (largest is " + str(ncnts) + " constraints " + str(nvars) + " variables)...") # Solve each of the sub-problems by enumerating all solutions # to the constraint satisfaction problem. for subset in subsets: subset.enumerateSolutions() if solving_msg: print(" done.") # Account for all remaining mines. It may be found that some # sub-problems have solutions that require too many or too few # mines. In these cases, some solutions will be deleted from # the SolutionSet. # The number of mines expected to be found in the unknown # positions is also calculated. remaining = self.map.mines_minus_marks() far = cspboard.nonConstrainedCount() far_max = remaining far_expected = float(remaining) for i in range(nsubsets): nmin = 0 nmax = far for j in range(nsubsets): if i != j: nmin += subsets[j].getMin() nmax += subsets[j].getMax() subsets[i].reduceMinMax(remaining - nmax, remaining - nmin) far_expected -= subsets[i].expectedMines() far_max -= subsets[i].getMin() # Using far_expected here seems to work better, but sometimes # yields negative probabilities. far_max doesn't have this # problem, but doesn't work as well. far_prob = far_expected / float(far) if far > 0 else 1 if far_prob < 0.01: far_prob = float(0.01) # Do any craps shoots. Even if we survive these, we are no # better off. crapshoot = False for i in reversed(range(nsubsets)): c = subsets[i].doCrapsShoot(self.map) if c != None: self.addConstraint(c) # throw away subset so we don't do anything with it # again until the constraints are next simplified nsubsets -= 1 subsets.pop(i) crapshoot = True elif self.map.done(): break if self.map.done(): break if nsubsets <= 0 and crapshoot: continue # Mark for-sure mines. for i in range(nsubsets): subsets[i].markMines(self.map) # If no mines are left in the unknown positions, probe them all. # This is very good for us and we go back to simplification # immediately afterwards. if far_max <= 0 and far > 0: positions = cspboard.enumerateUnknown() for position in positions: position.probe(self.map) self.addConstraint(position.newConstraint()) continue # Determine best position to make a probe (a guess). best_subset = -1 best_prob = far_prob surething = False for i in range(nsubsets): prob = subsets[i].findBestProbe() if prob <= 0: surething = True self.addConstraint(subsets[i].doBestProbe(self.map)) elif prob <= best_prob: best_prob = prob best_subset = i if surething: continue # If best guess is a constrained position, probe it. if best_subset >= 0: if VERBOSE: print("GUESS: " + str(int((1 - best_prob) * 100)) + "% educated ...") c = subsets[best_subset].doBestProbe(self.map) if c != None: self.addConstraint(c) if VERBOSE: print(" good.") elif VERBOSE: print(" FAILED") # Otherwise, we probe one of the unknown positions. else: # first check the corners positions = cspboard.enumerateCorners() category = "corner" if positions == None: # next check for edges positions = cspboard.enumerateEdges() category = "edge" if positions == None: # next check for a boundary position positions = cspboard.enumerateMaxBoundary() category = "boundary" if positions == None: # finally, if all else fails, probe some random position positions = cspboard.enumerateUnknown() category = "far" if positions == None: print("WHAT! No boundary or unknown?") if VERBOSE: print("GUESS: " + str(int((1 - best_prob) * 100)) + "% " + category + " ...") i = self.map.pick(len(positions)) s = positions[i].probe(self.map) if s >= 0: self.addConstraint(positions[i].newConstraint()) if VERBOSE: print(" ok.") elif VERBOSE: print(" FAILED!") # miscellaneous stats if VERBOSE and solutionset.largest_nvars > 0: print("Largest System Solved: " + solutionset.largest_neqns + " equations " + solutionset.largest_nvars + " variables " + solutionset.largest_nsols + " solutions")
import sweeper import minemap import numpy as np import time # map_generator = utils.MineMap() # board = map_generator.board # mines = map_generator.get_mines() # print(board) if __name__ == '__main__': avg, avg_improve, time_con, time_con_improve = 0, 0, 0, 0 for i in range(100): map_generator = minemap.MineMap(x=16, y=16, p=38) board = map_generator.board mine = map_generator.mine_number sweep = sweeper.Sweeper(board, map_generator.mine_number) start = time.time() while sweep.flip(): sweep.sweep_safe() while sweep.sweep_mine(): continue end = time.time() time_con += end - start t = sweep.temp / mine avg += t sweep_improve = sweeper.Sweeper(board, map_generator.mine_number) start_improve = time.time() while sweep_improve.flip_by_possibility(): sweep_improve.sweep_safe() while sweep_improve.sweep_mine(): continue
# time_con_improve += end_improve - start_improve # t_improve = sweep_improve.temp / mine # avg_improve += t_improve # # sweeper.draw_board() # # map_generator = minemap.MineMap() # # map_generator.drawboard(board) # # print(sweeper.sweeper_map) # # print(board) # print("Progress:{}%".format(((i + 1) * 100 / 100)), flush=True) # avg /= 100 # avg_improve /= 100 # print(str(avg) + " -> " + str(time_con)) # print(str(avg_improve) + " -> " + str(time_con_improve)) avg, avg_improve, time_con, time_con_improve = 0, 0, 0, 0 for i in range(100): map_generator = minemap.MineMap(x=16, y=16, p=38) board = map_generator.board mine = map_generator.mine_number sweep = sweeper.Sweeper(board, map_generator.mine_number) start = time.time() while sweep.flip(): sweep.sweep_safe() while sweep.sweep_mine(): continue end = time.time() time_con += end - start t = sweep.temp / mine avg += t map_generator = minemap.MineMap(x=25, y=25) board = map_generator.board