I have investigated some alternative approaches to RNG. Some discussion here is misleading, other is spot on. First let's start with approach similar to deck of cards.
You probably want a small stack with fixed content, otherwise it defeats purpose and you are better using RNG. Numbers are poped from stack, when empty replenished with numbers and then shuffled (you can find algorithms for shuffling arrays). You need only entropy for shuffling, poping numbers can be done linear. Here is example of stack with 20 element with numbers in range 1-6 (I just made it up, so nothing special):
1, 2-2-2, 3-3-3-3-3-3, 4-4-4-4-4-4, 5-5-5, 6
Distribution of numbers isn't even, so you already get different odds: 5% chance for one, 15% for two, 30% for three and so on. Let's say that one is a miss and six is a critical hit - you can actually get two of those in a row (same number at the end of one stack and at the beginning of another). This should be a rare event, also periods without misses after and before event will be longer. You will also never get more than two misses in a row.
Why small stack? If you increase size of stack, you will probably want to increase probability of poping specific number. Not only streaks will be more common then, but also those streaks will be longer. Deck/stack approach gives you control over streaks and guaranteed occurrences.
About predictability from player perspective - if you don't know where stack starts/ends it is hard to abuse. One way to mitigate that is to change size of stack a little bit, every time it is created e.g. you discard one to five elements from deck with 50 elements.
Omnivore and Bear mentioned progressive system. Similar solution is used for drops in World of Warcraft:
http://www.shacknews.com/article/57886/blizzard-details-secret-world-of . I won't describe it, since article is pretty clear.
You can find some nice discussion here:
http://stackoverflow.com/questions/910215/need-for-predictable-random-generator . Just to quote:
Given the behavior you're asking for, I think you're randomizing the wrong variable.
Rather than randomizing whether this hit will be critical, try randomizing the number of turns until the next critical hit occurs. For example, just pick a number between 2 & 9 every time the player gets a critical, and then give them their next critical after that many rounds have passed. You can also use dice methods to get closer to a normal distribution -- for example, you will get your next critical in 2D4 turns.
I believe this technique gets used in RPGs that have random encounters in the overworld as well -- you randomize a step counter, and after that many steps, you get hit again. It feels a lot more fair because you almost never get hit by two encounters in a row -- if that happens even once, the players get irritable.