Archive for the 'Programming' Category

23
Feb
21

Bob’s Fury Update: Bug Squished!

For quite some time I’ve had a very nasty bug in my game, where basically it would lock up whenever a sound was played through any sound device on my microbyte 386sx machine. What made this bug tricky to fix is that it worked perfectly fine on other hardware I had available and on the emulation I was using for testing (which was Dosbox).

I had already discounted any results from Dosbox, as it is widely known that the emulation is not hardware accurate. So I tested on the hardware I had available. Unfortunately I don’t have a lot of old 286 and 386 machines laying around, so I tested on the Microbyte 386sx and my Pentium MMX system. The big clue I got from that is that the sound code worked fine on the Pentium but not on the 386.

This is where I was stalled for quite a while, I tested much of the code and couldn’t figure out the fault. What I needed was another 286 or 386 machine to be sure it wasn’t just a quirk of the Microbyte, but this wasn’t something I could do easily. Recently I found an alternative solution that helped me solve the problem.

I have been watching some of Jim Leonard’s videos, as he makes some really good content about PC’s and is generally extremely knowledgeable. He had some of the same sorts of issues with developing DOS software using Dosbox for emulation, which is why he tends to use real hardware where possible. However he did recommend a PC emulator I hadn’t heard of called 86box.

So I downloaded 86box and fired it up. I was able to set up a virtual machine fairly quickly and found I could change some key configuration options I would later need. Most importantly I could replicate the crash in the emulator and experiment to find the cause.

Knowing that some aspect of the hardware configuration was causing the crash, I changed the configuration of 86box until the game didn’t crash, the key element turned out to be enabling the NPU. With it enabled the sound code worked a treat even on an emulated 386 system.

The reason for the crash, whilst difficult to work out, is actually quite simple. I have an interrupt hooked on $1C for playing sounds of any type, during the interrupt it would figure out the length of the next sound in timer ticks. This would use some simple floating point arithmetic.

Because I had configured the pascal compiler to use 80287 instructions and included emulation for when a NPU isn’t present the code would crash during the $1C interrupt. This would happen because of how the NPU emulation works. If a 286+ CPU encounters a floating point instruction and there is no NPU present it fires an interrupt, which redirects to the software emulation.

The problem plays out like this: In the main code there were some floating point calculations, these would use the emulation which could then be interrupted by more code also needing the NPU. This would mess up the internal state of the emulation causing a crash. This can’t happen with a real NPU because it can’t be interrupted mid instruction.

The solution was fairly simple, I turned off 80287 instructions and emulation and made minor adjustments to code so as to not require it. This got it working on real machines without a math-coprocessor and in 86box so I was quite pleased. I’m not entirely sure why I had used the 80287 code generation in the first place, but I can see why it persisted in my code for so long. Many of the machines I had tested on over the years were 486+ class computers, these all have the co-processor built in, so the problem wouldn’t appear. Dosbox didn’t expose the bug because there is no configuration option for turning off NPU support.

There is more work yet to do, such as implementing a lookup table to save on some of the calculations, and fixing other bugs. I’m now automatically packaging a download based on my most recent subversion revision which you can find here. I’m thinking about eventually hosting the binaries and code on somewhere like github.

03
Apr
20

Sparcie goes to youtube!

I’ve been thinking about creating youtube content for years, recently I finally got around to trying my hand at content creation. The technical aspects I’ve had sorted out for quite a while as I’ve been involved in supporting the technical aspects of remote teaching for quite a long time. It’s mostly the content itself which is the biggest challenge for me.

So I set myself up to record at home on my PC, I’ve installed some tools such as OBS, Audacity, Shotcut, and Handbrake, then sorted out the hardware as best I could. At the moment my microphone is probably the part that lets me down the most, being a relatively cheap one, but with everyone currently needing such technology it’s hard to get good equipment. I have an old web camera that is also sub optimal, but I don’t really plan on using it at this stage.

