REM "Labyrinthe Twist" @Cassiope34 0719 GR.OPEN 255,142,160,170,0,0 % 150,215,150,0,0 % landscape gr.screen w,h : scx =1280 : scy =800 : sx =w/scx : sy =h/scy : gr.scale sx, sy File.Root tmp$ IsApk =!Is_In("rfo-basic",tmp$) % to know if it's an APK for the way to exit Device b Bundle.get b, "Language", lang$ if left$(lower$(lang$),2)="fr" then lang =2 else lang =1 % French or English lang =1 GOSUB Fonctions path$ ="" filename$ ="LabyTwist.sav" ARRAY.LOAD diX[], 0, 1, 0,-1,-1 % 1 =North, 2 =East, 3 =South, 4 =West ARRAY.LOAD diY[],-1, 0, 1, 0,-1 % 5 =N.E. ARRAY.LOAD menu$[],"I.A. is the player 1","I.A. is the player 2","I.A. versus I.A. " % don't play. (default)" DIM c[8,8], po[8,8], chm[8,8], p[2], pp[2], ob[16], obptr[16], bmph[2], haie[25], pr[25], sh[25], rot[25] DIM crtOb[2], crtMag[2], obj$[2], otbmp[2], obt[2], nobr[2], nbfee[2], fee[2], pjr[2], db[8,8] % debug DIM main[2], tbt[2], tbc[2], pclr[2], c4[4], obpj[2], clob[4], fpp[2], btj[2], objr[2], crtM[28] GOSUB InitBmp WakeLock 3 startj =int(rnd()*2)+1 DO new =0 : fin =0 : j =3-startj : startj =j : mfin$ ="" GOSUB InitGame Do gr.show main[j] : gr.hide main[3-j] STARTX =int(pp[j]/10) : STARTY =mod(pp[j],10) : GOSUB Linked : GOSUB ShowLinked gr.modify played, "x", pgx+(STARTX-1)*dc, "y", pgy+(STARTY-1)*dc do gr.touch touched, x, y gr.modify heure, "text", left$(USING$(,"%tT",time()),5) : pause 10 if !background() then gr.render until touched | new | quit if new | quit then D_U.break if fin then popup mfin$ : D_u.continue x/=sx : y/=sy : cx1 =int((x-pgx)/dc)+(x>pgx) : cy1 =int((y-pgy)/dc)+(y>pgy) % calcul case touchée... while touched gr.touch touched, tx, ty repeat tx/=sx : ty/=sy : cx =int((tx-pgx)/dc)+(tx>pgx) : cy =int((ty-pgy)/dc)+(ty>pgy) : ok =0 GOSUB RotEdge % une haie pivotée ? if nh % n° de la haie pivotée. gr.get.position pr[nh],hx,hy : gr.modify hedge, "x", hx-0.5*dc, "y",hy-0.5*dc % rond rouge (haie touchée) GOSUB Rotation : GOSUB EffLinked %: Gosub AffCases % debug if pp[j] =objr[j] then ok =1 : TARGX =xn(pp[j]) : TARGY =yn(pp[j]) : GOSUB Capture else if cx>0 & cx<9 & cy>0 & cy<9 & cx=cx1 & cy=cy1 % case de posé et de levé identiques. if IS_IN(xy$(cx,cy),chf$) % un case touchée parmis les possibles pour 'j' sauf la case de j... btj[j] =2 % couleur du texte sur le bouton "Validate". if xyn(cx,cy) =objr[j] then ok =1 : btj[j] =1 TARGX =cx : TARGY =cy : GOSUB Go : GOSUB Capture %: GOSUB EffLinked gr.modify tbt[j], "paint", tbc[btj[j]] else % seul cas : case fée hors zone verte + le pion sur une case verte fée + carte fée selectionnée. xpj =xn(pp[j]) : ypj =yn(pp[j]) if !IS_IN(xy$(cx,cy),chf$) & po[cx,cy]=20 & po[xpj,ypj]=20 & fee[j]>1 gr.modify SelFee, "x", 40+(scx-200)*(j=2), "y", 580 move(p[j], pgx+((dc-42)/2)+(cx-1)*dc, pgy+((dc-69)/2)+(cy-1)*dc, 8) pause 300 : gr.modify SelFee, "y", -200 pp[j] =xyn(cx,cy) : GOSUB EffLinked fee[j]-=2 : gr.modify nbfee[j], "text", int$(fee[j]) if fee[j]=0 then gr.modify crtMag[j], "bitmap", Magie endif endif else if ((j=1 & (cx=-1 | cx=0)) | (j=2 & (cx=9 | cx=10))) & (cy=5 | cy=6) & btj[j] =2 % bouton validation touché ok =1 : GOSUB Tirage % uniquement lorsque objet non atteind. elseif cy =4 & cx =-1 do : pclr[1]+=1-4*(pclr[1]=4) : until pclr[1]<>pclr[2] % chgt de couleur pion 1 (gauche) gr.modify pjr[1], "bitmap", pion[pclr[1]] gr.modify p[1], "bitmap", pion[pclr[1]] gr.set.stroke 4 : gr.modify obpj[1], "paint", clob[pclr[1]] elseif cy =4 & cx =10 do : pclr[2]+=1-4*(pclr[2]=4) : until pclr[2]<>pclr[1] % chgt de couleur pion 2 (droite) gr.modify pjr[2], "bitmap", pion[pclr[2]] gr.modify p[2], "bitmap", pion[pclr[2]] gr.set.stroke 4 : gr.modify obpj[2], "paint", clob[pclr[2]] endif endif endif if ok GOSUB DetectEog : GOSUB EffLinked oldnh =0 : j =3-j : gr_UP( p[j] ) % chgt de joueur. btj[1] =1 : gr.modify tbt[1], "paint", tbc[btj[j]] % couleur du texte sur le bouton "Validate". btj[2] =1 : gr.modify tbt[2], "paint", tbc[btj[j]] gr.modify hedge, "y", -dc ! bientôt l'AI ici ? endif Until new UNTIL quit WakeLock 3 GOSUB SaveGame if IsApk then EXIT END "Bye...!" OnBackKey: if help : help =0 : move(bhelp, 90, -600, 4) else : GOSUB BoiteMenu endif Back.Resume BoiteMenu: Dialog.message win$," What do you want ?", ok, " Exit ", " New Game ?", " Rules " new =(ok=2) : quit =(ok=1) if ok =3 then move(bhelp, 90, 90, 4) : help =1 return AI: % futur... RETURN DetectEog: % end of game detection g1 =0 : g2 =0 if obt[1]=0 & objr[1]=pp[1] then g1 =1 if obt[2]=0 & objr[2]=pp[2] then g2 =2 if g1>0 & g2>0 fin =3 : mfin$ =" There's no winner! " else if j<>startj then fin =g1+g2 if fin then mfin$ ="The "+word$(PawnsCl$,pclr[fin])+" player is the winner! " endif if len(mfin$) then Popup mfin$ Return Tirage: % tirage carte magie ( Fee ou non ) quand objet non atteind. if CarteM<28 duree =900 : f =crtM[CarteM] : CarteM++ if f then crtt =CarteFee else crtt =NoChance gr.modify CrtMobile, "bitmap", crtt, "y", 325, "x", -100+(scx+200)*(j=2) if j=1 then xx =50 else xx =scx-150 move(CrtMobile, xx, 325, 8) : pause duree if f move(CrtMobile, xx, 590, 10) : fee[j]++ : gr.modify nbfee[j], "text", int$(fee[j]) gr.modify crtMag[j], "bitmap", CarteFee : move(CrtMobile, -100+(scx+200)*(j=2), 325, 0) else move(CrtMobile, -100+(scx+200)*(j=2), 325, 10) endif endif Return RotEdge: % détermine n° de la haie et son 'sens' de rotation manuel. nh =0 : sens =0 : cc =cx1*1000+cy1*100+cx*10+cy if cx>0 & cx<9 & cx1 & cx1<9 & cy>0 & cy<9 & cy1>0 & cy1<9 & (abs(cx-cx1)=1 | abs(cy-cy1)=1) & (cx-cx1)*(cy-cy1)=0 for nn=1 to 25 c4[1] =val(word$(pr$,nn)) : c4[2] =c4[1]-10 : c4[3] =c4[1]-11 : c4[4] =c4[1]-1 : nh =nn if cc=c4[1]*100+c4[2] | cc=c4[2]*100+c4[3] | cc=c4[3]*100+c4[4] | cc=c4[4]*100+c4[1] sens =1 : f_n.break elseif cc=c4[1]*100+c4[4] | cc=c4[4]*100+c4[3] | cc=c4[3]*100+c4[2] | cc=c4[2]*100+c4[1] sens =-1 : f_n.break endif next if oldnh & nh<>oldnh then nh =0 else oldnh =nh % pour empêcher de tourner une autre haie que celle déjà tournée 1 fois endif return Rotation: % graphics rotate 'nh' 1/4 of turn smoothly... and pawns if there has... if nh>0 & sens<>0 cc$ ="" : for c=1 to 4 : cc$+=int$(c4[c])+" " : next : Array.Fill fpp[],0 if sens<>0 & c4[1]>0 & (IS_IN(int$(pp[1]),cc$) | IS_IN(int$(pp[2]),cc$)) % un pion (ou +) sur une des cases. vr$ =word$("8124 0000 1248",sens+2) for c=1 to 4 xc =int(c4[c]/10) : yc =mod(c4[c],10) : vr =val(mid$(vr$,c,1)) cd =c+sens-4*(c=4)*(sens>0)+4*(c=1)*(sens<0) % case voisine de destination éventuelle. if pp[1]=c4[c] & BAND(c[xc,yc],vr) fpp[1] =c4[cd] : xd1 =int(pp[1]/10) : yd1 =mod(pp[1],10) : xd1 =pgx+(xd1-1)*dc : yd1 =pgx+(yd1-1)*dc xa1 =int(fpp[1]/10) : ya1 =mod(fpp[1],10) : xpa1 =pgx+(xa1-1)*dc : ypa1 =pgx+(ya1-1)*dc d1 =CAP(xd1,yd1,xpa1,ypa1) : gr.get.position p[1], px1, py1 endif if pp[2]=c4[c] & BAND(c[xc,yc],vr) fpp[2] =c4[cd] : xd2 =int(pp[2]/10) : yd2 =mod(pp[2],10) : xd2 =pgx+(xd2-1)*dc : yd2 =pgx+(yd2-1)*dc xa2 =int(fpp[2]/10) : ya2 =mod(fpp[2],10) : xpa2 =pgx+(xa2-1)*dc : ypa2 =pgx+(ya2-1)*dc d2 =CAP(xd2,yd2,xpa2,ypa2) : gr.get.position p[2], px2, py2 endif next endif inc =sens*5 : ang =val(word$("0 90 0 90 180 270",sh[nh])) % 'inc' doit absolument être un multiple de 90. mv =0 : inp =int(dc/(90/abs(inc))) for a=1 to int(sens*90/inc) ang+=inc : gr.modify rot[nh], "angle", ang : mv+=inp % la haie n°nh if fpp[1] then gr.modify p[1], "x", px1+diX[d1]*mv, "y", py1+diY[d1]*mv % les pions if fpp[2] then gr.modify p[2], "x", px2+diX[d2]*mv, "y", py2+diY[d2]*mv gr.render next if fpp[1] gr.modify p[1], "x", pgx+((dc-42)/2)+(xa1-1)*dc, "y", pgy+((dc-69)/2)+(ya1-1)*dc : pp[1] =fpp[1] % placement endif if fpp[2] gr.modify p[2], "x", pgx+((dc-42)/2)+(xa2-1)*dc, "y", pgy+((dc-69)/2)+(ya2-1)*dc : pp[2] =fpp[2] % correct endif np =val(word$(sr$,nh)) % type de haie if np =2 : sh[nh] =3-sh[nh] % haie 2 branches else : sh[nh] =sh[nh]+sens-4*(sh[nh]=6)*(sens>0)+4*(sh[nh]=3)*(sens<0) % haie 3 branches endif GOSUB Maj4cases endif Return Maj4cases: % mise à jour des 4 cases autour de la haie n° 'nh' pivotée d'un quart de tour et pions... !! cc$ ="" : for c=1 to 4 : cc$+=int$(c4[c])+" " : next if sens<>0 & c4[1]>0 & (IS_IN(int$(pp[1]),cc$) | IS_IN(int$(pp[2]),cc$)) % un pion (ou +) sur une des cases. vr$ =word$("8124 0000 1248",sens+2) for c=1 to 4 xc =int(c4[c]/10) : yc =mod(c4[c],10) : vr =val(mid$(vr$,c,1)) cd =c+sens-4*(c=4)*(sens>0)+4*(c=1)*(sens<0) % case voisine de destination éventuelle. if pp[1]=c4[c] & BAND(c[xc,yc],vr) then pp[1] =c4[cd] if pp[2]=c4[c] & BAND(c[xc,yc],vr) then pp[2] =c4[cd] next endif !! xp =x(word$(pr$,nh)) : yp =y(word$(pr$,nh)) % la case en bas à droite des 4 cases concernées par la haie 'nh' os$ ="08022080;10100404;080200000;00100400;00002080;10000004" d =0 : ox =xp : oy =yp : cc$ =word$(os$,sh[nh],";") for c=1 to 8 e =val(word$("1 8 1 2 2 4 8 4",c)) : ee =val(mid$(cc$,c,1)) : si =2*(ee=0)-1 if BAND(c[ox,oy],e)=ee then c[ox,oy] =c[ox,oy]+si*e if !mod(c,2) : d++ if d<4 : i =val(mid$("451",d,1)) : ox =xp+diX[i] : oy =yp+diY[i] else : F_n.Break endif endif next Return Linked: % make chf$ with all cells linked to STARTX,STARTY. chf$ =xy$(STARTX,STARTY)+" " : nc =1 Do n$ =word$(chf$,nc) if len(n$) : xc =x(n$) : yc =y(n$) for i=1 to 4 % 1=North, 2=Est, 3=South, 4=West Xnext =xc+diX[i] : Ynext =yc+diY[i] % neighboring cell in the direction i. if Xnext>0 & Ynext>0 & Xnext<9 & Ynext<9 % stay into the gameboard d =val(mid$("3412",i,1)) % the opposite direction of i. if !BAND(c[xc,yc],POW(2,i-1)) & !BAND(c[Xnext,Ynext],POW(2,d-1)) % can go in 'i' direction. cc$ =xy$(Xnext,Ynext) : if !IS_IN(cc$,chf$) then chf$+=cc$+" " % make the string of linked cells. endif endif next : nc++ endif Until n$="" return ShowLinked: for c=1 to len(chf$)/3 : x =x(word$(chf$,c)) : y =y(word$(chf$,c)) : gr.show chm[x,y] : next return EffLinked: for y=1 to 8 : for x=1 to 8 : gr.hide chm[x,y] : next : next : gr.render Return Go: % move the pawn to TARGX,TARGY by the best path. pas =16 : TARGX =cx : TARGY =cy : GOSUB PathFinder % shortest path from STARTX,STARTY to TARGX,TARGY lc =len(dest$)/3 : if !lc then return for c=lc-1 to 1 step -1 cc$ =word$(dest$,c) : ax =x(cc$) : ay =y(cc$) move2(p[j], pgx+((dc-42)/2)+(ax-1)*dc, pgy+((dc-69)/2)+(ay-1)*dc, pas) next pp[j] =TARGX*10+TARGY % nouvelles coordonnées du pion. gr.modify played, "x", pgx+(TARGX-1)*dc, "y", pgy+(TARGY-1)*dc Return Capture: % controle si le pion est sur la case de l'objet qu'il devait récupérer. if obt[j]>0 if po[TARGX,TARGY] =val(word$(obj$[j],obt[j])) : obt[j]-- : gr.modify nobr[j], "text", int$(obt[j]) if obt[j] : gr.modify otbmp[j], "bitmap", obj[val(word$(obj$[j],obt[j]))] else : gr.hide otbmp[j] endif GOSUB MarqOb endif endif RETURN MarqOb: % montre et mémorise ds objr[j] le nouvel objet que 'j' doit récupérer. if obt[j] : xj =0 : yj =0 for y=1 to 8 for x=1 to 8 if po[x,y] =val(word$(obj$[j],obt[j])) gr.modify obpj[j], "x", pgx+(x-0.5)*dc, "y", pgy+(y-0.5)*dc : xj =x : yj =y : F_n.break endif next if xj then F_n.break next else % position de départ à rejoindre... xj =1+7*(j=2) : yj =1 : gr.modify obpj[j], "x", pgx+(xj-0.5)*dc, "y", pgy+(yj-0.5)*dc endif objr[j] =xyn(xj,yj) % case du nouvel objet à récupérer pour j. Return PathFinder: % ************ RECHERCHE du PLUS COURT CHEMIN ************* xc =STARTX % case courante yc =STARTY ppp =0 % distance pour arriver là du parent... ici 0 puisque c'est la case de départ ! success =0 ! la case son parent ppp son cout (sur 3 chiffres) lf$ ="_"+USING$(,"%02.0f",STARTX)+USING$(,"%02.0f",STARTY)~ +USING$(,"%02.0f",STARTX)+USING$(,"%02.0f",STARTY) % liste fermée lo$ ="" % liste ouverte DO FOR i=1 to 4 % check all 4 directions Xnext =xc+diX[i] % coordonnée de la case voisine dans la direction i. Ynext =yc+diY[i] if Xnext>0 & Ynext>0 & Xnext<9 & Ynext<9 % reste sur le plateau d =val(mid$("3412",i,1)) if !BAND(c[xc,yc],POW(2,i-1)) & !BAND(c[Xnext,Ynext],POW(2,d-1)) % can go in 'i' direction. ccc =ppp + abs(TARGY-Ynext) + abs(TARGX-Xnext) % Calcul du Cout de cette case voisine. ct$ ="_"+ USING$(,"%02.0f",Xnext)+ USING$(,"%02.0f",Ynext) % case à rechercher... if Ynext=TARGY & Xnext=TARGX % arrivée... lf$ = lf$ + ct$ +USING$(,"%02.0f",xc)+USING$(,"%02.0f",yc) % liste fermée success = 1 : F_n.break else if Is_In(ct$, lf$) = 0 % si la case n'est PAS dans la liste fermée ... slo = Is_In(ct$, lo$) % on la cherche dans la Liste Ouverte lo$ if slo = 0 % si la case n'est pas dans la liste ouverte : on l'y met et c'est tout... lo$= lo$ +ct$ + USING$(,"%02.0f",xc)+ USING$(,"%02.0f",yc)~ + USING$(,"%03.0f",ppp)+ USING$(,"%03.0f",ccc) % liste ouverte else ! si elle y est : comparer les 2 coûts cclo = val(mid$(lo$, slo + 12, 3)) % cout de cette case déjà présente dans lo$ if ccc < cclo % si le cout actuel est inférieur à celui de cette case trouvée dans lo$ : ! mise à jour des données de cette case dans la liste ouverte : " parent ppp et cout" lt$ = left$(lo$,slo+4) % partie gauche de lo$ y compris les XXYY de la case à mettre à jour lt$ = lt$ + USING$(,"%02.0f",xc) + USING$(,"%02.0f",yc)~ + USING$(,"%03.0f",ppp) + USING$(,"%03.0f",ccc) % mise à jour du parent + cout lo$ = lt$ + right$(lo$,len(lo$)-len(lt$)) % reconstruction de lo$ endif endif endif endif endif endif NEXT if success then D_u.break nclo = len(lo$)/15 % nbre total de cases dans lo$ (liste ouverte) (rappel: 1 case = 15 caractères) if nclo = 0 % si liste ouverte vide = pas de solution... on arrête. D_u.break elseif nclo = 1 % s'il n'y a qu'une case dans lo$ alors c'est celle là qui est sélectionnée bien sur...! ncppc =1 else % localise dans lo$ le n° de la case qui a le plus petit cout... = ncppc mc =val(right$(lo$,3)) % cout référence = celui de la DERNIERE case enregistrée dans lo$ ncppc =nclo for n=nclo to 1 step -1 % puis on remonte case par case dans lo$ en partant de la fin... mc2 =val(mid$(lo$, n*15-2, 3)) % cout de la case précédente dans lo$ if mc2 < mc % cout inférieur trouvé... mc =mc2 ncppc =n % ncppc = localisation (base 15) dans lo$ de la case qui a le plus petit coût. endif next endif lt$ =mid$(lo$,(ncppc-1)*15+1,15) % la case choisie dans lo$ est mise dans une chaine temporaire. xc =val(mid$(lt$,2,2)) % devient la nouvelle case courante, (et donc le nouveau parent...) yc =val(mid$(lt$,4,2)) ppp =val(mid$(lt$,10,3)) + 1 % nouveau cout pour venir jusqu'ici (dans le chemin) lf$ +=left$(lt$,9) % ajoutée à la liste fermée (constitution du chemin) ! retrait de cette case de lo$ (liste ouverte) : lt$ =left$(lo$,(ncppc-1)*15) % partie gauche de lo$ avant la case choisie rst =nclo - (len(lt$)/15+1) lo$ =lt$ + right$(lo$,rst*15) % reconstitution de la Liste Ouverte UNTIL success>0 % -------------- FIN de la RECHERCHE du PLUS COURT CHEMIN --------------- dest$ ="" if success pl =0 : i =Is_In("_"+USING$(,"%02.0f",Xnext)+USING$(,"%02.0f",Ynext), lf$) while i > 1 ax =val(mid$(lf$,i+5,2)) : ay =val(mid$(lf$,i+7,2)) i =Is_In("_"+USING$(,"%02.0f",ax)+USING$(,"%02.0f",ay), lf$) dest$+=xy$(ax,ay)+" " : pl++ Repeat dest$ =xy$(TARGX,TARGY)+" "+dest$ % le parcours le plus court entre STARTX,STARTY & TARGX,TARGY endif RETURN InitBmp: % creation des bitmaps dc =98 pgx =(scx-(8*dc))/2 pgy =(scy-(8*dc))/2 DIM obj[16], pion[4] Gr.Bitmap.Load src, path$+"LabyTwist.png" : n =0 for y=1 to 2 : for x=1 to 8 n++ : Gr.Bitmap.Crop obj[n], src, (x-1)*50, (y-1)*50, 50,50 % 16 objets next : next for p=1 to 4 : Gr.Bitmap.Crop pion[p], src, 400+(p-1)*42, 1, 41,69 : next % pions Gr.Bitmap.Crop fond, src, 0,100,dc,dc % graviers Gr.Bitmap.Crop Fairy, src, 601,0,94,147 % grande Fee Gr.Bitmap.Crop Fee, src, 504,74,61,90 % petite Fee Gr.Bitmap.Crop main1, src, 565,154,65,46 % main joueur 1 (gauche) Gr.Bitmap.Crop main2, src, 630,154,65,46 % main joueur 2 (droite) Gr.Bitmap.Crop cadre1, src, 134,101,pgx,48 % haut gauche Gr.Bitmap.Crop cadre2, src, 134,152,pgx,48 % bas gauche Gr.Bitmap.Crop cadre3, src, 500-pgx,101,pgx,48 % haut droit Gr.Bitmap.Crop cadre4, src, 500-pgx,152,pgx,48 % bas droit Gr.Bitmap.Crop cadre5, src, 134,126,pgx,48 % centre gauche Gr.Bitmap.Crop cadre6, src, 500-pgx,126,pgx,48 % centre droit gr.bitmap.crop coin1, src, 145,118,100,55 % haut gauche gr.bitmap.crop coin2, src, 145,128,100,55 % bas gauche gr.bitmap.crop coin3, src, 392,118,100,55 % haut gauche gr.bitmap.crop coin4, src, 392,128,100,55 % haut gauche Gr.Bitmap.Delete src gr.set.stroke 2 Gr.Bitmap.Create SelFeeBmp, 120, 170 Gr.Bitmap.Drawinto.Start SelFeeBmp gr.color 100, 255, 253, 228, 0 : gr_Rect(0,0,34,120,170,0) gr.color 170, 255, 253, 228, 0 : gr_Rect(2,2,28,116,166,0) gr.color 255, 255, 253, 228, 0 : gr_Rect(4,4,26,112,162,0) gr.color 170, 255, 253, 228, 0 : gr_Rect(6,6,24,108,158,0) Gr.Bitmap.Create CarteFee, 100, 150 Gr.Bitmap.Drawinto.Start CarteFee clr("255 92 88 185 1") : gr_Rect(0,0,16,100,150,1) gr.bitmap.draw nul, Fairy,3,1 Gr.Bitmap.Create Magie, 100, 150 Gr.Bitmap.Drawinto.Start Magie clr("255 92 88 185 1") : gr_Rect(0,0,16,100,150,1) : clr("255 255 255 255 1") for p=1 to 250 : x =int(rnd()*100) : y =int(rnd()*150) : gr.point nul,x,y : next Gr.Bitmap.Create CarteObjet, 100, 140 Gr.Bitmap.Drawinto.Start CarteObjet clr("255 92 88 185 1") : gr_Rect(0,0,16,100,140,1) : clr("255 255 255 255 1") for p=1 to 200 : x =int(rnd()*100) : y =int(rnd()*140) : gr.point nul,x,y : next clr("255 220 220 220 1") : gr.circle nul, 50, 70, 32 Gr.Bitmap.Create NoChance, 100, 150 Gr.Bitmap.Drawinto.Start NoChance clr("255 92 88 185 1") : gr_Rect(0,0,16,100,150,1) : clr("255 255 255 255 1") for p=1 to 250 : x =int(rnd()*100) : y =int(rnd()*150) : gr.point nul,x,y : next clr("255 60 240 50 2") : gr.text.size 24 : gr.text.align 2 : gr.set.stroke 2 gr.text.draw nul, 50, 55, "NO" gr.text.draw nul, 50, 100, "CHANCE" : gr.text.align 1 Gr.Bitmap.Create carre, dc,dc % fond d'une case Gr.Bitmap.Drawinto.Start carre gr.bitmap.draw nul, fond, 0,0 clr("255 190 190 190 1") : gr_Rect(1,1, 16, dc-1,dc-1, 0) dh =2*dc Gr.Bitmap.Create bmph[1], dh,dh % haie 2 branches horizontales. Gr.Bitmap.Drawinto.Start bmph[1] clr("255 50 200 54 1") : cc =dh/12 for x=2 to 11 : gr.circle nul, (x-0.5)*cc, dh/2, cc/1.5 : next Gr.Bitmap.Create bmph[2], dh,dh % haie 3 branches horizontales et vers le haut. Gr.Bitmap.Drawinto.Start bmph[2] for x=2 to 11 : gr.circle nul, (x-0.5)*cc, dh/2, cc/1.5 : next for y=2 to 6 : gr.circle nul, dh/2, (y-0.5)*cc, cc/1.5 : next gr.bitmap.create pplayed, dc, dc % white circle to show the last cell selected gr.bitmap.drawinto.start pplayed gr.color 100, 255, 253, 228, 0 : gr.circle nul, dc/2, dc/2, dc/2-4 gr.color 170, 255, 253, 228, 0 : gr.circle nul, dc/2, dc/2, dc/2-6 gr.color 255, 255, 253, 228, 0 : gr.circle nul, dc/2, dc/2, dc/2-8 gr.color 170, 255, 253, 228, 0 : gr.circle nul, dc/2, dc/2, dc/2-10 gr.bitmap.create phedge, dc, dc % red circle to show the last hedge touched gr.bitmap.drawinto.start phedge gr.color 100, 255, 84, 0, 0 : gr.circle nul, dc/2, dc/2, dc/3.2-4 gr.color 170, 255, 84, 0, 0 : gr.circle nul, dc/2, dc/2, dc/3.2-6 gr.color 255, 255, 84, 0, 0 : gr.circle nul, dc/2, dc/2, dc/3.2-8 gr.color 170, 255, 84, 0, 0 : gr.circle nul, dc/2, dc/2, dc/3.2-10 gr.bitmap.create plateau, 800, 800 gr.bitmap.drawinto.start plateau nx =(800-(8*dc))/2 ny =(800-(8*dc))/2 for y=1 to 8 : for x=1 to 8 gr.color 255 : gr.bitmap.draw nul, carre, nx+(x-1)*dc, ny+(y-1)*dc next : next cc =dc/8 : clr("255 80 160 78 1") % cadre vert for x=1 to 65 : gr.circle nul, nx+(x-1)*cc, ny, cc/1.5 : next for x=1 to 65 : gr.circle nul, nx+(x-1)*cc, ny+8*dc, cc/1.5 : next for y=1 to 65 : gr.circle nul, nx, ny+(y-1)*cc, cc/1.5 : next for y=1 to 65 : gr.circle nul, nx+8*dc, ny+(y-1)*cc, cc/1.5 : next gr.bitmap.create bbhelp, 1100, 580 gr.bitmap.drawinto.start bbhelp clr("255 110 194 114 2") : gr_Rect(0,0, 80, 1100,580, 1) gr.text.size 36 : clr("255 255 250 152 2") : gr.set.stroke 3 : gr.text.align 1 gr.text.draw nul, 300, 42, "- - Labyrinthe Twist - -" gr.text.size 27 : clr("255 255 250 152 1") : gr.set.stroke 2 DIM txt$[13] if lang=2 txt$[1] =" Chaque joueur doit récupérer 8 objets puis revenir à son point de départ." txt$[2] ="A son tour, il ne peut tourner qu'une seule haie (ou aucune) dans le sens qu'il veut," txt$[3] =" et déplacer son pion seulement oú le labyrinthe lui permet, avant ou/et après avoir" txt$[4] =" éventuellement tourné une haie." txt$[5] ="Une haie tournée entraine avec elle tous les pions se trouvant sur une case voisine." txt$[6] ="Si lors de son tour, le joueur n'atteint pas son objet, il devra valider son tour et recevra" txt$[7] =" une des 28 cartes magie. Il a alors 2 chances sur 3 de recevoir une carte fée." txt$[8] ="Il lui coûtera 2 cartes fées pour se téléporter d'une case fée de son chemin vers une" txt$[9] =" autre case fée de son choix dans le labyrinthe." txt$[10] ="Il peut y avoir égalité si les 2 joueurs rejoignent leur point de départ lors du" txt$[11] =" même tour de jeu." else txt$[1] =" Each player must collect 8 items and then return to his starting point." txt$[2] ="In turn, he can rotate only one hedge (or none) in the direction he wants, and move" txt$[3] =" his pawn only where the labyrinth allows him, before or/and after having possibly" txt$[4] =" rotated an hedge." txt$[5] ="A rotated hedge leads with it all pawns on a neighboring cells." txt$[6] ="If during his turn, the player doesn't reach his item, he will have to validate his turn and" txt$[7] =" receive one of the 28 magic cards, so he has 2 chances out of 3 to receive a fairy card." txt$[8] ="It will cost him 2 fairy cards to teleport his pawn from a fairy cell from his path to" txt$[9] =" another fairy cell of his choice in the labyrinth." txt$[10] ="There can be tie if both players join their starting point at the same game turn..." endif ec =44 : for t=1 to 13 : gr.text.draw nul, 28, 50+t*ec, txt$[t] : next gr.text.draw nul, 500, 570, "Initial game: 'Labyrinth Twist' by Ravensburger" Gr.Bitmap.Drawinto.End PawnsCl$ ="RED YELLOW GREEN BLUE" Return InitGame: % init each starting new game GR.CLS : array.fill c[],0 : array.fill obt[],0 : array.fill fee[],0 : nh=0 : prt =0 pr$ ="22 42 62 82 33 53 73 24 44 64 84 35 55 75 26 46 66 86 37 57 77 28 48 68 88" % position des points de rotation haies sr$ ="2 3 2 2 3 2 3 2 3 3 3 2 2 2 3 3 3 2 3 2 3 2 2 3 2" % type de haie (2 ou 3 branches) gr.bitmap.draw nul, cadre1, 0,0 : gr.bitmap.draw nul, cadre3, scx-pgx,0 for c=1 to 15 : gr.bitmap.draw nul, cadre5, 0,c*48 : gr.bitmap.draw nul, cadre6, scx-pgx,c*48 : next gr.bitmap.draw nul, cadre2, 0,scy-48 : gr.bitmap.draw nul, cadre4, scx-pgx,scy-48 gr.bitmap.draw nul, plateau, int((scx-800)/2), 0 clr("60 0 255 75 1") % fond vert clair pour montrer les cases lièes... for y=1 to 8 : for x=1 to 8 gr.rect chm[x,y], pgx+5+(x-1)*dc, pgy+5+(y-1)*dc, pgx-5+x*dc, pgy-5+y*dc : gr.hide chm[x,y] c[x,y] =2*(x=8)+8*(x=1) : c[x,y]+=1*(y=1)+4*(y=8) % les murs fixes des cases des bords. next : next fee$ ="61 42 13 74 25 86 67 38" : gr.color 130 for fe=1 to 8 % placement des Fées x =x(word$(fee$,fe)) : y =y(word$(fee$,fe)) gr.bitmap.draw nul, Fee, pgx+18+(x-1)*dc, pgy+4+(y-1)*dc : po[x,y] =20 next gr.color 255 pob$ ="21 51 52 82 33 63 24 54 15 75 36 66 47 77 28 68" % positions fixes des objets. ho$ ="" for ob=1 to 16 % placement des objets x =x(word$(pob$,ob)) : y =y(word$(pob$,ob)) Do : ho =int(rnd()*16)+1 : Until !IS_IN(USING$(,"%02.0f",ho),ho$) : ho$+=USING$(,"%02.0f ",ho) gr.bitmap.draw obptr[ob], obj[ho], pgx+((dc-50)/2)+(x-1)*dc, pgy+((dc-50)/2)+(y-1)*dc : po[x,y] =ho next clr("130 240 240 240 1") : gr.oval nul, 48, 310, 112, 405 : gr.oval nul, scx-112, 310, scx-48, 405 pclr[1] =1 : pclr[2] =4 : gr.color 255 gr.bitmap.draw pjr[1], pion[pclr[1]], 60, 320 % pion du camps gr.bitmap.draw pjr[2], pion[pclr[2]], scx-100, 320 aff =0 : sens =0 : array.fill c4[],0 for nh=1 to 25 % installe les haies tournées au hasard th =val(word$(sr$,nh)) : if th=2 then sh[nh] =int(rnd()*2)+1 else sh[nh] =int(rnd()*4)+3 % sens de la haie. c$ =word$(pr$,nh) : x =x(c$)-1 : y =y(c$)-1 : ang =val(word$("0 90 0 90 180 270",sh[nh])) gr.rotate.start ang, pgx+x*dc, pgy+y*dc, rot[nh] gr.bitmap.draw haie[nh], bmph[th-1], pgx+(x-1)*dc, pgy+(y-1)*dc gr.rotate.end GOSUB Maj4cases % maj des 4 cases autour de la haie 'nh' next aff =1 gr.bitmap.draw p[1], pion[pclr[1]], pgx+((dc-42)/2)+(1-1)*dc, pgy+((dc-69)/2)+(1-1)*dc : pp[1] =1*10+1 % pions gr.bitmap.draw p[2], pion[pclr[2]], pgx+((dc-42)/2)+(8-1)*dc, pgy+((dc-69)/2)+(1-1)*dc : pp[2] =8*10+1 % plateau clr("255 48 228 100 1") % les 25 points à toucher pour faire tourner les haies... vert for pr=1 to 25 c$ =word$(pr$,pr) : x =x(c$) : y =y(c$) : gr.circle pr[pr], pgx+(x-1)*dc, pgy+(y-1)*dc, dc/6 next gr.bitmap.draw played, pplayed, pgx+(1-1)*dc, pgy+(1-1)*dc-200 % le rond blanc... gr.bitmap.draw hedge, phedge, pgx+0.5*dc, pgy+0.5*dc-200 % le rond rouge... Array.Fill obj$[],"" : nob =8 % distribution des 'nob' (8 max) objets à récupérer par joueur. for nj=1 to 2 : for no=1 to nob co$ =obj$[1]+obj$[2] : Do : o =int(rnd()*16)+1 : Until !IS_IN(USING$(,"%02.0f",o),co$) obj$[nj]+=USING$(,"%02.0f ",o) next : next gr.set.stroke 3 clr("255 255 0 0 0") : gr.circle obpj[1], pgx+(2-0.5)*dc, pgy+(1-0.5)*dc, dc/2.8 : gr.paint.get clob[1] clr("255 0 0 255 0") : gr.circle obpj[2], pgx+(8-0.5)*dc, pgy+(2-0.5)*dc, dc/2.8 : gr.paint.get clob[4] clr("255 255 255 0 0") : gr.paint.get clob[2] clr("255 0 255 0 0") : gr.paint.get clob[3] gr.bitmap.draw crtOb[1], CarteObjet, 50, 130 % la carte du haut indique l'objet à récupérer gr.bitmap.draw crtMag[1], Magie, 50, 590 % la carte Fée : si x2 on peut utiliser un saut... gr.bitmap.draw crtOb[2], CarteObjet, scx-150, 130 gr.bitmap.draw crtMag[2], Magie, scx-150, 590 gr.bitmap.draw CrtMobile, Magie, scx, 325 gr.bitmap.draw SelFee, SelFeeBmp, scx-160, -200 % le selecteur de carte Fée obt[1] =nob : gr.bitmap.draw otbmp[1], obj[val(word$(obj$[1],obt[1]))], 75,175 obt[2] =nob : gr.bitmap.draw otbmp[2], obj[val(word$(obj$[2],obt[2]))], scx-125,175 Gr.bitmap.draw main[1], main1, pgx-100, 340 Gr.bitmap.draw main[2], main2, scx-215, 340 gr.set.stroke 2 clr("255 98 216 200 2") : gr.text.size 58 gr.text.draw nobr[1], 170, 260, int$(obt[1]) gr.text.draw nobr[2], scx-200, 260, int$(obt[2]) gr.text.draw nbfee[1], 170, scy-80, int$(fee[1]) gr.text.draw nbfee[2], scx-200, scy-80, int$(fee[2]) gr.bitmap.draw nul,coin1, 20, 30 gr.bitmap.draw nul,coin2, 20, 40 gr.bitmap.draw nul,coin3, 120, 30 gr.bitmap.draw nul,coin4, 120, 40 clr("255 255 128 39 2") : clr("255 255 200 14 2") : gr.text.size 34 gr.text.align 2 : gr.text.draw action1, 120, 74, "Laby-Twist" gr.oval start, 48,410,112,420 gr.bitmap.draw nul,coin1, scx-190, 30 gr.bitmap.draw nul,coin2, scx-190, 40 gr.bitmap.draw nul,coin3, scx-160, 30 gr.bitmap.draw nul,coin4, scx-160, 40 clr("255 255 128 39 1") : gr.text.size 38 gr.text.draw heure, scx-126, 76, left$(using$(,"%tT",time()),5) gr.bitmap.draw nul,coin1, 40, 450 % bouton de gauche (joueur 1) gr.bitmap.draw nul,coin2, 40, 490 gr.bitmap.draw nul,coin3, 115, 450 gr.bitmap.draw nul,coin4, 115, 490 clr("80 66 220 54 2") : gr.text.size 36 gr.text.draw tbt[1], 126, 510, "Validate" gr.bitmap.draw nul,coin1, scx-210, 450 % bouton de droite (joueur 2) gr.bitmap.draw nul,coin2, scx-210, 490 gr.bitmap.draw nul,coin3, scx-140, 450 gr.bitmap.draw nul,coin4, scx-140, 490 gr.text.draw tbt[2], scx-126, 510, "Validate" btj[1] =1 : btj[2] =1 : gr.paint.get tbc[1] clr("255 66 220 54 2") : gr.paint.get tbc[2] % 2 colors for button text Array.Fill crtM[],0 % le paquet des 28 cartes magie. prc =66 % pourcentage de cartes fées dans ce paquet. ncf =int(28*(prc/100)) for c=1 to 28 if c<=ncf then crtM[c] =1 % 1 = carte fée, 0 = pas de chance...! next for c=1 to 28 % Shuffle it. c1 =int(rnd()*28)+1 : do : c2 =int(rnd()*28)+1 : until c2<>c1 : swap crtM[c1], crtM[c2] next CarteM =1 % la carte du dessus du paquet... File.Exists fe, filename$ if fe then GOSUB LoadGame : File.Delete fe, filename$ oldj =j : j =1 : GOSUB MarqOb : j =2 : GOSUB MarqOb : j =oldj gr.modify start, "left", 48+(scx-160)*(startj=2), "right", 112+(scx-160)*(startj=2) % who started gr.bitmap.draw bhelp, bbhelp, 90, -580 clr("255 0 0 255 1") : gr.text.size 28 : gr.text.align 1 : gr.text.draw mess, 20, 436, "" % debug gr.text.size 26 : gr.text.align 3 for y=1 to 8 : for x=1 to 8 gr.text.draw db[x,y], pgx-12+x*dc, pgy-12+y*dc, int$(c[x,y]) next : next gr.text.align 1 : GOSUB AffCases RETURN AffCases: % juste pour debug for y=1 to 8 : for x=1 to 8 gr.modify db[x,y], "text", int$(c[x,y]) : gr.hide db[x,y] next : next Return SaveGame: Text.Open W, fi, filename$ % much compatible with OliBasic... Text.WriteLn fi, j, pp[1], pclr[1], pp[2], pclr[2], obt[1], obt[2], fee[1], fee[2],~ obj$[1], obj$[2], carteM, startj, objr[1], objr[2], oldnh for y=1 to 8 : c$ ="" for x=1 to 8 : c$+=USING$(,"%02.0f ",c[x,y]) : next Text.WriteLn fi, c$ next for y=1 to 8 : c$ ="" for x=1 to 8 : c$+=USING$(,"%02.0f ",po[x,y]) : next Text.WriteLn fi, c$ next c$ ="" : for h=1 to 25 : c$+=int$(sh[h]) : next : Text.WriteLn fi, c$ c$ ="" : for c=1 to 28 : c$+=int$(crtM[c]) : next : Text.WriteLn fi, c$ Text.Close fi Return LoadGame: Text.Open R, fi, filename$ Text.ReadLn fi, c$ j =val(word$(c$,1,",")) : oldnh =val(word$(c$,16,",")) pp[1] =val(word$(c$,2,",")) : pclr[1] =val(word$(c$,3,",")) pp[2] =val(word$(c$,4,",")) : pclr[2] =val(word$(c$,5,",")) obt[1] =val(word$(c$,6,",")) : fee[1] =val(word$(c$,8,",")) obt[2] =val(word$(c$,7,",")) : fee[2] =val(word$(c$,9,",")) obj$[1] =word$(c$,10,",") : obj$[2] =word$(c$,11,",") carteM =val(word$(c$,12,",")) : startj =val(word$(c$,13,",")) objr[1] =val(word$(c$,14,",")) : objr[2] =val(word$(c$,15,",")) for y=1 to 8 Text.ReadLn fi, c$ : for x=1 to 8 : c[x,y] =val(word$(c$,x)) :next next for y=1 to 8 Text.ReadLn fi, c$ : for x=1 to 8 : po[x,y] =val(word$(c$,x)) :next next Text.ReadLn fi, c$ : for h=1 to 25 : sh[h] =val(mid$(c$,h,1)) : next Text.ReadLn fi, cr$ : for c=1 to 28 : crtM[c] =val(mid$(cr$,c,1)) : next Text.Close fi for h=1 to 25 : ang =val(word$("0 90 0 90 180 270",sh[h])) : gr.modify rot[h], "angle", ang : next for nj=1 to 2 px =x(int$(pp[nj])) : py =y(int$(pp[nj])) : gr.modify pjr[nj], "bitmap", pion[pclr[nj]] gr.modify p[nj], "x", pgx+((dc-42)/2)+(px-1)*dc, "y", pgy+((dc-69)/2)+(py-1)*dc, "bitmap", pion[pclr[nj]] gr.modify nobr[nj], "text", int$(obt[nj]) if obt[nj] then gr.modify otbmp[nj], "bitmap", obj[val(word$(obj$[nj],obt[nj]))] else gr.hide otbmp[nj] gr.modify nbfee[nj], "text", int$(fee[nj]) if fee[nj] then gr.modify crtMag[nj], "bitmap", CarteFee next for o=1 to 16 x =x(word$(pob$,o)) : y =y(word$(pob$,o)) : gr.modify obptr[o], "bitmap", obj[po[x,y]] next if oldnh then gr.get.position pr[oldnh],hx,hy : gr.modify hedge, "x", hx-0.5*dc, "y",hy-0.5*dc % rond rouge (haie touchée) STARTX =x(int$(pp[j])) : STARTY =y(int$(pp[j])) : GOSUB Linked : GOSUB ShowLinked gr.modify played, "x", pgx+(STARTX-1)*dc, "y", pgy+(STARTY-1)*dc oldstartj =startj : startj =3-j : GOSUB DetectEog : startj =oldstartj % si fin de jeu... Return Fonctions: % all functions needed... Fn.def xy$(x,y) % 2 digit because x nor y > 9... Fn.rtn int$(x*10+y) Fn.end Fn.def x(c$) % val 'x' from c$ ( see the 'xy$(x,y)' function ) Fn.rtn int(val(c$)/10) Fn.end Fn.def y(c$) % val 'y' from c$ Fn.rtn mod(val(c$),10) Fn.end Fn.def xn(v) % 'x' from number (00 to 99) Fn.rtn int(v/10) Fn.end Fn.def yn(v) % 'y' from number (00 to 99) Fn.rtn mod(v,10) Fn.end Fn.def xyn(x,y) % make number with 2 values from x & y < 9. Fn.rtn x*10+y Fn.end Fn.def CAP(xa,ya,xb,yb) % direction from xa,ya to xb,yb 1=north to 8=north-west d =HYPOT((xa-xb),(ya-yb))+0.000001 % distance between xa,ya & xb,yb a =int(todegrees(acos((xb-xa)/d))) % angle if yb>ya then a =360-a a2 =a-135 : a2+=360*(a2<0) : fn.rtn 4-abs(int(a2/90)) % if from 1 to 4 ! a2 =a-112.5 : a2+=360*(a2<0) : fn.rtn 8-abs(int(a2/45)) % if from 1 to 8 Fn.end FN.DEF clr( c$ ) % c$ format: "alpha R V B mode" gr.color val(word$(c$,1)), val(word$(c$,2)), val(word$(c$,3)), val(word$(c$,4)), val(word$(c$,5)) FN.END Fn.def gr_UP( ptr ) % put the graphic pointer 'ptr' UP to all other. gr.getDL ndl[],1 : array.length sz, ndl[] if !ptr | sz=1 | ndl[sz] =ptr then array.delete ndl[] : Fn.rtn 0 array.search ndl[],ptr,nptr if nptr then for nn=nptr to sz-1 : ndl[nn] =ndl[nn+1] : next : ndl[sz] =ptr : gr.newDL ndl[] array.delete ndl[] Fn.end Fn.def move(ptr, arx, ary, speed) % move smoothly the bitmap 'ptr' to arx,ary gr_UP( ptr ) if speed>1 do gr.get.position ptr,dpx,dpy : ix =int((dpx-arx)/speed) : iy =int((dpy-ary)/speed) if abs(ix)<3 & abs(iy)<3 then D_u.break gr.modify ptr, "x",dpx-ix, "y",dpy-iy : gr.render until 0 endif gr.modify ptr, "x",arx, "y",ary : gr.render Fn.end Fn.def move2(ptr, arx, ary, pas) % move smoothly the bitmap 'ptr' to arx,ary gr_UP( ptr ) if pas>1 gr.get.position ptr,dpx,dpy : ex =int((arx-dpx)/pas) : ey =int((ary-dpy)/pas) for e=1 to pas-1 : gr.move ptr, ex, ey : gr.render : next endif gr.modify ptr, "x",arx, "y",ary : gr.render Fn.end FN.DEF gr_Rect(x,y, c, lx,ly, fill) % make rectangle with rounded corners. GR.ARC nul, x, y, x+c, y+c, -90, -90, fill % top left GR.ARC nul, x+lx-c,y, x+lx, y+c, -90, 90, fill % top right GR.ARC nul, x, y+ly-c,x+c, y+ly, -180, -90, fill % bottom left GR.ARC nul, x+lx-c, y+ly-c, x+lx, y+ly, 0, 90, fill % bottom right if !fill GR.LINE r1, x+c/2, y, x+lx-c/2, y % left GR.LINE r2, x, y+c/2, x, y+ly-c/2 % up GR.LINE r3, x+c/2, y+ly, x+lx-c/2, y+ly % right GR.LINE r4, x+lx, y+c/2, x+lx, y+ly-c/2 % down else c*=0.4 gr.rect nul, x+c, y, x+lx-c, y+ly gr.rect nul, x, y+c, x+lx, y+ly-c endif FN.END RETURN