diff options
| author | Linus Nielsen Feltzing <linus@haxx.se> | 2004-08-21 23:05:36 +0000 |
|---|---|---|
| committer | Linus Nielsen Feltzing <linus@haxx.se> | 2004-08-21 23:05:36 +0000 |
| commit | 1e9de584f604f7d9da4e2e1ee7ce25c909ec1969 (patch) | |
| tree | 501ce92d31f0232c5702b702482d5df9540e7b4d /apps/plugins | |
| parent | ae7df4d0ac4c88d77a95f6056d105f7c0ccf608a (diff) | |
| download | rockbox-1e9de584f604f7d9da4e2e1ee7ce25c909ec1969.zip rockbox-1e9de584f604f7d9da4e2e1ee7ce25c909ec1969.tar.gz rockbox-1e9de584f604f7d9da4e2e1ee7ce25c909ec1969.tar.bz2 rockbox-1e9de584f604f7d9da4e2e1ee7ce25c909ec1969.tar.xz | |
Patch #1011849 by Antoine Cellerier
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5003 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
| -rw-r--r-- | apps/plugins/solitaire.c | 637 |
1 files changed, 349 insertions, 288 deletions
diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c index 04fde17..f2d2663 100644 --- a/apps/plugins/solitaire.c +++ b/apps/plugins/solitaire.c @@ -21,8 +21,7 @@ Solitaire by dionoea use arrows to move the cursor -use ON to select cards in the columns, move cards inside the columns, - reveal hidden cards, ... +use ON to select cards, move cards, reveal hidden cards, ... use PLAY to move a card from the remains' stack to the top of the cursor use F1 to put card under cursor on one of the 4 final color stacks use F2 to un-select card if a card was selected, else draw 3 new cards @@ -57,7 +56,7 @@ static struct plugin_api* rb; #define HELP_BUTTON_F2 "Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack." #define HELP_BUTTON_F3 "Put the card on top of the remains' stack on one of the 4 final color stacks." #define HELP_BUTTON_PLAY "Put the card on top of the remains' stack on top of the cursor." -#define HELP_BUTTON_ON "Select cards in the columns, Move cards inside the columns, reveal hidden cards ..." +#define HELP_BUTTON_ON "Select cards, Move cards, reveal hidden cards ..." static unsigned char colors[4][8] = { /* Spades */ @@ -229,6 +228,14 @@ static unsigned char numbers[13][8] = { /* number of columns */ #define COL_NUM 7 +/* pseudo column numbers to be used for cursor coordinates */ +/* columns COL_NUM t COL_NUM + COLORS - 1 correspond to the color stacks */ +#define STACKS_COL COL_NUM +/* column COL_NUM + COLORS corresponds to the remains' stack */ +#define REM_COL (STACKS_COL + COLORS) + +#define NOT_A_COL 255 + /* number of cards that are drawn on the remains' stack (by pressing F2) */ #define CARDS_PER_DRAW 3 @@ -261,14 +268,17 @@ unsigned char next_random_card(card *deck){ } /* help for the not so intuitive interface */ -void solitaire_help(void) -{ +void solitaire_help(void){ + rb->lcd_clear_display(); rb->lcd_putsxy(0, 0, "Press a key to see"); rb->lcd_putsxy(0, 7, "it's role."); rb->lcd_putsxy(0, 21, "Press OFF to"); - rb->lcd_putsxy(0, 28, "return to menu"); + rb->lcd_putsxy(0, 28, "return to menu."); + rb->lcd_putsxy(0, 42, "All actions can"); + rb->lcd_putsxy(0, 49, "be done using"); + rb->lcd_putsxy(0, 56, "arrows, ON and F2."); rb->lcd_update(); @@ -363,6 +373,7 @@ int solitaire_menu(unsigned char when) { solitaire_help(); break; } + break; case BUTTON_F1: case BUTTON_F2: @@ -410,7 +421,7 @@ void solitaire_init(void){ for(j=0;j<CARDS_PER_COLOR;j++){ deck[i*CARDS_PER_COLOR+j].color = i; deck[i*CARDS_PER_COLOR+j].num = j; - deck[i*CARDS_PER_COLOR+j].known = 0; + deck[i*CARDS_PER_COLOR+j].known = 1; deck[i*CARDS_PER_COLOR+j].used = 0; deck[i*CARDS_PER_COLOR+j].next = NOT_A_CARD; } @@ -428,7 +439,7 @@ void solitaire_init(void){ deck[c].next = next_random_card(deck); c = deck[c].next; } - if(j==i) deck[c].known = 1; + if(j<i) deck[c].known = 0; } } @@ -459,15 +470,187 @@ void solitaire_init(void){ cur_rem = NOT_A_CARD; } +/* find the column number in which 'card' can be found */ +unsigned char find_card_col(unsigned char card){ + int i; + unsigned char c; + + if(card == NOT_A_CARD) return NOT_A_COL; + + for(i=0; i<COL_NUM; i++){ + c = cols[i]; + while(c!=NOT_A_CARD){ + if(c == card) return i; + c = deck[c].next; + } + } + + for(i=0; i<COLORS; i++){ + c = stacks[i]; + while(c!=NOT_A_CARD){ + if(c == card) return STACKS_COL + i; + c = deck[c].next; + } + } + + return REM_COL; +} + +/* find the card preceding 'card' */ +/* if it doesn't exist, return NOT_A_CARD */ +unsigned char find_prev_card(unsigned char card){ + int i; + + for(i=0; i<COLORS*CARDS_PER_COLOR; i++){ + if(deck[i].next == card) return i; + } + + return NOT_A_CARD; +} + +/* find the last card of a given column */ +unsigned char find_last_card(unsigned char col){ + unsigned char c; + + if(col < COL_NUM){ + c = cols[col]; + } else if(col < REM_COL){ + c = stacks[col - STACKS_COL]; + } else { + c = rem; + } + + if(c == NOT_A_CARD) + return c; + else { + while(deck[c].next != NOT_A_CARD){ + c = deck[c].next; + } + return c; + } +} + +#define MOVE_OK 0 +#define MOVE_NOT_OK 1 +unsigned char move_card(unsigned char dest_col, unsigned char src_card){ + /* the column on which to take src_card */ + unsigned char src_col; + + /* the last card of dest_col */ + unsigned char dest_card; + + /* the card under src_card */ + unsigned char src_card_prev; + + /* you can't move no card (at least, it doesn't have any consequence) */ + if(src_card == NOT_A_CARD) return MOVE_NOT_OK; + /* you can't put a card back on the remains' stack */ + if(dest_col == REM_COL) return MOVE_NOT_OK; + + src_col = find_card_col(src_card); + dest_card = find_last_card(dest_col); + src_card_prev = find_prev_card(src_card); + + /* you can't move more than one card at a time from the colors stack */ + /* to the rest of the game */ + if(src_col >= COL_NUM && src_col < REM_COL + && deck[src_card].next != NOT_A_CARD){ + return MOVE_NOT_OK; + } + + /* if we (that means dest) are on one of the 7 columns ... */ + if(dest_col < COL_NUM){ + /* ... check is we are on an empty color and that the src is a king */ + if(dest_card == NOT_A_CARD + && deck[src_card].num == CARDS_PER_COLOR - 1){ + /* this is a winning combination */ + cols[dest_col] = src_card; + } + /* ... or check if the cards follow one another and have same color */ + else if((deck[dest_card].color + deck[src_card].color)%2==1 + && deck[dest_card].num == deck[src_card].num + 1){ + /* this is a winning combination */ + deck[dest_card].next = src_card; + } + /* ... or, humpf, well that's not good news */ + else { + /* this is not a winning combination */ + return MOVE_NOT_OK; + } + } + /* if we are on one of the 4 color stacks ... */ + else if(dest_col < REM_COL){ + /* ... check if we are on an empty stack, that the src is an + * ace and that this is the good color stack */ + if(dest_card == NOT_A_CARD + && deck[src_card].num == 0 + && deck[src_card].color == dest_col - STACKS_COL){ + /* this is a winning combination */ + stacks[dest_col - STACKS_COL] = src_card; + } + /* ... or check if the cards follow one another, have the same + * color and {that src has no .next element or is from the remains' + * stack} */ + else if(deck[dest_card].color == deck[src_card].color + && deck[dest_card].num + 1 == deck[src_card].num + && (deck[src_card].next == NOT_A_CARD || src_col == REM_COL) ){ + /* this is a winning combination */ + deck[dest_card].next = src_card; + } + /* ... or, well that's not good news */ + else { + /* this is not a winnong combination */ + return MOVE_NOT_OK; + } + } + /* if we are on the remains' stack */ + else { + /* you can't move a card back to the remains' stack */ + return MOVE_NOT_OK; + } + + /* if the src card is from the remains' stack, we don't want to take + * the following cards */ + if(src_col == REM_COL){ + /* if src card is the first card from the stack */ + if(src_card_prev == NOT_A_CARD){ + rem = deck[src_card].next; + } + /* if src card is not the first card from the stack */ + else { + deck[src_card_prev].next = deck[src_card].next; + } + cur_rem = src_card_prev; + deck[src_card].next = NOT_A_CARD; + } + /* if the src card is from somewhere else, just take everything */ + else { + if(src_card_prev == NOT_A_CARD){ + if(src_col < COL_NUM){ + cols[src_col] = NOT_A_CARD; + } else { + stacks[src_col - STACKS_COL] = NOT_A_CARD; + } + } else { + deck[src_card_prev].next = NOT_A_CARD; + } + } + + /* tada ! */ + return MOVE_OK; +} + +#define SOLITAIRE_WIN 0 +#define SOLITAIRE_QUIT 1 /* the game */ -void solitaire(void){ +int solitaire(void){ int i,j; unsigned char c; int biggest_col_length; - if(solitaire_menu(MENU_BEFOREGAME) == MENU_QUIT) return; + if(solitaire_menu(MENU_BEFOREGAME) == MENU_QUIT) return SOLITAIRE_QUIT; solitaire_init(); while(true){ @@ -491,7 +674,7 @@ void solitaire(void){ /* if there aren't any, that means you won :) */ if(biggest_col_length == 0 && rem == NOT_A_CARD){ rb->splash(HZ*2, true, "You Won :)"); - return; + return SOLITAIRE_WIN; } /* draw the columns */ @@ -499,59 +682,48 @@ void solitaire(void){ c = cols[i]; j = 0; while(true){ - if(c==NOT_A_CARD) break; + if(c==NOT_A_CARD) { + /* draw the cursor on empty columns */ + if(cur_col == i){ + rb->lcd_invertrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+2, 2, CARD_WIDTH-3, CARD_HEIGHT-1); + } + break; + } /* clear the card's spot */ - rb->lcd_clearrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM, - j+1, CARD_WIDTH, CARD_HEIGHT-1); + rb->lcd_clearrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM, j+1, CARD_WIDTH, CARD_HEIGHT-1); /* known card */ - if(deck[c].known) { - rb->lcd_bitmap(numbers[deck[c].num], - i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, - j, 8, 8, true); - rb->lcd_bitmap(colors[deck[c].color], - i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+7, - j, 8, 8, true); + if(deck[c].known){ + rb->lcd_bitmap(numbers[deck[c].num], i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, j, 8, 8, true); + rb->lcd_bitmap(colors[deck[c].color], i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+7, j, 8, 8, true); } /* draw top line of the card */ - rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, - j,i*(LCD_WIDTH - CARD_WIDTH)/ - COL_NUM+CARD_WIDTH-1,j); + rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1,j,i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+CARD_WIDTH-1,j); /* selected card */ if(c == sel_card && sel_card != NOT_A_CARD){ - rb->lcd_drawrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, - j+1, CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_drawrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); } /* cursor (or not) */ if(c == cur_card){ - rb->lcd_invertrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, - j+1, CARD_WIDTH-1, CARD_HEIGHT-1); + rb->lcd_invertrect(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); /* go to the next card */ c = deck[c].next; - if(c == NOT_A_CARD) - break; + if(c == NOT_A_CARD) break; j += CARD_HEIGHT - 2; - } - else { + } else { /* go to the next card */ c = deck[c].next; - if(c == NOT_A_CARD) - break; - j += min(CARD_HEIGHT - 2, - (LCD_HEIGHT - CARD_HEIGHT)/biggest_col_length); + if(c == NOT_A_CARD) break; + j += min(CARD_HEIGHT - 2, (LCD_HEIGHT - CARD_HEIGHT)/biggest_col_length); } } - /* draw line to the left of the column */ - rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM, - 1,i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM, - j+CARD_HEIGHT-1); - /* draw line to the right of the column */ - rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+CARD_WIDTH, - 1,i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+CARD_WIDTH, - j+CARD_HEIGHT-1); - /* draw bottom of the last card */ - rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1, - j+CARD_HEIGHT,i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+ - CARD_WIDTH-1,j+CARD_HEIGHT); + if(cols[i]!=NOT_A_CARD){ + /* draw line to the left of the column */ + rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM,1,i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM,j+CARD_HEIGHT-1); + /* draw line to the right of the column */ + rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+CARD_WIDTH,1,i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+CARD_WIDTH,j+CARD_HEIGHT-1); + /* draw bottom of the last card */ + rb->lcd_drawline(i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+1,j+CARD_HEIGHT,i*(LCD_WIDTH - CARD_WIDTH)/COL_NUM+CARD_WIDTH-1,j+CARD_HEIGHT); + } } /* draw the stacks */ @@ -563,32 +735,43 @@ void solitaire(void){ } } if(c != NOT_A_CARD) { - rb->lcd_bitmap(numbers[deck[c].num], LCD_WIDTH - CARD_WIDTH+1, - i*CARD_HEIGHT, 8, 8, true); + rb->lcd_bitmap(numbers[deck[c].num], LCD_WIDTH - CARD_WIDTH+1, i*CARD_HEIGHT, 8, 8, true); + } + rb->lcd_bitmap(colors[i], LCD_WIDTH - CARD_WIDTH+7, i*CARD_HEIGHT, 8, 8, true); + /* draw a selected card */ + if(c != NOT_A_CARD) { + if(sel_card == c){ + rb->lcd_drawrect(LCD_WIDTH - CARD_WIDTH+1, i*CARD_HEIGHT + 1, CARD_WIDTH-1, CARD_HEIGHT-1); + } + } + rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1,i*CARD_HEIGHT,LCD_WIDTH - 1,i*CARD_HEIGHT); + rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH,i*CARD_HEIGHT+1,LCD_WIDTH - CARD_WIDTH,(i+1)*CARD_HEIGHT-1); + rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1,(i+1)*CARD_HEIGHT,LCD_WIDTH - 1,(i+1)*CARD_HEIGHT); + /* draw the cursor on one of the stacks */ + if(cur_col == STACKS_COL + i){ + rb->lcd_invertrect(LCD_WIDTH - CARD_WIDTH+1, i*CARD_HEIGHT + 1, CARD_WIDTH-1, CARD_HEIGHT-1); } - rb->lcd_bitmap(colors[i], LCD_WIDTH - CARD_WIDTH+7, - i*CARD_HEIGHT, 8, 8, true); - rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1, - i*CARD_HEIGHT,LCD_WIDTH - 1,i*CARD_HEIGHT); - rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1, - (i+1)*CARD_HEIGHT,LCD_WIDTH - 1, - (i+1)*CARD_HEIGHT); } /* draw the remains */ - rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1, - LCD_HEIGHT-CARD_HEIGHT-1, - LCD_WIDTH - 1,LCD_HEIGHT-CARD_HEIGHT-1); - rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1, - LCD_HEIGHT-1,LCD_WIDTH - 1,LCD_HEIGHT-1); - if(cur_rem != NOT_A_CARD){ - rb->lcd_bitmap(numbers[deck[cur_rem].num], - LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT, - 8, 8, true); - rb->lcd_bitmap(colors[deck[cur_rem].color], - LCD_WIDTH - CARD_WIDTH+7, - LCD_HEIGHT-CARD_HEIGHT, 8, 8, true); + if(rem != NOT_A_CARD) { + rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1,LCD_HEIGHT-CARD_HEIGHT-1,LCD_WIDTH - 1,LCD_HEIGHT-CARD_HEIGHT-1); + rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH,LCD_HEIGHT-CARD_HEIGHT,LCD_WIDTH - CARD_WIDTH,LCD_HEIGHT-2); + rb->lcd_drawline(LCD_WIDTH - CARD_WIDTH+1,LCD_HEIGHT-1,LCD_WIDTH - 1,LCD_HEIGHT-1); + if(cur_rem != NOT_A_CARD){ + rb->lcd_bitmap(numbers[deck[cur_rem].num], LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT, 8, 8, true); + rb->lcd_bitmap(colors[deck[cur_rem].color], LCD_WIDTH - CARD_WIDTH+7, LCD_HEIGHT-CARD_HEIGHT, 8, 8, true); + /* draw a selected card */ + if(sel_card == cur_rem){ + rb->lcd_drawrect(LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT,CARD_WIDTH-1, CARD_HEIGHT-1); + } + } } + /* draw the cursor */ + if(cur_col == REM_COL){ + rb->lcd_invertrect(LCD_WIDTH - CARD_WIDTH+1, LCD_HEIGHT-CARD_HEIGHT,CARD_WIDTH-1, CARD_HEIGHT-1); + } + rb->lcd_update(); @@ -596,269 +779,139 @@ void solitaire(void){ switch(rb->button_get(true)){ /* move cursor to the last card of the previous column */ + /* or to the previous color stack */ + /* or to the remains stack */ case BUTTON_RIGHT: - cur_col = (cur_col+1)%COL_NUM; - cur_card = cols[cur_col]; - if(cur_card != NOT_A_CARD){ - while(deck[cur_card].next != NOT_A_CARD){ - cur_card = deck[cur_card].next; - } + if(cur_col >= COL_NUM){ + cur_col = 0; + } else if(cur_col == COL_NUM - 1){ + cur_col = REM_COL; + } else { + cur_col = (cur_col+1)%(REM_COL+1); } + if(cur_col == REM_COL){ + cur_card = cur_rem; + break; + } + cur_card = find_last_card(cur_col); break; - /* move cursor to the last card of the next column */ + /* move cursor to the last card of the next column */ + /* or to the next color stack */ + /* or to the remains stack */ case BUTTON_LEFT: - cur_col = (cur_col + COL_NUM - 1)%COL_NUM; - cur_card = cols[cur_col]; - if(cur_card != NOT_A_CARD){ - while(deck[cur_card].next != NOT_A_CARD){ - cur_card = deck[cur_card].next; - } + if(cur_col == 0){ + cur_col = REM_COL; + } else if(cur_col >= COL_NUM) { + cur_col = COL_NUM - 1; + } else { + cur_col = (cur_col + REM_COL)%(REM_COL+1); + } + if(cur_col == REM_COL){ + cur_card = cur_rem; + break; } + cur_card = find_last_card(cur_col); break; - /* move cursor to card that's bellow */ + /* move cursor to card that's bellow */ case BUTTON_DOWN: + if(cur_col >= COL_NUM) { + cur_col = (cur_col - COL_NUM + 1)%(COLORS + 1) + COL_NUM; + if(cur_col == REM_COL){ + cur_card = cur_rem; + } else { + cur_card = find_last_card(cur_col); + } + break; + } if(cur_card == NOT_A_CARD) break; if(deck[cur_card].next != NOT_A_CARD){ cur_card = deck[cur_card].next; } else { cur_card = cols[cur_col]; + while(deck[cur_card].known == 0 + && deck[cur_card].next != NOT_A_CARD){ + cur_card = deck[cur_card].next; + } } break; - /* move cursor to card that's above */ + /* move cursor to card that's above */ case BUTTON_UP: - if(cur_card == NOT_A_CARD) break; - if(cols[cur_col] == cur_card){ - while(deck[cur_card].next != NOT_A_CARD){ - cur_card = deck[cur_card].next; - } - } else { - c = cols[cur_col]; - while(deck[c].next != cur_card){ - c = deck[c].next; + if(cur_col >= COL_NUM) { + cur_col = (cur_col - COL_NUM + COLORS)%(COLORS + 1) + COL_NUM; + if(cur_col == REM_COL){ + cur_card = cur_rem; + } else { + cur_card = find_last_card(cur_col); } - cur_card = c; + break; } + if(cur_card == NOT_A_CARD) break; + do{ + cur_card = find_prev_card(cur_card); + if(cur_card == NOT_A_CARD){ + cur_card = find_last_card(cur_col); + } + } while (deck[cur_card].next != NOT_A_CARD + && deck[cur_card].known == 0); break; - /* Try to put card under cursor on one of the stacks */ + /* Try to put card under cursor on one of the stacks */ case BUTTON_F1: - /* check if a card is selected */ - /* else there would be nothing to move on the stacks ! */ if(cur_card != NOT_A_CARD){ - /* find the last card in the color's stack and put it's number in 'c'. */ - c = stacks[deck[cur_card].color]; - if(c!=NOT_A_CARD){ - while(deck[c].next!=NOT_A_CARD){ - c = deck[c].next; - } - } - /* if 'c' isn't a card, that means that the stack is empty */ - /* which implies that only an ace can be moved */ - if(c == NOT_A_CARD){ - /* check if the selected card is an ace */ - /* we don't have to check if any card is in the *.next */ - /* position since the ace is the last possible card */ - if(deck[cur_card].num == 0){ - /* remove 'cur_card' from any *.next postition ... */ - /* ... by looking in the columns */ - for(i=0;i<COL_NUM;i++){ - if(cols[i]==cur_card) cols[i] = NOT_A_CARD; - } - /* ... and in the entire deck */ - /* TODO : check if looking in the cols is really needed */ - for(i=0;i<COLORS*CARDS_PER_COLOR;i++){ - if(deck[i].next==cur_card) deck[i].next = NOT_A_CARD; - } - /* move cur_card on top of the stack */ - stacks[deck[cur_card].color] = cur_card; - /* assign the card at the bottom of cur_col to cur_card */ - cur_card = cols[cur_col]; - if(cur_card != NOT_A_CARD){ - while(deck[cur_card].next != NOT_A_CARD){ - cur_card = deck[cur_card].next; - } - } - /* clear the selection indicator */ - sel_card = NOT_A_CARD; - } - } - /* the stack is not empty */ - /* so we can move any card other than an ace */ - /* we thus check that the card we are moving is the next on the stack and that it isn't under any card */ - else if(deck[cur_card].num == deck[c].num + 1 && - deck[cur_card].next == NOT_A_CARD) { - /* same as above */ - for(i=0;i<COL_NUM;i++) { - if(cols[i]==cur_card) - cols[i] = NOT_A_CARD; - } - /* re same */ - for(i=0;i<COLORS*CARDS_PER_COLOR;i++){ - if(deck[i].next==cur_card) - deck[i].next = NOT_A_CARD; - } - /* ... */ - deck[c].next = cur_card; - cur_card = cols[cur_col]; - if(cur_card != NOT_A_CARD){ - while(deck[cur_card].next != NOT_A_CARD){ - cur_card = deck[cur_card].next; - } - } - sel_card = NOT_A_CARD; - } + move_card(deck[cur_card].color + STACKS_COL, cur_card); } break; - /* Move cards arround, Uncover cards, ... */ + /* Move cards arround, Uncover cards, ... */ case BUTTON_ON: if(sel_card == NOT_A_CARD) { - if((cur_card != NOT_A_CARD? - deck[cur_card].next == NOT_A_CARD && - deck[cur_card].known==0:0)) { - deck[cur_card].known = 1; - } else { - sel_card = cur_card; + if(cur_card != NOT_A_CARD){ + /* reveal a hidden card */ + if(deck[cur_card].next == NOT_A_CARD && deck[cur_card].known==0){ + deck[cur_card].known = 1; + /* select a card */ + } else { + sel_card = cur_card; + } } + /* unselect card or try putting card on one of the 4 stacks */ } else if(sel_card == cur_card) { + move_card(deck[sel_card].color + COL_NUM, sel_card); sel_card = NOT_A_CARD; - } else if(cur_card != NOT_A_CARD){ - if(deck[cur_card].num == deck[sel_card].num + 1 && - (deck[cur_card].color + deck[sel_card].color)%2 == 1 ){ - for(i=0;i<COL_NUM;i++){ - if(cols[i]==sel_card) - cols[i] = NOT_A_CARD; - } - for(i=0;i<COLORS*CARDS_PER_COLOR;i++){ - if(deck[i].next==sel_card) - deck[i].next = NOT_A_CARD; - } - deck[cur_card].next = sel_card; - sel_card = NOT_A_CARD; - } - } else if(cur_card == NOT_A_CARD){ - if(deck[sel_card].num == CARDS_PER_COLOR - 1){ - for(i=0;i<COL_NUM;i++){ - if(cols[i]==sel_card) - cols[i] = NOT_A_CARD; - } - for(i=0;i<COLORS*CARDS_PER_COLOR;i++){ - if(deck[i].next==sel_card) - deck[i].next = NOT_A_CARD; - } - cols[cur_col] = sel_card; + /* try moving cards */ + } else { + if(move_card(cur_col, sel_card) == MOVE_OK){ sel_card = NOT_A_CARD; } } break; - /* If the card on the top of the remains can be put where */ - /* the cursor is, go ahead */ + /* If the card on the top of the remains can be put where */ + /* the cursor is, go ahead */ case BUTTON_PLAY: - /* check if a card is face up on the remains' stack */ - if(cur_rem != NOT_A_CARD){ - /* if no card is selected, it means the col is empty */ - /* thus, only a king can be moved */ - if(cur_card == NOT_A_CARD){ - /* check if selcted card is a king */ - if(deck[cur_rem].num == CARDS_PER_COLOR - 1){ - /* find the previous card on the remains' stack */ - c = rem; - /* if the current card on the remains' stack */ - /* is the first card of the stack, then ... */ - if(c == cur_rem){ - c = NOT_A_CARD; - rem = deck[cur_rem].next; - } - /* else ... */ - else { - while(deck[c].next != cur_rem){ - c = deck[c].next; - } - deck[c].next = deck[cur_rem].next; - } - cols[cur_col] = cur_rem; - deck[cur_rem].next = NOT_A_CARD; - deck[cur_rem].known = 1; - cur_rem = c; - } - } else if(deck[cur_rem].num + 1 == deck[cur_card].num && - (deck[cur_rem].color + - deck[cur_card].color)%2==1) { - c = rem; - if(c == cur_rem){ - c = NOT_A_CARD; - rem = deck[cur_rem].next; - } else { - while(deck[c].next != cur_rem){ - c = deck[c].next; - } - deck[c].next = deck[cur_rem].next; - } - deck[cur_card].next = cur_rem; - deck[cur_rem].next = NOT_A_CARD; - deck[cur_rem].known = 1; - cur_rem = c; - } - } + move_card(cur_col, cur_rem); break; - /* If the card on top of the remains can be put on one */ - /* of the stacks, do so */ + /* If the card on top of the remains can be put on one */ + /* of the stacks, do so */ case BUTTON_F3: if(cur_rem != NOT_A_CARD){ - if(deck[cur_rem].num == 0){ - c = rem; - if(c == cur_rem){ - c = NOT_A_CARD; - rem = deck[cur_rem].next; - } else { - while(deck[c].next != cur_rem){ - c = deck[c].next; - } - deck[c].next = deck[cur_rem].next; - } - deck[cur_rem].next = NOT_A_CARD; - deck[cur_rem].known = 1; - stacks[deck[cur_rem].color] = cur_rem; - cur_rem = c; - } else { - - i = stacks[deck[cur_rem].color]; - if(i==NOT_A_CARD) break; - while(deck[i].next != NOT_A_CARD){ - i = deck[i].next; - } - if(deck[i].num + 1 == deck[cur_rem].num){ - c = rem; - if(c == cur_rem){ - c = NOT_A_CARD; - rem = deck[cur_rem].next; - } else { - while(deck[c].next != cur_rem){ - c = deck[c].next; - } - deck[c].next = deck[cur_rem].next; - } - deck[i].next = cur_rem; - deck[cur_rem].next = NOT_A_CARD; - deck[cur_rem].known = 1; - cur_rem = c; - } - } + move_card(deck[cur_rem].color + COL_NUM, cur_rem); } - break; + break; - /* unselect selected card or ... */ - /* draw new cards from the remains of the deck */ + /* unselect selected card or ... */ + /* draw new cards from the remains of the deck */ case BUTTON_F2: if(sel_card != NOT_A_CARD){ /* unselect selected card */ sel_card = NOT_A_CARD; - } else if(rem != NOT_A_CARD) { + break; + } + if(rem != NOT_A_CARD) { /* draw new cards form the remains of the deck */ if(cur_rem == NOT_A_CARD){ cur_rem = rem; @@ -870,24 +923,30 @@ void solitaire(void){ cur_rem = deck[cur_rem].next; i--; } - /* test if any cards are really left on the remains' stack */ + /* test if any cards are really left on */ + /* the remains' stack */ if(i == CARDS_PER_DRAW){ cur_rem = NOT_A_CARD; } } break; - /* Show the menu */ + /* Show the menu */ case BUTTON_OFF: switch(solitaire_menu(MENU_DURINGGAME)){ case MENU_QUIT: - return; + return SOLITAIRE_QUIT; case MENU_RESTART: solitaire_init(); break; } } + + /* fix incoherences concerning cur_col and cur_card */ + c = find_card_col(cur_card); + if(c != NOT_A_COL && c != cur_col) + cur_card = find_last_card(cur_col); } } @@ -903,7 +962,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb->splash(HZ*2, true, "Welcome to Solitaire !"); /* play the game :) */ - solitaire(); + /* Keep playing if a game was won (that means display the menu after */ + /* winning instead of quiting) */ + while(solitaire() == SOLITAIRE_WIN); /* Exit the plugin */ return PLUGIN_OK; |