diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/solitaire.c | 106 |
1 files changed, 60 insertions, 46 deletions
diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c index 066af9da73..1ef1cf5c90 100644 --- a/apps/plugins/solitaire.c +++ b/apps/plugins/solitaire.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2004 dionoea (Antoine Cellerier) | 10 | * Copyright (C) 2004-2005 dionoea (Antoine Cellerier) |
11 | * | 11 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 12 | * All files in this archive are subject to the GNU General Public License. |
13 | * See the file COPYING in the source tree root for full license agreement. | 13 | * See the file COPYING in the source tree root for full license agreement. |
@@ -328,10 +328,10 @@ typedef struct card { | |||
328 | 328 | ||
329 | unsigned char next_random_card(card *deck){ | 329 | unsigned char next_random_card(card *deck){ |
330 | unsigned char i,r; | 330 | unsigned char i,r; |
331 | 331 | ||
332 | r = rb->rand()%(COLORS * CARDS_PER_COLOR)+1; | 332 | r = rb->rand()%(COLORS * CARDS_PER_COLOR)+1; |
333 | i = 0; | 333 | i = 0; |
334 | 334 | ||
335 | while(r>0){ | 335 | while(r>0){ |
336 | i = (i + 1)%(COLORS * CARDS_PER_COLOR); | 336 | i = (i + 1)%(COLORS * CARDS_PER_COLOR); |
337 | if(!deck[i].used) r--; | 337 | if(!deck[i].used) r--; |
@@ -352,7 +352,7 @@ int solitaire_help(void){ | |||
352 | int lastbutton = BUTTON_NONE; | 352 | int lastbutton = BUTTON_NONE; |
353 | 353 | ||
354 | while(1){ | 354 | while(1){ |
355 | 355 | ||
356 | rb->lcd_clear_display(); | 356 | rb->lcd_clear_display(); |
357 | 357 | ||
358 | #if CONFIG_KEYPAD == RECORDER_PAD | 358 | #if CONFIG_KEYPAD == RECORDER_PAD |
@@ -382,7 +382,7 @@ int solitaire_help(void){ | |||
382 | #endif | 382 | #endif |
383 | 383 | ||
384 | rb->lcd_update(); | 384 | rb->lcd_update(); |
385 | 385 | ||
386 | button = rb->button_get(true); | 386 | button = rb->button_get(true); |
387 | switch(button){ | 387 | switch(button){ |
388 | case SOL_UP: | 388 | case SOL_UP: |
@@ -459,7 +459,7 @@ int solitaire_help(void){ | |||
459 | 459 | ||
460 | case SOL_QUIT: | 460 | case SOL_QUIT: |
461 | return HELP_QUIT; | 461 | return HELP_QUIT; |
462 | 462 | ||
463 | default: | 463 | default: |
464 | if(rb->default_event_handler(button) == SYS_USB_CONNECTED) | 464 | if(rb->default_event_handler(button) == SYS_USB_CONNECTED) |
465 | return HELP_USB; | 465 | return HELP_USB; |
@@ -488,7 +488,7 @@ int solitaire_help(void){ | |||
488 | /* text displayed changes depending on the 'when' parameter */ | 488 | /* text displayed changes depending on the 'when' parameter */ |
489 | int solitaire_menu(unsigned char when) | 489 | int solitaire_menu(unsigned char when) |
490 | { | 490 | { |
491 | static char menu[2][MENU_LENGTH][13] = | 491 | static char menu[2][MENU_LENGTH][13] = |
492 | { { "Start Game", | 492 | { { "Start Game", |
493 | "", | 493 | "", |
494 | "Help", | 494 | "Help", |
@@ -498,7 +498,7 @@ int solitaire_menu(unsigned char when) | |||
498 | "Help", | 498 | "Help", |
499 | "Quit"} | 499 | "Quit"} |
500 | }; | 500 | }; |
501 | 501 | ||
502 | int i; | 502 | int i; |
503 | int cursor=0; | 503 | int cursor=0; |
504 | int button; | 504 | int button; |
@@ -506,16 +506,16 @@ int solitaire_menu(unsigned char when) | |||
506 | 506 | ||
507 | rb->lcd_getstringsize("A", NULL, &fh); | 507 | rb->lcd_getstringsize("A", NULL, &fh); |
508 | fh++; | 508 | fh++; |
509 | 509 | ||
510 | if(when!=MENU_BEFOREGAME && when!=MENU_DURINGGAME) | 510 | if(when!=MENU_BEFOREGAME && when!=MENU_DURINGGAME) |
511 | when = MENU_DURINGGAME; | 511 | when = MENU_DURINGGAME; |
512 | 512 | ||
513 | while(1){ | 513 | while(1){ |
514 | 514 | ||
515 | rb->lcd_clear_display(); | 515 | rb->lcd_clear_display(); |
516 | 516 | ||
517 | rb->lcd_putsxy(20, 1, "Solitaire"); | 517 | rb->lcd_putsxy(20, 1, "Solitaire"); |
518 | 518 | ||
519 | for(i = 0; i<MENU_LENGTH; i++){ | 519 | for(i = 0; i<MENU_LENGTH; i++){ |
520 | rb->lcd_putsxy(1, 17+fh*i, menu[when][i]); | 520 | rb->lcd_putsxy(1, 17+fh*i, menu[when][i]); |
521 | if(cursor == i) { | 521 | if(cursor == i) { |
@@ -556,7 +556,7 @@ int solitaire_menu(unsigned char when) | |||
556 | break; | 556 | break; |
557 | } | 557 | } |
558 | break; | 558 | break; |
559 | 559 | ||
560 | case SOL_MENU_INFO: | 560 | case SOL_MENU_INFO: |
561 | #if defined(SOL_MENU_INFO2) && defined(SOL_MENU_INFO3) | 561 | #if defined(SOL_MENU_INFO2) && defined(SOL_MENU_INFO3) |
562 | case SOL_MENU_INFO2: | 562 | case SOL_MENU_INFO2: |
@@ -612,7 +612,7 @@ void solitaire_init(void){ | |||
612 | deck[i*CARDS_PER_COLOR+j].next = NOT_A_CARD; | 612 | deck[i*CARDS_PER_COLOR+j].next = NOT_A_CARD; |
613 | } | 613 | } |
614 | } | 614 | } |
615 | 615 | ||
616 | /* deal the cards ... */ | 616 | /* deal the cards ... */ |
617 | /* ... in the columns */ | 617 | /* ... in the columns */ |
618 | for(i=0; i<COL_NUM; i++){ | 618 | for(i=0; i<COL_NUM; i++){ |
@@ -632,29 +632,29 @@ void solitaire_init(void){ | |||
632 | /* ... shuffle what's left of the deck */ | 632 | /* ... shuffle what's left of the deck */ |
633 | rem = next_random_card(deck); | 633 | rem = next_random_card(deck); |
634 | c = rem; | 634 | c = rem; |
635 | 635 | ||
636 | for(i=1; i<COLORS * CARDS_PER_COLOR - COL_NUM * (COL_NUM + 1)/2; i++){ | 636 | for(i=1; i<COLORS * CARDS_PER_COLOR - COL_NUM * (COL_NUM + 1)/2; i++){ |
637 | deck[c].next = next_random_card(deck); | 637 | deck[c].next = next_random_card(deck); |
638 | c = deck[c].next; | 638 | c = deck[c].next; |
639 | } | 639 | } |
640 | 640 | ||
641 | /* we now finished dealing the cards. The game can start ! (at last) */ | 641 | /* we now finished dealing the cards. The game can start ! (at last) */ |
642 | 642 | ||
643 | /* init the stack */ | 643 | /* init the stack */ |
644 | for(i = 0; i<COLORS;i++){ | 644 | for(i = 0; i<COLORS; i++){ |
645 | stacks[i] = NOT_A_CARD; | 645 | stacks[i] = NOT_A_CARD; |
646 | } | 646 | } |
647 | 647 | ||
648 | /* the cursor starts on upper left card */ | 648 | /* the cursor starts on upper left card */ |
649 | cur_card = cols[0]; | 649 | cur_card = cols[0]; |
650 | cur_col = 0; | 650 | cur_col = 0; |
651 | 651 | ||
652 | /* no card is selected */ | 652 | /* no card is selected */ |
653 | sel_card = NOT_A_CARD; | 653 | sel_card = NOT_A_CARD; |
654 | 654 | ||
655 | /* init the remainder */ | 655 | /* init the remainder */ |
656 | cur_rem = NOT_A_CARD; | 656 | cur_rem = NOT_A_CARD; |
657 | } | 657 | } |
658 | 658 | ||
659 | /* find the column number in which 'card' can be found */ | 659 | /* find the column number in which 'card' can be found */ |
660 | unsigned char find_card_col(unsigned char card){ | 660 | unsigned char find_card_col(unsigned char card){ |
@@ -724,15 +724,15 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
724 | 724 | ||
725 | /* the last card of dest_col */ | 725 | /* the last card of dest_col */ |
726 | unsigned char dest_card; | 726 | unsigned char dest_card; |
727 | 727 | ||
728 | /* the card under src_card */ | 728 | /* the card under src_card */ |
729 | unsigned char src_card_prev; | 729 | unsigned char src_card_prev; |
730 | 730 | ||
731 | /* you can't move no card (at least, it doesn't have any consequence) */ | 731 | /* you can't move no card (at least, it doesn't have any consequence) */ |
732 | if(src_card == NOT_A_CARD) return MOVE_NOT_OK; | 732 | if(src_card == NOT_A_CARD) return MOVE_NOT_OK; |
733 | /* you can't put a card back on the remains' stack */ | 733 | /* you can't put a card back on the remains' stack */ |
734 | if(dest_col == REM_COL) return MOVE_NOT_OK; | 734 | if(dest_col == REM_COL) return MOVE_NOT_OK; |
735 | 735 | ||
736 | src_col = find_card_col(src_card); | 736 | src_col = find_card_col(src_card); |
737 | dest_card = find_last_card(dest_col); | 737 | dest_card = find_last_card(dest_col); |
738 | src_card_prev = find_prev_card(src_card); | 738 | src_card_prev = find_prev_card(src_card); |
@@ -743,7 +743,7 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
743 | && deck[src_card].next != NOT_A_CARD){ | 743 | && deck[src_card].next != NOT_A_CARD){ |
744 | return MOVE_NOT_OK; | 744 | return MOVE_NOT_OK; |
745 | } | 745 | } |
746 | 746 | ||
747 | /* if we (that means dest) are on one of the 7 columns ... */ | 747 | /* if we (that means dest) are on one of the 7 columns ... */ |
748 | if(dest_col < COL_NUM){ | 748 | if(dest_col < COL_NUM){ |
749 | /* ... check is we are on an empty color and that the src is a king */ | 749 | /* ... check is we are on an empty color and that the src is a king */ |
@@ -774,7 +774,7 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
774 | /* this is a winning combination */ | 774 | /* this is a winning combination */ |
775 | stacks[dest_col - STACKS_COL] = src_card; | 775 | stacks[dest_col - STACKS_COL] = src_card; |
776 | } | 776 | } |
777 | /* ... or check if the cards follow one another, have the same | 777 | /* ... or check if the cards follow one another, have the same |
778 | * color and {that src has no .next element or is from the remains' | 778 | * color and {that src has no .next element or is from the remains' |
779 | * stack} */ | 779 | * stack} */ |
780 | else if(deck[dest_card].color == deck[src_card].color | 780 | else if(deck[dest_card].color == deck[src_card].color |
@@ -794,7 +794,7 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
794 | /* you can't move a card back to the remains' stack */ | 794 | /* you can't move a card back to the remains' stack */ |
795 | return MOVE_NOT_OK; | 795 | return MOVE_NOT_OK; |
796 | } | 796 | } |
797 | 797 | ||
798 | /* if the src card is from the remains' stack, we don't want to take | 798 | /* if the src card is from the remains' stack, we don't want to take |
799 | * the following cards */ | 799 | * the following cards */ |
800 | if(src_col == REM_COL){ | 800 | if(src_col == REM_COL){ |
@@ -832,12 +832,18 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
832 | 832 | ||
833 | /* the game */ | 833 | /* the game */ |
834 | int solitaire(void){ | 834 | int solitaire(void){ |
835 | 835 | ||
836 | int i,j; | 836 | int i,j; |
837 | int button, lastbutton = 0; | 837 | int button, lastbutton = 0; |
838 | unsigned char c; | 838 | unsigned char c; |
839 | int biggest_col_length; | 839 | int biggest_col_length; |
840 | 840 | ||
841 | struct tm time; | ||
842 | time = *(rb->get_time()); | ||
843 | rb->srand( ( ( ( time.tm_year + 365 * time.tm_yday ) * 24 | ||
844 | + time.tm_hour ) * 60 + time.tm_min ) * 60 + time.tm_sec ); | ||
845 | |||
846 | |||
841 | switch(solitaire_menu(MENU_BEFOREGAME)) { | 847 | switch(solitaire_menu(MENU_BEFOREGAME)) { |
842 | case MENU_QUIT: | 848 | case MENU_QUIT: |
843 | return SOLITAIRE_QUIT; | 849 | return SOLITAIRE_QUIT; |
@@ -847,14 +853,14 @@ int solitaire(void){ | |||
847 | } | 853 | } |
848 | 854 | ||
849 | solitaire_init(); | 855 | solitaire_init(); |
850 | 856 | ||
851 | while(true){ | 857 | while(true){ |
852 | 858 | ||
853 | rb->lcd_clear_display(); | 859 | rb->lcd_clear_display(); |
854 | 860 | ||
855 | /* get the biggest column length so that display can be "optimized" */ | 861 | /* get the biggest column length so that display can be "optimized" */ |
856 | biggest_col_length = 0; | 862 | biggest_col_length = 0; |
857 | 863 | ||
858 | for(i=0;i<COL_NUM;i++){ | 864 | for(i=0;i<COL_NUM;i++){ |
859 | j = 0; | 865 | j = 0; |
860 | c = cols[i]; | 866 | c = cols[i]; |
@@ -864,14 +870,14 @@ int solitaire(void){ | |||
864 | } | 870 | } |
865 | if(j>biggest_col_length) biggest_col_length = j; | 871 | if(j>biggest_col_length) biggest_col_length = j; |
866 | } | 872 | } |
867 | 873 | ||
868 | /* check if there are cards remaining in the game. */ | 874 | /* check if there are cards remaining in the game. */ |
869 | /* if there aren't any, that means you won :) */ | 875 | /* if there aren't any, that means you won :) */ |
870 | if(biggest_col_length == 0 && rem == NOT_A_CARD){ | 876 | if(biggest_col_length == 0 && rem == NOT_A_CARD){ |
871 | rb->splash(HZ*2, true, "You Won :)"); | 877 | rb->splash(HZ*2, true, "You Won :)"); |
872 | return SOLITAIRE_WIN; | 878 | return SOLITAIRE_WIN; |
873 | } | 879 | } |
874 | 880 | ||
875 | /* draw the columns */ | 881 | /* draw the columns */ |
876 | for(i=0;i<COL_NUM;i++){ | 882 | for(i=0;i<COL_NUM;i++){ |
877 | c = cols[i]; | 883 | c = cols[i]; |
@@ -975,14 +981,14 @@ int solitaire(void){ | |||
975 | rb->lcd_fillrect(LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT,CARD_WIDTH-1, CARD_HEIGHT-1); | 981 | rb->lcd_fillrect(LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT,CARD_WIDTH-1, CARD_HEIGHT-1); |
976 | rb->lcd_set_drawmode(DRMODE_SOLID); | 982 | rb->lcd_set_drawmode(DRMODE_SOLID); |
977 | } | 983 | } |
978 | 984 | ||
979 | 985 | ||
980 | rb->lcd_update(); | 986 | rb->lcd_update(); |
981 | 987 | ||
982 | /* what to do when a key is pressed ... */ | 988 | /* what to do when a key is pressed ... */ |
983 | button = rb->button_get(true); | 989 | button = rb->button_get(true); |
984 | switch(button){ | 990 | switch(button){ |
985 | 991 | ||
986 | /* move cursor to the last card of the previous column */ | 992 | /* move cursor to the last card of the previous column */ |
987 | /* or to the previous color stack */ | 993 | /* or to the previous color stack */ |
988 | /* or to the remains stack */ | 994 | /* or to the remains stack */ |
@@ -1004,7 +1010,7 @@ int solitaire(void){ | |||
1004 | } | 1010 | } |
1005 | cur_card = find_last_card(cur_col); | 1011 | cur_card = find_last_card(cur_col); |
1006 | break; | 1012 | break; |
1007 | 1013 | ||
1008 | /* move cursor to the last card of the next column */ | 1014 | /* move cursor to the last card of the next column */ |
1009 | /* or to the next color stack */ | 1015 | /* or to the next color stack */ |
1010 | /* or to the remains stack */ | 1016 | /* or to the remains stack */ |
@@ -1026,7 +1032,7 @@ int solitaire(void){ | |||
1026 | } | 1032 | } |
1027 | cur_card = find_last_card(cur_col); | 1033 | cur_card = find_last_card(cur_col); |
1028 | break; | 1034 | break; |
1029 | 1035 | ||
1030 | /* move cursor to card that's bellow */ | 1036 | /* move cursor to card that's bellow */ |
1031 | case SOL_DOWN: | 1037 | case SOL_DOWN: |
1032 | #ifdef SOL_DOWN_PRE | 1038 | #ifdef SOL_DOWN_PRE |
@@ -1053,7 +1059,7 @@ int solitaire(void){ | |||
1053 | } | 1059 | } |
1054 | } | 1060 | } |
1055 | break; | 1061 | break; |
1056 | 1062 | ||
1057 | /* move cursor to card that's above */ | 1063 | /* move cursor to card that's above */ |
1058 | case SOL_UP: | 1064 | case SOL_UP: |
1059 | #ifdef SOL_UP_PRE | 1065 | #ifdef SOL_UP_PRE |
@@ -1117,7 +1123,7 @@ int solitaire(void){ | |||
1117 | } | 1123 | } |
1118 | } | 1124 | } |
1119 | break; | 1125 | break; |
1120 | 1126 | ||
1121 | /* If the card on the top of the remains can be put where */ | 1127 | /* If the card on the top of the remains can be put where */ |
1122 | /* the cursor is, go ahead */ | 1128 | /* the cursor is, go ahead */ |
1123 | case SOL_REM2CUR: | 1129 | case SOL_REM2CUR: |
@@ -1153,6 +1159,7 @@ int solitaire(void){ | |||
1153 | break; | 1159 | break; |
1154 | } | 1160 | } |
1155 | if(rem != NOT_A_CARD) { | 1161 | if(rem != NOT_A_CARD) { |
1162 | int cur_rem_old = cur_rem; | ||
1156 | /* draw new cards form the remains of the deck */ | 1163 | /* draw new cards form the remains of the deck */ |
1157 | if(cur_rem == NOT_A_CARD){ | 1164 | if(cur_rem == NOT_A_CARD){ |
1158 | cur_rem = rem; | 1165 | cur_rem = rem; |
@@ -1169,15 +1176,19 @@ int solitaire(void){ | |||
1169 | if(i == CARDS_PER_DRAW){ | 1176 | if(i == CARDS_PER_DRAW){ |
1170 | cur_rem = NOT_A_CARD; | 1177 | cur_rem = NOT_A_CARD; |
1171 | } | 1178 | } |
1179 | /* if cursor was on remains' stack when new cards were | ||
1180 | * drawn, put cursor on top of remains' stack */ | ||
1181 | if(cur_col == REM_COL && cur_card == cur_rem_old) | ||
1182 | cur_card = cur_rem; | ||
1172 | } | 1183 | } |
1173 | break; | 1184 | break; |
1174 | 1185 | ||
1175 | /* Show the menu */ | 1186 | /* Show the menu */ |
1176 | case SOL_QUIT: | 1187 | case SOL_QUIT: |
1177 | switch(solitaire_menu(MENU_DURINGGAME)){ | 1188 | switch(solitaire_menu(MENU_DURINGGAME)){ |
1178 | case MENU_QUIT: | 1189 | case MENU_QUIT: |
1179 | return SOLITAIRE_QUIT; | 1190 | return SOLITAIRE_QUIT; |
1180 | 1191 | ||
1181 | case MENU_USB: | 1192 | case MENU_USB: |
1182 | return SOLITAIRE_USB; | 1193 | return SOLITAIRE_USB; |
1183 | 1194 | ||
@@ -1190,7 +1201,7 @@ int solitaire(void){ | |||
1190 | return SOLITAIRE_USB; | 1201 | return SOLITAIRE_USB; |
1191 | break; | 1202 | break; |
1192 | } | 1203 | } |
1193 | 1204 | ||
1194 | if(button != BUTTON_NONE) | 1205 | if(button != BUTTON_NONE) |
1195 | lastbutton = button; | 1206 | lastbutton = button; |
1196 | 1207 | ||
@@ -1198,6 +1209,9 @@ int solitaire(void){ | |||
1198 | c = find_card_col(cur_card); | 1209 | c = find_card_col(cur_card); |
1199 | if(c != NOT_A_COL && c != cur_col) | 1210 | if(c != NOT_A_COL && c != cur_col) |
1200 | cur_card = find_last_card(cur_col); | 1211 | cur_card = find_last_card(cur_col); |
1212 | |||
1213 | if(cur_card == NOT_A_CARD && find_last_card(cur_col) != NOT_A_CARD) | ||
1214 | cur_card = find_last_card(cur_col); | ||
1201 | } | 1215 | } |
1202 | } | 1216 | } |
1203 | 1217 | ||
@@ -1210,10 +1224,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
1210 | (void)parameter; | 1224 | (void)parameter; |
1211 | rb = api; | 1225 | rb = api; |
1212 | /* end of plugin init */ | 1226 | /* end of plugin init */ |
1213 | 1227 | ||
1214 | /* Welcome to Solitaire ! */ | 1228 | /* Welcome to Solitaire ! */ |
1215 | rb->splash(HZ*2, true, "Welcome to Solitaire !"); | 1229 | rb->splash(HZ*2, true, "Welcome to Solitaire !"); |
1216 | 1230 | ||
1217 | /* play the game :) */ | 1231 | /* play the game :) */ |
1218 | /* Keep playing if a game was won (that means display the menu after */ | 1232 | /* Keep playing if a game was won (that means display the menu after */ |
1219 | /* winning instead of quiting) */ | 1233 | /* winning instead of quiting) */ |