[Game]Pok2048

game
open-source
release
puzzle

#1

2048 game I made as a testing game when setting up my dev environment. If you don’t know the rules, Wikipedia has you covered :slight_smile:

com-resize

Code and bin can be found here:

Everything is CC0 licensed, so you can do anything with it. Feel free to play around, port it to other platforms, report bugs etc. If you enjoy the game and want to thank me, the best way to do it is by sharing your games as free and open source – with appropriate licenses – as well.

Thank you and enjoy the game :slight_smile:


#2

I really like it, the animation is nice a smooth, it plays really nice. Well Done!


#3

@drummyfish

Theres a badge coming for this!


#4

Looks cool! I need to do it


#5

Well done! Now just use @spinal’s sound example code and add “plop” sound effects to it :wink:


#6

If you want to fix the digits issue with the timer, consider this:

// Extract individual digits of a std::uint8_t
template< std::size_t size >
void extractDigits(std::uint8_t (&buffer)[size], std::uint8_t value)
{
	for(std::size_t i = 0; i < size; ++i)
	{
		buffer[i] = value % 10;
		value /= 10;
	}
}

// Extract individual digits of a std::uint16_t
template< std::size_t size >
void extractDigits(std::uint8_t (&buffer)[size], std::uint16_t value)
{
	for(std::size_t i = 0; i < size; ++i)
	{
		buffer[i] = value % 10;
		value /= 10;
	}
}

// Extract individual digits of a std::uint32_t
template< std::size_t size >
void extractDigits(std::uint8_t (&buffer)[size], std::uint32_t value)
{
	for(std::size_t i = 0; i < size; ++i)
	{
		buffer[i] = value % 10;
		value /= 10;
	}
}

// Extract individual digits of a std::uint32_t
template< std::size_t size > void extractDigits(std::uint8_t (&buffer)[size], std::uint64_t value)
{
	for(std::size_t i = 0; i < size; ++i)
	{
		buffer[i] = value % 10;
		value /= 10;
	}
}

Used like:

std::uint8_t digits[2];
extractDigits(digits, time.seconds);
Display::print(digits[0]);
Display::print(digits[1);

And if that’s not fast enough, std::div might be faster (but be careful about the signedness).


#7

What’s the issue? :smiley: Anyway thanks for the tips, I keep them all in mind, just am usually lazy to apply them right away if there’s no bug etc. Notice that I’ve started using enums with underlaying types :slight_smile:


#8

Usually timers have leading zeroes.
E.g. it should count up 00:01 to 00:09 before hitting 00:10

The one on your .gif doesn’t. (Maybe you’ve fixed it since you made the .gif, maybe not.)

True, but they’re still not scoped :P

Actually, putting the underlying type as uint8_t might not be optimal on Pokitto because of the 32 bit thing.

Though since they’re only being assigned and there’s no maths involved then it might not be too much of an issue.
I guess it depends on usage.


#9

When computing a remainder and a quotient on an LPC chip, this might be the faster way:

typedef struct {
    int quot;
    int rem;
} IDIV_RETURN_T;

typedef struct {
    unsigned quot;
    unsigned rem;
} UIDIV_RETURN_T;

typedef struct {
    int (*sidiv)(int numerator, int denominator); /*!< Signed integer division */
    unsigned (*uidiv)(unsigned numerator, unsigned denominator); /*!< Unsigned integer division */
    IDIV_RETURN_T (*sidivmod)(int numerator, int denominator); /*!< Signed integer division with remainder */
    UIDIV_RETURN_T (*uidivmod)(unsigned numerator, unsigned denominator); /*!< Unsigned integer division
									    with remainder */
} ROM_DIV_API_T;

typedef struct {
const uint32_t usbdApiBase; /*!< USBD API function table base address */
const uint32_t reserved0;
/*!< Reserved */
const uint32_t reserved1;
/*!< Reserved */
const void *pPWRD; /*!< Power API function table base address */
const ROM_DIV_API_T *divApiBase; /*!< Divider API function table base address */
} LPC_ROM_API_T;

#define LPC_ROM_API_BASE_LOC (0x1FFF1FF8UL)
#define LPC_ROM_API (*(LPC_ROM_API_T * *) LPC_ROM_API_BASE_LOC)

Used like this:

const ROM_DIV_API_T *pROMDiv = LPC_ROM_API->divApiBase;
UIDIV_RETURN_T ret = pROMDiv->uidivmod( numerator, denominator );

ret.quot will contain numerator / denominator, and ret.rem will contain numerator % denominator.


#10

Ok downloaded it and I do like it, I would add sound though, perhaps a sound like the iPhone space bar sound for a 1+1 and get slightly higher pitched as the number gets bigger.


#11

Great idea! I was thinking about sound but I have trouble with my simulator producing sound, so I’d have to keep testing it right on Pokitto, which is uncomfortable, so I just left it.

Once either I fix my simulator sound or I replace it with the emulator I may add it. Or, you (or someone else) can add it – the source code is right there :slight_smile: If it’s good && I like it && you agree, I’ll include it in the “official” game here :slight_smile:


#12

I have been unable to find the reason why sound crashes on linux/mac. it is SDL related.

Any help would be appreciated


#13

I’ve been looking into it too, valgrind says it crashes in pulseaudio library called from SDL, that’s all I know. I’ll try to figure out the exact line of code when I’m bored.


#14

I think, but do not know for sure, that it is some sort of a race condition


#15

I am really loving this game, I had two 128’s on the board, but couldn’t introduce them lol.


#16

I used to be addicted to this game a few years back. After some practice I’ve been able to win, but now it’s been some time and can’t do it, had to cheat in order to test winning the game :smiley: Fun fact: there are people who can get much higher than 2048, search on YouTube.


#17

std::div might be implemented like that already.

I’d look to check but I can’t remember where the stdlib files are.


#18

That’s very part-specific code. If GCC knew about it, libc wouldn’t need to implement division.


#19

It’s possible that it’s used in the library definition but not the compiler.
As far as I’m aware the compiler and the standard library were written by different people.
It would make sense that GCC wouldn’t be aware of something so part specific, but the writers of the stdlib might be (I would assume there’s a different define for each target MCU and thus detecting which optimisations are available would just be a bit of conditional compilation).


#20

This is a nice little game, very addictive!