484 Pages

## Snake Edit

This is a standardish snake game. You eat the food and avoid running into your tail. This includes randomly generated brick things and a wrapped screen.

## Variables Edit

Variables you will need: LSNAKE A B C U V W X Z θ

## Programs Edit

This used three main programs, prgmGSNAKEA (the opening animation), prgmGSNAKE (the actual game), and prgmGSNAKER (the food respawn sequence).

## Opening Animation Edit

The opening animation is a subprogram called at the start of the game.

```ClrHome
Func
FnOff 0,1,2,3,4,5,6,7,8,9
PlotsOff 1,2,3
ClrDraw
CoordOff
GridOff
AxesOff
LabelOff
ExprOff

-62→Ymin
1→ΔX
1→ΔY
36.64→A
0→θ
25→Z
0→X
While fPart(A)>.03 and θ=0
X+1→X
getKey→θ
A+3((Z=26)-(Z=24))-.02(Z=25)→A
Pt-On(iPart(A),-100fPart(A),2)
If X=5
26→Z
If X=11
25→Z
If X=17
24→Z
If  X=23
25→Z
If X=29
26→Z
If X=35
25→Z
End
For(X,0,50)
If θ
50→X
getKey→θ
End
```

### Explanation Edit

```ClrHome
Func
FnOff 0,1,2,3,4,5,6,7,8,9
PlotsOff 1,2,3
ClrDraw
CoordOff
GridOff
AxesOff
LabelOff
ExprOff
```

This section makes sure nothing like graphs or axes show up on the screen so your lovely image isn't interrupted by, say, Y=log(X) tearing across your screen.

```0→Xmin
-62→Ymin
1→ΔX
1→ΔY
```

This section sets the screen so that each pixel has an integer equivalent (0 to 94,-62 to 0).

```36.64→A
0→θ
25→Z
0→X
```

This sets the starting values for the direction the snake travels, where it starts, and user input. The integer part of "A" is the 'X' coordinate, and the decimal the 'Y' coordinate. "Z" is the direction it is traveling (26 = right, 24 = left, 25 = up). "θ" is used for the last key press. "X" is simply a counter.

```While fPart(A)>.03 and θ=0
X+1→X
getKey→θ
A+3((Z=26)-(Z=24))-.02(Z=25)→A
Pt-On(iPart(A),-100fPart(A),2)
```

This part is essentialy my game stripped down to only three movement directions and the display. Instead of writing the animation seperate, I copied part of the actual game and simply timed changing the direction by simulating user input.

```If X=5
26→Z
If X=11
25→Z
If X=17
24→Z
If  X=23
25→Z
If X=29
26→Z
If X=35
25→Z
End
```

This is the part that has the snake change direction after each amount of time passes. This causes the snake to travel in an "S" pattern across the screen.

```For(X,0,50)
If θ
50→X
getKey→θ
End
```

This just pauses it for a moment. At any point the animation is skipped by pressing any key, and it jumps right to the game.

## The Game Edit

```prgmGSNAKEA
Lbl 0
ClrHome
Menu("     SNAKE!     ","PLAY",1,"HELP",2,"EXIT",3     //5 spaces, SNAKE!, 5 spaces
Lbl 3
ClrHome
ClrDraw
Output(1,1,"
Stop
Lbl 2
ClrHome
Output(1,1,"PRESS THE ARROWS TO MOVE. YOU ARE THE SNAKE. YOU MUST EAT THE FOOD TO GAIN POINTS. DO NOT RUN INTO YOUR TAIL OR BRICKS."
Pause
ClrHome
Goto 0
Lbl 1
ClrHome
Func
FnOff 0,1,2,3,4,5,6,7,8,9
PlotsOff 1,2,3
ClrDraw
CoordOff
GridOff
AxesOff
LabelOff
ExprOff
0→Xmin
-62→Ymin
1→ΔX
1→ΔY
{8.02,5.02,2.02}→LSNAKE
8.02→A
32.02→B
0→C
For(U,0,30
3randInt(2,29)-1→V
1-3randInt(2,19→W
Pt-On(V,W,2
Pt-On(V,W
End
Pt-On(8,-2,2
Pt-On(5,-2,2
Pt-On(2,-2,2
Pt-On(iPart(B),-100fPart(B),3
DelVar θ
26→Z
Horizontal 0
Horizontal -61
Vertical 0
Vertical 94
While θ≠23 and θ≠45
getKey→θ
If (θ=24 and Z≠26) or (θ=25 and Z≠34) or (θ=26 and Z≠24) or (θ=34 and Z≠25)
θ→Z
A+3((Z=26 and iPart(A)<92)-(Z-24 and iPart(A)>2))+90((Z=24 and iPart(A)=2)-(Z=26 and iPart(A)=92))+.03((Z=25 and fPart(A)<.59)-(Z=25 and fPart(A)>.02))+.57((Z=25 and fPart(A)=.02)-(Z=34 and fPart(A)=.59))→A
If fPart(C)=0
Pt-Off(iPart(LSNAKE(dim(LSNAKE,-100fPart(LSNAKE(dim(LSNAKE,2
If pxl-Test(100fPart(A)-1,iPart(A)-1)=1
45→θ
Pt-On(iPart(A),-100fPart(A),2
augment({A},LSNAKE)→LSNAKE
dim(LSNAKE)-not(fPart(C))→dim(LSNAKE
C-100-1(fPart(C)≠0)→C
If A=B
prgmGSNAKER
End
Pause
ClrHome
Disp "SCORE:
Output(1,8,iPart(C)
Pause
ClrHome
Goto 0
```

