Jump to content

Recommended Posts

Posted

Yeah, I know it's been done before but this is my attempt at the game.

The puzzles are pretty easy cause I didn't bother looking up a proper algorithm to determine which clues to keep. I was going to fix it after finishing the UI but lost interest and hit the pub instead :graduated:

anyway here is some code,

Matt

#include <guibutton.au3>
#include <guiconstants.au3>
GUICreate("", 510, 360)
GUISetState()
Global $Buttons[9][9], $Game, $Work[9][9], $mode[9][9], $focus[2]
Local $x, $y
For $i = 0 To 80
 $x = Int($i / 9)
 $y = Mod($i, 9)
 $mode[$x][$y] = "0              "
 If IsInt($x / 3) And IsInt($y / 3) Then GUICtrlCreateGraphic($x * 40, $y * 40, 120, 120, 0x00800000)
 $Buttons[$x][$y] = GUICtrlCreateButton("", $x * 40 + 1, $y * 40 + 1, 38, 38, 0x01)
 GUICtrlSetFont($Buttons[$x][$y], 20, -1, -1, "Courier New")
Next
Local $NewBoard = GUICtrlCreateButton("New Game {F5}", 380, 20, 110, 20)
GUICtrlCreateLabel("Arrows" & @TAB & "Move" & @CRLF & @CRLF & "1 - 9" & @TAB & "Enter number" & @CRLF & @CRLF & "0, Del" & @TAB & "Clear number" & @CRLF & @CRLF & _
 "Space" & @TAB & "Add note" & @CRLF & @CRLF _
, 380, 250, 110, 100)
Local $NavU, $NavD, $NavL, $NavR
$NavU = GUICtrlCreateDummy()
$NavD = GUICtrlCreateDummy()
$NavL = GUICtrlCreateDummy()
$NavR = GUICtrlCreateDummy()
Local $accel[17][2]
$accel[0][0] = "{f5}"
$accel[0][1] = $NewBoard
$accel[1][0] = "{left}"
$accel[1][1] = $NavL
$accel[2][0] = "{right}"
$accel[2][1] = $NavR
$accel[3][0] = "{up}"
$accel[3][1] = $NavU
$accel[4][0] = "{down}"
$accel[4][1] = $NavD
Global $NumDummies[10]
For $i = 0 To 9
 $NumDummies[$i] = GUICtrlCreateDummy()
 $accel[$i + 5][0] = String($i)
 $accel[$i + 5][1] = $NumDummies[$i]
Next
$accel[15][0] = "{bs}"
$accel[15][1] = $NumDummies[0]
$accel[16][0] = "{DEL}"
$accel[16][1] = $NumDummies[0]
GUISetAccelerators($accel)
Local $Game = _NewBoard()
_RmvNums()
while 1
 $Msg = GUIGetMsg()
 Switch $Msg
  Case -3
   exit
  Case $NewBoard
   $Game = _NewBoard()
   _RmvNums()
  Case $NavU
   _Nav("U")
  Case $NavD
   _Nav("D")
  Case $NavL
   _Nav("L")
  Case $NavR
   _Nav("R")
  Case $Buttons[0][0] To $Buttons[8][8]
   _Flip($Msg)
  Case $NumDummies[0] To $NumDummies[9]
   _Num($Msg)
 EndSwitch
WEnd

Func _NewBoard()
 Local $Array[9][9], $redo = 0
 Local $Numbers[9] = [1,2,3,4,5,6,7,8,9]
 Local $rnd
 Local $errorcnt
 For $x = 0 To 8
  For $y = 0 To 8
   GUICtrlSetColor($Buttons[$x][$y], 0)
   GUICtrlSetBkColor($buttons[$x][$y], 0xEEEEEE)
   $Work[$x][$y] = ""
   $mode[$x][$y] = "0                "
   For $i = 0 To $x - 1
    If $Array[$i][$y] Then $Numbers[$Array[$i][$y] - 1] = 0
   Next
   For $i = 0 To $y - 1
    If $Array[$x][$i] Then $Numbers[$Array[$x][$i] - 1] = 0
   Next
   For $i = Int($x / 3) * 3 To Int($x / 3) * 3 + 2
    For $j = Int($y / 3) * 3 To Int($y / 3) * 3 + 2
     If $i = $x And $j = $y Then
      ExitLoop 2
     EndIf
     If $Array[$i][$j] Then $Numbers[$Array[$i][$j] - 1] = 0
    Next
   Next
   $rnd = ""
   For $i = 0 To 8
    If $Numbers[$i] Then
     $rnd &= $Numbers[$i]
    EndIf
    $Numbers[$i] = $i + 1
   Next
   If $rnd Then
    $Array[$x][$y] = StringMid($rnd, Random(1, StringLen($rnd), 1), 1)
    If Not $Array[$x][$y] Then $Array[$x][$y] = $rnd
    GUICtrlSetData($Buttons[$x][$y], $Array[$x][$y])
   Else
    $errorcnt += 1
    If $errorcnt = 50 Then Return _NewBoard()
    $redo = Random(0, $y - 1, 1)
    If $Array[$x][$redo] Then
     $Numbers[$Array[$x][$redo] - 1] = 0
     For $i = $redo To $y
      $Array[$x][$i] = ""
      GUICtrlSetData($Buttons[$x][$i], $Array[$x][$i])
     Next
     $y = $redo -1
    Else
     Return _NewBoard()
    EndIf
   EndIf
  Next
 Next
 Return $Array
