choose a random passage that hasn't been chosen yet; once all have been chosen, reset the tracking to make all passages available again */
| 3428 | /* choose a random passage that hasn't been chosen yet; once all have |
| 3429 | been chosen, reset the tracking to make all passages available again */ |
| 3430 | staticfn int |
| 3431 | choose_passage(int passagecnt, /* total of available passages */ |
| 3432 | unsigned oid) /* book.o_id, used to determine whether |
| 3433 | re-reading same book */ |
| 3434 | { |
| 3435 | int idx, res; |
| 3436 | |
| 3437 | if (passagecnt < 1) |
| 3438 | return 0; |
| 3439 | |
| 3440 | /* if a different book or we've used up all the passages already, |
| 3441 | reset in order to have all 'passagecnt' passages available */ |
| 3442 | if (oid != svc.context.novel.id || svc.context.novel.count == 0) { |
| 3443 | int i, range = passagecnt, limit = MAXPASSAGES; |
| 3444 | |
| 3445 | svc.context.novel.id = oid; |
| 3446 | if (range <= limit) { |
| 3447 | /* collect all of the N indices */ |
| 3448 | svc.context.novel.count = passagecnt; |
| 3449 | for (idx = 0; idx < MAXPASSAGES; idx++) |
| 3450 | svc.context.novel.pasg[idx] = (xint16) ((idx < passagecnt) |
| 3451 | ? idx + 1 : 0); |
| 3452 | } else { |
| 3453 | /* collect MAXPASSAGES of the N indices */ |
| 3454 | svc.context.novel.count = MAXPASSAGES; |
| 3455 | for (idx = i = 0; i < passagecnt; ++i, --range) |
| 3456 | if (range > 0 && rn2(range) < limit) { |
| 3457 | svc.context.novel.pasg[idx++] = (xint16) (i + 1); |
| 3458 | --limit; |
| 3459 | } |
| 3460 | } |
| 3461 | } |
| 3462 | |
| 3463 | idx = rn2(svc.context.novel.count); |
| 3464 | res = (int) svc.context.novel.pasg[idx]; |
| 3465 | /* move the last slot's passage index into the slot just used |
| 3466 | and reduce the number of passages available */ |
| 3467 | svc.context.novel.pasg[idx] |
| 3468 | = svc.context.novel.pasg[--svc.context.novel.count]; |
| 3469 | return res; |
| 3470 | } |
| 3471 | |
| 3472 | /* Returns True if you were able to read something. */ |
| 3473 | boolean |