Ich arbeite mit Swift 3 und Xcode.Sehr langsamer Minesweeper rekursiver Algorithmus in Swift
Ich erstelle ein iOS-Spiel, das im Grunde ein Minesweeper ist, aber es gibt keine Quadrate, sondern Sechsecke, also kann jedes Sechseck bis zu 6 Minen in seiner Umgebung haben.
Ich habe einen rekursiven Algorithmus erstellt, so dass, wenn der Spieler ein Sechseck berührt, wenn es keine Bombe ist, dann eine rekursive Funktion genannt "offenbaren", die: - wenn eine oder mehrere meins in der Umgebung und die berührt Sechseck ist immer noch versteckt (durch versteckte ich meine wir wissen nicht, ob es eine Mine ist oder nicht), enthüllen Sie das Sechseck & legen Sie die Nummer der umliegenden Mine Label, und stoppen Sie die Funktion - wenn keine Mine in der Umgebung, für jede in der Nähe Hexagon, das ausgeblendet ist, rufen Sie die Funktion "Offenlegung" auf.
Also hier ist, was mein Code wie folgt aussieht:
class Hexagon: SKShapeNode
{
var mine: Bool
var hide: Bool
var proximityMines: Int
init(mine: Bool = false, proximityMines: Int = 0, hide: Bool = true)
{
self.mine = mine // if it's a mine
self.proximityMines = proximityMines // number of surrounding mines (that I calculated using a function after I generated the level)
self.hide = hide // if the hexagon is still hidden
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
func reveal(hexagon: Hexagon)
{
if hexagon.proximityMines == 0 && hexagon.hide == true // if there are no mines in the surrounding
{
hexagon.hide = false // we update the value of this hexagon
setNumberLabel(hexagon: hexagon) // we set the .proximityMines number as a label (here 0)
for proxyHexagon in proximityHexagons(hexagon: hexagon) // for each surrounding hexagon ...
{
if proxyHexagon.hide == true // ... that is still hidden
{
reveal(hexagon: proxyHexagon) // we call this function again
}
}
}
else if hexagon.proximityMines != 0 && hexagon.hide == true // else if there are mines in the surrounding
{
hexagon.hide = false // update
setNumberLabel(hexagon: hexagon) // set label
}
}
die proximityHexagons(hexagon: Hexagon)
Funktion gibt ein Array alle umgebenden Hexagons eines gegebenen Sechseck enthält.
Also habe ich meinen Algorithmus immer wieder überprüft, und ich denke wirklich, dass es der Gute ist.
Aber Tatsache ist, dass, wenn ich eine Ebene mit 0 oder eine wirklich geringe Menge von mir zu erstellen, und ich auf ein Sechseck klicken, dauert es etwa 2 Sekunden für die rekursive Funktion, alle leeren Sechsecke zu aktualisieren. Meine Karte enthält mehr oder weniger 260 Sechsecke, und ich debugged die Anzahl der Aufrufe von reveal()
und es ist ungefähr die gleiche Menge.
Warum dauert es so viel Zeit? Ich glaube nicht, dass das iPhone 6 mit dieser Menge an Operationen nicht fertig wird! Ich habe es auf meinem iPhone versucht, kein Emulator. Haben Sie eine Idee?
Sie rufen es rekursiv auf jedem umgebenden Sechseck zu jedem umgebenden Sechseck an. Ich bin kein Experte, aber ich denke, das ist O (N * N!)? vielleicht O (N^N)? Und Sie überprüfen jedes Sechseck jedes Mal. Du musst eine Reihe von überdachten Sechsecken behalten, die du bei jeder Aufdeckung entfernst, und nur diese überprüfen. –
Wenn reveal() nur einmal für jedes Sechseck auf Ihrer Karte aufgerufen wird, scheint Ihr Algorithmus in Ordnung zu sein. Vielleicht gibt es einige UI-bedingte Verlangsamung durch die Einstellung der Nummer Label-Blockierung bei einem synchronen Anruf oder so ähnlich? Überprüfen Sie auch, wie lange Ihre Funktion proximityHexagons() dauert. Eine Idee könnte sein, eine hiddenProximityHexagons() - Funktion zu schreiben, die nur Hexagone zurückgibt, wo hide == true ist. Überprüfen Sie auch, ob Sie Objektreferenzen oder neu erstellte Objekte aus der Funktion – samgak
@ twiz_ zurückgeben, nein, ich rufe die Funktion genau die gleiche Zeit wie die Menge an Sechseck, so dass das Problem nicht da war. – Drakalex