/* programm solitaire version 1.0 */
#include <exec/exec.h>
int eingabe;

extern BYTE endfeld[34];
extern BYTE startfeld[34];

BYTE  momfeld [34];
BYTE anzahlzug;

/* Informationen über Sprünge : pro Feld (1..33) 8 Informationen :
   1 Feld oben , 2 Feld oben , 1 Feld unten , 2 unten , 1 links, 2 links ,
   1 rechts , 2 rechts  falls ein Sprung in eine richtung nicht geht
   stehen der erste und der zweite Eintrag auf 0
*/

BYTE zuege [34] [8] =
     { {0,0,0,0,0,0,0,0}
      , {2,3,0,0,0,0,4,9}        /* {0,0,4,9,0,0,2,3}      */
      , {0,0,0,0,0,0,5,10}       /* {0,0,5,10,0,0,0,0}     */
      , {0,0,2,1,0,0,6,11}       /* {0,0,6,11,2,1,0,0}     */
      , {5,6,0,0,0,0,9,16}       /* {0,0,9,16,0,0,5,6}     */
      , {0,0,0,0,0,0,10,17}      /* {0,0,10,17,0,0,0,0}    */
      , {0,0,5,4,0,0,11,18}      /* {0,0,11,18,5,4,0,0}    */
      , {8,9,0,0,0,0,14,21}      /* {0,0,14,21,0,0,8,9}    */
      , {9,10,0,0,0,0,15,22}     /* {0,0,15,22,0,0,9,10}   */
      , {10,11,8,7,4,1,16,23}    /* {4,1,16,23,8,7,10,11}  */
      , {11,12,9,8,5,2,17,24}    /* {5,2,17,24,9,8,11,12}  */
      , {12,13,10,9,6,3,18,25}   /* {6,3,18,25,10,9,12,13} */
      , {0,0,11,10,0,0,19,26}    /* {0,0,19,26,11,10,0,0}  */
      , {0,0,12,11,0,0,20,27}    /* {0,0,20,27,12,11,0,0}  */
      , {15,16,0,0,0,0,0,0}      /* {0,0,0,0,0,0,15,16}    */
      , {16,17,0,0,0,0,0,0}      /* {0,0,0,0,0,0,16,17}    */
      , {17,18,15,14,9,4,23,28}  /* {9,4,23,28,15,14,17,18}*/
      , {18,19,16,15,10,5,24,29} /* {10,5,24,29,16,15,18,19}*/
      , {19,20,17,16,11,6,25,30} /* {11,6,25,30,17,16,19,20}*/
      , {0,0,18,17,0,0,0,0}      /* {0,0,0,0,18,17,0,0}     */
      , {0,0,19,18,0,0,0,0}      /* {0,0,0,0,19,18,0,0}     */
      , {22,23,0,0,14,7,0,0}     /* {14,7,0,0,0,0,22,23}    */
      , {23,24,0,0,15,8,0,0}     /* {15,8,0,0,0,0,23,24}    */
      , {24,25,22,21,16,9,28,31} /* {16,9,28,31,22,21,24,25}*/
      , {25,26,23,22,17,10,29,32}/* {17,10,29,32,23,22,25,26}*/
      , {26,27,24,23,18,11,30,33}/* {18,11,30,33,24,23,26,27}*/
      , {0,0,25,24,19,12,0,0}    /* {19,12,0,0,25,24,0,0}    */
      , {0,0,26,25,20,13,0,0}    /* {20,13,0,0,26,25,0,0}    */
      , {29,30,0,0,23,16,0,0}    /* {23,16,0,0,0,0,29,30}    */
      , {0,0,0,0,24,17,0,0}      /* {24,17,0,0,0,0,0,0}      */
      , {0,0,29,28,25,18,0,0}    /* {25,18,0,0,29,28,0,0}    */
      , {32,33,0,0,28,23,0,0}    /* {28,23,0,0,0,0,32,33}    */
      , {0,0,0,0,29,24,0,0}      /* {29,24,0,0,0,0,0,0}      */
      , {0,0,32,31,30,25,0,0}    /* {30,25,0,0,32,31,0,0}    */
      };

struct zug
 { BYTE   ursprung;
   BYTE   richtung;
 };

struct zug zugmenge [100];
struct zug momzug;
 
/* int testzug (zugt,feld) */
/* struct zug *zugt;       */
/* BYTE feld[34];          */

#asm
   public _testzug