So what kind of content do I have planned? I’ve been planning on making some videos about gwbasic for some time, as the content I have seen hasn’t really been the sort that I’d like to watch. My first video is basically telling the story and demonstrating one of my gwbasic games that I made when I was a kid. In the future I’ll also cover stuff made by other people and in other languages such as QBasic and Pascal. However my focus is less on the programming and more on the programs themselves. Although if someone really wants a tutorial I may make a few.

I am thinking of doing gaming related content as well, perhaps some windows 9x games. I play a lot of Minecraft so that may get a showing as well.

Here’s my first video, warts and all. Let me know what you think.

27
Feb
20

Bob’s Fury Update: Bug Hunting

I’ve been doing some coding on Bob’s fury lately, basically making adjustments and making code faster in the hope that I could make it work well on a 286 class machine. I have been using dosbox to develop and test, but this doesn’t fully test the compatibility or stability of software as dosbox has its own quirks and does not behave exactly as real hardware does. This is where my old Microbyte 386sx computer steps in, here’s a photo from when I first bought it.

It has been very useful for performance testings as it has a turbo feature that is software controlled. You can not only toggle the CPU speed with a key stroke, but you can set the slower speed in the BIOS configuration. This has allowed me to test with the machine running at its stock 20Mhz as well as a slower speed, I’ve used 10Mhz for my testing as a rough equivalent of many 286 machines. The testing I was able to do has shown that my game should be playable on a 286 depending on the video mode. CGA and VGA both have acceptable speed for game play, whilst EGA is marginal.

The testing did however uncover a rather annoying and difficult to squish bug. If I have the sound turned on (PC speaker is all this machine supports) the system will freeze when a game event that plays the explosion sound happens. Hunting bugs such as this are difficult as there is little feedback about the potential causes. It sounds like the code supporting the PC speaker should be at fault, so that’s where I began the search for the bug.

For the PC speaker I found a support library many years ago that allowed you to use the music macro language used by the play statement in GWbasic and QBasic. It hooks interrupt 1Ch (the system timer interrupt) to update the state of the PC speaker. Whilst I haven’t had any previous issues I wondered if there was a fault that could cause the crash. At first I wondered if using floating point instructions could have been the cause. The library has a small section using floating point to determine the number of ticks a note should last. On a system such as the 386sx without a FPU such instructions cause an interrupt so that emulation in software can take over. This interrupt within an interrupt was what I thought may be the cause.

So I constructed a test program hooking the same interrupt and performing a series of floating point calculations as a test, this didn’t yield the result I’d hoped as the test program worked fine. So I then wondered if the 386 was getting another type of problem that would cause an unwanted interrupt. So I copied sections of code from the library into the test program to run in a normal procedure that would show run-time error messages and debug information I could use. No run-time errors appeared and the results of the required calculations appeared to be correct.

I have a few ideas left to test, but I’m left with quite a puzzle regarding the cause. This does illustrate the need for testing on actual hardware, it’s usually better to test on many machines. Unfortunately I don’t have a large supply of 286 and 386 class machines, although I have a few I may be able to repair. I need to test on another machine because there could be something specific in the design of the Microbyte machine that isn’t compatible and is causing the issue.

09
Apr
19

Modern BASIC: PCBasic and QB64

Last month I had intended to make the next Sparcstation desktop post, but unfortunately have been having trouble getting the software I had intended to cover to build. So that’s still in the works and today we’re going to look at something else interesting: modern implementations of old BASIC Languages. It seems I’m not the only one that feels nostalgia for the old BASIC interpreters that were common to almost every machine. The two I’m looking at today are particularly nostalgic for me as I learned to program on the original interpreters.

The first, PC-BASIC is made by Rob Hagemans and is an extremely well polished GWBasic emulator. It seems to be 100% compatible as I’ve been able to run all of my old basic programs including ones that use graphics and sound. Here are some images of programs running.

This slideshow requires JavaScript.

