Friday 6 May 2022

A Tale Of Two Banners: ZX

For the 40th Anniversary of the ZX Spectrum's announcement on April 23rd, 1982, I decided to write a little banner program.

Here's an example of what it can do:

May be a cartoon

ZX Spectrum BASIC is blessed with a large number of useful commands to access graphics, so the program was quite easy to write and relatively short:

No photo description available.

No photo description available.

As you can see, there's very little to this program. How does it work?

The main part of the program, obviously is the mechanism for enlarging the characters. This is surprisingly easy. The ZX Spectrum has 16 graphics characters arranged as Battenberg (as in the cake) graphics which occupy character codes 128 to 143.


The ZX Spectrum also has a POINT(x,y) function, which returns the pixel value at coordinates (x,y). By POINT ing at (x,y), (x+1,y), (x, y+1), (x+1, y+1) we can simply multiply each point by the appropriate Battenberg pixel value and add 128 to generate the correct graphics character. This is why you can see a tiny version of the '!' character in the bottom right-hand corner: the standard character is displayed and then it is scanned and the appropriate Battenberg characters are generated.

The program allows for the banner to be edited by simply supporting a carriage return feature and by wrapping the bottom line back to the top line.

The harder part is to generate the stripy coloured lines at the bottom right-hand corner. The difficulty with the ZX Spectrum is that it's not possible for more than 2 different colours (an INK colour and a PAPER colour) to occupy the same character square. So, to make the stripes we have to carefully make sure that each stripe is exactly 1 character wide and map the colours so that the stripe never clashes.

To do this we define a graphic character, UDG "a", whose address in RAM is returned by USR "a" as a diagonal triangle filling the bottom half of the character. This gives us the diagonal stripes by using the previous ink colour as the next paper colour on the next stripe - a classic ZX Spectrum colour trick! (You can see how it works from the image below where alternate diagonal rows are brighter ).

No photo description available.

To make the program a little bit more fun, each character is assigned a random colour and the cursor flashes.  Because the ZX Spectrum came out in a 16kB form, and one of my friends had one at the time, I thought it would be considerate to make sure the program would run on either model (it's so short, I could hardly fail 😉 !).

You can type in the program by going to the ZX Spectrum Javascript website! Here's the keyboard to help you! https://jsspeccy.zxdemo.org .

Following this I thought I'd do the same, for the Commodore VIC-20. It turns out that, despite arguably superior graphics capabilities (well, it can do 2 bits per pixel graphics!), it's far harder (see Part 2).


Sunday 1 May 2022

Gini Sim: Interactive

 In May 2014 I wrote a post on modelling the  Lorenz Curve,  which is an income or wealth curve whose curvature is expressed as the Gini Coefficient. In this model an ideal society has a straight-line curve and the more unequal a society is, the greater the curvature.

The post shows how a pure, free-market economy naturally gives rise to the highest possible gini coefficient, approaching 1 over time. This is the case even if the population involved has no ulterior profit motive and all participants play by the same, equally applied rules. The post provides a program, written in JavaScript which simulates the process, but the program doesn't run, it's just a listing.

Informally, the algorithm works as follows. There are 100 players. At first each player is given the same amount of cash: $10. $1 is randomly taken from the pool of money, and so the player who owned it now has $1 less; then another $1 is picked randomly from the remaining pool and the player who owns that one is now given the previously taken $1. So, usually, one player loses $1 and another player gains $1 (unless the same player gets picked for both steps).

Intuitively you would think that the probabilities would even out. As a player loses money, they are less likely to have money taken from them (and given to them), but likewise, as a player gains money, they are more likely to have money taken from them (and also given to them).

This is not what happens. Instead as players gain money, they are more likely to gain in subsequent transactions. This is because the probabilities change between transactions, in favour of previous winners. For example, consider a situation near the end game where one player has $1 and the remaining player has $99,999. Although 99.999% of the time, the dominant player will have $1 removed, 99.999% it will be returned with another 0.001% of an opportunity that it goes to the lesser player. However, in the 0.001% of the time that the lesser player's $1 is removed, it becomes impossible to receive that $1, and in subsequent plays, they now have a 0% of winning.

In the real world, this corresponds to the way in which larger players, who occupy more of the market, are more likely to be chosen to trade with: thus increasing their market share. In this version, the javascript is embedded in the article itself and thus it can be played live. You can see a Lorenz Curve being mapped out in realtime as it becomes more extreme. A variant allows you to generate interest with a given probability (interest works by leaving the 'loser' with the original $1 they had), but it has no effect on the overall outcome: the richest get richer while the poorest lose everything.




Simulation

Your browser does not support the HTML5 canvas tag.