Plis Necesito ayuda Para Programar Sudoku en Vb!!!!!!

Iniciado por Quenene, 25 Febrero 2006, 14:43 PM

0 Miembros y 1 Visitante están viendo este tema.

Quenene

Por favor, tengo poco tiempo usando Vb pero necesito Programar Sudoku para Vb, Sudoku es un juego que debe cumplir 3 condiciones. Es una Matriz 9x9 subdividida en 9 matrices 3x3, debe tener numeros del 1 al 9 en todas sus filas sin que se repita ningun numero, debe tener numeros del 1 al 9 en todas sus columnas sin que se repita ningun numero; y por ultimo debe tener numeros del 1 al 9 en cada matriz 3x3 sin que se repitan ningun numero.

Para mas informacion sobre el juego y para que puedan ayudarme mejor aqui esta esta pagina: http://es.wikipedia.org/wiki/Sudoku
en esta pagina hablan del método de backtracking o "vuelta atrás" Yo no tengo ni idea por favor quien pueda orientarme, este es mi mail queneneyeaa@gmail.com
GRACIAS POR SU AYUDA

BenRu

Leete algo de IA (Inteligencia Artificial) y como no, un manual de visual basic

Quenene

Realmente ya se programar todo lo refernte a Matrices y condicones con el if o el select case... Pero no logro encontrar la forma de lograr que el porgrama llene la matriz cumpliendo todas las condiciones sin que se cuelgue, ya sea porque procedimientos anidados unos o con otros.
Bueno solo buscaba sugerencias :(

xXnewbieXx

quenene, q necesitas para tu programa? veo q BenRu menciona IA. 1 colega mio hizo un zudoku d esos y lo uniko k aplicaba era el Rnd, colocando al principio numeros aleatorios del 1 al 9 en casillas aleatorias tbn con el Rnd.
Dps d colocar 1 numero comprobabas la suma de los numeros de las casillas algo asi, la verdad es q tp t puedo ayudar muxo pq no m fije en q consistía el juego pero era algo asi. si consigo k el colega m pase el codigo lo posteo a ver si t sirve d ayuda ;)
saludos.
Hardware: Lo que golpeas. Software: La causa

Error 943 - El sistema esta funcionando demasiado bien, se caerá para seguir con la rutina...

juampivicius

Mira yo en un tiempo también pensé en programar un sodoku..porque lo jugaba en un diario y ya lo conocía de antes jaja...acá encontré en una página  www.geardome.com/sudoku.php
Está hecho en java script y por lo que vi es un tanto complejo ...se podría haber hecho..y con respecto  el anterior comentario creo que te puede orientar un poco...

saludos

Quenene