The graphics and sound are indeed very accurate compared to MS-DOS hardware and the original interpreter. There is good support for all the graphics modes including those from special machines such as the Tandy/PCjr and Olivetti machines that had special versions of the interpreter. The PC speaker is emulated quite well (better than under Dosbox) and support for Tandy 3-voice sound is included. I’m not sure if it was deliberate, but it seems that the processing speed on my laptop is similar to what I used to experience on our old 386sx back in the day.

The next program, QB64, is a new language designed to mimic QBasic and QuickBasic with extensions that provide access to modern graphics and sound libraries. It can build native executables for Linux, Windows and Mac OS, so it’s pretty impressive and capable of producing programs for modern systems. Here are some programs running.

This slideshow requires JavaScript.

I tried to compile some of my old programs, from both GWBasic and Qbasic, and found some worked without modification whilst others didn’t work or required modification. I had some issues with the programs that did build, the first and most obvious is that the programs started in what is initially a very small window. Resizing the window doesn’t stretch the display, but pressing alt+enter does give a nice full screen display. The second issue is more complex and arises from the fact the programs are compiled and not interpreted. Basically they run way too fast because they are running at native speeds on modern hardware. This issue however should be fixable by modifying your programs with better timing code. Thirdly I’ve found one or two features from the old languages aren’t implemented, meaning some old programs won’t work, the Gorilla game that came with Qbasic being one.

An IDE is provided which looks almost identical to QBasic, so it’s very familiar and relatively easy to use. Auto indentation seems to fix old programs as they are loaded and parsed, and there is some very nice syntax highlighting, making even old programs much more readable. Although one negative point is the built-in help only covers items specific to QB64 and has omitted a language reference for the base QBasic language.

Given that we can run the original interpreters in Dosbox, how do these modern interpretations compare?

PC-BASIC is quite good in the compatibility department, working with basically everything I threw at it. The only real disadvantage it has is speed compared to running GWBasic in Dosbox, and the ability to change the emulation speed. On the other hand it has some features that appeared in real hardware, but aren’t emulated in Dosbox. (such as screen borders on CRTs) It also gives access to features found on special versions of GWBasic, such as the special Tandy graphics and sound that would be otherwise inaccessible on the standard interpreter. You can get this interpreter from his github website, I recommend using the development version as it is more compatible and has fewer bugs.

QB64 doesn’t fair so well with every older program, those that work do so quite well however. Many programs will work with a little modification, whilst others will require major re-working. I suspect the main benefit of QB64 is less about running old programs and more about building new programs. It features some extensions to the QBasic/QuickBasic language that allow more modern features of the operating system to be used such as 3d graphic acceleration and digital sound. You can get QB64 from their website, I used the stable version and found it worked quite well.

30
Jul
18

Bob’s Fury progress update

You may have noticed that I’ve been playing with a number of homebrew MS-DOS games lately. This has given me a little more motivation to work on my own project, my simple flick-screen platform game Bob’s fury.

The main body of work left is to create the levels for the game and any content required for them. For me this has been the hardest and most time consuming aspect of making the game as it requires a lot of play testing and planning. Recently whilst visiting my folks I had some time to produce a new level, I’ve updated the download to include it.

I’m hoping that it won’t take as long to build the next level, I got one pretty decent tip from watching some interviews of Brenda Romero. Basically the tip is starting at the end/goal and build outwards from there. I had been doing the opposite, which made the process harder, partly because you have to keep where you’re going in mind before having built the area.

The other stumbling block I have is coming up with ideas for levels. There’s not much I can do to stream line this, so it will probably continue to be a road block. I will probably simply make fewer levels for each “episode” so I don’t require as many ideas.

I’ve also released the level editor for any one interested. You can find it here.

22
Feb
17

Making a new GWBasic game.

