To get good at duckhunt you need to be able to manage your experience wisely.

Watch for freetime! When the freetime timer expires, you get your gun back (if it's confiscated) and your magazines are refilled for free. Use dhfreetime to see when freetime happens.

Keep a slot open for new mags! You can find mags in the bushes after killing a duck sometimes. If you have max mags it gets deleted, and that wastes 13 exp!

Remember spawn order

Ducks either get shot, or they leave, in the same order in which they spawn.

Early game

In the beginning you start with a bad gun with a lot of bullets per mag and abysmal accuracy. At this moment, buying mags is better than buying bullets. I recommend getting a 4-leaf clover dhbuy 10 if you have more than 20 exp and then just shoot any duck you can. I also recommend buying a sight for the early game dhbuy 7 to minimize missed shots and chances for accidents. You could buy grease to stop jamming, but I reckon it's a waste of exp. You could get an infrared detector to help save bullets and -2 exp, but I’d just use dhhug to see if there‘s a duck when I'm not sure.

A silencer is really useful in the early game, since you miss loads of shots and the loud noise can still scare ducks away.

Late game

Eventually you'll get a fancy sniper rifle with only 1 bullet per mag. At this point in the game buying bullets is better than buying mags. Also, a 4-leaf clover (dhbuy 10) is necessary to get on top, and an infrared detector (dhbuy 8) is really recommended to avoid waste. You can always drop 4 or 5 bread pieces on a channel and hope it lures more ducks. (dhbuy 21)

Avoid buying some items, most are not worth it at this point. Grease, Silencers, ... Most of the anti-sabotage items, such as the weapon cleaning, are useless and should not be bought.

Never ever buy the life insurance. It's simply not worth it.

Extra tips

You can usually tell when there's no duck by looking for the last duck spawned, and for the last message of, "You killed the duck in ?? seconds"... But don't assume that the time for the last duck killed is always for the last duck spawned -- convert the seconds to minutes, subtract from time of that message, and compare to previous message timestamps to see which duck it might have been. If you're still not sure if there's a duck left in the channel, use dh!hug instead of dh!bang, so you don't waste a bullet.