void FillKnowledgeTree(KnowledgeTree knowledgeTree, Board board, Dictionary <Board, Tuple <int, Board> > seenCache) { knowledgeTree.Board = board.ToString(); knowledgeTree.Number = TreeNodeNumber++; var knowledge = Knowledge[board.Template.Value][board.ColorCount][board]; if (knowledge.Exists()) { if (knowledge.Reason != "good swap") { knowledgeTree.Note = knowledge.Reason; } else { Tuple <int, Board> seenBoard; if (seenCache.TryGetValue(board, out seenBoard)) { knowledgeTree.Note = "same as #" + seenBoard.Item1; return; } var f = knowledge.Board.FindPermutation(board); var colors = Board.ApplyMapping(f, new[] { knowledge.ColorPair.Item1, knowledge.ColorPair.Item2 }).ToList(); var colorPair = new Tuple <int, int>(colors[0], colors[1]); foreach (var swap in knowledge.Swaps) { var tempBoard = board.Clone(); var moves = swap.Item2.Select(m => MetaKnowledge.MapMove(f, m)).ToList(); tempBoard.DoMoveCombination(moves); var childKnowledgeTree = knowledgeTree.AddChild(swap); childKnowledgeTree.ColorPair = colorPair; FillKnowledgeTree(childKnowledgeTree, tempBoard, seenCache); } } } else { throw new Exception("something went wrong in building search tree"); } seenCache[board] = new Tuple <int, Board>(knowledgeTree.Number, board); }
public Tuple <Graph, Dictionary <int, KeyValuePair <Board, BoardKnowledge> >, Dictionary <Tuple <int, int>, Tuple <List <List <int> >, List <Move>, string> > > GenerateTemplateKnowledgeGraph(Template template) { var templateKnowledge = Knowledge[template]; var colorCount = MetaKnowledge.Naturals().First(n => templateKnowledge.KnowledgeExists(n) && !templateKnowledge.KnowledgeExists(n + 1)); var nextVertexID = 0; var vertexLookup = new Dictionary <Board, int>(); var swapLookup = new Dictionary <Tuple <int, int>, Tuple <List <List <int> >, List <Move>, string> >(); var boardLookup = new Dictionary <int, KeyValuePair <Board, BoardKnowledge> >(); var outEdges = new Dictionary <int, List <int> >(); foreach (var kvp in templateKnowledge[colorCount].EnumerateBoardKnowledge()) { vertexLookup[kvp.Key] = nextVertexID; boardLookup[nextVertexID] = kvp; outEdges[nextVertexID] = new List <int>(); nextVertexID++; } foreach (var b in templateKnowledge.LostBoards) { vertexLookup[b] = nextVertexID; boardLookup[nextVertexID] = new KeyValuePair <Board, BoardKnowledge>(b, new BoardKnowledge(b, "breaker wins")); outEdges[nextVertexID] = new List <int>(); nextVertexID++; } foreach (var kvp in templateKnowledge[colorCount].EnumerateBoardKnowledge()) { if (kvp.Value.Reason == "good swap") { var v = vertexLookup[kvp.Key]; var f = kvp.Value.Board.FindPermutation(kvp.Key); var colors = Board.ApplyMapping(f, new[] { kvp.Value.ColorPair.Item1, kvp.Value.ColorPair.Item2 }).ToList(); var colorPair = new Tuple <int, int>(colors[0], colors[1]); foreach (var swap in kvp.Value.Swaps) { var tempBoard = kvp.Key.Clone(); var moves = swap.Item2.Select(m => MetaKnowledge.MapMove(f, m)).ToList(); tempBoard.DoMoveCombination(moves); var w = vertexLookup[tempBoard]; outEdges[v].Add(w); swapLookup[new Tuple <int, int>(v, w)] = swap; } } } var edgeWeights = new List <int>(); for (int i = 0; i < nextVertexID; i++) { for (int j = i + 1; j < nextVertexID; j++) { if (outEdges[i].Contains(j)) { edgeWeights.Add(1); } else if (outEdges[j].Contains(i)) { edgeWeights.Add(-1); } else { edgeWeights.Add(0); } } } return(new Tuple <Graph, Dictionary <int, KeyValuePair <Board, BoardKnowledge> >, Dictionary <Tuple <int, int>, Tuple <List <List <int> >, List <Move>, string> > >(new Graph(edgeWeights), boardLookup, swapLookup)); }