EndFunc
func _RmvNums()
 $Work = $Game
 Local $x, $y, $removed
 For $x = 0 To 8
  For $y = 0 To 8
   If $work[$x][$y] Then GUICtrlSetState($buttons[$x][$y], $GUI_ENABLE)
  Next
 Next
 For $x = 0 To 8
  For $y = 0 To 8
   If Not $work[$x][$y] Then ContinueLoop
   If _Test($work, $x, $y, 8) Then
    $work[$x][$y] = ""
    GUICtrlSetData($Buttons[$x][$y], "")
    $removed += 1
   EndIf
  Next
 Next
 For $x = 0 To 8
  For $y = 0 To 8
   If Not $work[$x][$y] Then ContinueLoop
   If _Test($work, $x, $y, 10) Then
    $work[$x][$y] = ""
    GUICtrlSetData($Buttons[$x][$y], "")
    $removed += 1
   EndIf
  Next
 Next
 GUICtrlSetState($Buttons[0][0], $GUI_FOCUS)
 _GUICtrlButton_SetFocus(GUICtrlGetHandle($Buttons[0][0]))
EndFunc
func _Nav($direction)
 Local $x, $y
 For $x = 0 To 8
  For $y = 0 To 8
   If _GUICtrlButton_GetFocus(GUICtrlGetHandle($Buttons[$x][$y])) Then
    If $direction = "U" Then
     $y -= 1
    ElseIf $direction = "D" Then
     $y += 1
    ElseIf $direction = "L" Then
     $x -= 1
    ElseIf $direction = "R" Then
     $x += 1
    EndIf
    If $y = -1 Then $y = 8
    If $y = 9 Then $y = 0
    If $x = -1 Then $x = 8
    If $x = 9 Then $x = 0
    While BitAND(GUICtrlGetState($Buttons[$x][$y]), $GUI_DISABLE)
     If $direction = "U" Then
      $y -= 1
     ElseIf $direction = "D" Then
      $y += 1
     ElseIf $direction = "L" Then
      $x -= 1
     ElseIf $direction = "R" Then
      $x += 1
     EndIf
     If $y = -1 Then $y = 8
     If $y = 9 Then $y = 0
     If $x = -1 Then $x = 8
     If $x = 9 Then $x = 0
    Wend
    GUICtrlSetState($Buttons[$x][$y], $GUI_FOCUS)
    _GUICtrlButton_SetFocus(GUICtrlGetHandle($Buttons[$x][$y]))
    $focus[0] = $x
    $focus[1] = $y
    Return
   EndIf
  Next
 Next
EndFunc
func _Num($num)
 For $i = 0 To 9
  If $num = $NumDummies[$i] Then $num = $i
 Next
 If Not $num Then $num = ""
 Local $x, $y
 For $x = 0 To 8
  For $y = 0 To 8
   If _GUICtrlButton_GetFocus(GUICtrlGetHandle($Buttons[$x][$y])) Then
    If StringLeft($mode[$x][$y], 1) = "0" Then
     If $Game[$x][$y] = String($num) Then
      $Work[$x][$y] = String($num)
      GUICtrlSetColor($Buttons[$x][$y], 0)
     ElseIf Not $Game[$x][$y] Then
      GUICtrlSetStyle($Buttons[$x][$y], 0)
     Else
      If $Work[$x][$y] Then Return
      GUICtrlSetColor($Buttons[$x][$y], 0xFF0000)
     EndIf
     GUICtrlSetState($Buttons[$x][$y], $GUI_FOCUS)
     _GUICtrlButton_SetFocus(GUICtrlGetHandle($Buttons[$x][$y]))
     $focus[0] = $x
     $focus[1] = $y
     GUICtrlSetData($Buttons[$x][$y], String($num))
     Return _CheckWin()
    Else
     If StringInStr(StringTrimLeft($mode[$x][$y], 1), $num) Then
      $mode[$x][$y] = StringLeft($mode[$x][$y], 1) & StringReplace(StringTrimLeft($mode[$x][$y], 1), String($num), " ")
     Else
      $mode[$x][$y] = StringLeft($mode[$x][$y], $num * 2 - 1) & $num & StringTrimLeft($mode[$x][$y], $num * 2)
     EndIf
     If $num = 0 Then $mode[$x][$y] = "1                 "
     Return GUICtrlSetData($Buttons[$x][$y], StringTrimLeft($mode[$x][$y], 1))
    EndIf
   EndIf
  Next
 Next
