It depends on your source of randomness. An unverified contract running some obfuscated code does not provide any additional security, since transactions can be locally simulated (they don't need to know the internals of your contract).
If contracts are able to interact with your contract, they could even simply send a transaction with a require statement that will revert if their desired outcome is not reached.
Assuming only externally owned accounts are able to interact with your contract, you could resort to some pseudo random source like blockhash. Since blockhash cannot be used on the current block, people have time (in theory) to simulate a transaction first and still make it into the next block. If you tied in something only determined by the latest block (block.timestamp or I've also seen block.difficulty), you end up limiting your randomness, because it is now more predictable. You are still vulnerable to miners, since they have the ability to influence values such as blockhash and the timestamp to some degree.
You definitely want to avoid the user having any control over the randomness (like basing it off any values they provide or can influence, like gasleft()) and limit predictability. One way to go (and which I think is a fairly good trade-off) is to have a 2-step process (chainlink is also a 2-step process) where the user commits their choice to some future block (say the next block) and you use the resulting blockhash as a source of randomness. Note that miners can still freely decide over the outcome (and they will if the incentive is big enough).