When I was young I learned to code using GWBasic, a BASIC interpreter that came with MS-DOS 4.01. I’ve posted some code and talked about it in the past, but not really developed anything new, that is until today. I’ve re-written a game from scratch I had lost on a corrupted floppy disk called dodge, yes it’s not much of a name but it basically describes the game play in that you dodge bad guys and collect score items for points.

The original had some basic EGA graphics, but this time I’ve used text-mode characters for a few reasons. Firstly it is easier to implement both in terms of artistry and coding. The original never played well due to slowness in the interpreter and the implementation that I had used. Finally using text mode increases the effective game play area by more than 2 times, which will allow for more interesting levels. I didn’t implement any sound either in the original or the new, but music often doesn’t work well on the PC speaker and I’m not much of a composer.

Being a much more mature programmer I’ve been able to make the game mechanics better and add features that the original never had. There are 5 built-in levels (encoded with RLE) and the capability to load a custom level from a text file. The original only had randomly generated levels that were far simpler. I’ve made the movement of enemies better than the original, and gravity affects most items so that they are reachable.

I could have coded the game using a modern text editor, but for that extra nostalgic feeling I coded the game in the interpreter itself. It’s not as intuitive of course as you can’t simply scroll back and forth through the program, instead needing to use the LIST command to see parts of the program. Luckily editing a line isn’t too bad, as after display it on screen you can edit it easily. The interpreter also has some nifty features that can speed up program entry. Many keywords such as print and input have keyboard shortcuts, usually alt and the first letter of the keyword. This not only sped up program entry, but enabled me to discover keywords when I was a kid before I got the user manual.

Using the interpreter to write the code does however demand much more of your memory, I don’t remember this bothering me much as a kid, but now as an adult I needed to keep notes on the structure of the program and variables used. I would have written these out by hand on a notebook back in the day, but doing the coding with the interpreter running in dosbox meant I could run a text editor for my notes. It’s probably one of my more complex gwbasic programs at 592 lines of code.

Overall it has been quite fun writing with gwbasic again, like revisiting somewhere you went as a kid. I’m making the code available at the usual places, both my download website, and my google drive (in case the website is down). The code should work on QBasic as well as the original interpreter.

31
Jan
17

Creating a benchmark: part 6 problem solved!

Quite some time ago, in fact more than a year ago now, I was working on a basic series of benchmarks to test the comparative performance of the Borland Graphics Interface (BGI) versus a hand coded graphics library. I ran into a problem with my hand coded library not working on some of my real hardware. I ran the tests on a Pentium MMX @ 200Mhz and a 386sx @ 20mhz, it ran fine on the newer machine whilst failing on the older one. I figured perhaps I was overloading the older graphics chip.

So coming back to the problem today with a renewed sense of determination, I did some reading. There happened to be a book in the university library about programming VGA graphics, and I noted that all of their code only copies single bytes to graphic memory at a time, I was copying 2 bytes (a 16 bit word) at a time so wondered if that might be the issue. I changed it and the program still crashed almost immediately.

After some tinkering and some basic math I worked out that sprites being drawn near to the bottom of the screen were the cause of the problem. The test algorithm actually allows sprites to be drawn partially obscured by the right or bottom edge of the screen. On most VGA cards this isn’t a problem, but the trident chip in the 386sx didn’t like any pixels being drawn outside of the visible frame buffer. After writing some basic clipping into the sprite routines the program worked all the way through.

I’ve tested 3 different programs on two different real machines (as opposed to emulation). BGIbench is the original program that uses the provided graphics libraries that came with Turbo Pascal, I’ve used it in conjunction with the VGA256 BGI driver. VGABench is the initial lazy implementation of a hand made graphics library, it’s implemented entirely in pascal and isn’t optimised at all. Lastly is VGABench2 which is an optimised version of VGABench using assembly where necessary, and in the case of line drawing a better algorithm. All three programs were coded and compiled with Turbo Pascal 6.0 and use the same basic test code.

