Vagrearg Logo  
Fruit Machine
The One-armed Bandit

Games are all around us. Games are actually mind-bogglingly complex the more simple they seem. Just thinking about man-machine interaction, game progression and win/lose situations makes up for a lot of thought and time spent on big pictures and small details.

While about to embark on a new journey, teaching young people about technology, made me revisit the very first real program I ever wrote. More than 30 years ago, I was learning 6802 microprocessor programming on a dev-kit system. The whole "microprocessor" stuff was so intriguing that I went through all lectures in few weeks instead of the allocated months of work. It allowed me to do something more and unfold a bit of creativity. Thanks to the teacher, I was allowed to do a lot of free-wheeling in his class.

The program I came up with was a One-armed Bandit (slot-machine) program on 7-segment displays. If I remember correctly, the dev-kit had 6 displays in a matrix, 4 to display address and 2 for data, and an 4x5 keyboard matrix for input and a speaker. Any user-code could take over the system and do whatever. The program was written in 6802 assembly and took up 2..3kByte of memory.

The large bin-of-components revealed I had lots of everything needed:
  • six 7-segment displays
  • an AtMega88PA
  • an ULN2003 driver
  • six buttons
  • a piezo transducer
  • resistors and capacitors

See also project update below.


Two hours of soldering later I had a board capable of reliving old memories.
The system runs on 3xAA batteries which should last for about 24 hours of continuous play. The batteries hold several months when the system is in sleep mode. No real optimization has been performed to reduce power consumption. A later version may revisit that part in the firmware, especially sleep-mode power reduction could be improved.

Diagram as PDF.

The hard part of the system is, as always, the software. The Fruit Machine is no exception. The features implemented include:
  • 4 reels with symbols
  • random positioning
  • animated reel movement
  • sound when reels are moving
  • hold any reel
  • start rolling/subtract credits
  • detect winnings/add credits
  • bonus button (double cost/win)
  • music
  • scrolling text
  • sleep mode
The firmware is available in source. It compiles with standard avr-gcc and avr-libc.
See below, code is updated with the new version.

The code is written in C. There was no real urge to re-live the pains of assembly when it is not strictly necessary. Using a high-level language is just so much easier.

The reels are defined by a simple symbol table with 16 entries. Only 9 symbols are used, where some are duplicated in the table to stack the odds of them occurring. Each real has a variable that indexes the reel-symbol-table to make up the four reels. Rolling reels will animate the next symbol into view.

Symbol selection from the table is performed with a random number generator. The basis is a standard pseudo random number generator (PRNG), based on a linear feedback shift register (LFSR) setup. The PRNG is mixed with two random sources. One from the least significant bit of the AtMega's ADC measuring temperature and the other source is from a free running counter (at ~1MHz) which is sampled each time the user presses a button. These two additional sources make the PRNG unpredictable for the purpose of this device. The use of a PRNG is decidedly different from the original implementation 30 years ago, which has no such advanced stuff.

Music is generated by the AVR processor using a timer to toggle an output-pin. This has the advantage that it can run asynchronously from the rest of the code. The timer is also useful to generate the correct pitch over several octaves. The melodies are then simple tables with a pitch and a duration.

It should be noted that no real statistical calculations were performed to ensure occurrence of any particular sequence at a specific rate (or at all, for that matter). That I would leave as an exercise to the reader.
It turns out that controlling the statistics for a real one-armed bandit are formidable and I have respect for those who have implemented "set returns at xx%". It is hard to have both (seemingly) random performance and predictable outcome. You'd need some advanced score-boarding to keep track of the winning combinations and adjust the outcomes accordingly. That is quite a setup and would also require some computing time. Although, the AVR processor has still plenty of memory left and is currently rather under-used at a maximum load of 35% (and 6% average).

If you feel up to it, please improve the algorithm(s) and show off the results ;-).
There are still so many funny little things that can be implemented with such small gadget... Maybe my future students can come up with some good suggestions.

A video to demonstrate:


The design had to be put on a PCB. The PCBs were actually made over half a year ago, but I never got to the point to put it all together. I had the whole stackup in my mind but time is a funny thing.

Anyway, a few new images as how it looks now:
fruit-final-front-off fruit-final-front
fruit-final-high-side fruit-final-low-side

The firmware and design files are available at the GitLab repository which you can browse, clone and download: fruitmachine/tree/master.

The code has changed a bit and it employs better random, incorporating a free running timer read at button press/release and the LSB of a temperature measurement into the LFSR generator. The win chances have been adjusted a bit and is much more balanced now. You can still get to the maximum, but it is a bit harder now. There is a magic key-combination to force the machine into sleep (hold all HOLD buttons down and press BONUS).

The new version was tested on a couple of teenagers and it was determined that the game is addictive and a great time-waster. Goal achieved :-)

Posted: 2014-06-25
Updated: 2015-05-28

Overengineering @ request