TI-FLOW

Client: Test Client 2
Task: Multimedia Design Production Development Quality Assurance
Skills: Ruby Writing
TI-FLOW is a revolutionary adaptation of Flow Free (Numberlink) for the TI-84 Plus. TI-FLOW makes extensive use of specially developed data compression methods, and contains many optimizations to provide the best experience to the user. The TI-FLOW package also includes a Java application to help people create their own TI-FLOW level packs.

You can download TI-FLOW from ticalc.org or Cemetech, or browse the source code below.

////////////TI-FLOW//////////////
//
//by Pablo Yong and Jonathan Bush
//   (earthnite)    (jonbush)
//2015 CC BY-NC-SA 4.0
//
//Lbls
//A = grid select
//B = reset board
//C = redraw board
//
//Z = select screen starting level
//X = position of save entry in |LFLO
//W = pack number
//V = level number starting at 1
//U = level size
//T = board offset
//theta = number of levels total
//vars during cursor
//A = cursor row
//B = cursor col
//C = Color
//R = Moves
//S = Exit code
//O = Number of moves for perfect x2
If 1<abs(startTmr-X
Then
    Disp "RUN PACK TO PLAY
    Return
End
ClrHome
StoreGDB 1
Func
AxesOff
PlotsOff 
FnOff 
GridOff
ClrDraw
SetUpEditor FLO
SetUpEditor 
For(A,1,7
    Text(~1,24,8+9A,sub("TI-FLOW",A,1
    rand(4
End
length(Str2
int(2Ans-1.5sum(seq(" "=sub(Str2,A,1),A,1,Ans
Text(44,46-Ans,Str2
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789theta -*/piZoomStat[]|E{}If ThenElseFor(While Repeat EndPause Lbl Goto IS>(DS<(prgmReturnStopsin(cos(tan(sin^-1(cos^-1(tan^-1(^^-1^^2sqrt(,>Dec^^3=!=>>=<<= and  or  xor not(NormalSciEngFloatRadianDegreeFuncParamPolarSeq^^o'^^r|Laugment(->Str0
inString(Ans,sub(Str1,2,1->theta
inString(Str0,sub(Str1,1,1->W
//find the positon of the save or create new entry
dim(|LFLO->A
If Ans
sum(not(cumSum(W/|E3=fPart(|LFLO
Ans+1->X
If Ans>A
Then
    5+A->dim(|LFLO
    W/|E3->|LFLO(X
End
//max(dim(|LFLO),5Ans->dim(|LFLO
rand(40
For(A,1,7
    Text(~1,24,8+9A," 
    rand(5
End
ClrDraw
Xmin+62DeltaX
{Xmin,Ans,Ans,Xmin,Xmin->L1
{Ymax,Ymax,Ymin,Ymin,Ymax->L2
Plot1(xyLine,L1,L2,plotdot
//grid to select
//For(A,1,28
//    Text(1,64+A,sub(".]!].!.11.!Î].!íí.!>=!.!ísí!.",A,1
//End
For(A,1,28
    64+A
    Text(1,Ans,sub(".]!].!.11.!Î].!íí.!>=!.!ísí!.",A,1
    Text(10,Ans,sub("+'? ''^^x '++ ''^^x '^^x^^x ?'?     ",A,1
    Text(17,Ans,sub("'++ ''^^x Y+Y ''^^x '++         ",A,1
End
StorePic 0
//Level select screen
PlotsOff 1
pi->Z
Lbl A
11->Xmin
1->DeltaX
~73->Ymin
1->DeltaY
pi->S
//|LFLO(5W-4->C
iPart(|LFLO(X->C
//remainder(theta,25
//min(theta,C+not(C->A
//int(25fPart(Ans/25
25int(min(theta-1,Ans)/25
If pi=Z
Ans->Z
//A-Ans-25not(Ans->Z
//min(25iPart(C/25),theta-Ans-25not(Ans->Z
Repeat D=21
    If S!=Z
    Then
        //|LFLO(5W-3+Z/25->P
        |LFLO(X+1+Z/25->P
        Z->S
        ClrDraw
        RecallPic 0
        For(A,0,min(24,theta-Ans-1
            4+12int(5fPart(A/5->E
            12int(A/5
            Text(4+Ans,E+2(A+Z<=9),A+Z
            If A+Z<C
            Then
                ~Ans-14
                Line(17+E,Ans,19+E,Ans
                If int(2fPart(.5P/2^A
                Line(18+E,Ans+1,18+E,Ans-1
            End
        End
        1->A
        1->B
    End
    12
    Repeat D=21 xor C<V-1 or theta<V or B^^2=6B
        For(E,0,Ans,Ans
            Line(AnsB+E,~AnsA-E,AnsB+Ans,~AnsA
            Line(AnsB+E,~AnsA-E,AnsB,~AnsA-Ans
        End
        Repeat Ans
            getKey->D
        End
        If Ans=45
        Goto Q
        A->M
        B->N
//        max(1,min(5,A-(D=25)+(D=34->A
max(1,min(5,A+sum(DeltaList(D={25,34->A
//        B-(D=24)+(D=26->B
D-25
B+Ans(1=abs(Ans->B
        Z+Ans+5A-5->V
        12
        For(E,0,Ans,Ans
            Line(AnsN+E,~AnsM-E,AnsN+Ans,~AnsM,0
            Line(AnsN+E,~AnsM-E,AnsN,~AnsM-Ans,0
        End
    End
    Z-25not(B+not(Z
    Ans+25(B=6
    Ansnot(Ans>=theta
    If Ans<=C
    Ans->Z
    M->A
    N->B
End
//draw stats
//using text to draw text ftw
ClrDraw
RecallPic 0
For(A,1,17
    64+A
    Text(24,Ans,sub("'Y' '^^x' Y+Y ''^^x  ",A,1
    Text(10,Ans,sub("'YY ^^oY^^o '^^x^^x '^^^x  ",A,1
    Text(31,Ans,sub("'Y? '++ '^^x' '+^^o+'",A,1
    Text(53,Ans,sub(" ++' '^^x' '?^^o     ",A,1
    Text(57,Ans,sub(" 'YY ^^oY^^o ''^^o '++ ",A,1
End
Text(8,82,"    00
Text(15,86,"00
//Text(22,86,"00
//Text(29,88,"-
For(A,1,12
    81+A
    Text(53,Ans,sub("''^^o    ^'^  ",A,1
    Text(57,Ans,sub("'^^x'    ?^^o?  ",A,1
End
//draw the checkerboard
Xmin+1
For(A,Ans,Ans+120,2
Line(Ans,~A,Ans+60,60-A
End
//For(A,Xmin+1,Xmin+121,2
//    Line(Xmin+1,~A,Xmin+61,60-A
//End
StorePic 9
Lbl C
//decode level info and draw board
seq(inString(Str0,sub(Str1,[recursiven],1)),[recursiven],2,V+2->L1
2+sum(Ans->A
//L1(V+1->O
//sub(Str1,2+A-Ans,Ans-1->Str2
//inString(Str0,sub(Str1,1+A-O,1->U
L1(V+1)-1->O
sub(Str1,1+A-Ans,Ans->Str2
inString(Str0,sub(Str1,A-O,1->U
DelVar [B]{Ans,Ans->dim([B]
30-3U->T
2-Ans->Xmin
1->DeltaX
T-64->Ymin
1->DeltaY
ClrDraw
RecallPic 9
//Text(8,86+4(W<9),W
Text(8,90-4int(log(W)),W
Text(15,86+4(V<=10),V-1
6U+4
For(A,3,Ans,2
    Line(2,~A,A,~2
    Line(Ans-A+2,~Ans,Ans,A-Ans-2
End
1->E
//For([recursiven],2+A-O,A
//For(A,1,O-1
For(A,1,O
    ~1+inString(Str0,sub(Str2,A,1->B
    6+6round(UfPart(Ans/U),0->C
    1+int(B/U->B
    int(E->[B](Ans,C/6
    Text(6B-5+T,C-3+T,sub(Str0,Ans,1
    ~6B-2
    Line(C-3,Ans,C-3,Ans+4,0
    Line(C+3,Ans,C+3,Ans+4,0
    Ans-1
    Line(C-2,Ans,C-2,Ans+6,0
    Line(C-1,Ans,C+2,Ans,0
    E+.5->E
End
//.5(O-1->O
//5length(Str2->O
StorePic 8
//Cursor stuff after this point needs work
1->E
1->F
//1->D
Lbl B
Text(22,86,"00
Text(29,88,"-
RecallPic 8
DelVar GDelVar RDelVar SDelVar C[B]->[A]
Repeat S
    getKey
    Repeat Ans
        E->A
        F->B
        20not(not(C->E
        T+{~5,~5,1,1->L1
        T+{~5,1,~5,1->L2
        Repeat Ans
            DS<(E,0
            While 0
                For([recursiven],1,4
                    Pxl-Change(6A+L1([recursiven]),6B+L2([recursiven]
                End
                6->E
                0
            End
            getKey->D
        End
        For(E,1,4(E<7
            Pxl-On(6A+L1(E),6B+L2(E
        End
        max(1,min(U,A+sum(DeltaList(Ans={25,34->E
        D-25
        max(1,min(U,B+Ans(1=abs(Ans->F
        [B](E,Ans
        If CAns and C!=Ans
        Then
            A->E
            B->F
        End
        1
        If C
        Then
            6F->G
            If not([A](E,F
            Then
                .01+[A](A,B->[A](E,F
                Line(6B,~6A,G,~6E,0
                If [B](A,B
                Text(6A-5+T,6B-3+T,sub(Str0,C,1
                //If [B](E,F
                //Text(6E-5+T,6F-3+T,sub(Str0,C,1
                0
            End
            If [A](A,B)=.01+[A](E,F
            Then
                Line(6B,~6A,G,~6E
                Pt-Off(G,~6E
                If [B](E,F
                Then
                    Text(6E-5+T,G-3+T,sub(Str0,C,1
                    ~6E-2
                    Line(G-3,Ans,G-3,Ans+5,0
                    Line(G+3,Ans,G+3,Ans+4,0
                    Ans-1
                    Line(G-2,Ans,G-2,Ans+6,0
                    Line(G-1,Ans,G+2,Ans,0
                End
                0->[A](A,B
            End
        End
        //If A+B=E+F and not(max(D={21,45})) or not(C) and min(D!={21,45
        //If not(C) and min(D!={21,45}) or AB=E\F and not(max(D={21,45
        If min(D!={21,45})(AB=E\F or not(C
        0
    End
    If D=45
        DelVar C1+not(R->S
    If D=21
    Then
        not(C)int([A](A,B->C
        Text(29,88,sub("-"+Str0,Ans+1,1
        R+not(not(Ans->R
        86+4(R<=9
        If R<=99
        Then
            Text(22,Ans,R
            Else
            Text(22,Ans," : )
        End
        If C and [B](A,B
        Then
            //Erase all flows of C
            0->I
            2C
            For(K,Ans-1,Ans
                ~1+inString(Str0,sub(Str2,K,1->G
                1+round(UfPart(Ans/U),0->H
                1+int(G/U
                If .01=fPart([A](Ans,H
                Then
                    Ans->I
                    H->J
                End
            End
            If I
            Then
                {I+.01J->L1
                Repeat I=dim(L1
                    dim(L1->I
                    int(L1(Ans->J
                    |E2fPart(L1(I->K
                    .01+[A](J,Ans->L
                    0
                    If L=[A](min(U,J+1),K
                    Then
                        1
                        Else
                        If L=[A](J,min(U,K+1
                        Then
                            .01
                            Else
                            If L=[A](max(1,J-1),K
                                Then
                                ~1
                                Else
                                If L=[A](J,max(1,K-1
                                ~.01
                            End
                        End
                    End
                    Ans+L1(I->L1(I+not(not(Ans
                End
                If 1<dim(L1
                Then
                    L1(dim(L1
                    int([B](int(Ans),|E2fPart(Ans->H
                    For(I,1,dim(L1)-1
                        int(L1(I->J
                        |E2fPart(L1(I->K
                        6Ans->N
                        Ans-6|E2fPart(L1(I+1->M
                        6(J-int(L1(I+1->L
                        ~6J
                        Line(N,Ans,N-M,Ans+L
                        If H
                        Then
                            If 1=abs(L1(I)-L1(I+1
                            Then
                                Line(N-1,Ans,N-1,Ans+L
                                Line(N+1,Ans,N+1,Ans+L
                                Else
                                Line(N,Ans-1,N-M,Ans-1
                                Line(N,Ans+1,N-M,Ans+1
                            End
                        End
                        [B](J,K->[A](J,K
                    End
                End
                dim(L1->J
                int(L1(Ans->K
                |E2fPart(L1(J
                [B](K,Ans->[A](K,Ans
                For(J,1,J,J-(J!=1
                    int(L1(J->H
                    |E2fPart(L1(J->I
                    6I-3->K
                    [B](H,I
                    If Ans
                    Then
                        Text(6H-5+T,K+T,sub(Str0,Ans,1
                        ~6H-2
                        Line(K,Ans,K,Ans+4,0
                        Line(K+6,Ans,K+6,Ans+4,0
                        Ans-1
                        Line(K+1,Ans,K+1,Ans+6,0
                        Line(K+2,Ans,K+5,Ans,0
                    End
                End
            End
        End
    End
    If C
    Then
        If fPart([A](E,F
        Then
            .02->G
            {E+.01F->L1
            If C!=int([A](E,F
            Then
                E+{1,0,~1,0->L1
                F+{0,1,0,~1->L2
                1+sum(not(cumSum([A](E,F)-.01=seq([A](max(1,min(U,L1(G))),max(1,min(U,Ans(G)))),G,1,4
                {L1(Ans)+.01L2(Ans->L1
            End
            6E+T-1
            For(D,0,not(pxl-Test(Ans,6F+T-1)pxl-Test(Ans-2,6F+T-3
                .01-Gnot(D->G
                int(L1(dim(L1->|N
                |E2fPart(L1(dim(L1->I%
                Repeat PV=dim(L1
                    dim(L1->PV
                    [A](|N,I%)-G->PMT
                    0
                    If PMT=[A](min(U,|N+1),I%
                    Then
                        |N+1->|N
                        1
                        Else
                        If PMT=[A](|N,min(U,I%+1
                        Then
                            I%+1->I%
                            .01
                            Else
                            If PMT=[A](max(1,|N-1),I%
                            Then
                                |N-1->|N
                                ~1
                                Else
                                If PMT=[A](|N,max(1,I%-1
                                Then
                                    I%-1->I%
                                    ~.01
                                End
                            End
                        End
                    End
                    Ans+L1(PV->L1(PV+not(not(Ans
                End
                If not(D
                Then
                    dim(L1->H
                    seq(L1(G),G,H,1,~1->L1
                End
            End
            //erase leading line
            If 1<dim(L1
            Then
                For(I,1,H-1
                    int(L1(I->J
                    |E2fPart(L1(I->K
                    6(Ans-|E2fPart(L1(I+1->M
                    6(J-int(L1(I+1->L
                    6K->|N
                    ~6J
                    Line(|N,Ans,|N-M,Ans+L
                    Pt-Off(|N-M,Ans+L
                    If D-1
                    Then
                        If 1=abs(L1(I)-L1(I+1
                        Then
                            Line(|N-1,Ans,|N-1,Ans+L
                            Line(|N+1,Ans,|N+1,Ans+L
                            Else
                            Line(|N,Ans-1,|N-M,Ans-1
                            Line(|N,Ans+1,|N-M,Ans+1
                        End
                    End
                    [B](J,K->[A](J,K
                End
                //thin trailing line
                //If D-1
                //    Then
                For(I,H,(D-1)dim(L1)-1
                    int(L1(I->J
                    |E2fPart(L1(I->K
                    6Ans->N
                    Ans-6|E2fPart(L1(I+1->M
                    6(J-int(L1(I+1->L
                    ~6J
                    If 1=abs(L1(I)-L1(I+1
                    Then
                        Line(N-1,Ans,N-1,Ans+L
                        Line(N+1,Ans,N+1,Ans+L
                        Else
                        Line(N,Ans-1,N-M,Ans-1
                        Line(N,Ans+1,N-M,Ans+1
                    End
                    6J-2+T->L
                    6K-2+T
                    If not(pxl-Test(L+2,Ans
                    Pxl-Off(L+1,Ans
                    If not(pxl-Test(L,Ans+2
                    Pxl-Off(L,Ans+1
                    If not(pxl-Test(L-2,Ans
                    Pxl-Off(L-1,Ans
                    If not(pxl-Test(L,Ans-2
                    Pxl-Off(L,Ans-1
                    End
                //End
                dim(L1
                For(J,1,Ans,Ans-1
                int(L1(J->H
                    |E2fPart(L1(J->I
                    6I-3->K
                    [B](H,I
                    If Ans
                    Then
                    Text(6H-5+T,K+T,sub(Str0,Ans,1
                        ~6H-2
                        Line(K,Ans,K,Ans+4,0
                        Line(K+6,Ans,K+6,Ans+4,0
                        Ans-1
                        Line(K+1,Ans,K+1,Ans+6,0
                        Line(K+2,Ans,K+5,Ans,0
                        End
                    End
                End
            End
        //Draw line
        [A](E,F
        If fPart(Ans
        Then
        Ans-.01->[A](E,F
            E->A
            F->B
            End
        .01+[A](A,B->[A](E,F
        Line(6B,~6A,6F,~6E,0
        If [B](A,B
        Text(6A-5+T,6B-3+T,sub(Str0,C,1
        //if node2, draw think line, check win
        If [B](E,F) and .01<fPart([A](E,F
        Then
        E->|N
            F->I%
            {E+.01Ans->L1
            Repeat PV=dim(L1
            dim(L1->PV
                [A](|N,I%)-.01->PMT
                0
                If PMT=[A](min(U,|N+1),I%
                Then
                |N+1->|N
                    1
                    Else
                    If PMT=[A](|N,min(U,I%+1
                    Then
                    I%+1->I%
                        .01
                        Else
                        If PMT=[A](max(1,|N-1),I%
                        Then
                        |N-1->|N
                            ~1
                            Else
                            If PMT=[A](|N,max(1,I%-1
                            Then
                            I%-1->I%
                                ~.01
                                End
                            End
                        End
                    End
                Ans+L1(PV->L1(PV+not(not(Ans
                End
            For(S,1,dim(L1)-1
            int(L1(S->J
                |E2fPart(L1(S->K
                6Ans->|N
                Ans-6|E2fPart(L1(S+1->M
                6(J-int(L1(S+1->L
                ~6J
                If 1=abs(L1(S)-L1(S+1
                Then
                Line(|N-1,Ans,|N-1,Ans+L,0
                    Line(|N+1,Ans,|N+1,Ans+L,0
                    Else
                    Line(|N,Ans-1,|N-M,Ans-1,0
                    Line(|N,Ans+1,|N-M,Ans+1,0
                    End
                End
            //Text(6E-5+T,6F-3+T,sub(Str0,[B](E,F),1
            Text(6E-5+T,6F-3+T,sub(Str0,C,1
            |E2fPart(L1(S
            //Text(6int(L1(I))-5+T,6Ans-3+T,sub(Str0,[B](int(L1(I)),Ans),1
            Text(6int(L1(S))-5+T,6Ans-3+T,sub(Str0,C,1
            DelVar CText(29,88,"-
            For(G,1,U
            Matr>list([A],G,L1
                min(S,min(fPart(L1->S
                End
            End
            End
End
//reset board
If S=1
Goto B
//go back to select
If S=2
Goto A
//Board solved
//max(V,|LFLO(5W-4->|LFLO(5W-4
|LFLO(X
max(V+fPart(Ans),Ans->|LFLO(X
//R=O->D
O=2R->D
//If perfect
If Ans
Then
{2^round(25fPart((V-1)/25),0),X+1+iPart(.04(V-1
    If not(int(2fPart(.5Ans(1)^^-1|LFLO(Ans(2
    Ans(1)+|LFLO(Ans(2->|LFLO(Ans(2
End
//Start of menu
rand(20
10->J
3+sum({V<theta,not(D->A
30-5Ans->B
Ans+JA+2->C
For(G,B,Ans,7
    min(G,C-7
    Text(~1,Ans,2,"         
    Text(~1,Ans,55," 
End
3+Xmin->H
Ans+56->G
Ymax-B-1->I
Ans-JA
Line(H,I,H,Ans
Line(G,I,G,Ans
Line(H,I,G,I
Line(H,Ans,G,Ans
"COMPLETE
If D
"PERFECT
Text(B+3,16+2D,Ans
13+B->B
Ans->C
{0
If V<theta
Then
    Text(B,12,"NEXT LEVEL
    B+J->B
    {0,1
End
If not(D
Then
    Text(B,12,"TRY AGAIN
    augment(Ans,{2
End
augment(Ans,{3,0->L1
B+Jnot(D
Text(Ans,12,"SELECT LEVEL
Text(Ans+J,12,"QUIT
2->D
Repeat Ans=21
max(2,min(A,D+sum(DeltaList(Ans={25,34->D
    JAns+C-20->B
    Text(Ans,6,">
    getKey
    //max(2,min(A,D-(Ans=25)+(Ans=34->D
    If Ans
    Text(B,6,"   
End
L1(D
If Ans=2
ClrDraw
If Ans=2
Goto B
If Ans=3
Goto A
IS>(V,V+Ans
//V+1->V
//If L1(D
Goto C
Lbl Q
//stuff to do when quitting:
ClrList L1,L2
DelVar [A]\DelVar [B]\DelVar Str0\DelVar Str1\DelVar Str2\RecallGDB 1
DelVar GDB1\DelVar Pic9\DelVar Pic0\DelVar Pic8\Archive |LFLO
ClrDraw
ClrHome
"