### Explanation Edit

```prgmGSNAKEA
Lbl 0
ClrHome
Menu("     SNAKE!     ","PLAY",1,"HELP",2,"EXIT",3     //5 spaces, SNAKE!, 5 spaces
```

This piece runs the start animation and is the main menu.

```Lbl 3
ClrHome
ClrDraw
Output(1,1,"
Stop
```

This exits the game. The output right before the stop keeps the "Done" from appearing at the end. Note: It will not reset your graph screen, so it's dimensions and settings will remain the same.

```Lbl 2
ClrHome
Output(1,1,"PRESS THE ARROWS TO MOVE. YOU ARE THE SNAKE. YOU MUST EAT THE FOOD TO GAIN POINTS. DO NOT RUN INTO YOUR TAIL OR BRICKS."
Pause
ClrHome
Goto 0
```

The help screen. This screen is a lot better than the one I personally wrote for mine, which consists of "BLARGH!".

```Lbl 1
ClrHome
Func
FnOff 0,1,2,3,4,5,6,7,8,9
PlotsOff 1,2,3
ClrDraw
CoordOff
GridOff
AxesOff
LabelOff
ExprOff
0→Xmin
-62→Ymin
1→ΔX
1→ΔY
```

This once again sets the graph screen to the right settings.

```{8.02,5.02,2.02}→LSNAKE
```

This list is the coordinates of your snake pieces. The integer is it's 'X' coordinate, and the decimal the 'Y' coordinate divided by 100.

```8.02→A
```

"A" is the 'X' and 'Y' coordinates for the head of the snake. It starts at 8,2; so A=8.02

```32.02→B
```

B is the food. It starts in one spot then jumps randomly when eaten.

```0→C
```

C is the score and counter for the food. The integer part of it is the score, and the decimal is the counter to how long your tail grows when you eat food.

```For(U,0,30
3randInt(2,29)-1→V
1-3randInt(2,19→W
Pt-On(V,W,2
Pt-On(V,W
End
```

This is a loop that puts random blocks on the screen.

```Pt-On(8,-2,2
Pt-On(5,-2,2
Pt-On(2,-2,2
Pt-On(iPart(B),-100fPart(B),3
```

Draws the food and snake.

```DelVar θ
26→Z
Horizontal 0
Horizontal -61
Vertical 0
Vertical 94
```

Draws walls and sets the initial direction to the right (26). Z is the direction that the snake is heading, based on keycodes.

```While θ≠23 and θ≠45
```

Constant repeats until you press Delete, Clear, or until the game sets θ to 45.

```getKey→θ
```

User Input. Theta is your keypress.

```If (θ=24 and Z≠26) or (θ=25 and Z≠34) or (θ=26 and Z≠24) or (θ=34 and Z≠25)
θ→Z
```

This "If" statement will check to make sure that you pressed an arrow key and you aren't trying to reverse your direction. If that is true, it stores the new direction as "Z". If you don't know what the key codes are, 24 = left, 25 = up, 26 = right, 34 = down.

```A+3((Z=26 and iPart(A)<92)-(Z-24 and iPart(A)>2))+90((Z=24 and iPart(A)=2)-(Z=26 and iPart(A)=92))+.03((Z=25 and fPart(A)<.59)-(Z=25 and fPart(A)>.02))+.57((Z=25 and fPart(A)=.02)-(Z=34 and fPart(A)=.59))→A
```

This long code is the movement sequence. The screen is divided into blocks of 3x3 pixels, so the snake needs you move 3 pixels each time to not die accidently.

```If fPart(C)=0
Pt-Off(iPart(LSNAKE(dim(LSNAKE))),-100fPart(LSNAKE(dim(LSNAKE))),2
```

If the decimal of "C" (the counter) is 0, then it removes the last block in the snake to keep it the same length. If it isn't the last block isn't removed, so the tail grows longer without extending outwards. The tail stays in the same place and the head keep moving.

```If pxl-Test(100fPart(A)-1,iPart(A)-1)=1
45→θ
```

