public void AddChild(Board newState, string lastMove) { Vertice child = new Vertice(newState, lastMove); child.parent = this; child.level = this.level + 1; children.Add(child); }
public Solver(Board rootBoard, int xTarget, int yTarget, int outputMode) { boardWidth = rootBoard.width; boardHeight = rootBoard.height; Hashtable HashTable = new Hashtable(); root = new Vertice(rootBoard, null); HashTable.Add(rootBoard.Hash(), rootBoard); syncHT = Hashtable.Synchronized(HashTable); queue = new ConcurrentQueue<Vertice>(); queue.Enqueue(root); solve(xTarget, yTarget, outputMode); }
/// <summary> /// For the state given, return all the possible moves. /// </summary> /// <param name="currentState">From which state to check</param> /// <returns>Unvisited states which can be got to in 1 move</returns> private List<Vertice> allPossibleMoves(Board currentState) { List<Vertice> result = new List<Vertice>(); List<char> checkedCars = new List<char>(); for (int y = 0; y < this.boardHeight; y++) for (int x = 0; x < this.boardWidth; x++) { char car = currentState.board[x, y]; //Is there a car at the current spot. //Or have we cheched this car already? if (car == '.' || checkedCars.Contains(car)) continue; //Console.WriteLine("Checking: " + car); //What direction does the car go? NS || WE //Console.WriteLine("x = " + x + " car = " + car + currentState.board[x + 1, y]); if (x+1 < this.boardWidth && currentState.board[x+1,y] == car) { //Console.WriteLine("Horizontal"); //Horizontal moving //Grab position of the car int[] oldTopLeftCorner = {x,y}; int endCar = x + 1; while(endCar + 1 < this.boardWidth && currentState.board[endCar + 1, y] == car) endCar++; int[] oldBottomRightCorner = { endCar, y }; //Scan left and right for open position, for each position open //we create a new vertice. // Xy for (int i = x - 1; i >= 0; i--) { //Console.WriteLine("Horizontal-LEFT"); if (currentState.board[i, y] != '.') break; int stepstaken = oldTopLeftCorner[0] - i; //Create new Board int[] newTopLeftCorner = {i, y}; int[] newBottomRightCorner = { endCar - stepstaken, y}; Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); if (!isVisitedState(newBoard)) { Vertice vResult = new Vertice(newBoard, car + "l" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } } //Now scan right of the car for (int i = endCar + 1; i < this.boardWidth; i++) { //Console.WriteLine("Horizontal-RIGHT"); if (currentState.board[i, y] != '.') break; int stepstaken = i - oldBottomRightCorner[0]; int[] newTopLeftCorner = { x + stepstaken, y }; int[] newBottomRightCorner = { endCar + stepstaken, y }; //Console.WriteLine("" + newTopLeftCorner[0] + newTopLeftCorner[1]); //Console.WriteLine("" + newBottomRightCorner[0] + newBottomRightCorner[1]); Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); if (!isVisitedState(newBoard)) { Vertice vResult = new Vertice(newBoard, car + "r" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } } } else { //Console.WriteLine("Vertical"); //Set the old positions int[] oldTopLeftCorner = { x, y }; int endCar = y + 1; while (endCar + 1 < this.boardHeight && currentState.board[x, endCar + 1] == car) endCar++; int[] oldBottomRightCorner = { x, endCar }; //Console.WriteLine("" + oldTopLeftCorner[0] + oldTopLeftCorner[1]); //Console.WriteLine("" + oldBottomRightCorner[0] + oldBottomRightCorner[1]); //Now look up and down for the all moves //Looking up here for (int i = y - 1; i >= 0; i--) { //Console.WriteLine("Vertical-UP"); //Console.WriteLine(currentState); //Console.WriteLine("Vertical-UP"); if (currentState.board[x, i] != '.') break; int stepstaken = oldTopLeftCorner[1] - i; //Create new Board int[] newTopLeftCorner = { x, i }; int[] newBottomRightCorner = { x, endCar - stepstaken }; //Console.WriteLine("" + newTopLeftCorner[0] + newTopLeftCorner[1]); //Console.WriteLine("" + newBottomRightCorner[0] + newBottomRightCorner[1]); Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); //Console.WriteLine(newBoard); if (!isVisitedState(newBoard)) { Vertice vResult = new Vertice(newBoard, car + "u" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } //Console.WriteLine("Vertical-UP"); //Console.WriteLine(currentState); //Console.WriteLine("Vertical-UP"); } //Now scan below the car for (int i = endCar + 1; i < this.boardHeight; i++) { //Console.WriteLine("Vertical-DOWN"); //Console.WriteLine("Vertical-DOWN: " + i); //Console.WriteLine("Vertical-DOWN: " + currentState.board[x, i]); if (currentState.board[x, i] != '.') break; int stepstaken = i - oldBottomRightCorner[1]; int[] newTopLeftCorner = { x, y + stepstaken }; int[] newBottomRightCorner = { x, endCar + stepstaken }; //Console.WriteLine("" + newTopLeftCorner[0] + newTopLeftCorner[1]); //Console.WriteLine("" + newBottomRightCorner[0] + newBottomRightCorner[1]); Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); if (!isVisitedState(newBoard)) { //Console.WriteLine("New Board added"); Vertice vResult = new Vertice(newBoard, car + "d" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } } } //Console.ReadKey(); //Console.WriteLine(""); checkedCars.Add(car); } return result; }
public void solve(int xTarget, int yTarget, int outputMode) { isSolved mt_isSolved = new isSolved(false); bool lengthCheckX = (xTarget - 1) >= 0; bool lengthCheckY = (yTarget - 1) >= 0; Vertice dequeue; Vertice solvedGame = null; while (!mt_isSolved.b && queue.TryDequeue(out dequeue)) { Board next = dequeue.state; List <Vertice> moves = new List <Vertice>(allPossibleMoves(next)); foreach (Vertice v in moves) { if (v.state.board[xTarget, yTarget] == 'x') { //Vertical + other lengths bool solveX = false; if (lengthCheckX) { solveX = (v.state.board[xTarget - 1, yTarget] != 'x') && (v.state.board[xTarget + 1, yTarget] == 'x'); } else { solveX = (v.state.board[xTarget + 1, yTarget] == 'x'); } bool solveY = false; if (lengthCheckY) { solveY = (v.state.board[xTarget, yTarget - 1] != 'x') && (v.state.board[xTarget, yTarget + 1] == 'x'); } else { solveX = (v.state.board[xTarget, yTarget + 1] == 'x'); } if ((v.state.board[xTarget, yTarget] == 'x') && (solveX || solveY)) { lock (mt_isSolved) { mt_isSolved.b = true; } } if (mt_isSolved.b) { solvedGame = v; } } dequeue.AddChild(v); queue.Enqueue(v); if (mt_isSolved.b) { break; } } } if (mt_isSolved.b) { if (outputMode == 0) { Console.WriteLine(solvedGame.countToRoot()); } else { Console.WriteLine(solvedGame.movesToRoot()); } } else if (queue.IsEmpty) { Console.WriteLine("Geen oplossing gevonden"); } }
/// <summary> /// For the state given, return all the possible moves. /// </summary> /// <param name="currentState">From which state to check</param> /// <returns>Unvisited states which can be got to in 1 move</returns> private List <Vertice> allPossibleMoves(Board currentState) { List <Vertice> result = new List <Vertice>(); List <char> checkedCars = new List <char>(); for (int y = 0; y < this.boardHeight; y++) { for (int x = 0; x < this.boardWidth; x++) { char car = currentState.board[x, y]; //Is there a car at the current spot. //Or have we cheched this car already? if (car == '.' || checkedCars.Contains(car)) { continue; } //Console.WriteLine("Checking: " + car); //What direction does the car go? NS || WE //Console.WriteLine("x = " + x + " car = " + car + currentState.board[x + 1, y]); if (x + 1 < this.boardWidth && currentState.board[x + 1, y] == car) { //Console.WriteLine("Horizontal"); //Horizontal moving //Grab position of the car int[] oldTopLeftCorner = { x, y }; int endCar = x + 1; while (endCar + 1 < this.boardWidth && currentState.board[endCar + 1, y] == car) { endCar++; } int[] oldBottomRightCorner = { endCar, y }; //Scan left and right for open position, for each position open //we create a new vertice. // Xy for (int i = x - 1; i >= 0; i--) { //Console.WriteLine("Horizontal-LEFT"); if (currentState.board[i, y] != '.') { break; } int stepstaken = oldTopLeftCorner[0] - i; //Create new Board int[] newTopLeftCorner = { i, y }; int[] newBottomRightCorner = { endCar - stepstaken, y }; Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); if (!isVisitedState(newBoard)) { Vertice vResult = new Vertice(newBoard, car + "l" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } } //Now scan right of the car for (int i = endCar + 1; i < this.boardWidth; i++) { //Console.WriteLine("Horizontal-RIGHT"); if (currentState.board[i, y] != '.') { break; } int stepstaken = i - oldBottomRightCorner[0]; int[] newTopLeftCorner = { x + stepstaken, y }; int[] newBottomRightCorner = { endCar + stepstaken, y }; //Console.WriteLine("" + newTopLeftCorner[0] + newTopLeftCorner[1]); //Console.WriteLine("" + newBottomRightCorner[0] + newBottomRightCorner[1]); Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); if (!isVisitedState(newBoard)) { Vertice vResult = new Vertice(newBoard, car + "r" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } } } else { //Console.WriteLine("Vertical"); //Set the old positions int[] oldTopLeftCorner = { x, y }; int endCar = y + 1; while (endCar + 1 < this.boardHeight && currentState.board[x, endCar + 1] == car) { endCar++; } int[] oldBottomRightCorner = { x, endCar }; //Console.WriteLine("" + oldTopLeftCorner[0] + oldTopLeftCorner[1]); //Console.WriteLine("" + oldBottomRightCorner[0] + oldBottomRightCorner[1]); //Now look up and down for the all moves //Looking up here for (int i = y - 1; i >= 0; i--) { //Console.WriteLine("Vertical-UP"); //Console.WriteLine(currentState); //Console.WriteLine("Vertical-UP"); if (currentState.board[x, i] != '.') { break; } int stepstaken = oldTopLeftCorner[1] - i; //Create new Board int[] newTopLeftCorner = { x, i }; int[] newBottomRightCorner = { x, endCar - stepstaken }; //Console.WriteLine("" + newTopLeftCorner[0] + newTopLeftCorner[1]); //Console.WriteLine("" + newBottomRightCorner[0] + newBottomRightCorner[1]); Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); //Console.WriteLine(newBoard); if (!isVisitedState(newBoard)) { Vertice vResult = new Vertice(newBoard, car + "u" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } //Console.WriteLine("Vertical-UP"); //Console.WriteLine(currentState); //Console.WriteLine("Vertical-UP"); } //Now scan below the car for (int i = endCar + 1; i < this.boardHeight; i++) { //Console.WriteLine("Vertical-DOWN"); //Console.WriteLine("Vertical-DOWN: " + i); //Console.WriteLine("Vertical-DOWN: " + currentState.board[x, i]); if (currentState.board[x, i] != '.') { break; } int stepstaken = i - oldBottomRightCorner[1]; int[] newTopLeftCorner = { x, y + stepstaken }; int[] newBottomRightCorner = { x, endCar + stepstaken }; //Console.WriteLine("" + newTopLeftCorner[0] + newTopLeftCorner[1]); //Console.WriteLine("" + newBottomRightCorner[0] + newBottomRightCorner[1]); Board newBoard = createNewState(currentState, car, oldTopLeftCorner, oldBottomRightCorner, newTopLeftCorner, newBottomRightCorner); if (!isVisitedState(newBoard)) { //Console.WriteLine("New Board added"); Vertice vResult = new Vertice(newBoard, car + "d" + stepstaken); //Console.WriteLine(vResult); result.Add(vResult); syncHT.Add(newBoard.Hash(), newBoard); } } } //Console.ReadKey(); //Console.WriteLine(""); checkedCars.Add(car); } } return(result); }
public void AddChild(Vertice v) { v.parent = this; v.level = this.level + 1; children.Add(v); }