public GameTree BuildGameTree(SuperSlimBoard board, bool win = true) { var seenBoards = new Dictionary <SuperSlimBoard, int>(); _gameTreeIndex = 1; return(BuildGameTree(board, seenBoards, win)); }
public bool IsSuperabundant(SuperSlimBoard b) { 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 = _graph.EdgesOn(subset.ToSet()); if (total < e) { return(false); } subset++; } if (ExtraPsi > 0) { return(total >= _graph.E + ExtraPsi); } return(true); }
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, int depth = 0) { seenBoards[board] = _gameTreeIndex; var tree = new GameTree() { Board = board, IsFixerWin = win }; tree.IsColorable = _coloringAnalyzer.Analyze(board); tree.IsSuperabundant = win || IsSuperabundant(board); tree.GameTreeIndex = _gameTreeIndex; _gameTreeIndex++; if (tree.IsColorable) { return(tree); } if (!tree.IsSuperabundant) { return(tree); } GameTreeInfo treeInfo; if (win) { _swapAnalyzer.WinTreeInfo.TryGetValue(board, out treeInfo); } else { _swapAnalyzer.LossTreeInfo.TryGetValue(board, out treeInfo); } if (treeInfo != null) { var localSeenBoards = new HashSet <SuperSlimBoard>(); foreach (var bc in treeInfo) { var childBoard = new SuperSlimBoard(board._trace, bc.Alpha, bc.Beta, bc.Response, board._stackCount); if (localSeenBoards.Contains(childBoard)) { continue; } localSeenBoards.Add(childBoard); if (!win && seenBoards.ContainsKey(childBoard)) { continue; } var childTree = BuildGameTree(childBoard, seenBoards, win, depth + 1); tree.AddChild(childTree, bc); } } return(tree); }
public bool Analyze(SuperSlimBoard board, HashSet <SuperSlimBoard> wonBoards) { if (ProofFindingMode) { return(AnalyzeForProofInternal(board, wonBoards)); } return(AnalyzeInternal(board, wonBoards)); }
public int ComputeAbundanceSurplus(SuperSlimBoard b) { int total = 0; for (int i = 0; i < b._length; i++) { total += b._trace[i].PopulationCount() / 2; } return(total - _graph.E); }
public bool AnalyzeWithoutEdge(SuperSlimBoard b, out Dictionary <int, long> coloring, int edgeIndex) { return(IsChoosable(Enumerable.Range(0, _lineGraph.N).Select(e => { if (e == edgeIndex) { return -1; } return _getEdgeColorList(b, e); }).ToList(), out coloring)); }
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())); }
void GenerateAllBoards(Template template, int colorCount, Action <Tuple <string, int> > progress = null) { if (progress != null) { progress(new Tuple <string, int>("Finding all positions...", 0)); } foreach (var t in BitLevelGeneration.Assignments_ulong.Generate(template.Sizes, colorCount)) { var b = new SuperSlimBoard(t, template.Sizes.Count); _remainingBoards.Add(b); } }
bool IsMatchingAbundant(SuperSlimBoard b, ulong subset, out int e) { e = _graph.EdgesOn(subset.ToSet()); int total = 0; for (int i = 0; i < b._length; i++) { var vc = (subset & b._trace[i]).ToSet(); total += _lineGraph.IndependenceNumber(_graph.EdgeIndicesOn(vc)); } return(total >= e); }
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 (WeaklyFixable && _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); }
IEnumerable <ColorPairOutcome> Analyze(SuperSlimBoard board) { 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)); } } return(colorPairs.OrderBy(cp => (board._trace[cp.Item1] ^ board._trace[cp.Item2]).PopulationCount()) .Select(cp => new ColorPairOutcome() { Colors = cp, FixerOutcomes = AnalyzeColorPair(cp, board) })); }
IEnumerable <FixerOutcome> AnalyzeColorPair(Tuple <int, int> colors, SuperSlimBoard board) { var i = colors.Item1; var j = colors.Item2; var x = board._trace[i]; var y = board._trace[j]; var swappable = x ^ y; foreach (var breakerChoice in GetBreakerChoices(swappable)) { GetFixerResponses(breakerChoice); var responses = Enumerable.Range(1, _fixerResponseCount - 1).Select(k => _fixerResponses[k]).Where(fr => fr.PopulationCount() <= 1); yield return(new FixerOutcome() { BreakerChoice = breakerChoice, Exits = responses.Select(response => new SuperSlimBoard(board._trace, i, j, response, board._stackCount)).ToList() }); } }
List <int> ComputeMatchingAbundanceShadow(SuperSlimBoard b) { var shadow = new List <int>(); ulong subset = 0; while (subset < (1UL << b._stackCount)) { int e; if (!IsMatchingAbundant(b, subset, out e)) { shadow.Add(e); } subset++; } shadow.Sort(); return(shadow); }
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 (WeaklyFixable && 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) { LastWinChildCount = swappable.PopulationCount(); return(true); } } return(false); }
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 NearlyColorableForSomeEdge(SuperSlimBoard board) { return(Enumerable.Range(0, _lineGraph.N).Any(e => NearlyColorableForEdge(board, e))); }
public GameTreeInfo GetWinTreeInfo(SuperSlimBoard board) { return(_swapAnalyzer.WinTreeInfo[board]); }
public bool Analyze(SuperSlimBoard b) { return(_lineGraph.IsChoosable(Enumerable.Range(0, _lineGraph.N).Select(e => _getEdgeColorList(b, e)).ToList())); }