Category: C

Space Invaders done faithfully in C

Space Invaders done faithfully in C

Si78 Space InvadersI was around when space invaders came out in the late 70s and played it a bit, although I preferred Galaxian, Gorf, Defender and Battle Zone (3D Tanks on the moon- vector graphics).

This project (catchily named si78) though is a memory accurate re-implementation of the 1978 arcade game Space Invaders in C.

To build and run this (on a Linux box) you’ll need to download the invaders ROM which is available in one of the Mame sets. The game is written in the subset of C99 that is compatible with C++, and uses no compiler extensions apart from attribute packed.

 

Improving on C strings

Improving on C strings

T
Image by Anja🤗#helpinghands #solidarity#stays healthy🙏 from Pixabay

Although C has many useful features, Text or string handling is not one of them. Unless you are writing text adventures, this is probably not a big deal and even games like Asteroids do write text messages, show the score etc.

Givn C’s age, it’s not surprising that people have tried to improve on C’s strings (char *) and one that I came across is the Better string library. The library is stand alone, portable and known to work with gcc/g++, MSVC++, Intel C++, WATCOM C/C++, Turbo C, Borland C++, IBM’s native CC compiler on Windows, Linux and Mac OS X. If you are bothered by buffer overflow type bugs, this is one area that BSL can definitely improve on. Note although the main documentation is just one text file, it is a very long file!

I haven’t tested it with clang but if it works with gcc the odds are it will work with clang.

I’ve added it to the C code links page.

 

Using Excel for level design

Using Excel for level design

Excel level spreadsheet for AsteroidsIn the asteroids game and shortly in my MatchThree game, I’ll be creating a level data array of struct. This has a struct for each level containing a count of particular features for that level.

This is the struct and array for a level in asteroids.

struct level {
	int nums[4]; // how many of each size of asteroid
	int aliens; // how many aliens
	float factor; // from 1.0 to 1.5 - multiply asteroid speed by this
};

struct level levels[50];

This is the first 3 levels and level 50.

#include "levels.h"

struct level levels[50] = {
{ .factor = (float)1,.aliens = 1,.nums = { 0,0,3,3 } }, // Level 1
{ .factor = (float)1,.aliens = 0,.nums = { 0,1,3,3 } }, // Level 2
{ .factor = (float)1,.aliens = 0,.nums = { 0,1,3,3 } }, // Level 3
..
{ .factor = (float)1.5,.aliens = 3,.nums = { 4,4,5,5 } } // Level 50

I didn’t type any of this in. Instead, I created that spreadsheet above. It’s easy to work out difficulty levels in column H.  The formula that calculates this is ins this on row 5. If you don’t know Excel, the $ in the factors means that as you copy this into successive row, it keeps the $ row value constant.

=(B5*B$4)+(C5*C$4)+(D5*D$4)+(E5*E$4)+(F5*F$4)+(G5*G$4)   - Row 5

=(B6*B$4)+(C6*C$4)+(D6*D$4)+(E6*E$4)+(F6*F$4)+(G6*G$4) - Row 6

So you can see its multiplying the values in rows 5 6 etc by the values in row 4.  Having put that in place I could tinker with the values in rows 5,6 etc to make the difficulty level increase roughly at the same pace. The difficulty level for level 50 is 77.5.

This is what the Excel formula looks like to generate the C code, it’s in cell M5 in the spreadsheet and then copied and pasted down.

="{.factor =(float)"&G5&", .aliens="&F5&", .nums = {"&B5&","&C5&","&D5&","&E5&"}}, // Level "&A5

and this is what it looks like. C code that can be copied and pasted directly. It even includes the comment for the level number!

{.factor =(float)1, .aliens=0, .nums = {0,0,3,3}}, // Level 1

Creating a spreadsheet and C code from it this way saved a lot of typing but let me quantify the numerical difficulty which increases from 17.5 on level 1 to 77.5 on level 50. There’s no meaning to this value, it’s just a calculation.

A tictactoe (aka noughts and crosses) game in C

A tictactoe (aka noughts and crosses) game in C

TicTacToe aka Noughts and Crosses
Image by Kevin Phillips from Pixabay

I was asked to write this a few month’s back and it took me 2 or 3 evenings. It’s 312 lines long in just one file. Hopefully there are enough sensible function and variable names to make sense of it.

It runs in a terminal. It was compiled with Visual Studio but should not need many changes to compile with gcc/clang. (I hope!).

I made extensive use of pointers. For instance this function uses pointers in a for-loop.

int InDanger(char piece, int * x, int * y) {

    for (*y = 0; *y < 3; (*y)++) {
        if (CountRows(piece, y,0)==2) return 1;
    }

    for (*x = 0; *x < 3; (*x)++) {
        if (CountCols(piece, x,0) == 2) return 2;
    }
    *x = 0;
    if (CountDiagonal(piece, x,0) == 2) return 3;
    *x = 2;
    if (CountDiagonal(piece, x,0) == 2) return 4;

    return 0; // no danger
}

I’ve added this to the GitHub C games repository and updated the C games source page.

Useful reference to C operators

Useful reference to C operators

Reference
Image by ElasticComputeFarm from Pixabay

Ever wondered what all the operators that you can use = are. Like ^=. Or what about operator precedence? Does * come before ++? (Answer no, ++ is higher precedence than *).

Do you know how

a & b == 7

is parsed? It’s actually a & (b==7)

This Wikipedia page lists all the operators with precedence order and as it includes C++, it lets you see what you can and can’t do in C and C++.  It’s worth bookmarking whenever you need to look these things up.

The Wayback machine-slightly offtopic

The Wayback machine-slightly offtopic

There is a wonderful website (archive.org) that makes a backup of websites. It even has one of this blog, taken on April 30th. It’s remarkable.

The reason I mention it is because I was looking at the backup of cplus.about.com, a website that I managed (curated, wrote tutorials etc.) on “Programming in C, C++, C#” (and even Go) between 2006 and 2013.  One of the things I ran there was a set of programming challenges and by the end I’d done a whopping 70 of them. I came up with the idea, published it, then adjudicated entries.

This page has a list of 65 of them.  There may be more from a later date but no more than 70.

As I can now gain access to most of them, I’m going to rerun a few here. starting with the first which I’ll publish tomorrow.

Who needs asm? cc65 C compiler

Who needs asm? cc65 C compiler

Commodore Computer
Image by OpenClipart-Vectors from Pixabay

Back in the day 1984-1989, I wrote games in Z80 and 6502 assembly. It would be another 10 years before I learnt C++ and ten years after that for C. But I would have killed to have had a C compiler that generated 6502 code back then. Writing assembly language code is slow and painstaking. You have to remember whats in each register (A,X and Y) and what you are using page 0 locations for.

It takes the same length of time to write and debug 10 lines of 6502 assembler as it does to write 10 lines of C.  But those ten lines of C can do way more than 10 lines of 6502 assembly.

On a 6502 which is an 8 bit CPU with 16-bit addressing, memory goes from 0-65535. It takes two bytes for an address unless it is in the first 256 bytes (0-255) which only needs 1 byte. You can optimise your code by using page 0 for many variables. It only takes 2-byte instructions to fetch them from memory and write them back. The first byte is the instruction, the 2nd the address. Compare that with the rest of memory where instructions are three bytes long with 2-bytes for the address.

CC65 is a C compiler that generates 6502 code. It’s mostly written in C. I’ve added a permanent link to it on the C Codes link page. Pictured is a CBM-64 like the one I used to own.

Deciding what level features to be used in the Match Three game

Deciding what level features to be used in the Match Three game

Match Three gameI’m at the point of deciding what features will be included in the game and then determining what % of features are used on each level. how to make the game harder etc. As with asteroids I’ll use Excel.

These are features to enhance the game and maybe increase difficulty.