Each program performs 7 tests based around primitive functions found in the BGI. Each test counts the number of primitives that can be drawn over a period of 30 seconds. VGABench doesn’t have a function for drawing circles so it has no results for that test. The tests in order: put-pixels simply draws individual pixels a random colour. Filled Boxes draws solid coloured rectangles in a pre-defined pattern. Circles draws a number of concentric circles in a per-determined way. Random lines does what you’d expect, drawing lines randomly. Horizontal and vertical lines are similarly obvious. Finally the sprite test draws a 10×10 bitmap at random locations on the screen.

At first glance it’s pretty obvious that optimised, hand written code is significantly faster on the Pentium, particularly for filled boxes and sprites where VGABench2 achieves roughly twice the output to the screen. I managed a five-fold increase in the rate of drawing circles, which is impressive as circles are the hardest to draw. The first VGA Bench however is not really much better than the BGI and in some tests actually performs worse. You’ll note that the put-pixel tests all come out fairly close in terms of results, this is because there is little to optimise there.

I suspected that the reason VGABench2 performed so well is because the code copies 16 bits at a time instead of 8bits. I tested this out by changing it to copy 8bits at a time and found it was still faster than the BGI, but by a much smaller margin. VGABench2 copying 16bits yields about 156k sprites, but modifying it to copy 8bits yielded about 80k compared to BGI which achieves around 73k sprites. The first VGABench demonstrates how important optimisation is. It copies data 16bits at a time, but doesn’t even achieve the performance that BGI does, managing around 68k sprites.

386sx-20

The picture looks quite different on the 386sx machine, with the performance looking much more even with a few exceptions. The BGI seems to perform comparatively well across most categories only lagging behind in drawing circles, filled boxes and sprites. My first lazy implementation, VGABench seems to lag behind in pretty much everything except drawing filled boxes, which barely outperforms the BGI.

The results for VGABench2 are good, but not as good as on the Pentium machine. Line drawing is basically the same speed as the BGI. Filled boxes achieves about twice the speed, and circles about 5 times the speed, but the sprites are comparatively slower at about 1.5 times the speed. The explanation for the performance of sprites and filled boxes is interesting and is related to how the test is implemented. The filled boxes are drawn in a deterministic way, a grid of 10×10 sized boxes, the sprites are distributed randomly. Filled boxes end up being drawn pretty much always on even addresses, and sprites will be drawn on even and odd addresses around the same amount. This affects speed because of something called word alignment.

The 386sx, 286 and 8086 processors have a 16 bit data bus, which means the processor can access 16bits at a time. The memory is organised as a bunch of 16bit words, so when accessing 16 bits on an even address only a single memory word is accessed, and when a 16 bit access needs an odd address, two memory words are required. This means doing 16bit reads/writes on odd addresses are half as fast as on even ones, in fact they are about the same speed as an 8 bit transfer.

In beginning to sum up the series, it’s important to remember why I started it at all. Basically I remembered hearing many people discouraging use of the BGI mostly because it is slow compared to hand crafted code. The tests I’ve done have confirmed this, but I feel that it’s also shown how a lazy (or poor) implementation can be even slower. My optimised code is faster, but took a lot of time and effort to create and is missing many features that the BGI provides, such as support for other graphics cards, clipping, and other graphics primitives that are more complicated. I can see why many people without the time and know-how would have found it easier to simply use the graphics library provided.

That being said, hand written optimised code certainly has an important place as well. It was pretty fun and challenging to try and make something faster, even though I almost certainly didn’t get my code anywhere near as fast as more proficient assembly programmers. Also it’s hand optimised code that made many PC action games possible at all. Gaming on the PC would be very different without the hardware guru’s that could squeeze amazing things out of basic hardware. Writing this has made me reconsider my stance on sticking with the BGI for my platform game, I probably won’t gain a lot of performance, but I may be able to get it to work on older hardware as a consequence.

Code and binaries are available from the pascal downloads.

29
Jan
16

Huffman Coding – Compression results

