/////////freecell version 3.0 //////// by: William Heaton ///////email questions or comments to //////acroporas@hotmail.com #define SAVE_SCREEN #define RETURN_VALUE #include #include #include #include #include #include #include #include #include #include #include #include short _ti89; int test(int x, int y); void box(int x, int y); void card(int x,int y, int sed); void ebox(int x,int y); void ecol(int y); void greyin(int x, int y); void col(int y); static char cards[8][20],suits[8][20]; unsigned char xcord[2][8]={{0,19,38,57,83,102,121,140},{0,20,40,60,80,100,120,140}},ycord[20]={0,21,27,33,39,45,51,57,63,69,75,81,81,81,81,81,81,81,81,81}; unsigned char dimond [] = {0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10}; unsigned char ten [] = {0x9C,0xA2,0xA2,0xA2,0xA2,0xA2,0x9C}; unsigned char heart [] = {0x6C,0xFE,0xFE,0x7C,0x38,0x10}; unsigned char club [] = {0xBB}; unsigned char spade [] = {0x10,0x38,0x7C,0xFE,0xFE,0x38,0x7C}; unsigned int ebox1 [] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; void _main(void) { static int location[2],selected[4],stats[3][2]={{0,0},{0,0},{0,0}},key[10]={337,340,344,338,13,268,264,4360,16649,277},intro=1,deal=0,autup=1; int x=0,y=0,z,move=0,nloc[2]={location[0],location[1]},px,py,vx,looking[5]={0,0,0,0,0}; float vy,t; char str[]=" "; HANDLE dlog; push_parse_text("freecell()"); ClrScr(); GrayOn (); SetPlane(1); beg: while (move!=268 && (intro!=2 || move==key[9])) { SetPlane(0); ClrScr(); SetPlane(1); ClrScr(); FontSetSys(F_8x10); DrawStr(47,5,"FreeCell",A_NORMAL); FontSetSys(F_4x6); DrawStr(60,25,"F1 Begin",A_NORMAL); DrawStr(60,32,"F2 Options",A_NORMAL); DrawStr(60,39,"F3 Exit",A_NORMAL); DrawStr(2,72,"Game Statistics",A_NORMAL); printf_xy(2,82,"Total: Won %i Lost %i",stats[0][0],stats[0][1]); printf_xy(2,92,"Streaks: Wins %i Losses %i Current %i",stats[1][0],abs(stats[1][1]),stats[2][0]); move=ngetchx(); if (move==270 || move==264) goto theend; if (move==269) { ClrScr(); DrawStr(59,1,"Options",A_NORMAL); DrawStr(3,15,"F1 Customize Keys",A_NORMAL); DrawStr(3,21,"F2 Reset Defaults",A_NORMAL); DrawStr(3,27,"F3 Reset Statistics",A_NORMAL); DrawStr(3,33,"F4 Turn ON/Off Title Screen",A_NORMAL); DrawStr(3,39,"F5 Turn ON/OFF AutoPlay",A_NORMAL); move=ngetchx(); if (move==272) { if (autup==1) autup=0; else autup=1; } if(move==271) { if (intro==1) intro=2; else intro=1; } if (move==270) { for(y=0;y<3;y++) { for (x=0;x<2;x++) stats[y][x]=0; } } if (move==269){key[0]=337; key[1]=340; key[2]=344; key[3]=338; key[4]=13; key[5]=268; key[6]=264; key[7]=4360; key[8]=16649; key[9]=277; intro=1; autup=1;} if (move==268) { ClrScr(); move=0; DrawStr(3,0,"Customize Keys",A_NORMAL); DrawStr(3,12,"Up",A_NORMAL); key[0]=ngetchx(); DrawStr(3,18,"Down",A_NORMAL); key[1]=ngetchx(); DrawStr(3,24,"Right",A_NORMAL); key[2]=ngetchx(); DrawStr(3,30,"Left",A_NORMAL); key[3]=ngetchx(); DrawStr(3,36,"Enter",A_NORMAL); key[4]=ngetchx(); DrawStr(3,42,"Enter",A_NORMAL); key[5]=ngetchx(); DrawStr(3,54,"Exit/Save",A_NORMAL); key[6]=ngetchx(); DrawStr(3,60,"Exit/Quit",A_NORMAL); key[7]=ngetchx(); DrawStr(3,66,"New Game",A_NORMAL); key[8]=ngetchx(); DrawStr(3,72,"Intro",A_NORMAL); key[9]=ngetchx(); } } FontSetSys(F_6x8); GKeyFlush(); } randomize(); if (deal==1) goto dun_dealing; deal: looking[0]=0; looking[1]=0; looking[2]=0; looking[3]=0; looking[4]=0; location[0]=0; location[1]=7; nloc[0]=0; nloc[1]=19; selected[0]=0; selected[1]=0; selected[2]=0; selected[3]=0; for (x=0;x<=7;x++) { for (y=0;y<=19;y++) { cards[x][y]=0; suits[x][y]=0; } } for (y=1;y<=7;y++) { for (x=0;x<=7;x++) { if (y==7 && x==4) goto dun_dealing; while(test(cards[x][y],suits[x][y])==0 || cards[x][y]==0) { cards[x][y]=1+random(13); suits[x][y]=1+random(4); } } } dun_dealing: deal=1; SetPlane(0); ClrScr(); SetPlane(1); ClrScr(); for(x=0;x<=7;x++) col(x); mainloop: if (min(min(cards[4][0],cards[5][0]),min(cards[6][0],cards[7][0]))==13) { GKeyFlush(); z=0; while(kbhit()==0) { z=z+1; if (z==5) z=1; x=xcord[0][z+3]; y=0; px=x; py=y; vy=random(15); vx=-random(6)-3; t=0; a: while(y < 79) { if (x<0) {vx=-vx; x=1; px=x; py=y; vy=t+vy; t=0;} if (x>160 || kbhit()!=0) goto b; card(x,y,suits[z+3][0]+5); t=t+0.25; y=trunc(0.5*t*t+vy*t+py); x=trunc(vx*t+px); } vy=-(t+vy)*0.73; px=x; y=78; py=78; t=0; goto a; b:; } GKeyFlush(); stats[2][1]=1; push_parse_text("you_won!"); deal=0; goto stats; } if (move==key[5] && selected[2]==0 && autup==1) { for(x=4;x<8;x++) looking[suits[x][0]]=cards[x][0]; for (vx=0;vx<=11;vx++) { x=vx; if (x<=7) { y=19; while (cards[ x ][ y ] == 0 && y != 0) y=y-1; if (y==0) y=21; } else { x=x-8; y=0; if(cards[x][y]==0) y=21; } if (y != 21 && cards[x][y] == looking[suits[x][y]]+1 && min(min(looking[1],looking[2]),min(looking[3],looking[4]))+2>=cards[x][y]) { for(z=4;z<8;z++) { if (suits[x][y]==suits[z][0] || (cards[z][0]==0 && cards[x][y]==1)) { cards[z][0]=cards[x][y]; suits[z][0]=suits[x][y]; cards[x][y]=0; suits[x][y]=0; card(z,0,1); if (y!=0) { ecol(xcord[1][x]); if (y==1) box(xcord[1][x],ycord[y]); col(x); } else ebox(xcord[0][x],ycord[y]); goto moved; } } } } } if (cards[ location[0] ][ location[1]+1 ] == 0 || location[1]==0) card(location[0],location[1],2); else card(location[0],location[1],1); if (selected[2]!=0) card(selected[0],selected[1],2); move=ngetchx(); if (move==key[6]) goto theend; if (cards[ location[0] ][ location[1]+1 ] == 0 && location[1] != 0) nloc[1]=19; if (move==KEY_ON) {off();} if (move==key[0]) { if (location[1]==1)goto moved; if (location[1]==0) location[1]=20; nloc[1]=location[1]-1;} if (move==key[1]) {if (nloc[1]==19) nloc[1]=-1;if (nloc[1]==0) nloc[1]=18; nloc[1]=nloc[1]+1;} if (move==key[2]) {nloc[0]=nloc[0]+1; if (nloc[0]==8) nloc[0]=0;} if (move==key[3]) {nloc[0]=nloc[0]-1; if (nloc[0]<0) nloc[0]=7;} if (move==key[4]) move=key[5]; if (move==key[8] || move==key[7]) {stats[2][1]=-1; goto stats;} if (move==key[9]) goto beg; if (move==key[5] && selected[3]!=0 && ((cards[location[0]][location[1]+1]==0 && ((suits[location[0]][location[1]]==0 && location[1] != 0) || (suits[location[0]][location[1]]+selected[3]<7 && suits[location[0]][location[1]]+selected[3]>3 && suits[location[0]][location[1]+x]!=selected[3] && cards[ location[0] ][ location[1]]-1==selected[2]))) || (location[1]==0 && (cards[selected[0]][selected[1]+1]==0 || location[1]==0) && ((location[0]>=4 && cards[ location[0] ][ location[1] ]+1==selected[2] && (suits[ location[0] ][ location[1] ]==selected[3] || suits[ location[0] ][ location[1] ]==0)) || (cards[location[0]][location[1]]==0 && location[0]<=3))))) { y=0; x=0; if (location[1]==0 || selected[1]==0) { if (location[1]!=0 && cards[location[0]][1]!=0) x=1; cards[ location[0] ][ location[1] +x]=selected[2]; suits[ location[0] ][ location[1] +x]=selected[3]; cards[ selected[0] ][ selected[1] ]=0; suits[ selected[0] ][ selected[1] ]=0; card(location[0],location[1],2); ecol(xcord[1][selected[0]]); goto moved; } for(z=0;z<=3;z++) {if (suits[z][0]==0) x=x+1;} for(z=0;z<=7;z++) {if (suits[z][1]==0) y=y+1;} if (location[1]==1) y=y-1; z=((((y*y)+y+2))*(x+1))/2; y=0; for(x=0;x<(20-selected[1]);x++) {if (cards[selected[0]][selected[1]+x] !=0) y=y+1;} if (y>z) { GrayOff(); dlog = DialogNewSimple(121,40); DialogAddTitle(dlog,"Illegal Move",BT_OK,BT_NONE); sprintf(str,"That move requries moving %i",y); DialogAddText(dlog,8,12,str); sprintf(str,"cards, you only have space for %i",z); DialogAddText(dlog,2,20,str); DialogDo(dlog,CENTER,CENTER,NULL,NULL); GrayOn(); ST_busy(ST_NORMAL); for(x=0;x<=7;x++) col(x); goto moved; } z=0; if (location[1]==1 && cards[location[0]][location[1]]==0) z=1; for (x=0;x=7 || suits[location[0]][location[1]+x]+suits[location[0]][location[1]+x-1]<=3 || suits[location[0]][location[1]+x]==suits[location[0]][location[1]+x-1] || suits[location[0]][location[1]+x]==0 || suits[location[0]][location[1]+x-1] == 0)) || (cards[ location[0] ][ location[1]+x ]+1 != cards[ location[0] ][ location[1]+x-1 ])) goto moved; x=x+1; nloc[1]=19; } selected[0]=location[0]; selected[1]=location[1]; selected[2]=cards[ location[0] ][ location[1] ]; selected[3]=suits[ location[0] ][ location[1] ]; } moved: if (y!=-6 && move==key[5]) {col(selected[0]); selected[0]=0; selected[1]=0; selected[2]=0; selected[3]=0;} y=0; while (cards[ nloc[0] ][ nloc[1] ] == 0 && nloc[1] != 0) nloc[1]=nloc[1]-1; if (nloc[1] == 0 && location[1] != 0 && location [0] != nloc[0]) nloc[1]=1; if (nloc[0] == location[0] && nloc[1] == location[1] && nloc[1] == 0 && (move == key[0] || move == key[1])) nloc[1]=1; if (location[1]==1 && (nloc[1] !=1 || nloc[0] != location[0]) && cards[ location[0] ][ location[1] ] == 0) ebox(xcord[1][location[0]],ycord[location[1]]); if (nloc[1]==0 && location[1]==0) card(location[0],0,1); col(location[0]); location[0]=nloc[0]; location[1]=nloc[1]; goto mainloop; stats: if ((stats[2][1]==1 && stats[2][0]>0) || (stats[2][1]==-1 && stats[2][0]<0)) stats[2][0]=stats[2][0]+stats[2][1]; else stats[2][0]=stats[2][1]; if (stats[1][0] <= stats[2][0] && stats[2][0]>0)stats[1][0]=stats[2][0]; if (stats[1][1] >= stats[2][0] && stats[2][0]<0) stats[1][1]=stats[2][0]; if (move==key[7]) {stats[0][1]=stats[0][1]+1; deal=0; goto theend;} if (stats[2][1]==1) {stats[0][0]=stats[0][0]+1; goto theend;} stats[0][1]=stats[0][1]+1; goto deal; theend: GrayOff (); } int test(int x,int y) { if (GetPix(x,101-y)) return (0); DrawPix (x,101-y,A_NORMAL); return (1); } void card(int x,int y, int sed) { int a=1,c=cards[x][y],s=suits[x][y]; x=xcord[min(y,1)][x]; y=ycord[y]; if (sed>3) {c=13; s=sed-5; sed=1;} if (c!=0) box(x,y); if (sed==2) greyin(x,y); if (c==0) { if ((y==0 || y==21) && sed==1) box(x,y); goto endcard; } if (sed==1) { if (y==81) greyin(x,y-6); box(x,y); if(s<=2) a=0; } SetPlane(a); if (c==1) c=14; if (c<=9) {printf_xy (x+1,y+2,"%i",c); printf_xy (x+9,y+12,"%i",c);} if (c==10) {Sprite8(x+2,y+2,7,ten,GetPlane(a),SPRT_OR); Sprite8(x+9,y+12,7,ten,GetPlane(a),SPRT_OR);} if (c==11) {printf_xy (x+1,y+2,"J"); printf_xy (x+9,y+12,"J");} if (c==12) {printf_xy (x+1,y+2,"Q"); printf_xy (x+9,y+12,"Q");} if (c==13) {printf_xy (x+1,y+2,"K"); printf_xy (x+9,y+12,"K");} if (c==14) {printf_xy (x+1,y+2,"A"); printf_xy (x+9,y+12,"A");} if (s==1) {Sprite8(x+9,y+2,7,dimond,GetPlane(a),SPRT_OR); Sprite8(x+2,y+12,7,dimond,GetPlane(a),SPRT_OR);} if (s==2) {Sprite8(x+9,y+3,6,heart,GetPlane(a),SPRT_OR); Sprite8(x+2,y+12,6,heart,GetPlane(a),SPRT_OR);} if (s>=3) {Sprite8(x+9,y+3,7,spade,GetPlane(a),SPRT_OR); Sprite8(x+2,y+12,7,spade,GetPlane(a),SPRT_OR);} if (s==4) {Sprite8(x+9,y+5,1,club,GetPlane(a),SPRT_AND); Sprite8(x+2,y+14,1,club,GetPlane(a),SPRT_AND);} endcard: ; } void col(int x) { int y; for(y=0;y<=19;y++) card(x,y,1); } void box(int x,int y) { ebox(x,y); SetPlane(1); DrawLine (x,y,x+17,y,A_NORMAL); DrawLine (x,y,x,y+20,A_NORMAL); DrawLine (x+17,y,x+17,y+20,A_NORMAL); DrawLine (x,y+20,x+17,y+20,A_NORMAL); } void ebox(int x,int y) { Sprite16(x+1,y+1,19,ebox1,GetPlane(0),SPRT_AND); Sprite16(x+1,y+1,19,ebox1,GetPlane(1),SPRT_AND); } void ecol(int y) { int z; SetPlane(0); for (z=21;z<=99;z++) DrawLine(y,z,y+20,z,A_REVERSE); SetPlane(1); for (z=21;z<=99;z++) DrawLine(y,z,y+19,z,A_REVERSE); } void greyin(int x,int y) { int z; ebox(x,y); SetPlane(0); for(z=y+1;z