_testzug:
   lea.l _momzug,a0        ;Adresse zugt Struktur
   lea.l _momfeld,a1       ;Adresse feld

   clr.l d0
   clr.l d1
   clr.l d2

   move.b 1(a0),d0         ;Richtung
   asl.b #1,d0             ;*2

   move.b (a0),d1          ;Ursprung
   move.b d1,d2
   asl.w #3,d1             ;*8
   add.w d0,d1             ;Wo Eintrag in Zuege

   lea.l _zuege,a6
   tst.b (a6,d1.w)
   beq NichtOk

   tst.b (a1,d2.w)         ;Ursprung
   beq NichtOk

   move.b (a6,d1.w),d2     ;Inhalt von Zuege
   tst.b (a1,d2.w)         ;Inhalt Sprung Zwischenfeld
   beq NichtOk

   move.b 1(a6,d1.w),d2
   tst.b (a1,d2.w)         ;Inahlt Sprung Endfeld
   bne NichtOk
   moveq.l #0,d0
   rts
NichtOk:
   moveq.l #1,d0
   rts
#endasm


/* tuezug(zug,feld) */
/* struct zug *zug; */
/* BYTE feld[34];   */

#asm
   public _tuezug
_tuezug:
   lea.l _momzug,a0
   lea.l _momfeld,a1

   clr.l d0
   clr.l d1
   clr.l d2

   move.b 1(a0),d0         ;richtung
   asl.b #1,d0

   move.b (a0),d1          ;ursprung
   move.b d1,d2
   asl.w #3,d1
   add.w d0,d1

   lea _zuege,a6
   move.b #0,(a1,d2.w)

   move.b (a6,d1.w),d2
   move.b #0,(a1,d2.w)

   move.b 1(a6,d1.w),d2
   move.b #1,(a1,d2.w)
   rts
#endasm

/* suchezug    sucht nächsten möglichen zug */

#asm
   public _suchezug
_suchezug:
   lea.l _momzug,a0
   cmp.b #33,(a0)
   bne label1
   cmp.b #3,1(a0)
   bne label1

   cmp.b #0,_anzahlzug
   bne ok:
   move.l #0,d0
   rts
ok:
   subq.b #1,_anzahlzug
   clr.l d0
   clr.l d1
   clr.l d2
   clr.l d3
   move.b _anzahlzug,d0
   asl.b #1,d0
   lea.l _zugmenge,a6
;
; ** rückzug **
;
   move.b 1(a6,d0.w),d1       ;richtung
   asl.b #1,d1
   move.b (a6,d0.w),d2        ;ursprung
   move.b d2,d3
   asl.w #3,d2
   add.w d1,d2                ;adresse in zuege

   lea.l _zuege,a6
   lea.l _momfeld,a1
   move.b #1,(a1,d3.w)
   move.b (a6,d2.w),d3
   move.b #1,(a1,d3.w)
   move.b 1(a6,d2.w),d3
   move.b #0,(a1,d3.w)
;
   lea.l _zugmenge,a6
   lea.l _momzug,a0
   move.b (a6,d0.w),(a0)
   move.b 1(a6,d0.w),1(a0)
   jmp _suchezug

label1:
   lea _momzug,a0
   cmp.b #3,1(a0)
   bne label2
   move.b #0,1(a0)
   addq.b #1,(a0)
   bra label3
label2:
   addq.b #1,1(a0)
;testzug aufrufen
label3:
   bsr _testzug
   tst.b d0
   bne _suchezug
   move.l #1,d0
   rts
#endasm

ausgabe (feld)
BYTE feld[34];
{
 register int i;

 for (i=0; i<34 ; printf("%d",feld[i]) , printf("    "),i++);
} 

/* int testend () */

#asm
   public _testend
_testend:
   move.l #_momfeld,a0
   move.l 4(sp),a1
   move.b #16,d0
loop:
   cmpm.w (a0)+,(a1)+
   bne.s unequal
   dbra  d0,loop
   move.l #0,d0
   rts
unequal:
   move.l #1,d0
   rts
#endasm
/* merkzug  trägt Zug ein und bereitet für nächsten Zug vor*/

#asm
   public _merkzug
_merkzug:
   clr.l d0
   move.b _anzahlzug,d0
   asl.b #1,d0
   lea.l _zugmenge,a6
   lea.l _momzug,a0
   move.b (a0),(a6,d0.w)      ;momzug merken ursprung
   move.b 1(a0),1(a6,d0.w)    ;richtung
   move.b #0,(a0)            ;ursprung = 0
   move.b #3,1(a0)           ;richtung = 3
   addq.b #1,_anzahlzug
   rts
#endasm


