Jump to content

Nibbles (Long long snake) game


james3mg
 Share

Recommended Posts

This is my first take at recreating the game called Nibbles available in Ubuntu. I remember an older version of the game where there weren't any computer competitors, so for this first draft, I'm staying more in that vein. Ergo, I changed the name to the oh-so-creative "Long long snake"

The goal of the game is to eat as many 'treats' as possible (the treats are your score, not the length of the snake). The challenge is that your tail (which you may not run into) grows every time you get a treat (and grows even more if you don't get a treat in time). Also, you move faster as time goes on. Use the keyboard arrows to move around, and don't run into the walls!

In the next version, I hope to have level advancement when you eat a certain number of treats; later levels will have computer-controlled snakes as well. I'll use A* to help them navigate, if I can manage it, and more difficult AI players would calculate the odds of getting the treat first, and go into a 'holding pattern' if it's unlikely they'll get there first...that would make it harder than everyone blindly trying to get the treat first, because they'll have a better chance of being closer to the treat than you. It will also be an easy matter to add other barriers to the playing field...expect to see that as well.edit:now included!

I've powered the collision-detection using the #included SQLite functions- it works quite well! I've also included a function that will create the 'treat' picture in the same directory as the script to display...that way I didn't have to mess with any FileInstall functions when I post just the script. :) Hotkeys are the best way of running this game, but it's got an alternative method (_isPressed) if they're not available. Also, the script unregisters the hotkeys and pauses when the window loses focus. That way, it "plays nice with others", at least as best as I'm able to make it do.

It's pretty rough- when you die, for instance, it shows you a bit of debugging information. I'll polish this up a bit as time goes on. For now, just give it a shot and post some feedback, if you would! Thanks! :D

#include <Misc.au3>
#include <SQLite.dll.au3>
#include <SQLite.au3>

Global $OrigSpeed=InputBox("Speed","Enter speed"&@CRLF&"(15-200 recommended)",30)
If @error OR NOT $OrigSpeed>0 Then Exit
Global $Speed=1/$OrigSpeed*1000
Global $Size=3, $Grow=0, $GrowAmt=4, $NumEaten=0, $Paused=0, $GUIWidth=640, $GUIHeight=480, $WinTitle="Long long snake", $TreatSize=12, $SinceTurn=1
Global $Direction=0, $PlayerCoord[2]=[($Size+1)*Round(.5*(1/($Size+1))*$GUIWidth),($Size+1)*Round(.5*(1/($Size+1))*$GUIHeight)], $WallIDs[1], $QueueKeystroke="", $NewQueueKeystroke=""
Global $SpeedTimer=TimerInit(), $DifficultyTimer=TimerInit(), $TreatTimer=TimerInit()
Global $aResult, $iRows, $iCols
Global $HotkeyMode=1

_SQLite_Startup()
_SQLite_Open()
_SQLite_Exec(-1,"Create table positions (lbl,num,x,y);")
For $x=0 To $GUIWidth Step $Size+1
    _SQLite_Exec(-1,"Insert into positions values ('the edge','',"&$x&",-"&$Size+1&"); Insert into positions values('the edge','',"&$x&","&$GUIHeight+1&");")
Next
For $y=0 To $GUIHeight Step $Size+1
    _SQLite_Exec(-1,"Insert into positions values ('the edge','',-"&$Size+1&","&$y&"); Insert into positions values('the edge','',"&$GUIWidth+1&","&$y&");")
Next

$NibblesGUI=GUICreate($WinTitle,$GUIWidth,$GUIHeight)
GUIRegisterMsg(0x0086,"WinActivated")
CreatePlayer()

$TreatPic=GUICtrlCreatePic(@ScriptDir&"\CherryTreat.bmp",0,0,$TreatSize,$TreatSize)
If $TreatPic=0 Then 
    MakeTreatPic()
    $TreatPic=GUICtrlCreatePic(@ScriptDir&"\CherryTreat.bmp",0,0,$TreatSize,$TreatSize)
EndIf
If $TreatPic=0 Then $TreatPic=GUICtrlCreateLabel("",0,0,$TreatSize,$TreatSize)
GUICtrlSetBkColor($TreatPic,0xFF0000)
SpawnTreat()

If HotKeySet("{Right}","Hotkeys")<>1 Then $HotkeyMode=0
If HotKeySet("{Up}","Hotkeys")<>1 Then $HotkeyMode=0
If HotKeySet("{Left}","Hotkeys")<>1 Then $HotkeyMode=0
If HotKeySet("{Down}","Hotkeys")<>1 Then $HotkeyMode=0

If $HotkeyMode=0 Then
    HotKeySet("{Right}")
    HotKeySet("{Up}")
    HotKeySet("{Left}")
    HotKeySet("{Down}")
    TrayTip("Warning","Another program has registered the arrow keys as hotkeys- the game may not be as responsive",10)
EndIf

GUISetState()
While 1
    While $Paused
        sleep(10)
    WEnd
    If GUIGetMsg()=-3 Then Exit
    If $HotkeyMode=0 Then
        If $QueueKeystroke<>"" Then Send(StringLeft($QueueKeystroke,StringLen($QueueKeystroke)-1)&" down}")
        $NewQueueKeystroke=""
        If _IsPressed(27) AND $Direction <> 2 Then
            If $SinceTurn>0 Then
                $Direction=0;right
                $SinceTurn=0
            Else
                $NewQueueKeystroke="{Right}"
            EndIf
        EndIf
        If _IsPressed(26) AND $Direction <> 3 Then
            If $SinceTurn>0 Then
                $Direction=1;up
                $SinceTurn=0
            Else
                $NewQueueKeystroke="{Up}"
            EndIf
        EndIf
        If _IsPressed(25) AND $Direction <> 0 Then
            If $SinceTurn>0 Then
                $Direction=2;left
                $SinceTurn=0
            Else
                $NewQueueKeystroke="{Left}"
            EndIf
        EndIf
        If _IsPressed(28) AND $Direction <> 1 Then
            If $SinceTurn>0 Then
                $Direction=3;down
                $SinceTurn=0
            Else
                $NewQueueKeystroke="{Down}"
            EndIf
        EndIf
        If $QueueKeystroke<>"" Then Send(StringLeft($QueueKeystroke,StringLen($QueueKeystroke)-1)&" up}")
        $QueueKeystroke=$NewQueueKeystroke
    Else
        If $QueueKeystroke<>"" Then Send($QueueKeystroke)
    EndIf
    If TimerDiff($DifficultyTimer) > 30000 Then
        $DifficultyTimer=TimerInit()
        $Speed=Round($Speed*.8)
    EndIf
    If TimerDiff($TreatTimer) > $Speed*500 Then
        SpawnTreat()
        $Grow=1
        $GrowAmt=35
    EndIf
    If TimerDiff($SpeedTimer) < $Speed Then ContinueLoop
    $SinceTurn+=1
    Local $FoundBarrier=0
    Switch $Direction
        Case 0
            _SQLite_GetTable2d(-1,"Select * from positions where (x BETWEEN "&$PlayerCoord[0]+1&" AND "&$PlayerCoord[0]+$Size*2+1&") and (y BETWEEN "&$PlayerCoord[1]-$Size&" AND "&$PlayerCoord[1]+$Size&") and NOT lbl='treat';",$aResult,$iRows,$iCols)
        Case 2
            _SQLite_GetTable2d(-1,"Select * from positions where x BETWEEN "&$PlayerCoord[0]-$Size*2-1&" AND "&$PlayerCoord[0]-1&" and y BETWEEN "&$PlayerCoord[1]-$Size&" AND "&$PlayerCoord[1]+$Size&" and NOT lbl='treat';",$aResult,$iRows,$iCols)
        Case 1
            _SQLite_GetTable2d(-1,"Select * from positions where (x BETWEEN "&$PlayerCoord[0]-$Size&" AND "&$PlayerCoord[0]+$Size&") and (y BETWEEN "&$PlayerCoord[1]-$Size*2-1&" AND "&$PlayerCoord[1]-1&") and NOT lbl='treat';",$aResult,$iRows,$iCols)
        Case 3
            _SQLite_GetTable2d(-1,"Select * from positions where (x BETWEEN "&$PlayerCoord[0]-$Size&" AND "&$PlayerCoord[0]+$Size&") and (y BETWEEN "&$PlayerCoord[1]+1&" AND "&$PlayerCoord[1]+$Size*2+1&") and NOT lbl='treat';",$aResult,$iRows,$iCols)
    EndSwitch
    If $iRows>0 Then Died()
    Local $FoundTreat=0
    Switch $Direction
        Case 0
            _SQLite_GetTable2d(-1,"Select * from positions where (x BETWEEN "&$PlayerCoord[0]+1&" AND "&$PlayerCoord[0]+$Size*2+1&") and (y BETWEEN "&$PlayerCoord[1]-$Size&" AND "&$PlayerCoord[1]+$Size&") and lbl='treat';",$aResult,$iRows,$iCols)
        Case 2
            _SQLite_GetTable2d(-1,"Select * from positions where x BETWEEN "&$PlayerCoord[0]-$Size*2-1&" AND "&$PlayerCoord[0]-1&" and y BETWEEN "&$PlayerCoord[1]-$Size&" AND "&$PlayerCoord[1]+$Size&" and lbl='treat';",$aResult,$iRows,$iCols)
        Case 1
            _SQLite_GetTable2d(-1,"Select * from positions where (x BETWEEN "&$PlayerCoord[0]-$Size&" AND "&$PlayerCoord[0]+$Size&") and (y BETWEEN "&$PlayerCoord[1]-$Size*2-1&" AND "&$PlayerCoord[1]-1&") and lbl='treat';",$aResult,$iRows,$iCols)
        Case 3
            _SQLite_GetTable2d(-1,"Select * from positions where (x BETWEEN "&$PlayerCoord[0]-$Size&" AND "&$PlayerCoord[0]+$Size&") and (y BETWEEN "&$PlayerCoord[1]+1&" AND "&$PlayerCoord[1]+$Size*2+1&") and lbl='treat';",$aResult,$iRows,$iCols)
    EndSwitch
    If $iRows>0 Then
        $Grow=1
        $GrowAmt=Random(5,20,1)
        SpawnTreat()
        $NumEaten+=1
        If Mod($NumEaten,5)=0 Then AddRandBarrier()
    EndIf
    $SpeedTimer=TimerInit()
    _SQLite_Exec(-1,"UPDATE positions set num=num+1 WHERE lbl='Player 1';")
    If NOT $Grow Then
        _SQLite_Exec(-1,"DELETE from positions WHERE lbl='Player 1' AND num="&UBound($Player)+1&";")
    ElseIf $Grow <= $GrowAmt Then
        _SQLite_GetTable2d(-1,"SELECT * from positions WHERE lbl='Player 1' AND num="&UBound($Player)+1&";",$aResult,$iRows,$iCols)
        ReDim $Player[UBound($Player)+1]
        $Player[UBound($Player)-1]=GUICtrlCreateLabel("",$aResult[1][2],$aResult[1][3],$Size,$Size)
        GUICtrlSetBkColor(-1,0x0000FF)
        _SQLite_Exec(-1,"INSERT into positions VALUES ('Player 1',"&UBound($Player)&","&$aResult[1][2]&","&$aResult[1][3]&");")
        $Grow+=1
        WinSetTitle($NibblesGUI,"",$WinTitle&" (Length: "&UBound($Player)&", Treats eaten: "&$NumEaten&")")
    Else
        _SQLite_Exec(-1,"DELETE from positions WHERE lbl='Player 1' AND num="&UBound($Player)+1&";")
        $Grow=0
    EndIf
    Switch $Direction
        Case 0
            $PlayerCoord[0]+=$Size+1
        Case 1
            $PlayerCoord[1]-=$Size+1
        Case 2
            $PlayerCoord[0]-=$Size+1
        Case 3
            $PlayerCoord[1]+=$Size+1
    EndSwitch
    _SQLite_Exec(-1,"INSERT into positions VALUES('Player 1',1,"&$PlayerCoord[0]&","&$PlayerCoord[1]&");")
    $temp=$Player[UBound($Player)-1]
    For $i=UBound($Player)-1 To 1 Step -1
        $Player[$i]=$Player[$i-1]
    Next
    $Player[0]=$temp
    GUICtrlSetPos($Player[0],$PlayerCoord[0],$PlayerCoord[1])
WEnd

Func CreatePlayer()
    Global $Player[4]
    $PlayerCoord[0]=($Size+1)*Round(.5*(1/($Size+1))*$GUIWidth)
    $PlayerCoord[1]=($Size+1)*Round(.5*(1/($Size+1))*$GUIHeight)
    $Direction=0
    For $i=0 To 3
        $Player[$i]=GUICtrlCreateLabel("",$PlayerCoord[0]-(($Size+1)*$i),$PlayerCoord[1],$Size,$Size)
        GUICtrlSetBkColor(-1,0x0000FF)
        _SQLite_Exec(-1,"Insert into positions values ('Player 1',"&$i+1&","&$PlayerCoord[0]-(($Size+1)*$i)&","&$PlayerCoord[1]&");")
    Next
    WinSetTitle($NibblesGUI,"",$WinTitle&" (Length: 4, Treats eaten: 0)")
EndFunc

Func Hotkeys()
    If $SinceTurn=0 Then
        $QueueKeystroke=@HotKeyPressed
        Return
    EndIf
    If @HotKeyPressed="{Right}" AND $Direction <> 2 Then $Direction=0
    If @HotKeyPressed="{Up}" AND $Direction <> 3 Then $Direction=1
    If @HotKeyPressed="{Left}" AND $Direction <> 0 Then $Direction=2
    If @HotKeyPressed="{Down}" AND $Direction <> 1 Then $Direction=3
    $QueueKeystroke=""
    $SinceTurn=0
EndFunc

Func Died()
    MsgBox(0,"Score "&UBound($Player),"Oops! You hit "&$aResult[1][0]&"!"&@CRLF&"Barrier: "&$aResult[1][2]&","&$aResult[1][3]&@CRLF&"You: "&$PlayerCoord[0]&","&$PlayerCoord[1])
    _SQLite_Exec(-1,"Delete from positions where lbl='Player 1';")
    For $i=0 To UBound($Player)-1
        GUICtrlDelete($Player[$i])
    Next
    $Grow=0
    $Speed=1/$OrigSpeed*1000
    $NumEaten=0
    For $i=0 To UBound($WallIDs)-1
        GUICtrlDelete($WallIDs[$i])
    Next
    ReDim $WallIDs[1]
    $WallIDs[0]=""
    _SQLite_Exec(-1,"Delete from positions where lbl='a wall';")
    $TreatTimer=TimerInit()
    CreatePlayer()
EndFunc

Func SpawnTreat()
    $TreatTimer=TimerInit()
    _SQLite_Exec(-1,"Delete from positions where lbl='treat';")
    Do
        Local $RandX=Random(0,(1/($Size+1))*($GUIWidth-12),1)*($Size+1), $RandY=Random(0,(1/($Size+1))*($GUIHeight-12),1)*($Size+1)
        _SQLite_GetTable2d(-1,"Select * from positions where x between "&$RandX-$Size&" and "&$RandX+$TreatSize+1&" AND y between "&$RandY-$Size&" and "&$RandY+$TreatSize+1&";",$aResult,$iRows,$iCols)
    Until $iRows=0
    For $y=0 To Round($TreatSize/$Size)-1
        For $x=0 To Round($TreatSize/$Size)-1
            _SQLite_Exec(-1,"INSERT into positions Values ('treat','1',"&$RandX+($x*($Size+1))&","&$RandY+($y*($Size+1))&");")
        Next
    Next
    GUICtrlSetPos($TreatPic,$RandX,$RandY)
EndFunc

Func AddRandBarrier()
    Local $BarrierDir=Random(0,1,1)
    If $BarrierDir=0 Then
        $BarrierLen=Random((.2*$GUIWidth)/($Size+1),(.67*$GUIWidth)/($Size+1),1)*($Size+1)
        Do
            Local $BarrierX=Random(0,($GUIWidth/($Size+1))*.8,1)*($Size+1), $BarrierY=Random(0,($GUIHeight/($Size+1))*.8,1)*($Size+1)
            _SQLite_GetTable2d(-1,"Select * from positions where x between "&$BarrierX&" AND "&$BarrierX+$BarrierLen&" and y between "&$BarrierY-$Size&" AND "&$BarrierY+$Size+1&" and (lbl like 'Treat' or lbl like 'Player %');",$aResult,$iRows,$iCols)
        Until $iRows=0
        If $WallIDs[UBound($WallIDs)-1]<> "" Then ReDim $WallIDs[UBound($WallIDs)+1]
        $WallIDs[UBound($WallIDs)-1] = GUICtrlCreateLabel("",$BarrierX,$BarrierY,$BarrierLen,$Size)
        GUICtrlSetBkColor(-1,0x999999)
        For $i=0 To $BarrierLen Step $Size+1
            _SQLite_Exec(-1,"Insert into positions values ('a wall','',"&$BarrierX+$i&","&$BarrierY&");")
        Next
    Else
        $BarrierLen=Random((.2*$GUIHeight)/($Size+1),(.67*$GUIHeight)/($Size+1),1)*($Size+1)
        Do
            Local $BarrierX=Random(0,($GUIWidth/($Size+1))*.8,1)*($Size+1), $BarrierY=Random(0,($GUIHeight/($Size+1))*.8,1)*($Size+1)
            _SQLite_GetTable2d(-1,"Select * from positions where x between "&$BarrierX-$Size&" AND "&$BarrierX+$Size+1&" and y between "&$BarrierY&" AND "&$BarrierY+$BarrierLen&" and (lbl like 'Treat' or lbl like 'Player %');",$aResult,$iRows,$iCols)
        Until $iRows=0
        If $WallIDs[UBound($WallIDs)-1]<> "" Then ReDim $WallIDs[UBound($WallIDs)+1]
        $WallIDs[UBound($WallIDs)-1] = GUICtrlCreateLabel("",$BarrierX,$BarrierY,$Size,$BarrierLen)
        GUICtrlSetBkColor(-1,0x999999)
        For $i=0 To $BarrierLen-$Size Step $Size+1
            _SQLite_Exec(-1,"Insert into positions values ('a wall','',"&$BarrierX&","&$BarrierY+$i&");")
        Next
    EndIf
EndFunc

Func MakeTreatPic()
    Local $TreatPicFile=FileOpen(@ScriptDir&"\CherryTreat.bmp",2)
    If $TreatPicFile=-1 Then Return
    FileWrite($TreatPicFile,Binary("0x424DC60400000000000036040000280000000C0000000C000000010008000000000090000000000000000000000000

0000000000000000000000000080000080000000808000800000008000800080800000C0C0C000C0DCC000F0CAA600002040

0000206000002080000020A0000020C0000020E00000400000004020000040400000406000004080000040A0000040C00000

40E00000600000006020000060400000606000006080000060A0000060C0000060E000008000000080200000804000008060

00008080000080A0000080C0000080E00000A0000000A0200000A0400000A0600000A0800000A0A00000A0C00000A0E00000

C0000000C0200000C0400000C0600000C0800000C0A00000C0C00000C0E00000E0000000E0200000E0400000E0600000E080

0000E0A00000E0C00000E0E00040000000400020004000400040006000400080004000A0004000C0004000E0004020000040

2020004020400040206000402080004020A0004020C0004020E00040400000404020004040400040406000404080004040A0

004040C0004040E00040600000406020004060400040606000406080004060A0004060C0004060E000408000004080200040

80400040806000408080004080A0004080C0004080E00040A0000040A0200040A0400040A0600040A0800040A0A00040A0C0

0040A0E00040C0000040C0200040C0400040C0600040C0800040C0A00040C0C00040C0E00040E0000040E0200040E0400040

E0600040E0800040E0A00040E0C00040E0E00080000000800020008000400080006000800080008000A0008000C0008000E0

0080200000802020008020400080206000802080008020A0008020C0008020E0008040000080402000804040008040600080

4080008040A0008040C0008040E00080600000806020008060400080606000806080008060A0008060C0008060E000808000

00808020008080400080806000808080008080A0008080C0008080E00080A0000080A0200080A0400080A0600080A0800080

A0A00080A0C00080A0E00080C0000080C0200080C0400080C0600080C0800080C0A00080C0C00080C0E00080E0000080E020

0080E0400080E0600080E0800080E0A00080E0C00080E0E000C0000000C0002000C0004000C0006000C0008000C000A000C0

00C000C000E000C0200000C0202000C0204000C0206000C0208000C020A000C020C000C020E000C0400000C0402000C04040

00C0406000C0408000C040A000C040C000C040E000C0600000C0602000C0604000C0606000C0608000C060A000C060C000C0

60E000C0800000C0802000C0804000C0806000C0808000C080A000C080C000C080E000C0A00000C0A02000C0A04000C0A060

00C0A08000C0A0A000C0A0C000C0A0E000C0C00000C0C02000C0C04000C0C06000C0C08000C0C0A000F0FBFF00A4A0A00080

8080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00FFFFFFFFFFFF0B4545010AFFFFFFFFFFFF4B4E

4E4E4645FFFF4D4E46454D4F4F4F4E460B4D4F4F4F4E4E5757574F4E4B4F57574F4F4E5757574F4EFF575757574F4E4D4F5B

4EFFFF54575756564DFFFF21FFFFFFFF544E5529FFFFFF21FFFFFFFFFFFFFFFF21FFFF21FFFFFFFFFFFFFFFFFF21FF1919FF

FFFFFFFFFFFFFFFF215A21FFFFFFFFFFFFFFFFFFFF2102FFFF"))
    FileClose($TreatPicFile)
EndFunc

Func WinActivated($hWndGUI,$MsgID,$WParam,$LParam)
    If $WParam=1 AND $hWndGUI=$NibblesGUI Then
        $Paused=0
        $NewHotkeyMode=1
        If HotKeySet("{Right}","Hotkeys")<>1 Then $NewHotkeyMode=0
        If HotKeySet("{Up}","Hotkeys")<>1 Then $NewHotkeyMode=0
        If HotKeySet("{Left}","Hotkeys")<>1 Then $NewHotkeyMode=0
        If HotKeySet("{Down}","Hotkeys")<>1 Then $NewHotkeyMode=0
        If $NewHotkeyMode=0 Then
            HotKeySet("{Right}")
            HotKeySet("{Up}")
            HotKeySet("{Left}")
            HotKeySet("{Down}")
        EndIf
        If $NewHotkeyMode=1 AND $HotkeyMode=0 Then TrayTip("Hotkey Information","The arrow hotkeys have been released by the other program; the game will run at full responsiveness now",10)
        If $NewHotkeyMode=0 AND $HotkeyMode=1 Then TrayTip("Warning","Another program has stolen the arrow hotkeys while the game was paused; the game will not be as responsive now",10)
        $HotkeyMode=$NewHotkeyMode
    Else
        GUISetState($GUI_SHOW,$hWndGUI)
        $Paused=1
        HotKeySet("{Right}")
        HotKeySet("{Up}")
        HotKeySet("{Left}")
        HotKeySet("{Down}")
    EndIf
EndFunc

Edit: The forum is breaking the binary string instead of wrapping it. When you copy it, hit delete on each of the hex lines so it's on one long line...sorry for the manual process :( Or you can just add a "Return" to the beginning of that function and delete the hex lines entirely and it'll display a red box instead of the picture.

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Well done and Thank you for sharing :)

Game works well.

No biggie, but I do get a scite console warning on start of the game.

+>09:59:58 Starting AutoIt3Wrapper v.1.10.1.7   Environment(Language:0409  Keyboard:00000409  OS:WIN_XP/Service Pack 2  CPU:X86)
>Running AU3Check (1.54.10.0)  from:C:\Program Files\AutoIt3
C:\AutoIt Stuff\bug.au3(118,93) : WARNING: $Player: possibly used before declaration.
        _SQLite_Exec(-1,"DELETE from positions WHERE lbl='Player 1' AND num="&UBound($Player)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\AutoIt Stuff\bug.au3 - 0 error(s), 1 warning(s)
->10:00:00 AU3Check ended.rc:1

Cheers

Link to comment
Share on other sites

Well done and Thank you for sharing :(

Game works well.

No biggie, but I do get a scite console warning on start of the game.

+>09:59:58 Starting AutoIt3Wrapper v.1.10.1.7   Environment(Language:0409  Keyboard:00000409  OS:WIN_XP/Service Pack 2  CPU:X86)
>Running AU3Check (1.54.10.0)  from:C:\Program Files\AutoIt3
C:\AutoIt Stuff\bug.au3(118,93) : WARNING: $Player: possibly used before declaration.
        _SQLite_Exec(-1,"DELETE from positions WHERE lbl='Player 1' AND num="&UBound($Player)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\AutoIt Stuff\bug.au3 - 0 error(s), 1 warning(s)
->10:00:00 AU3Check ended.rc:1

Cheers

I'm aware of that, but thanks. Many of my scripts have similar warnings...I seem to have a habit of defining global variables in functions. The good news is there's no way the var is referred to before the function is called, so it's OK. It's just not 'best coding practice'.

Glad you guys like it :D Hopefully I can live up to my 'grand' dreams of improving it :)

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

I've updated the script in the original post- now every five treats you eat will add a new wall barrier into the playing field.

It also includes a few bug fixes...the most important of which was that the vertical border wasn't a hard barrier all the way to the bottom of the playing field, allowing the player to go off-screen to the left and right near the bottom. Also, the treat will always spawn fully on-screen now.

I'm looking for a better way of doing the sql calls- I should be able to use x<num AND x>num in a single sqlite call instead of looping through several numbers in the script with multiple calls...that will also fix the rare bug of a wall appearing across a player's tail or through the treat.

Thanks for the continued feedback!

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Cool script. The only thing I could see wrong with it would be that treats don't effect your score at all. This would be fine if your length only increased when you ate something, but since it goes automatically, you maybe want to make the treats worth more than just adding barriers. Due to this, you can just try to go as long as possible and avoid treats! =)

"A man who has never gone to school may steal from a freight car; but if he has a university education, he may steal the whole railroad." - Theodore Roosevelt
Link to comment
Share on other sites

I've updated the original script again- it's MUCH more efficient in its SQL calls now, and collision detection is more reliable to boot. The treats will no longer regenerate overlapping your tail, nor will they regenerate spanning a wall. Same goes for walls :(

I've also gone through and removed all the hard-coded numbers I had in the original release (I think :D ) so that, by modifying a few key variables at the top of the script, you can get a custom-sized board, snake and treat (though you'd have to use your own picture if you changed the size of the treat).

I've tested everything in the most rigorously constraints my reflexes could handle: a board of 200x200 and snake size of 6. Everything continues to work as designed and seems to scale admirably. So I'm calling this a pretty stable interim release. I still intend to add AI snakes as well...in fact that's about the only thing on my mental checklist that I haven't addressed, so they'll probably make their debut in the next release (unlikely to be today). :)

Thanks for your comments so far...regarding the issues brought to my attention:

@Homer90001: the 'score' should be the number of treats you've eaten, not the length of the snake. I'll probably eventually just delete the readout showing you how long the snake is entirely. Furthermore, when it grows automatically (after the treat regenerates), it grows much more (twice as much, if I remember correctly) than the maximum it would possibly grow just by eating the treat. So you're punished for avoiding the treat. Does that answer your concern? Edit: Alternately, I could add a line that tells it to add a barrier for every treat you miss, making it significantly harder each time. If I did that, I might kick the frequency of a barrier being added anyway up from every 5 treats to every 10. Would that be better?

@d2addict4: I don't know if you mean 500 treats eaten, or snake length of 500. I assume snake length. Try the new version- it's got a much better collision detection, as I mentioned, and I'm hoping that solves your problem. If it doesn't, let me know and I'll look into it more. However, NOTHING changes as the snake gets longer other than the number of elements in the SQLite table (which isn't supposed to change the speed of its returns). My early versions (before the first one I posted) had each block moving with every increment, so it bogged down quickly as the snake grew. My way of avoiding that is that I only move the end of the tail up to the head position each increment...so no matter how long the snake is, only one block is being moved to move the snake. So I don't think that's the reason for the slowdown. Anyway, I've got far fewer than 1/4 the elements in the table and calls to the database now, so that should help if SQL was in fact the bottleneck.

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Sorry for what amounts to little more than a bump, but I was wondering if there were any outstanding issues with the new version that anybody's found? I'm trying to labor through implementing A* pathfinding (decided to make my own as SQL calls seem to be to be a better method than the extensive use of the array udf, as toady did, masterfully I should add), but I don't want to progress too far if there's any issues with the underlying game.

Thanks for any feedback you can provide! :)

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Sorry for what amounts to little more than a bump, but I was wondering if there were any outstanding issues with the new version that anybody's found? I'm trying to labor through implementing A* pathfinding (decided to make my own as SQL calls seem to be to be a better method than the extensive use of the array udf, as toady did, masterfully I should add), but I don't want to progress too far if there's any issues with the underlying game.

Thanks for any feedback you can provide! :)

Weird shit:

Posted Image

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

Weird shit:

Posted Image

looks right to me...am I missing something?
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

Well, in trying to figure out what monoceres was referring to, I was running a few tests and remembered a few annoying bugs I wanted to squash. So while waiting for his reply, I squashed them :) (updated op)

At some $size s (like 7), the top and left walls were hit prematurely...so that's fixed.

Also, at larger sizes, sometimes the treat would get hit prematurely. Also fixed.

Finally, if you were quicker than the game when changing directions twice, it was possible to double back on yourself and die. That's also been eliminated. The extra keystroke is captured and re-sent once the snake has moved one space, no matter if you're in hotkey or _ispressed mode (not a small feat :( )

Let me know if you find something else!

Edited by james3mg
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...