After Abbuc 2013 games were released, new post about highscore was created at AtariAge HighScoreClub (HSC). Several Atarians posted their score with screenshots, but MaPa posted quite high score from AssebloidsXE. When most of players could not get 5000 points, MaPa got more than 38000. That is pretty sick score, so I decided to break this record.
Unfortunately my brain/cognitive senses are not that good for such task. I have tried to play that game couple times, but I just could not succeed. I believe this game suits for people who have gift of being good at similar tasks which require fast response of selecting from multiple targets. I’m not such person, really I cannot focus after few seconds, my brain starts melting and my eyes go squint.
Well, at least my brain can focus well on some other tasks, so I tried to solve such issue from other perspective.
So I opened my “beloved” D7 and started coding some expert-system app which could do the magic. All I needed was figure out these 3 points:
- send keystroke from my app to Altirra emulator to be able to control the game (tactile sense)
- grab screen of Altirra and recognize patterns (sight sense)
- build bot AI logic according to game rules (intelligence)
It does not sound very hard to do, but it required quite an effort. Let’s take point by point…
Thats something I was sure I could do quite fast. So I googled few articles and started coding. First I had to get handle of Altirra’s window by it’s title, which was quite easy. Then I had to find several ways of sending keystrokes using sendmessage, postmessage and some others, tried two without success, but third did the trick. Suddenly I was able to put Altirra window into foreground and emulate pressing arrow up button from my app. Funny thing is that this stupid app (which only held arrow up button) was able to get score of 3500 points on first try :D.
2. Pattern recognition – computer vision
This is something I am bit familiar with from my college days. I wrote my diploma about object tracking and coded app that used my own tracking algorithm and returns coordinates of tracked object. It was reading realtime MJpeg data from IP camera directly through sockets, decoding, processing and tracking. Fortunately I didn’t have to do such complicated code to solve AssembloidsXE.
Grabbing application window required some googling, but it worked pretty well from the beginning. Tricky thing was that I had to setup Altirra to display game in square pixels (fixed multiple only), but still I had to manually resize window because of black borders. My app just grabbed middle part of window which contains only pieces of face that have to be placed.
Then I naively grabbed 1 pixel from each corner and tried to process it. I was well aware that it is very small chance this might work, but I tried it. So next step was to code some normalizer, which counts average pixel color from given region. Color was then easily determined by choosing highest color component (RGB) and position (corner) of face element was recognized even easier.
3. Artificial intelligence
I tried two approaches to solve game logic and it is quite interesting, that easy one was better one. I defined arrays that contain which parts and which colors of four destination faces are already placed so solver counts it exactly same as game. This part surprisingly worked at first try without need to tune it up. These arrays are used to determine next move (which key to press) and there were these two algorithms:
a) Fill face as fast as possible, try to fill faces from those which have higher number of parts already placed and don’t think about colors.
b) If there is more than 1 incomplete face, try to find incomplete face which consist only of color of current facepart and try to fill it. If this is not the case, use logic from a).
Testing proved that algorithm a) gives better results especially because player gets extra points for clearing whole game area. Algorithm b) was able to fill “full” faces, but it almost never cleared game area which made it lose. There is also second aspect which is not that apparent… videoram data is not very well synchronized with PMG data, so app sometimes grabs frames, where is videodata shown without PMG (due to improper synchronization in game) so system evaluates such facepart as grey, even it is green red or blue. Then it is pretty hard to keep algorithm b) effective.
I am sure it is possible to use fuzzy logic and maybe put some randomness which could bring better results, but I was quite satisfied with results I got.
See recorded video (original footage is about 85 minutes long), achieved score: 97740
As you can see, some glitches started to appear after long time of gameplay – “full face” label glitch, music glitches, finally gameplay glitch that caused GAMEOVER and title screen glitch.
You can download my assembloids Jebator app (including source code) from here:
UPDATE: I created modified AssJebator (v0.2) which contains editbox, so you can have any Altirra config (window title) to use it.
How to use it:
Please keep in mind that this app is quite raw.
- Check/Update window title of your emulator in editbox on the top of window, otherwise window handle won’t be found and you cannot continue.
- Press “init” button to find emulator window by AssJebator app, if not successfull, check point 1.
- Press “grab” button – you have to align your Altirra window correctly to grab and recognize faceparts. You have to tune this up manually, you can press grab button as many times as you like
- Press “process” button – it executes recognition phase and shows results (facepart color and facepart placement)
- Start new game and press “Jeb” button during countdown execute solver in automatic mode.
- Wait for hiscore or game crash 🙂