Βρείτε τις πιθανές θέσεις σε μια σκακιέρα όπου 8 βασίλισσες είναι τοποθετημένες έτσι ώστε καμία να μην απειλείται από την άλλη.
Ένα γνωστό σε πολλούς πρόβλημα το οποίο δεν είναι και πολύ εύκολο.
Φανταστείτε τώρα η σκακιέρα να μην είναι 8x8 αλλά 15x15 ή οτιδήποτε άλλο και έστω οι βασίλισσες 13. το πρόβλημα θα γίνει αρκετά δύσκολο για όλους μας.
Το παρακάτω πρόγραμμα δίνει όλες τις λύσεις για 1-15 βασίλισσες και για σκακιέρα 1x1 έως 100x100, αρκεί βέβαια να υπάρχει λύση. Μην ζητήσει κανείς την λύση για 6 βασίλισσες και σκακιέρα 3x3, σίγουρα δεν υπάρχει!
Οι θέσεις των βασιλισσών θα εμφανιστούν με κόκκινο χρώμα. Ενώ με μαύρο τις θέσεις εκείνες που ελέγχουν μία ή παραπάνω βασίλισσες και με μπλε εκείνες που είναι τελείως ελεύθερες
Δεν θα πω τίποτα για τον κώδικα – ούτως η άλλος σε μερικά σημεία είναι «ελαφρώς» ακατανόητος ακόμα και για μένα που το έγραψα πριν λίγους μήνες !
Θα πώς όμως αρκετά για την επόμενη έκδοση του προγράμματος σε κάποιο άλλο σημείο. Προς το παρόν σας δίνω τον κώδικα το οποίο έχει μερικά προβληματάκια και που θα τα σχολιάσουμε σε επόμενο tutorial.
Γραμμένο σε Visual Basic 6
Private queens ‘= 5 ‘1-15
Private MAX ‘= 4 ‘megethos skakieras
Private PINAK(100, 100) As Long ‘max tablo=100
‘MsgBox “rtg”
Erase PINAK()
End If
queens = Combo1.Text
MAX = Combo2.Text
Pic.AutoRedraw = True
Pic.Cls
pause = 0
‘*** dokimes
‘PINAK(1, 2) = 2 ^ (8 + 0)
‘PINAK(2, 3) = 2 ^ (8 + 1)
‘PINAK(3, 4) = 2 ^ (8 + 2)
‘PINAK(4, 5) = 2 ^ (8 + 3)
‘PINAK(5, 6) = 2 ^ (8 + 4)
‘PINAK(6, 7) = 2 ^ (8 + 5)
‘PINAK(7,
= 2 ^ (8 + 6)
‘PINAK(8, 1) = 2 ^ (8 + 7)
Private Function FIND(LEVEL)
param = queens
‘MsgBox PINAK(1, 1)
Do
DoEvents
If pause = 0 Then Exit Do
‘MsgBox LEVEL
‘MsgBox (2 ^ (2 * queens) – 2 ^ (queens))
If LEVEL = queens Then
kl = 0
‘Pic.Cls
For y = 1 To MAX
For x = 1 To MAX
ISO = Pic.ScaleWidth / (MAX + 2)
Pic.DrawWidth = 12
Pic.Circle (x * ISO, y * ISO), ISO / 5, Pic.BackColor
If PINAK(y, x) And (2 ^ param – 1) Then Pic.Circle (x * ISO, y * ISO), ISO / 5, RGB(0, 0, 0)
If PINAK(y, x) And (2 ^ (2 * param) – 2 ^ (param)) Then ‘65280 gia 8 basilises
Pic.Circle (x * ISO, y * ISO), ISO / 5, RGB(200, 0, 0)
fg$ = LTrim$(Str$(Log(PINAK(y, x) And (2 ^ (2 * param) – 2 ^ (param))) / Log(2) – (param – 1)))
SX = Pic.TextWidth(fg$)
SY = Pic.TextHeight(” “)
Pic.CurrentX = x * ISO – SX / 2
Pic.CurrentY = y * ISO – SY / 2
Pic.ForeColor = RGB(255, 255, 255)
Pic.Print fg$
‘MsgBox fg$
‘MsgBox Log((PINAK(Y, X) And 65280) – 255) / Log(2)
kl = kl + 1
End If
Next x
Next y
Pic.Refresh
End If
If LEVEL = -1 Then MsgBox (“ADINATO na simvei”): End
If LEVEL = queens Then
‘MsgBox (“FOUND A SOLUTION!”)
FIND = LEVEL – 1: Exit Function
End If
‘VRES AN IPARXI IDI
find_x = 0
FIND_Y = 0
For y = 1 To MAX
For x = 1 To MAX
If (PINAK(y, x) And 2 ^ (LEVEL + queens)) Then
find_x = x
FIND_Y = y
Exit For
End If
Next x
Next y
‘If LEVEL = 7 Then MsgBox find_x
‘AN IPARXEI APEKATASTASI
If find_x > 0 Then
PINAK(FIND_Y, find_x) = PINAK(FIND_Y, find_x) Xor (2 ^ (LEVEL + queens))
For B = 1 To MAX
For a = 1 To MAX
If PINAK(B, a) And (2 ^ LEVEL) Then
PINAK(B, a) = PINAK(B, a) Xor (2 ^ LEVEL)
End If
Next a
Next B
End If
‘If LEVEL = 1 Then MsgBox find_x
‘VRES EPOMENI THESI
If FIND_Y = 0 Then FIND_Y = 1
find_x = find_x + 1
If find_x > MAX Then find_x = 1: FIND_Y = FIND_Y + 1
If FIND_Y > MAX Then
FIND = LEVEL – 1
Exit Function
End If
y = FIND_Y
x = find_x
‘MsgBox “X ” & X
‘MsgBox “Y ” & Y
Do
If x > MAX Then x = 1: y = y + 1
If y > MAX Then
FIND = LEVEL – 1
Exit Function
End If
‘ELENXOS AN APILEITAI
IS_APILI = False
If PINAK(y, x) > 0 Then IS_APILI = True
‘ AN DEN APILEITE TOTE
If IS_APILI = False Then
For X1 = 1 To MAX
PINAK(y, X1) = PINAK(y, X1) Or 2 ^ (LEVEL)
Next X1
‘KATHETA
For Y1 = 1 To MAX
PINAK(Y1, x) = PINAK(Y1, x) Or 2 ^ (LEVEL)
Next Y1
‘DIAGONIA
L_X = x – y + 1
For L_Y = 1 To MAX
L_X2 = 2 * x – L_X
‘DIAG_1
If L_X > 0 And L_X <= MAX Then
PINAK(L_Y, L_X) = PINAK(L_Y, L_X) Or 2 ^ (LEVEL)
End If
‘DIAG 2
If L_X2 > 0 And L_X2 <= MAX Then
PINAK(L_Y, L_X2) = PINAK(L_Y, L_X2) Or 2 ^ (LEVEL)
End If
L_X = L_X + 1
Next L_Y
PINAK(y, x) = PINAK(y, x) Or 2 ^ (LEVEL + queens)
PINAK(y, x) = PINAK(y, x) Or 2 ^ (LEVEL)
‘TELOS KATAXORISIS
LEVEL = FIND(LEVEL + 1)
‘If LEVEL = 7 Then MsgBox “a”
GoTo start
End If ‘TELOS TOU AN DEN APILITE
x = x + 1
End Function
Private Sub Command2_Click()
If pause = 0 Then pause = 1: Exit Sub
If pause = 1 Then pause = 0
End Sub
Private Sub Form_Load()
For a = 1 To 15
Combo1.AddItem a
Next
Combo1.ListIndex = 8
Combo2.AddItem a
Next
End Sub
χωρίς σχόλια
RSS για τα σχόλια αυτού του άρθρου | TrackBack URL