Coye Gracias por su ayuda, yo le he estado dando a ver si me sale pero hasta ahora he logrado que programe las casillas del 1 al 9 sin que se repitan en cada una de las matrices. El programa con la funcion Rnd rellena el tablero haciendo que se cumplan estas 2 condiciones 2 veces, la tercera vez se cuelga, no se ahi les paso el codigo a ver que me dicen

    ---------------------------------------------------------------
    Dim A(1 To 9, 1 To 9) As Byte, B(0 To 8) As Byte, C(1 To 9) As Byte, Numero As Byte, Sec2 As String
    Dim I As Single, J As Single, Sec As String, Digito As Byte, S As String, K As Byte, M As String, P As String
    Dim Sec1 As String, Sec3 As String, Bandera As Boolean
    -------------------------------------------------
    Private Sub Genera_Matriz()
    Sec2 = ""        'Como no se muede inicializar una variable tipo Strign en "0" se inicializa en ""(vacio)
    For K = 0 To N - 1
        Bandera = True
        With GridY
        .RowHeight(K) = 900
        Sec = ""
          Sec1 = IIf((K Mod 3) = 0, "", Sec1)
          Sec2 = IIf((K Mod 3) = 0, "", Sec2)
          Sec3 = IIf((K Mod 3) = 0, "", Sec3)
         For I = 3 * Int(K / 3) To 3 * Int(K / 3) + 2   'para que recorra las filas se le cambia
            For J = 3 * (K Mod 3) To 3 * (K Mod 3) + 2
                Digito = Int(N * Rnd + 1)        'del 1 al 9
            If InStr(Sec, CStr(Digito)) = 0 Then       'CStr conviete Digito a tipo String
                Sec = Sec & Digito
                            'CVar devuelve Digito de tipo String a tipo anterior, en este caso a tipo byte
                 Select Case I
                Case Is = 0, 3, 6
                    If InStr(Sec1, CStr(Digito)) = 0 Then
                        Sec1 = Sec1 & Digito
                        A(I + 1, J + 1) = CVar(Digito)
                    Else
                    Sec = Mid(Sec, 1, Len(Sec) - 1)
                    J = J - 1
                    End If
                Case Is = 1, 4, 7
                    If InStr(Sec2, CStr(Digito)) = 0 Then
                        Sec2 = Sec2 & Digito
                        A(I + 1, J + 1) = CVar(Digito)
                    Else
                    Sec = Mid(Sec, 1, Len(Sec) - 1)
                    J = J - 1
                    End If
                Case Is = 2, 5, 8
                 If InStr(Sec3, CStr(Digito)) = 0 Then
                        Sec3 = Sec3 & Digito
                        A(I + 1, J + 1) = CVar(Digito)
                    Else
                        Select Case K
                        Case Is = 0, 3, 6
                        J = J - 1
                        Case Is = 1, 2, 4, 6, 7
                        Bandera = False
                        Select Case J
                        Case Is = 4, 7
                        Sec1 = Mid(Sec1, 1, Len(Sec1) - 3)
                        Sec2 = Mid(Sec2, 1, Len(Sec2) - 3)
                        Sec3 = Mid(Sec3, 1, Len(Sec3) - 1)
                        Case Is = 5, 8
                        Sec1 = Mid(Sec1, 1, Len(Sec1) - 3)
                        Sec2 = Mid(Sec2, 1, Len(Sec2) - 3)
                        Sec3 = Mid(Sec3, 1, Len(Sec3) - 2)
                        End Select
                        End Select
                    End If
                End Select
            Else
                J = J - 1
            End If
            Next J
            Next I
        End With
    Llena_MatrizA
    If Bandera = False Then K = K - 1
    Next K
    End Sub
    Const N = 9
Mi Problema es que en algunos casos se cuelga el programa y en otros casos corre bien

.Slasher-K.

Bueh no pensaba postear más pero los desafíos me gustan xD, y pensé que era más dificil esto pero la verdad que el algoritmo es más simple de lo que creía -_-

No lo terminé completo porque esto suena a tarea del colegio y no quiero ayudar a la pereza, pero con esta base es más que suficiente. Lo único que falta es agregar los números aleatorios y comprobar que no se repitan números en regiones, que también es muy sencillo.

Para implementar este ejemplo se necesita lo siguiente:

Un formulario con las siguientes propiedades:

BorderStyle = 0 (None)
KeyPreview = True
ShowInTaskBar = True


Un cuadro de texto con las siguientes propiedades:

Nombre: txtNum
Index = 0
Appearance = 0 (Flat)


Luego sólo peguen el siguiente código en el formulario y voilà. Por cierto, dije que el código era de ejemplo por lo que debería estar lo más reducido posible, pero le agregué un par de elementos visuales para mejorar la interfaz, así que aumentó un poco, pero en sí el algoritmo de comprobación es la función RightValue.

Screenshot:




Option Explicit

Private iCurCol   As Integer
Private iCurLin   As Integer
Private iCurIndex As Integer

Private sLastVal As String

Sub LoadInterface()
      Dim snLeft!, snTop!
      Dim iAddH%, iAddY%
      Dim iLin%, i%

  For i = 1 To 80
    If (i Mod 9) = 0 Then
      iLin = iLin + 1
    End If
   
    Call Load(txtNum(i))
   
    With txtNum(i)
      If (i Mod 3) = 0 Then
        iAddH = (10 * (i Mod 9))
      End If
     
      If (iLin Mod 3) = 0 Then
        iAddY = (10 * (iLin Mod 9))
      End If
     
      snLeft = (.Width * (i Mod 9)) + iAddH
      snTop = iLin * .Height + iAddY
     
      Call .Move(snLeft, snTop)
     
      .Visible = True
    End With
  Next
 
  Width = txtNum(0).Width * 9 + iAddH
  Height = Width
End Sub