If the corner of the head is at a pixel which is on, it ends the game. The only things that do that are the snake blocks themselves and the blocks in the map. Because the head isn't drawn yet, this only accounts for running into things.

```Pt-On(iPart(A),-100fPart(A),2
```

This draws where the head is.

```augment({A},LSNAKE)→LSNAKE
```

This adds the new coordinates to the list of snake coordinates.

```dim(LSNAKE)-not(fPart(C))→dim(LSNAKE
C-100-1(fPart(C)≠0)→C
```

If the counter is off, it removes the last item in the list. If the counter is on, it doesn't. It also decrements the counter if it is not equal to zero.

```If A=B
prgmGSNAKER
```

This respawns the food once it is eaten.

```End
```

End of loop.

```Pause
ClrHome
Disp "SCORE:
Output(1,8,iPart(C)
Pause
ClrHome
Goto 0
```

This displays the score and sends you back to the main menu.

## Food Spawn Edit

The respawn for the food is complicated, so I made it a subprogram.

```Pt-Off(iPart(B),-100fPart(B)
Repeat not(pxl-Test(100fPart(B)-1,iPart(B)-1)) and sum({pxl-Test(100fPart(B)-4,iPart(B)-1),pxl-Test(100fPart(B)+2,iPart(B)-1),pxl-Test(100fPart(B)-1,iPart(B)-4),pxl-Test(100fPart(B)-1,iPart(B)+2)})<3
3randInt(2,29)-1+.01(3randInt(2,19))-1)→B
End
C+1.03→C
Pt-On(iPart(B),-100fPart(B),3
```

### Explanation Edit

```Pt-Off(iPart(B),-100fPart(B)
```

This removes the old food from the screen. Because the food is in a cross, and surrounded by a box, we only need to turn off the middle pixel to remove it.

```Repeat not(pxl-Test(100fPart(B)-1,iPart(B)-1)) and sum({pxl-Test(100fPart(B)-4,iPart(B)-1),pxl-Test(100fPart(B)+2,iPart(B)-1),pxl-Test(100fPart(B)-1,iPart(B)-4),pxl-Test(100fPart(B)-1,iPart(B)+2)})<3
```

This large "Repeat" conditional checks to make sure the food does not spawn on your tail or another brick. It also checks to make sure at least two spots next to it are open so that it doesn't spawn where you can't get to it.

```3randInt(2,29)-1+.01(3randInt(2,19))-1)→B
End
```

This puts the food randomly on the screen and randomly spawns the food.

```C+1.03→C
Pt-On(iPart(B),-100fPart(B),3
```

This adds one point, sets the timer to three, and it draws the new food particle.

## Enjoy! Edit

This works like a charm on my TI-84 plus Silver Edition, but I don't know how it works on anything else.

This is a newer and probably faster version of the same game.

``````:ClrHome
:Float
:Func
:Full
:FnOff
:PlotsOff
:CoordOff
:GridOff
:AxesOff
:LabelOff
:ExprOff
:ClrDraw
:0→Xmin
:-62→Ymin
:1→ΔX
:1→ΔY
:Lbl 0
:Lbl 1
:For(θ,0,3
:Vertical θ
:Vertical θ+91
:End
:For(θ,-2,0
:Horizontal θ
:Horizontal θ-60
:End
:{5.31→L1
:5.31→N
:47.31→I%
:26→PV
:.03→PMT
:Pt-On(47,-31,3
:While not(pxl-Test(t(E2fPart(N)-1, iPart(N-1
:Pt-On(iPart((N),-fPart(N),2
:getKey→FV
:If FV=45 or ((FV=24 and PV≠26) or (FV=25 and PV≠34) or (FV=26 and PV≠24) or (FV=34 and PV≠25
:FV→PV
::N+3((PV=26)-(PV=24)+.01((PV=34)-(PV=25→N
:augment({{N},L1→L1
:If not(fPart(PMT
:Pt-Off(iPart(Ans(dim(Ans))),-,-E2fPart(Ans(dim(Ans))),2
:dim(Ans)-not(fPart(PMT→dim(L1
:PMT-.01(0≠fPart(PMT→PMT
:If  N≠I%
:Then
:Pt-Off(iPart(I%),-,-E2fPart(I%
:Repeat not(pxl-Test((E2fPart(Ans)-1,iPart(Ans
:3randInt(2,30)-1+.01(1+3randInt(1,10
:End
:Ans→I%
:Pt-On(iPart(I%),--E2fPart(I%),3
:PMT+1.03→PMT
:End
:End
:Pause
:ClrDraw
:Output(1,8,iPart(PMT
:Pause "SCORE:
:ClrHome
:Goto 0
:Lbl 2
:Delvar L :Delvar L1
:ClrHome
:Output(1,1,"
```
```