EndFunc
Func _Test($Array, $x, $y, $spreadLimit = 9)
 Local $Numbers[9] = [1,2,3,4,5,6,7,8,9], $Possibs
 local $spread
 For $i = 0 To 8
  If $Array[$i][$y] And $i <> $x Then $Numbers[$Array[$i][$y] - 1] = 0
 Next
 For $i = 0 To 8
  If $Array[$x][$i] And $i <> $y Then $Numbers[$Array[$x][$i] - 1] = 0
 Next
 For $i = Int($x / 3) * 3 To Int($x / 3) * 3 + 2
  For $j = Int($y / 3) * 3 To Int($y / 3) * 3 + 2
   If $i <> $x And $j <> $y Then
    If $Array[$i][$j] Then $Numbers[$Array[$i][$j] - 1] = 0
   EndIf
   If Not $Array[$i][$j] Then $spread += 1
   If $spread < 9 Then
    If Random(0, 8) > $spreadLimit - 1 Then Return 0
   EndIf
  Next
 Next
 $Possibs = ""
 For $i = 0 To 8
  If $Numbers[$i] Then
   $Possibs &= $Numbers[$i]
  EndIf
  $Numbers[$i] = $i + 1
 Next
 If StringLen($Possibs) = 1 Then Return $Possibs
EndFunc
Func _Flip($MSG)
 Local $x, $y
 For $x = 0 To 8
  For $y = 0 To 8
   If $MSG = $Buttons[$x][$y] Then ExitLoop 2
  Next
 Next
 If $focus[0] <> $x Or $focus[1] <> $y Then
  $focus[0] = $x
  $focus[1] = $y
  Return
 EndIf
 If StringLeft($mode[$x][$y], 1) = "0" Then
  If $work[$x][$y] Then Return
  $mode[$x][$y] = "1" & StringTrimLeft($mode[$x][$y], 1)
  GUICtrlSetFont($Buttons[$x][$y], 6, -1, -1, "Courier New")
  GUICtrlSetData($Buttons[$x][$y], StringTrimLeft($mode[$x][$y], 1))
  GUICtrlSetStyle($Buttons[$x][$y], 0x2000)
 Else
  $mode[$x][$y] = "0" & StringTrimLeft($mode[$x][$y], 1)
  GUICtrlSetFont($Buttons[$x][$y], 20, -1, -1, "Courier New")
  GUICtrlSetData($Buttons[$x][$y], $work[$x][$y])
  GUICtrlSetStyle($Buttons[$x][$y], 0x300)
  GUICtrlSetBkColor($buttons[$x][$y], 0xEEEEEE)
 EndIf
 $focus[0] = $x
 $focus[1] = $y
 GUICtrlSetState($Buttons[$x][$y], $GUI_FOCUS)
 _GUICtrlButton_SetFocus(GUICtrlGetHandle($Buttons[$x][$y]))
EndFunc
Func _CheckWin()
 For $x = 0 To 8
  For $y = 0 To 8
   If Not $work[$x][$y] Then Return
  Next
 Next
 Local $x, $y, $Words[6] = ["One Up! ", "Winner! ", "Solved! ", "Hooray! ", "You Won ", " ~ :) ~ "], $rnd
 Local $word = $Words[Random(0,5,1)]
 For $i = 0 To 8
  For $j = 0 To 8
   If Not $i And not $j Then $rnd = Random(0,1, 1)
   If $rnd Then
    $x = $i
    $y = $j
   Else
    $x = $j
    $y = $i
   EndIf
   GUICtrlSetData($Buttons[$x][$y], StringMid($word, Mod($x + $y, 8) + 1, 1))
   GUICtrlSetState($buttons[$y][$x], $GUI_ENABLE)
   GUICtrlSetColor($Buttons[$y][$x], Random(0, 0xffffff, 1))
   GUICtrlSetBkColor($Buttons[$x][$y], 0xffffff)
   Sleep(25)
  Next
 Next
 $Game = _NewBoard()
 _RmvNums()
EndFunc
  • 2 weeks later...
Posted (edited)

Really? It was supposed to be intuitive... maybe I was off the mark with this one.

Edit: ahh.. an oversight. Only the numbers across the top work (my laptop doesn't have a numpad).

It can easilly be fixed but in the end there is probably no point.

Edited by MattyD

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...