  • Wanted animals. Most levels have a target of a number of pieces of one type. The level is completed when all of that piece have been removed. These ‘wanted’ animals are shown onscreen with a count of how many remain.
  • Locked pieces. On some levels, pieces are randomly locked. The lock is removed only when the piece is in a matched line or in the area affected (from bonus pieces). Locked pieces do not move even if there is a space beneath them. For really hard levels, two locks can be used on a piece. Each lock has to be removed.
  • Skulls. Some levels have a number of skull pieces to be removed. This can only be done by removing pieces below so the skull drops and eventually reaches the bottom row where it is automatically removed.
  • Timed levels. Some levels will have a count down timer; so many animal pieces have to be removed before the timer runs out.
  • Bonus Pieces. These appear when a 4-match, a 5-match or a 6-match occurs and show special pieces- a 4-piece, 5-piece etc. Two 4-pieces dragged together clear a 5 x5 area of all pieces (remove locks on locked pieces). Two 5-pieces dragged together wipe out all pieces in both the row and column. A 4 and a 5-piece together wipe out all animal pieces of the animal piece (picked randomly) next to the 5-piece. Two 6-pieces together wipe out all pieces on the board (locked pieces aren’t wiped, just unlocked). A 6-piece dragged on a 4-piece or 5-piece wipes out all pieces in 3 rows wide and 3 columns deeps.
  • Board Rotation. The board can be rotated clockwise or anti-clockwise. This allows spaces created under locked pieces to be possibly filled. It also helps get rid of skulls that are now on the bottom row. But some levels start with a number of board rotations. Once used up, the only way to earn them is to do something like drag two four-match pieces together.

So now I have to decide how these fit together on the different levels, what weighting each has and calculate a difficulty score that should increase as you progress through levels. Oh the joys of game design!

Back writing book two

Back writing book two

Hexagons
Image by Clker-Free-Vector-Images from Pixabay

This time it’s about Learning to program games in C on the Raspberry Pi. Most of the books I’ve seen are about programming in Python, but C combined with SDL2 gives you an edge. I already know that I can get 150 frames per second in Asteroids on a Raspberry Pi 4B.

The three games for the book are

  1. Asteroids. Fully developed
  2. MatchThree. About 1/2 developed.
  3. Empire type game. Map generator plus large scrolling hexagon map with fog-of-war shrouding and computer AI opponents. This will be based on the existing Empire code.

The third game is one I originally wrote thirty-three years ago (Dark Empire) in Z80 assembler for the Zx Spectrum. I then converted all 5000 lines of code into CBM-64 6502 assembly in one month working seven all-nighters, with the last three on three successive days. That one wasn’t in hexagons but squares and of course there was no mouse.

On the morning after the last all-nighter I drove across Manchester to deliver the tape master copy to a railway station to be sent to the publisher in London and when I got home, I slept for 24 hours solid. I doubt I could do an all-nighter now, but 33 years ago …