Before the Christmas break I started writing a encoding/compression library based on a technique called Huffman coding. I’ve since completed and tested the encoder and decoder, today we’ll discuss the results of several compression tests in comparison to the RLE encoding technique. Here are links back to the posts for Huffman Coding and Run-Length Encoding.

So I’ve collected a few different types of data files with different characteristics. First up is a MS-DOS executable, these binary data files typically don’t contain runs of data and will tend to contain most if not all symbols. Next is a ASCII text file, which will typically only use alphabetic, numeric and punctuation characters. Lastly a small number of graphics files, in raw bitmap form, these particular images are fairly basic (only a handful of colours).

Here’s a table showing the results.

Compression ratio table

You’ll note that the Huffman encoder achieves better results in every example! The worst result for it being the MS-DOS executable, which is of course expected. I was pleasantly surprised that the small graphic files compressed quite well, this is likely because of how few symbols are in these files. If there had been a large variety of symbols the dictionary and the encoded data would be much larger.

Run-length encoding was obviously much worse, and in the case of ASCII text and executable data it actually increased the size of the data! Knowing how it works this is hardly surprising. I did expect RLE to perform better than Huffman coding for the graphic data, but I suspect the low colour count in these files is an influencing factor.

So I thought I’d create a graphic data file that had a higher colour count that would favour RLE to see if it can do better under specific conditions. The graphic data I created is a sprite 32×32 pixels with horizontal coloured stripes, each a unique colour. The size of the raw file came out at 1026 bytes.

The Huffman encoder produced a file of 766 bytes and the RLE produced one of 68 bytes! Whilst the Huffman encoder still managed to compress the data, it couldn’t match the best case scenario for RLE.

There are good reasons to use both compression techniques. Run-length encoding doesn’t require much CPU power to encode or decode, so it can be done on very weak machines (even old 8-bit machines), but it only compresses data with many runs in it well. This turns out to be useful for graphics and level data. Huffman coding will pretty much always reduce the size of the data encoded, sometimes significantly, but it is much more complex. It requires more RAM and CPU power to achieve this result, so it can’t be used on every machine, although most modern processors would have no trouble at all.

I’ve made the code for the Huffman encoder/decoder available in pascal for download. be aware the encoder still has some debug code in it that will write to the screen.

30
Nov
15

Huffman Coding

Quite some time ago I did a short post about a compression technique called run-length encoding (or RLE), that was a commonly used compression method for graphic and level data. At the time I wrote and implemented it for the graphics and level data for my home-brew game Bobs Fury with quite the success, significantly reducing the disk space required for the base game.

I do however have some files left, which are largely just ASCII text, that don’t compress well or at all using that technique. I’d like to make them smaller, and of course harder to read as they contain story text, not that my game has a brilliant story, but you get the idea. Step in an encoding technique called Huffman coding.

Essentially the encoding algorithm encodes symbols as a variable length stream of bits. The most frequently used symbols are represented by shorter bit streams, whilst the least used have longer ones. Normally in a computer each symbol would be encoded as a fixed number of bits, such as say 8-bit or 16, so this results (hopefully) in shorter encodings for most symbols, and longer ones only for the rarely used ones.

The tricky part is creating the Huffman tree, which is basically a code-book representing how each symbol is encoded or decoded. Here is a quick tutorial on how they are created, which will also give you a feel for how the encoding works. It’s also commonly known as a dictionary, or code book.

A fixed tree can be used for everything, but would not do the best job for every set of data being compressed. So typically a tree is created and stored along with the encoded data to achieve the best compression possible. This of course does add some overhead, which could be a problem if the resulting encoding isn’t much shorter than the original.

Huffman coding typically works poorly when the symbols all appear in the text at roughly the same frequency. The worst case being everything with exactly the same frequency. Notably it won’t produce an encoding that is longer than the original data, although with the overhead of storing the tree, you could end up with a larger data file. In practise this rarely happens.

