English · Русский
A gambling machine with a face, written in C on Turbo C++ in 2017 — by a tenth-grader who had not yet heard of functions taking arguments. You bet, you name a number, a brick of C4 counts down, and the machine rolls three dice in its own two eyes and its nose. It has been preserved exactly as it was, typos included.
The game needs a DOS machine, so it comes with one.
1. Install DOSBox https://www.dosbox.com
2. Unpack Turbo C++ 3.0 to C:\TURBOC3 (inside DOSBox)
3. Drop BoneMachine.c next to it, open it in the IDE, and press Ctrl+F9
initgraph() looks for the BGI drivers in c:\turboc3\bgi, so EGAVGA.BGI has to be there —
that is the one thing that goes wrong for everyone. Full walkthrough, including the mouse and
the usual errors: docs/RUN.md.
You type a starting balance, pick a number from 1 to 6, and watch three dice come up. The dice are not drawn as dice — they appear inside the machine's face, one per pupil and one on the nose. Guess right and the mouth turns green and grins; guess wrong and it turns red.
| Mode | You name | You win if | Chance | Balance |
|---|---|---|---|---|
| Guess 1 of 3 | one number | any of the three rolls matches it | 42.1% | +150 / −30 |
| Guess 2 of 3 | two numbers | any roll matches either of them | 70.4% | +150 / −30 |
Which brings us to the best bug in the repository.
The payout is fixed at +150 for a win and −30 for a loss, and nobody checked that against
the odds. Mode 1 wins 1 − (5/6)³ = 42.1% of the time, so the expected result of a round is
+45.8 chips for the player. Mode 2, with two distinct guesses, wins 1 − (4/6)³ = 70.4% of
the time: +96.7 per round.
The machine is not rigged against you. It is rigged for you, and it cannot be beaten by playing badly — only by getting bored. Sixteen-year-old me built a casino that pays rent.
Every screen below is reconstructed straight from the BGI coordinates in the source — the same
bar3d, line and outtextxy calls the code makes. No emulator screenshots, no touch-ups.
The one liberty taken is the typeface: BGI's 8×8 bitmap font is stood in for by an ordinary
monospace, on the same eight-pixel grid.
| One file | BoneMachine.c, 1344 lines, no headers of its own |
| Functions | 15 — main plus 14, and eleven of them take no arguments at all |
| Comments | 196 lines carry one, and the vocabulary slips into transliterated Russian: Graphics_Fon is fon, background; punkt is a menu item |
| Graphics | BGI primitives only: bar3d, line, floodfill, outtextxy |
| Mouse | int86(0x33, …) — raw DOS interrupts, polled every 30 ms |
| Navigation | goto. Seven labels. It is a state machine, if you squint |
| Version | 6.0, dated 18/05/2017 · 21:39 in the header comment |
The 367-line main() is a menu drawn three times over, once per highlighted row,
because that was easier than tracking a selection index. Every screen transition is a goto
into the middle of another loop. It should not be readable, and yet it is.
A guided walk through the whole thing — the interrupt handling, the redraw model, the
goto graph, and the parts that are genuinely clever — is in
docs/CODE-TOUR.md.
Not a list of regrets. A list of things the code teaches by doing them the hard way.
gotoinstead of state. Three menu layouts are copy-pasted, one per highlight, and jumped between by label. Oneint selectedand a redraw loop would have replaced all of it.- Two modes, one algorithm.
Game_Mode_1andGame_Mode_2are ~240 lines each and differ by onescanfand one||. That is roughly a third of the program, duplicated. - Six cases to print one digit.
switch(Random1 = random(6)+1)has acaseper face, each callingouttextxywith a different string literal. - Everything is global.
balance, the three rolls, the guesses and the menu index all live at file scope, so no function needs a parameter and no function can be tested. Mouse_Regs()is declaredintand returns nothing. Turbo C++ let that through. So did I.- Nobody did the arithmetic. See above: the house loses about 46 chips a round.
graphics.h and dos.h are Borland's, so this will not build with GCC or Clang — the drawing
calls and the int86 mouse both need replacing. That makes it a pleasant afternoon project:
the whole game is 15 functions and one screen resolution.
If you port it to SDL2, raylib, WebAssembly or anything else, open an issue and it gets linked right here. Ports are the one contribution this repository actively wants; the 2017 code itself stays exactly as it is, bugs and all. Documentation fixes and translations are welcome too — CONTRIBUTING.md says what is in scope and what is not.
MIT — take it, learn from it, ship it.
The licence this README used to claim
Nostalgia Public License v1.0
- May: feel nostalgic, smile, remember 2016.
- May: use the code for teaching — both as an example and as a warning.
- May: show a friend and say "this was my first program".
- May not: seriously criticise a sixteen-year-old.
Superseded by the MIT licence above, which has the advantage of existing.
Version 6.0 · 18/05/2017 · 21:39 · by IAMN1
"If this program works, IAMN1 wrote it. If it does not, I have no idea who wrote it."
— the header comment, 2017
