public GameTree BuildGameTree(SuperSlimBoard board, bool win = true) { var seenBoards = new Dictionary <SuperSlimBoard, int>(); _gameTreeIndex = 1; return(BuildGameTree(board, seenBoards, win)); }
public static bool IsSuperabundantForGraph(SuperSlimBoard b, Graph g, int extraPsi = 0) { ulong subset = 0; int total = 0; while (subset < (1UL << b._stackCount)) { total = 0; for (int i = 0; i < b._length; i++) { total += (subset & b._trace[i]).PopulationCount() / 2; } var e = g.EdgesOn(subset.ToSet()); if (total < e) { return(false); } subset++; } if (extraPsi > 0) { return(total >= g.E + extraPsi); } return(true); }
static int InternalIntersectionInCommonCount(Graph g, SuperSlimBoard board) { long and = -1L; foreach (var v in g.Vertices) { if (g.Degree(v) <= 1) { continue; } var neighborStack = 0L; foreach (var w in g.Neighbors[v]) { if (g.Degree(w) > 1) { continue; } neighborStack |= board.Stacks.Value[w]; } and &= board.Stacks.Value[v] & neighborStack; } return(and.PopulationCount()); }
long GetEdgeColorList(SuperSlimBoard b, int e) { var v1 = _edges[e].Item1; var v2 = _edges[e].Item2; var stacks = b.Stacks.Value; return(stacks[v1] & stacks[v2]); }
GameTree BuildGameTree(SuperSlimBoard board, Dictionary <SuperSlimBoard, int> seenBoards, bool win = true) { seenBoards[board] = _gameTreeIndex; var tree = new GameTree() { Board = board }; tree.IsColorable = _coloringAnalyzer.Analyze(board); tree.IsSuperabundant = win || IsSuperabundant(board); tree.GameTreeIndex = _gameTreeIndex; tree.Reduction = CheckReducibility(board); _gameTreeIndex++; if (tree.IsColorable) { return(tree); } if (!tree.IsSuperabundant) { return(tree); } if (tree.Reduction != null) { return(tree); } var treeInfo = win ? _swapAnalyzer.WinTreeInfo[board] : _swapAnalyzer.LossTreeInfo[board]; foreach (var bc in treeInfo) { var childBoard = new SuperSlimBoard(board._trace, bc.Alpha, bc.Beta, bc.Response, board._stackCount); int index; if (seenBoards.TryGetValue(childBoard, out index)) { var ct = new GameTree() { Board = childBoard }; ct.IsColorable = _coloringAnalyzer.Analyze(childBoard); ct.IsSuperabundant = win || IsSuperabundant(board); ct.GameTreeIndex = _gameTreeIndex++; ct.SameAsIndex = index; tree.AddChild(ct, bc); continue; } var childTree = BuildGameTree(childBoard, seenBoards, win); tree.AddChild(childTree, bc); } return(tree); }
bool CheckOrdering(SuperSlimBoard a, SuperSlimBoard b) { var order = PartialOrderOnBoards; if (order == null) { return(false); } return(order(this, a, b) > 0); }
public int ComputeAbundanceSurplus(SuperSlimBoard b) { int total = 0; for (int i = 0; i < b._length; i++) { total += b._trace[i].PopulationCount() / 2; } return(total - G.E); }
public bool ColorableWithoutEdge(SuperSlimBoard b, int edgeIndex) { return(_lineGraph.IsChoosable(Enumerable.Range(0, _lineGraph.N).Select(e => { if (e == edgeIndex) { return -1; } return _getEdgeColorList(b, e); }).ToList())); }
Reduction CanReduce(Graph g, SuperSlimBoard board, Func <Graph, List <Reduction>, Reduction> reducibilityChecker) { var edges = g.Edges.Value; var pendantEdges = g.PendantEdges.Value; foreach (var tup in pendantEdges) { var v = tup.Item1; var w = tup.Item2; if (g.Degree(w) > 1) { v = tup.Item2; w = tup.Item1; } var dv = g.Degree(v); var dw = g.Degree(w); if (ForbiddenEdge != null && (w == ForbiddenEdge.Item1 || w == ForbiddenEdge.Item2)) { continue; } var h = g.RemoveEdge(tup); var list = board.Stacks.Value[v] & board.Stacks.Value[w]; var reductions = new List <Reduction>(); foreach (var c in list.GetBits()) { var reducedStacks = board.Stacks.Value.ToList(); reducedStacks[w] = 0; reducedStacks[v] ^= c; var reducedBoard = new SuperSlimBoard(reducedStacks); reductions.Add(new Reduction() { Color = c, Board = reducedBoard, Stem = v, Leaf = w }); } var r = reducibilityChecker(h, reductions); if (r != null) { return(r); } } return(null); }
public Reduction CheckReducibility(SuperSlimBoard board, Action <Tuple <string, int> > progress = null) { if (ReductionMode == FixerBreakeReductionMode.None) { return(null); } SubFixableMind.Value.Progress = progress; if (ReductionMode == FixerBreakeReductionMode.Superabundant) { return(SubFixableMind.Value.CanReduceToSuperabundant(G, board, ExtraPsi)); } return(SubFixableMind.Value.CanReduceToWin(G, board)); }
public static int InternalIntersectionOrder(SuperSlimMind mind, SuperSlimBoard a, SuperSlimBoard b) { var asum = -InternalIntersectionCount(mind.G, a); var bsum = -InternalIntersectionCount(mind.G, b); if (asum < bsum) { return(-1); } if (asum > bsum) { return(1); } return(0); }
static int InternalIntersectionCount(Graph g, SuperSlimBoard board) { long and = -1L; foreach (var v in g.Vertices) { if (g.Degree(v) <= 1) { continue; } and &= board.Stacks.Value[v]; } return(and.PopulationCount()); }
bool AnalyzeInternal(SuperSlimBoard board, HashSet <SuperSlimBoard> wonBoards) { for (int i = 0; i < board._length; i++) { for (int j = i + 1; j < board._length; j++) { var x = board._trace[i]; var y = board._trace[j]; var swappable = x ^ y; var winningSwapAlwaysExists = true; foreach (var breakerChoice in GetBreakerChoices(swappable)) { var winningSwapExists = false; GetFixerResponses(breakerChoice); for (int k = 1; k < _fixerResponseCount; k++) { if (_swapMode == FixerBreakerSwapMode.SingleSwap && _fixerResponses[k].PopulationCount() > 2) { continue; } var childBoard = new SuperSlimBoard(board._trace, i, j, _fixerResponses[k], board._stackCount); if (wonBoards.Contains(childBoard)) { winningSwapExists = true; break; } } if (!winningSwapExists) { winningSwapAlwaysExists = false; break; } } if (winningSwapAlwaysExists) { return(true); } } } return(false); }
public bool Equals(SuperSlimBoard other) { if (other == null || _length != other._length) { return(false); } for (int i = 0; i < _length; i++) { if (_trace[i] != other._trace[i]) { return(false); } } return(true); }
bool AnalyzeOriginalFixerBreaker(SuperSlimBoard board, HashSet <SuperSlimBoard> wonBoards) { var colorPairs = new List <Tuple <int, int> >(); for (int i = 0; i < board._length; i++) { for (int j = i + 1; j < board._length; j++) { colorPairs.Add(new Tuple <int, int>(i, j)); } } foreach (var cp in colorPairs.OrderBy(cp => (board._trace[cp.Item1] ^ board._trace[cp.Item2]).PopulationCount())) { var i = cp.Item1; var j = cp.Item2; var x = board._trace[i]; var y = board._trace[j]; var swappable = x ^ y; foreach (var v in swappable.GetBits()) { var good = true; var responses = new [] { v }.Concat((swappable ^ v).GetBits().Select(w => w | v)); foreach (var response in responses) { var childBoard = new SuperSlimBoard(board._trace, i, j, response, board._stackCount); if (!wonBoards.Contains(childBoard)) { good = false; break; } } if (good) { return(true); } } } return(false); }
public static int BestKnownOrder(SuperSlimMind mind, SuperSlimBoard a, SuperSlimBoard b) { var ep = GlobalExtraPsiOrder(mind, a, b); if (ep != 0) { return(ep); } var ii = InternalIntersectionOrder(mind, a, b); if (ii != 0) { return(ii); } return(0); }
public bool Analyze(SuperSlimBoard board, HashSet <SuperSlimBoard> wonBoards) { if (ProofFindingMode) { if (_swapMode == FixerBreakerSwapMode.Original) { return(AnalyzeForProofInternalOriginalFixerBreaker(board, wonBoards)); } return(AnalyzeForProofInternal(board, wonBoards)); } if (_swapMode == FixerBreakerSwapMode.Original) { return(AnalyzeOriginalFixerBreaker(board, wonBoards)); } return(AnalyzeInternal(board, wonBoards)); }
bool AnalyzeForProofInternal(SuperSlimBoard board, HashSet <SuperSlimBoard> wonBoards) { var winInfo = new GameTreeInfo(); WinTreeInfo[board] = winInfo; var lossInfo = new GameTreeInfo(); LossTreeInfo[board] = lossInfo; var colorPairs = new List <Tuple <int, int> >(); for (int i = 0; i < board._length; i++) { for (int j = i + 1; j < board._length; j++) { colorPairs.Add(new Tuple <int, int>(i, j)); } } foreach (var cp in colorPairs.OrderBy(cp => (board._trace[cp.Item1] ^ board._trace[cp.Item2]).PopulationCount())) { var i = cp.Item1; var j = cp.Item2; var x = board._trace[i]; var y = board._trace[j]; var swappable = x ^ y; var winningSwapAlwaysExists = true; foreach (var breakerChoice in GetBreakerChoices(swappable)) { var winningSwapExists = false; GetFixerResponses(breakerChoice); var responses = Enumerable.Range(1, _fixerResponseCount - 1).Select(k => _fixerResponses[k]).OrderBy(fr => fr.PopulationCount()); foreach (var response in responses) { if (_swapMode == FixerBreakerSwapMode.SingleSwap && response.PopulationCount() > 2) { break; } var childBoard = new SuperSlimBoard(board._trace, i, j, response, board._stackCount); if (wonBoards.Contains(childBoard)) { winningSwapExists = true; winInfo.Add(breakerChoice, i, j, response); break; } else { lossInfo.Add(breakerChoice, i, j, response); } } if (!winningSwapExists) { winInfo.Clear(); winningSwapAlwaysExists = false; break; } } if (winningSwapAlwaysExists) { return(true); } } return(false); }
public Reduction CanReduceToSuperabundant(Graph g, SuperSlimBoard board, int extraPsi) { return(CanReduce(g, board, (h, l) => l.FirstOrDefault(r => SuperSlimMind.IsSuperabundantForGraph(r.Board, h, extraPsi)))); }
public static int GlobalExtraPsiOrder(SuperSlimMind mind, SuperSlimBoard a, SuperSlimBoard b) { return(mind.ComputeAbundanceSurplus(a).CompareTo(mind.ComputeAbundanceSurplus(b))); }
public Reduction CanReduceToWin(Graph g, SuperSlimBoard board) { return(CanReduce(g, board, CheckReductionForWin)); }
public static int CurrentOrder(SuperSlimMind mind, SuperSlimBoard a, SuperSlimBoard b) { return(BestKnownOrder(mind, a, b)); }
public bool Analyze(SuperSlimBoard b, out Dictionary <int, long> coloring) { return(IsChoosable(Enumerable.Range(0, _lineGraph.N).Select(e => _getEdgeColorList(b, e)).ToList(), out coloring)); }
bool NearlyColorableForEdge(SuperSlimBoard board, int edgeIndex) { return(_coloringAnalyzer.ColorableWithoutEdge(board, edgeIndex)); }
public bool Analyze(SuperSlimBoard b) { return(_lineGraph.IsChoosable(Enumerable.Range(0, _lineGraph.N).Select(e => _getEdgeColorList(b, e)).ToList())); }
public bool NearlyColorableForSomeEdge(SuperSlimBoard board) { return(Enumerable.Range(0, _lineG.N).Any(e => NearlyColorableForEdge(board, e))); }
public bool IsSuperabundant(SuperSlimBoard b) { return(IsSuperabundantForGraph(b, G)); }
public GameTreeInfo GetWinTreeInfo(SuperSlimBoard board) { return(_swapAnalyzer.WinTreeInfo[board]); }