Other data such as English text stored in ASCII actually compresses quite well. As usually not all the 255 characters are used, most encodings will be shorter than 8 bits per symbol. Also because natural language uses some letters more than others the average encoding length for all the symbols will be shorter.

Huffman coding was actually invented quite some time ago (1951) by David Huffman, well before it came into common use. Check out the Wikipedia page for more information. It’s a part of many commonly used compression programs and formats such a Zip and Bzip. Older 8-bit machines typically weren’t powerful enough, so it wasn’t commonly used until more powerful machines with more memory became available.

It took me much longer than usual to write this post primarily because I began the process of writing an encoder and decoder, but because of the complexity, it’s taken up much more time than I expected. Currently I have just finished the encoder, but have yet to test it. I had hoped to get the code running first, but that will have to wait.

20
Oct
15

QBasic Gorillas

Qbasic GorillasToday I’m looking at the classic old artillery game Gorillas, it was an example program for the Qbasic interpreter that was packaged with MS-DOS 5.0 and later. Because it was so widespread, being on practically every machine of its time, it was widely played and loved by many. I first encountered it on our high school computers in computer studies classes, we often got to play some games after we finished our work. We played many games, but Gorillas  (and Nibbles) were favourites.

Dancing Gorillas!

Dancing Gorillas!

Being written in Qbasic graphics and sound support is fairly basic. Unless you’re using an old machine with CGA only, the graphics are in high resolution EGA (640x350x16) and whilst not spectacular have some charm. Sound is PC speaker, again largely due to the limits of Qbasic. Most sounds are fairly basic, although the intro tune is kinda cool.

City Skyline

City Skyline

The game field consists of a city skyline with two Gorillas atop a building at opposite ends of the screen. Each Gorilla takes turns hurling an explosive banana at the other, with the player aiming the shots by entering the angle and velocity. The round only ends when one of the Gorillas is hit by a banana, with the survivor being the winner. There was no computer AI, so you had to play it in a hot-seat style or on your own. It’s simple and fun to play, although there isn’t much variety.

Target hit!

Target hit!

Normally this is where a post like this would end, with some kind of summary of what I thought. Today however I decided to have a quick go at making a simple modification to the game, adding an AI to the game so you can play solo. The tricky part with making an AI player in this case isn’t making something that will play well, but making something a human has a chance of beating. I could quite easily make it simply calculate the ideal velocity and angle, but that wouldn’t be much fun.

A winner is you.

A winner is you.

So what have I done instead? It’s a fairly simple algorithm, I set the initial aim to some sensible defaults and after each shot adjust the velocity depending on whether the shot landed short or long. This actually proved to be quite good at making hits, but not before making a few shots giving a human player a chance. Occasionally they will make a hit on the first shot, but that only happens when the buildings are set up just right. One circumstance that the computer does poorly is when a tall building is blocking the path of the bananas. I deal with this to a degree by making the angle higher when the banana doesn’t go very far. It will still take many shots for the AI to succeed.

I’ve made the modified version available here. It requires the original Qbasic to run and DOS in one form or another (Dosbox recommended). The game is pretty much unchanged apart from adding the AI, which you activate by naming a player Computer. You can have the computer play itself by naming both players Computer. Another improved version of the game exists, and has improvements such as a league table and improved graphics and sound. It’s called Gorillas Deluxe and can be found here.




Enter your email address to follow this blog and receive notifications of new posts by email.


Mister G Kids

A daily comic about real stuff little kids say in school. By Matt GajdoĊĦ

Random Battles: my life long level grind

completing every RPG, ever.

Gough's Tech Zone

Reversing the mindless enslavement of humans by technology.

Retrocosm's Vintage Computing, Tech & Scale RC Blog

Random mutterings on retro computing, old technology, some new, plus radio controlled scale modelling.

ancientelectronics

retro computing and gaming plus a little more

Retrocomputing with 90's SPARC

21st-Century computing, the hard way