Monsteropolis Casino

(Andrew) #1

I was sidetracked from my first game to write this one by my D&D group.

It’s going to be from the perspective of a casino worker not a player.

Lizard Racing -you can watch the lizards run, but that’s about it, managing betting hasn’t been implemented yet.
Nilbogs Revenge -is going to be a dice game that hasn’t been implemented yet
Other Game -I don’t know what this is yet, but I thought three was a nice round number. It should fit the theme somehow, I’m open to suggestions.

https://github.com/bridge2nowhere/monsteropolisCasino

5 Likes

(Pharap) #2

By the way, a byte can’t actually store -1 because it’s unsigned, -1 will be converted to 255.

byte (a.k.a. uint8_t) can store values between 0 and 255 (inclusive).

If you go File > Preferences and set Compiler warnings to All then the compiler will actually tell you this:

monsteropolis\monsteropolis.ino:13:29: warning: narrowing conversion of ‘-1’ from ‘int’ to ‘byte {aka unsigned char}’ inside { } [-Wnarrowing]

byte racer[4] = {-1,-1,-1,-1};

If you need -1 you should use int8_t which can store values between -128 and 127 (inclusive).

(I can see a few other things that could be improved, e.g. all your lizard names are currently being stored in RAM rather than progmem, but I don’t want to bombard you with advice/suggestions unless you’re prepared for it.)

0 Likes

(Andrew) #3

I’m having a problem where the screen gets weird for one of the lizards. I think that it’s reading past the end of the array at some point, but I can’t pin it down.

1 Like

(Andrew) #4

Game was updated today. Betting is implemented, but the odds don’t affect the lizards yet.

1 Like

(Pharap) #5

The lizard’s name or are you actually drawing lizards.

At a glance the first thing I can think of is that you’re writing

const char * const liz0 PROGMEM = "Iv";

Instead of

const char liz0[] PROGMEM = "Iv";

Which means you’re probably storing a pointer to RAM instead of storing the actual string in progmem.

0 Likes

(Pharap) #6

I found your problem. In fact there’s a few problems.

Firstly, what I said earlier about using const char * const liz0 PROGMEM = "Iv"; instead of const char liz0[] PROGMEM = "Iv"; was right.
You weren’t actually putting the strings into progmem, the strings were staying in RAM and you were putting pointers to the strings in progmem.
By using const char liz0[] PROGMEM = "Iv"; instead, RAM usage went down by ~200 bytes.

That in turn explains why

const char * getLizardName(uint8_t index) {
  return reinterpret_cast<const char *>(pgm_read_ptr(&LizardNames[index]));
}

was working.

If you hand a const char * to print, it tries to print a string in RAM.
To get print to print a string from PROGMEM you have to pass it a __FlashStringHelper.

Which is why getLizardName should be:

const __FlashStringHelper * getLizardName(uint8_t index) {
  return reinterpret_cast<const __FlashStringHelper *>(pgm_read_ptr(&LizardNames[index]));
}

And finally, you were missing liz11 from LizardNames.
I spotted a lizard name was missing by printing out racer[i] and finding that Stistink was showing up as 34 instead of 35, and I discovered which name by listing the names vertically like so:

const char * const LizardNames[] PROGMEM
{
	liz0,
	liz1,
	liz2,
	liz3,
	liz4,
	liz5,
	liz6,
	liz7,
	liz8,
	liz9,
	liz10,
	liz12,
	liz13,
	liz14,
	liz15,
	liz16,
	liz17,
	liz18,
	liz19,
	liz20,
	liz21,
	liz22,
	liz23,
	liz24,
	liz25
	liz26,
	liz27,
	liz28,
	liz29,
	liz30,
	liz31,
	liz32,
	liz33,
	liz34,
	liz35
};

One final thing:
If you want to make the best use of memory, make sure to wrap every string you pass to print with the F macro (e.g. arduboy.print(F("You Win ")) instead of arduboy.print("You Win ")),
and if you’re only printing a single character then use a character literal (e.g. arduboy.print(' ') instead of arduboy.print(" "))

1 Like

(Andrew) #7

I updated my game as you suggested. I’m a bit out of my depth with the way C handles strings. New version is on the github.

2 Likes

(Pharap) #8

C++, not C (there’s a big difference).
Both make use of null-terminated strings, but the compiler is C++ by default.

The whole ‘progmem’ thing is actually AVR-specific,
and the use of __FlashStringHelper is Arduino-specific.

__FlashStringHelper exists as a way for the print function to recognise that the string is stored in progmem.
It actually gets converted back into a const char * inside the print function so it can be read from,
but the const __FlashStringHelper * type allows the compiler to pick the right overload of print (i.e. the one reading from progmem instead of RAM).

The F macro performs the dual role of putting the string literal in progmem and converting it to const __FlashStringHelper *, but it’s only useful for passing string literals directly into a call to print.

Looks like you got all the mentioned issues sorted.
The memory usage ought to be a lot lower now.

0 Likes

(Andrew) #9

First version of Nilbogs Revenge is up and running and on github. It’s not pretty but it is mostly working. I’m going to hopefully get dice sprites loaded up tonight.

I’m a little torn on how to make the games work from the casinos perspective. Can you swipe in loaded dice? What’s the story?

0 Likes

(Simon) #10

Swipe as in ‘swipe the screen’? No.

I built a version of the game Farkle where you had to select / discard dice. It may help.

0 Likes

(Andrew) #11

No swipe as in try and sneak in “loaded” dice so that the NPC gambling at the table doesn’t notice. I wanted this to be from the dealers perspective not the players sitting at the table.

0 Likes

(Simon) #12

Ahh … that makes sense.

That would be cool. Are you planning on adding graphics for the other players? You could have them looking ahead most of the time but occasionally a furtive glance to the left or right. If all players (assume more than one) are glancing to the side at the same time, you could press a button and do the swap. If one is watching you get caught out …

0 Likes

(Andrew) #13

I was thinking more of a D&D style dexterity check

0 Likes

(Stephane C) #14

That game could be really interesting. J am intrigued.

0 Likes

(Pharap) #15

Technically the two-argument version of random (random(lower, upper)) is already loaded.
It uses the modulo operator to limit its numbers which means it has a thing called ‘modulo bias’.
‘modulo bias’ makes some numbers more likely to appear than others.
(There’s an explanation of how it works here.)

But anyway, depending on how you want the mechanic to work it’s probably possible.

1 Like