Function RightVal(ByVal Col As Integer, ByVal Lin As Integer, ByVal Index As Integer, ByVal Value As Integer) As Boolean
          Dim iIndex%, i%
          Dim iSelIndex%
          Dim iVal%

  iIndex = Index
 
  If (iIndex Mod 9) > 0 Then
    Do While ((iIndex Mod 9) <> 0)
      iIndex = iIndex - 1
    Loop
  End If
 
  For i = iIndex To iIndex + 8
    If txtNum(i) <> vbNullString Then
      If (Val(txtNum(i)) = Value) And (i <> Index) Then
        Exit Function
      End If
    End If
  Next
 
  For i = 0 To 8
    iSelIndex = (i * 9) + Col
   
    If txtNum(iSelIndex) <> vbNullString Then
      If Val(txtNum(iSelIndex)) = Value And (iSelIndex <> Index) Then
        Exit Function
      End If
    End If
  Next
 
  RightVal = True
End Function

Sub HighlightLin(ByVal Col As Integer, ByVal Lin As Integer, ByVal Index As Integer)
          Dim iIndex%, i%
          Dim iSelIndex%
          Dim iVal%

  iIndex = Index
 
  If (iIndex Mod 9) > 0 Then
    Do While ((iIndex Mod 9) <> 0)
      iIndex = iIndex - 1
    Loop
  End If
 
  For i = 0 To 80
    txtNum(i).BackColor = vbWindowBackground
  Next
 
  For i = iIndex To iIndex + 8
    txtNum(i).BackColor = vbCyan
  Next
 
  For i = 0 To 8
    iSelIndex = (i * 9) + Col
    txtNum(iSelIndex).BackColor = vbCyan
  Next
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  If KeyCode = vbKeyEscape Then End
End Sub

Private Sub Form_Load()
  txtNum(0) = vbNullString
  Call txtNum(0).Move(0, 0, 360, 360)
  BackColor = 0
 
  Call LoadInterface
End Sub

Private Sub txtNum_GotFocus(Index As Integer)
  txtNum(Index).SelStart = 0
  txtNum(Index).SelLength = Len(txtNum(Index))
 
  iCurIndex = Index
  iCurCol = (iCurIndex Mod 9)
  iCurLin = (iCurIndex \ 9)
 
  Call HighlightLin(iCurCol, iCurLin, iCurIndex)
 
  sLastVal = txtNum(Index)
End Sub

Private Sub txtNum_KeyDown(Index As Integer, KeyCode As Integer, Shift As Integer)
  On Error Resume Next
 
  Select Case KeyCode
    Case vbKeyUp:     Call txtNum(Index - 9).SetFocus
    Case vbKeyDown:   Call txtNum(Index + 9).SetFocus
    Case vbKeyLeft:   Call txtNum(Index - 1).SetFocus
    Case vbKeyRight:  Call txtNum(Index + 1).SetFocus
  End Select
End Sub

Private Sub txtNum_LostFocus(Index As Integer)
        Dim i%
       
  If txtNum(Index) = vbNullString Then Exit Sub
 
  iCurCol = (iCurIndex Mod 9)
  iCurLin = (iCurIndex \ 9)
 
  If Not RightVal(iCurCol, iCurLin, iCurIndex, Val(txtNum(Index))) Then
    Call MsgBox("El número ingresado no es correcto", vbExclamation)
   
    txtNum(Index) = sLastVal
  Else
    For i = 0 To 80
      If txtNum(i) = vbNullString Then Exit Sub
    Next
   
    Call MsgBox("Felicitaciones, ganaste!!", vbExclamation)
    Call Clipboard.SetData(Image, vbCFBitmap)
  End If
End Sub


Otra cosa, no se necesita nada de IA, esto es lógica xD, ya dejen de decir pendejadas, si no saben cómo hacer algo no inventen ni respondan para aumentar el nº de post.

Cualquier duda consulte a su médico porque en este foro no soy bienvenido xD.

Saludos.

Pseudoroot

Slasher-K, es lamentable que no seas bienvenido. eso va en contra de todos nosotros que pretendemos aprender Visual Basic..
www.g e d z a c.com

www.espavirus.com/foro

BenRu

Ese creo que no es el verdadero slasher keeper, se registro antes de que se "fuera"

Chief

BenRu , ese es el verdadero Slasher-k, y me dijo que te dijera esto :

Citardecile que soy yo y que digo que aprenda a programar, o por lo menos a diferenciar un algoritmo simple de IA

eso, es cita de Slasher-k.


Salu2!
sr. oscuro