Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 22.63 KB | None | 0 0
  1. import java.io._
  2. import scala.io.Source
  3.  
  4. object PuzzleSolver extends App {
  5.  
  6.   class Square(xNumber:Int, yNumber:Int, values:List[String] = List("-","S"), solved:Boolean = false) {
  7.     var possibleValues = values
  8.     val x = xNumber
  9.     val y = yNumber
  10.     var s = solved
  11.  
  12.  
  13.     def setValues(solution: String):Unit = {
  14.       this.s = true
  15.       this.possibleValues = List(solution)
  16.       // new Square(this.box, this.x, this.y, List(solution), true)
  17.     }
  18.  
  19.     def getValue:String = {
  20.       if(this.s) possibleValues.head
  21.       else "Not solved"
  22.     }
  23.  
  24.     def removeValue(wrongSolution:String):Square = {
  25.       val newList = this.possibleValues.filter(_ != wrongSolution)
  26.       if(newList.length > 1)
  27.         new Square(x, y, newList, false)
  28.       else
  29.         new Square(x,y,newList,true)
  30.     }
  31.  
  32.     // Returns a list with all neighbour squares in clockwise rotation
  33.     def getNeighbours(boardSize:Int):List[String] = {
  34.       var right = ""
  35.       var left = ""
  36.       var over = ""
  37.       var under = ""
  38.  
  39.       if(x == boardSize) right = "-"
  40.       else {
  41.         if(getSquare(x+1, y).possibleValues.length > 1) right = "?"
  42.         else right = getSquare(x+1,y).possibleValues.head
  43.       }
  44.  
  45.       if(x == 1) left = "-"
  46.       else {
  47.         if(getSquare(x-1, y).possibleValues.length > 1) left = "?"
  48.         else left = getSquare(x-1, y).possibleValues.head
  49.       }
  50.  
  51.       if(y == 1) over = "-"
  52.       else {
  53.         if(getSquare(x, y-1).possibleValues.length > 1) over = "?"
  54.         else over = getSquare(x, y-1).possibleValues.head
  55.       }
  56.  
  57.       if(y == boardSize) under = "-"
  58.       else {
  59.         if(getSquare(x, y+1).possibleValues.length > 1) under = "?"
  60.         else under = getSquare(x, y+1).possibleValues.head
  61.       }
  62.  
  63.       val neighbours = List[String](right, under, left, over)
  64.       neighbours
  65.     }
  66.  
  67.   }
  68.  
  69.   //Global variables
  70.   //TODO: Minimize these
  71.   var allSquares = List[Square]()
  72.   var unsolvedSquares = List[Square]()
  73.   var boatsList = List[List[Square]]()
  74.   var savedShips = List[(Int, Int)]()
  75.  
  76.   def getAllFromX(i:Int):List[Square] = {
  77.     allSquares.filter(_.x == i)
  78.   }
  79.  
  80.   def getAllFromY(i:Int):List[Square] = {
  81.     allSquares.filter(_.y == i)
  82.   }
  83.  
  84.   def getSquare(x:Int, y:Int):Square = {
  85.     allSquares.filter(_.x == x).filter(_.y == y).head
  86.   }
  87.  
  88.   def setValue(x:Int, y:Int, solution:String):Unit = {
  89.     val s = getSquare(x,y)
  90.     allSquares = allSquares.filter(_ != s)
  91.     s.setValues(solution)
  92.     allSquares = allSquares :+ s
  93.   }
  94.  
  95.   def removeValue(x:Int, y:Int, wrongSolution:String):Unit = {
  96.     var s = getSquare(x,y)
  97.     allSquares = allSquares.filter(_ != s)
  98.     s = s.removeValue(wrongSolution)
  99.     allSquares = allSquares :+ s
  100.   }
  101.  
  102.   def getShips(ships:String):List[(Int, Int)] = {
  103.     var boats = List[(Int, Int)]()
  104.     var shipList = List[String]()
  105.  
  106.     // Read in ships from file
  107.     for(i <- 0 until ships.length){
  108.       if(ships.charAt(i) == 'x'){
  109.         shipList = shipList ::: List(s"${ships(i-1)}${ships(i)}${ships(i+1)}")
  110.       }
  111.     }
  112.  
  113.     var amount = 0
  114.     var size = 0
  115.     var xIndex = 0
  116.  
  117.     // Save ships in a list of tuples(amount, size)
  118.     // Example: (3, 1) means 3x1, or 3 boats of size 1
  119.     for(ship <- shipList){
  120.       xIndex = ship.indexOf('x')
  121.       amount = ship.substring(0, xIndex).toInt
  122.       size = ship.substring(xIndex + 1, ship.length).toInt
  123.  
  124.       boats = boats :+ (amount, size)
  125.     }
  126.  
  127.     // Return tuple list:
  128.     boats
  129.   }
  130.  
  131.   // Takes in a size as parameter, and loops through the list of tuples for the correct size
  132.   // When it finds the correct tuple, decrement the amount
  133.   // Return the new list
  134.   def decrementBoats(size:Int, boats:List[(Int, Int)]):List[(Int, Int)] = {
  135.     var boats2 = List[(Int, Int)]()
  136.     for(boat <- boats){
  137.       if(boat._2 == size && boat._1 > 0) boats2 = boats2 :+ (boat._1 - 1, boat._2)
  138.       else {
  139.         println("Already placed all boats of size " + size)
  140.         boats2 = boats2 :+ (boat._1, boat._2)
  141.       }
  142.     }
  143.     boats2
  144.   }
  145.  
  146.   def incrementBoats(size:Int, boats:List[(Int, Int)]):List[(Int, Int)] = {
  147.     var boats2 = List[(Int, Int)]()
  148.     for(boat <- boats){
  149.       if(boat._2 == size) boats2 = boats2 :+ (boat._1 + 1, boat._2)
  150.       else boats2 = boats2 :+ (boat._1, boat._2)
  151.     }
  152.     boats2
  153.   }
  154.  
  155.  
  156.   def allowedMove(horizontalHints:List[Int], verticalHints:List[Int]):Boolean = {
  157.     var boardSize = horizontalHints.length
  158.     // Check if board fulfills all rules
  159.     // No boats touch each other
  160.     // Correct amount of boats in each row/col according to hints
  161.     var i = 1
  162.     for(hint <- horizontalHints){
  163.       if(getAllFromX(i).count((s:Square) => s.getValue == "S") > hint) return false
  164.       i += 1
  165.     }
  166.     i = 1
  167.     for(hint <- verticalHints){
  168.       if(getAllFromY(i).count((s:Square) => s.getValue == "S") > hint) return false
  169.       i += 1
  170.     }
  171.  
  172.     /*
  173.     for(boat <- boatsList){
  174.       if(!isBoatBuilt(boat, boardSize, "built")) return false
  175.     }
  176.     */
  177.  
  178.     true
  179.   }
  180.  
  181.  
  182.   def bruteforceParty(changeSquare:Int, boats:List[(Int, Int)], horizontalHints:List[Int], verticalHints:List[Int]):List[(Int, Int)] = {
  183.     println("Arrived at the bruteforce party")
  184.     unsolvedSquares = getUnsolved
  185.  
  186.     if(unsolvedSquares.isEmpty) return boats
  187.  
  188.     val x = unsolvedSquares(changeSquare).x
  189.     val y = unsolvedSquares(changeSquare).y
  190.  
  191.     //Change the first square in unsolvedSquare, set it to value "boat"
  192.     val chosen = allSquares.filter((s:Square) => getSquare(s.x, s.y) == unsolvedSquares.head)
  193.     chosen.head.setValues("S")
  194.     if(!allowedMove(horizontalHints, verticalHints)) {
  195.       println("Not allowed")
  196.       chosen.head.removeValue("S")
  197.     }
  198.     println("Value of (" + getSquare(x, y).x + "," + getSquare(x, y).y + ") is changed to S\n")
  199.  
  200.     var updatedShips = boats
  201.     updatedShips = updateBoatsList(horizontalHints.length, boats)
  202.     println(updatedShips)
  203.  
  204.     updatedShips
  205.   }
  206.  
  207.  
  208.   def getUnsolved:List[Square] = {
  209.     unsolvedSquares = allSquares.filter((u:Square) => !u.s)
  210.     unsolvedSquares
  211.   }
  212.  
  213.   def updateUnsolved():List[Square] = {
  214.     unsolvedSquares = unsolvedSquares.drop(1)
  215.     unsolvedSquares
  216.   }
  217.  
  218.   def isBoatBuilt(boat:List[Square], boardSize:Int, usage:String):Boolean = {
  219.     //Check for boat of size 1 (one boat-tile is surrounded by water)
  220.     if(boat.length == 1){
  221.       if(boat.head.getNeighbours(boardSize).forall((n:String) => n == "-")) return true
  222.     }
  223.  
  224.     else {
  225.       val headNeighbours = boat.head.getNeighbours(boardSize)
  226.       val lastNeighbours = boat.last.getNeighbours(boardSize)
  227.  
  228.       if (usage == "built") {
  229.         //Check for horizontal boat
  230.         //Head -> left tile = water, right tile = boat
  231.         //Last -> left tile = boat, right tile = water
  232.         if (headNeighbours(2) == "-" && headNeighbours.head == "S"
  233.           && lastNeighbours(2) == "S" && lastNeighbours.head == "-") return true
  234.  
  235.         //Check for vertical boat
  236.         //Head -> upper tile = water, lower tile = boat
  237.         //Last -> upper tile = boat, lower tile = water
  238.         if (headNeighbours(3) == "-" && headNeighbours(1) == "S"
  239.           && lastNeighbours(3) == "S" && lastNeighbours(1) == "-") return true
  240.  
  241.       } else if (usage == "finished") {
  242.         //Horizontal
  243.         if (headNeighbours(2) == "-" && headNeighbours.head != "?"
  244.           && lastNeighbours(2) != "?" && lastNeighbours.head == "-") return true
  245.  
  246.         //Vertical
  247.         if (headNeighbours(3) == "-" && headNeighbours(1) != "?"
  248.           && lastNeighbours(3) != "?" && lastNeighbours(1) == "-") return true
  249.       }
  250.     }
  251.     false
  252.   }
  253.  
  254.   //TODO: Comment this function
  255.   def updateBoatsList(boardSize:Int, ships:List[(Int, Int)]):List[(Int, Int)] = {
  256.     var boat = List[Square]()
  257.     var boat2 = List[Square]()
  258.     var updatedShips = ships
  259.  
  260.     //Horizontal boats
  261.     for(row <- 1 to boardSize) {
  262.       val line = getAllFromY(row)
  263.       for (i <- 1 to boardSize) {
  264.         if (line.filter((s: Square) => s.x == i).head.possibleValues.head == "S") {
  265.           boat2 = boat2 :+ line.filter((s:Square) => s.x == i).head
  266.           if(row == boardSize && i == boardSize){
  267.             if(boat2.length > boat.length){
  268.               boat = boat2
  269.               if(isBoatBuilt(boat, boardSize, "built")) {
  270.                 if(!boatsList.contains(boat)) {
  271.                   updatedShips = decrementBoats(boat.length, updatedShips)
  272.                   boatsList = boatsList :+ boat
  273.                 }
  274.               }
  275.             }
  276.           }
  277.         }
  278.         else {
  279.           if(boat2.length > boat.length){
  280.             boat = boat2
  281.             if(isBoatBuilt(boat, boardSize, "built")) {
  282.               if(!boatsList.contains(boat)) {
  283.                 boatsList = boatsList :+ boat
  284.                 updatedShips = decrementBoats(boat.length, updatedShips)
  285.               }
  286.             }
  287.             boat = List[Square]()
  288.             boat2 = List[Square]()
  289.           }
  290.         }
  291.       }
  292.     }
  293.  
  294.     boat = List[Square]()
  295.     boat2 = List[Square]()
  296.  
  297.     //Vertical boats
  298.     for(col <- 1 to boardSize) {
  299.       val line = getAllFromX(col)
  300.       for (i <- 1 to boardSize) {
  301.         if (line.filter((s: Square) => s.y == i).head.possibleValues.head == "S") {
  302.           boat2 = boat2 :+ line.filter((s:Square) => s.y == i).head
  303.           if(col == boardSize && i == boardSize){
  304.             if(boat2.length > boat.length){
  305.               boat = boat2
  306.               if(isBoatBuilt(boat, boardSize, "built")) {
  307.                 if(!boatsList.contains(boat)) {
  308.                   boatsList = boatsList :+ boat
  309.                   updatedShips = decrementBoats(boat.length, updatedShips)
  310.                 }
  311.               }
  312.             }
  313.           }
  314.         }
  315.         else {
  316.           if(boat2.length > boat.length){
  317.             boat = boat2
  318.             if(isBoatBuilt(boat, boardSize, "built")) {
  319.               if(!boatsList.contains(boat)) {
  320.                 boatsList = boatsList :+ boat
  321.                 updatedShips = decrementBoats(boat.length, updatedShips)
  322.               }
  323.             }
  324.             boat = List[Square]()
  325.             boat2 = List[Square]()
  326.           }
  327.         }
  328.       }
  329.     }
  330.     updatedShips
  331.   }
  332.  
  333.   def getHints(hintLine:String):List[Int] = {
  334.     var hint = List[Int]()
  335.     for(i <- 0 until hintLine.length){
  336.       if(hintLine.charAt(i) == ' '){
  337.         hint = hint ::: List(hintLine.charAt(i+1).toString.toInt)
  338.       }
  339.     }
  340.     hint
  341.   }
  342.  
  343.   def waterZeros(verticalHints:List[Int], horizontalHints:List[Int], size:Int):Unit = {
  344.     horizontalHints.foreach(hint => if(hint == 0) getAllFromX(horizontalHints.indexOf(hint)+1).foreach(u => setValue(u.x, u.y,"-")))
  345.     verticalHints.foreach(hint => if(hint == 0) getAllFromY(verticalHints.indexOf(hint)+1).foreach(u => setValue(u.x, u.y,"-")))
  346.   }
  347.  
  348.   def fillAroundHints():Unit={
  349.     allSquares.filter(_.possibleValues.length==1).foreach(k=> k.possibleValues.head match {
  350.       case "*" => {
  351.         allSquares.filter((b: Square) => (b.y == k.y - 1 && (b.x == k.x - 1 || b.x == k.x || b.x == k.x + 1)) || (b.y == k.y + 1 && (b.x == k.x - 1 || b.x == k.x || b.x == k.x + 1)) || (b.y == k.y && (b.x == k.x - 1 || b.x == k.x + 1))).foreach(z => setValue(z.x, z.y, "-"))
  352.         setValue(k.x, k.y, "S")
  353.       }
  354.       case "<" => {
  355.         allSquares.filter((b: Square) => (b.y == k.y - 1 && (b.x == k.x - 1 || b.x == k.x || b.x == k.x + 1)) || (b.y == k.y + 1 && (b.x == k.x - 1 || b.x == k.x || b.x == k.x + 1)) || (b.y == k.y && b.x == k.x - 1)).foreach(z => setValue(z.x, z.y, "-"))
  356.         if(getSquare(k.x+1,k.y).possibleValues.length!=1)setValue(k.x + 1, k.y, "S")
  357.         setValue(k.x, k.y, "S")
  358.       }
  359.       case ">" => {
  360.         allSquares.filter((b: Square) => (b.y == k.y - 1 && (b.x == k.x - 1 || b.x == k.x || b.x == k.x + 1)) || (b.y == k.y + 1 && (b.x == k.x - 1 || b.x == k.x || b.x == k.x + 1)) || (b.y == k.y && b.x == k.x + 1)).foreach(z => setValue(z.x, z.y, "-"))
  361.         if(getSquare(k.x-1,k.y).possibleValues.length!=1)setValue(k.x - 1, k.y, "S")
  362.         setValue(k.x, k.y, "S")
  363.       }
  364.       case "A" => {
  365.         allSquares.filter((b:Square)=> (b.y == k.y-1 && (b.x ==k.x-1||b.x ==k.x || b.x ==k.x+1)) || (b.y ==k.y+1 && (b.x ==k.x-1|| b.x==k.x+1)) || (b.y==k.y && (b.x==k.x-1 || b.x==k.x+1))).foreach(z=>setValue(z.x,z.y,"-"))
  366.         if(getSquare(k.x,k.y+1).possibleValues.length!=1)setValue(k.x, k.y+1, "S")
  367.         setValue(k.x, k.y, "S")
  368.       }
  369.       case "V" => {
  370.         allSquares.filter((b:Square)=> (b.y == k.y-1 && (b.x ==k.x-1|| b.x ==k.x+1)) || (b.y ==k.y+1 && (b.x ==k.x-1||b.x==k.x || b.x==k.x+1)) || (b.y==k.y && (b.x==k.x-1 || b.x==k.x+1))).foreach(z=>setValue(z.x,z.y,"-"))
  371.         if(getSquare(k.x,k.y-1).possibleValues.length!=1)setValue(k.x, k.y-1, "S")
  372.         setValue(k.x, k.y, "S")
  373.       }
  374.       case "+" => allSquares.filter((b:Square)=> (b.y == k.y-1 && (b.x ==k.x-1|| b.x ==k.x+1)) || (b.y ==k.y+1 && (b.x ==k.x-1|| b.x==k.x+1))).foreach(z=>setValue(z.x,z.y,"-"))
  375.       case "S" => allSquares.filter((b:Square)=> (b.y == k.y-1 && (b.x ==k.x-1|| b.x ==k.x+1)) || (b.y ==k.y+1 && (b.x ==k.x-1|| b.x==k.x+1))).foreach(z=>setValue(z.x,z.y,"-"))
  376.       case "-" =>
  377.     })
  378.   }
  379.  
  380.   def fillOnebyOneSquares(size:Int):Unit = {
  381.     allSquares.filter(_.possibleValues.length==2).filter(_.getNeighbours(size)==List("-","-","-","-")).foreach(i=>setValue(i.x,i.y,"-"))
  382.   }
  383.  
  384.   def fillByDecreasingSize(boardSize:Int, currentRound:Int, boats:List[(Int, Int)], currentSize:(Int, Int)): Unit = {
  385.     var boat = List[Square]()
  386.     var boat2 = List[Square]()
  387.  
  388.     for(row <- 1 to boardSize) {
  389.       val line = getAllFromY(row)
  390.       for (i <- 1 to boardSize) {
  391.         if (line.filter((s: Square) => s.x == i).head.possibleValues.head == "S") {
  392.           boat2 = boat2 :+ line.filter((s:Square) => s.x == i).head
  393.         }
  394.         else {
  395.           if(boat2.length > boat.length){
  396.             boat = boat2
  397.             if(isBoatBuilt(boat, boardSize, "finished")) {
  398.               if(boat.head.x-1 != 0) {
  399.                 setValue(boat.head.x - 1, boat.head.y, "-")
  400.               }
  401.               if(boat.last.x+1 <= boardSize){
  402.                 setValue(boat.last.x + 1,boat.last.y, "-")
  403.  
  404.               }
  405.             }
  406.             boat = List[Square]()
  407.             boat2 = List[Square]()
  408.           }
  409.         }
  410.       }
  411.     }
  412.  
  413.     boat = List[Square]()
  414.     boat2 = List[Square]()
  415.  
  416.     //Vertical boats
  417.     for(col <- 1 to boardSize) {
  418.       val line = getAllFromX(col)
  419.       for (i <- 1 to boardSize) {
  420.         if (line.filter((s: Square) => s.y == i).head.possibleValues.head == "S") {
  421.           boat2 = boat2 :+ line.filter((s:Square) => s.y == i).head
  422.         }
  423.         else {
  424.           if(boat2.length > boat.length){
  425.             boat = boat2
  426.             if(isBoatBuilt(boat, boardSize, "finished")) {
  427.               if(boat.head.y-1 > 0) {
  428.                 setValue(boat.head.x, boat.head.y-1, "-")
  429.               }
  430.               if(boat.last.y+1 <= boardSize){
  431.                 setValue(boat.head.x,boat.last.y + 1, "-")
  432.               }
  433.             }
  434.             boat = List[Square]()
  435.             boat2 = List[Square]()
  436.           }
  437.         }
  438.       }
  439.     }
  440.  
  441.     //fill currentsize-1's
  442.     if(currentSize._2 == 2) return
  443.     fillByDecreasingSize(boardSize, currentRound + 1, boats, boats(boats.length - currentRound - 1))
  444.  
  445.   }
  446.  
  447.   def checkPlus(k:Square):Unit={
  448.     if(getSquare(k.x,k.y-1).possibleValues == List("-") || getSquare(k.x,k.y+1).possibleValues == List("-")){
  449.       setValue(k.x+1,k.y,"S")
  450.       setValue(k.x-1,k.y,"S")
  451.       setValue(k.x,k.y,"S")
  452.     }
  453.     else if (getSquare(k.x+1,k.y).possibleValues == List("-") || getSquare(k.x-1,k.y).possibleValues == List("-")){
  454.       setValue(k.x,k.y+1,"S")
  455.       setValue(k.x,k.y-1,"S")
  456.       setValue(k.x,k.y,"S")
  457.     }
  458.   }
  459.  
  460.  
  461.   // Fills water in the corner squares of each boat
  462.   def waterCorners():Unit = {
  463.     allSquares.filter(_.possibleValues.head == "S").foreach(k => k.possibleValues.head match {
  464.       case "S" => allSquares.filter((b:Square) => (b.y == k.y-1 && (b.x ==k.x-1|| b.x ==k.x+1)) || (b.y ==k.y+1 && (b.x ==k.x-1|| b.x==k.x+1))).foreach(z=>setValue(z.x,z.y,"-"))
  465.       case _ =>
  466.     })
  467.   }
  468.  
  469.   def checkBoatsXY(horizontal:List[Int], vertical:List[Int], size:Int):Unit = {
  470.     for (i <- 0 until size) {
  471.       if (getAllFromX(i + 1).filter(_.possibleValues.length == 1).count(_.possibleValues.head != "-") == horizontal(i)) {
  472.         getAllFromX(i + 1).filter(_.possibleValues.length != 1).foreach(u => setValue(u.x, u.y, "-"))
  473.       } else if (horizontal(i) - getAllFromX(i + 1).count(_.possibleValues.head == "S") == getAllFromX(i + 1).count(_.possibleValues.length != 1)){
  474.         getAllFromX(i + 1).filter(_.possibleValues.length != 1).foreach(u => setValue(u.x, u.y, "S"))
  475.       }
  476.  
  477.       if (getAllFromY(i + 1).filter(_.possibleValues.length == 1).count(_.possibleValues.head != "-") == vertical(i)) {
  478.         getAllFromY(i + 1).filter(_.possibleValues.length != 1).foreach(u => setValue(u.x, u.y, "-"))
  479.       } else if (vertical(i) - getAllFromY(i + 1).count(_.possibleValues.head == "S") == getAllFromY(i + 1).count(_.possibleValues.length != 1)) {
  480.         getAllFromY(i + 1).filter(_.possibleValues.length != 1).foreach(u => setValue(u.x, u.y, "S"))
  481.       }
  482.     }
  483.   }
  484.  
  485.   def checkIfSolved(ships:List[(Int, Int)]):Boolean = {
  486.     allSquares.forall(_.s) && ships.forall(_._1 == 0)
  487.   }
  488.  
  489.   def printToFile(solved:String):Unit = {
  490.     val out = new BufferedWriter(new FileWriter(new File("puzzle_solved.txt")))
  491.  
  492.     out.write(solved)
  493.     out.close()
  494.   }
  495.  
  496.   def mainSolver(path:String):Unit = {
  497.     val lines = Source.fromFile(path).getLines.toList
  498.     var smolLines = lines
  499.     val puzzleAmount = lines(0).charAt(8).toString.toInt
  500.     var solved = "Puzzles " + puzzleAmount +"\n"
  501.     var currentBoard = List[Square]()
  502.     var lastBoard = List[Square]()
  503.     var updatedShips = List[(Int, Int)]()
  504.     var bruteForceTries = 1
  505.     var bfInnerLoop = 0
  506.     var bfFlag = true
  507.     var savedBoard = List[Square]()
  508.  
  509.     smolLines = smolLines.drop(1)
  510.  
  511.     for(i <- 0 until puzzleAmount){ //one loop is one puzzle solving sequence
  512.  
  513.       smolLines = smolLines.drop(1)
  514.       val ships = getShips(smolLines.head)
  515.       smolLines = smolLines.drop(1)
  516.       val horizontalHints = getHints(smolLines.head)
  517.       smolLines = smolLines.drop(1)
  518.       val verticalHints = getHints(smolLines.head)
  519.       val size = verticalHints.length
  520.       smolLines = smolLines.drop(1)
  521.       smolLines = smolLines.drop(1)
  522.  
  523.       for (y <- 0 until size) {
  524.         var boatline = smolLines.head.filter(_ != ' ')
  525.  
  526.         for (x <- 0 until size) {
  527.           if (boatline.charAt(x) != '?') {
  528.             allSquares = allSquares ::: List(new Square(x + 1, y + 1, List(boatline.charAt(x).toString), true))
  529.           } else {
  530.             allSquares = allSquares ::: List(new Square(x + 1, y + 1))
  531.           }
  532.         }
  533.         smolLines = smolLines.drop(1)
  534.       }
  535.  
  536.       currentBoard = allSquares
  537.       updatedShips = ships
  538.  
  539.       /*****************************************************************************************************************/
  540.  
  541.       def printTempSolution():Unit = {
  542.         print("   ")
  543.         horizontalHints.foreach((h:Int) => print(h + " "))
  544.         println()
  545.         for(y <- 1 to size){
  546.           print(verticalHints(y-1) + "  ")
  547.           for(x <- 1 to size){
  548.             if(getSquare(x,y).possibleValues.length > 1) print("? ")
  549.             else print(getSquare(x,y).possibleValues.head + " ")
  550.           }
  551.           println()
  552.         }
  553.         println()
  554.       }
  555.  
  556.       def printSavedBoard():Unit = {
  557.         for(y <- 1 to size){
  558.           for(x <- 1 to size){
  559.             if(savedBoard.filter((k:Square) => k.x == x && k.y == y).head.possibleValues.length > 1) print("? ")
  560.             else print(savedBoard.filter((k:Square) => k.x == x && k.y == y).head.possibleValues.head + " ")
  561.           }
  562.           println()
  563.         }
  564.         println()
  565.       }
  566.  
  567.       printTempSolution() // Original puzzle
  568.       fillAroundHints()
  569.       waterZeros(verticalHints, horizontalHints, size)
  570.       printTempSolution()
  571.  
  572.       while (!checkIfSolved(updatedShips)) {
  573.         lastBoard = currentBoard
  574.         checkBoatsXY(horizontalHints, verticalHints, size)
  575.         waterCorners()
  576.         printTempSolution()
  577.         currentBoard = allSquares
  578.  
  579.         for (x <- 1 to size) {
  580.           for (y <- 1 to size) {
  581.             if (getSquare(x, y).possibleValues == List("+")) checkPlus(getSquare(x, y))
  582.           }
  583.         }
  584.  
  585.         updatedShips = updateBoatsList(size, updatedShips)
  586.  
  587.         //If all boats of size 0 has been placed, fill all empty 1x1-squares with water
  588.         //if(updatedShips.head._2 == 1 && updatedShips.head._1 == 0) fillOnebyOneSquares(size)
  589.         //if(updatedShips.last._1 == 0) fillByDecreasingSize(size,0, updatedShips, updatedShips.last)
  590.  
  591.  
  592.         if(currentBoard == lastBoard) {
  593.           println("I AM STUCK PLEASE HELP")
  594.           if(bfFlag){
  595.             savedBoard = currentBoard
  596.             savedShips = updatedShips
  597.  
  598.             println("------------------------------------Saved board and ships")
  599.             printSavedBoard()
  600.             bfFlag = false
  601.           }
  602.           updatedShips = bruteforceParty(bfInnerLoop, updatedShips, horizontalHints, verticalHints)
  603.           println("Bruteforce inner loop: " + bfInnerLoop)
  604.           println("--------------------------------------Saved board is now:")
  605.           printSavedBoard()
  606.           bfInnerLoop += 1
  607.         }
  608.  
  609.  
  610.         if(allSquares.forall(_.possibleValues.length == 1) && !checkIfSolved(updatedShips)){
  611.  
  612.           println("--------------------------------------Loaded board and ships")
  613.           printSavedBoard()
  614.  
  615.           printTempSolution()
  616.           allSquares = savedBoard
  617.           updatedShips = savedShips
  618.           bfInnerLoop = 0
  619.           bruteForceTries += 1
  620.  
  621.         }
  622.  
  623.         println("Bruteforce tries: " + bruteForceTries)
  624.  
  625.       }
  626.  
  627.       /****************************************************************************************************************/
  628.  
  629.  
  630.       updatedShips = updateBoatsList(size, updatedShips)
  631.       println("Ships: " + ships)
  632.       println("Updated: " + updatedShips)
  633.       println("Vertical: " + verticalHints)
  634.       println("Horizontal: " + horizontalHints)
  635.  
  636.       solved += "Size " + size + "x" + size + "\n"
  637.  
  638.       for(y <- 1 to size) {
  639.         for(x <- 1 to size){
  640.           solved += getSquare(x,y).possibleValues.head + " "
  641.           print(getSquare(x,y).possibleValues.head + " ")
  642.         }
  643.         solved += "\n"
  644.         println()
  645.       }
  646.  
  647.       //println(size)
  648.       allSquares = List[Square]()
  649.       boatsList = List[List[Square]]()
  650.       println("\n")
  651.     }
  652.  
  653.     printToFile(solved)
  654.   }
  655.  
  656.   mainSolver("puzzle_unsolved.txt")
  657.  
  658. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement