Files
Momentum-Firmware/applications/plugins/blackjack/card.c
2022-10-13 21:17:26 +02:00

239 lines
7.8 KiB
C

#include "card.h"
#include <math.h>
//region CardDesign
bool pips[4][49] =
{
{
//spades
0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 0, 1, 1,
0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0
},
{
//hearts
0, 1, 0, 0, 0, 1, 0,
1, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 0,
0, 0, 1, 1, 1, 0, 0,
0, 0, 0, 1, 0, 0, 0,
},
{
//diamonds
0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 0,
0, 0, 1, 1, 1, 0, 0,
0, 0, 0, 1, 0, 0, 0
},
{
//clubs
0, 0, 1, 1, 1, 0, 0,
0, 0, 1, 1, 1, 0, 0,
1, 1, 0, 1, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 0, 1, 1,
0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0
}
};
bool backDesign[4] = {
0, 1,
1, 0
};
//endregion
uint8_t characters[13] =
{
2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A'
};
//region Player card positions
uint8_t playerCardPositions[22][4] = {
//first row
{108, 38, 0, 0},
{98, 38, 0, 1},
{88, 38, 0, 1},
{78, 38, 0, 1},
{68, 38, 0, 1},
{58, 38, 0, 1},
{48, 38, 0, 1},
{38, 38, 0, 1},
//second row
{104, 26, 1, 0},
{94, 26, 1, 1},
{84, 26, 1, 1},
{74, 26, 1, 1},
{64, 26, 1, 1},
{54, 26, 1, 1},
{44, 26, 1, 1},
//third row
{99, 14, 1, 0},
{89, 14, 1, 1},
{79, 14, 1, 1},
{69, 14, 1, 1},
{59, 14, 1, 1},
{49, 14, 1, 1},
};
//endregion
void drawPlayerDeck(const Card cards[21], uint8_t count, Canvas *const canvas) {
for (uint8_t i = 0; i < count; i++) {
CardState state = Normal;
if (playerCardPositions[i][2] == 1 && playerCardPositions[i][3] == 1)
state = BottomAndRightCut;
else if (playerCardPositions[i][3] == 1)
state = RightCut;
else if (playerCardPositions[i][2] == 1)
state = BottomCut;
drawCardAt(playerCardPositions[i][0], playerCardPositions[i][1], cards[i].pip, cards[i].character, state,
canvas);
}
}
void drawCardAt(uint8_t pos_x, uint8_t pos_y, uint8_t pip, uint8_t character, CardState state, Canvas *const canvas) {
if (state == Normal) {
canvas_set_color(canvas, ColorWhite);
canvas_draw_box(canvas, pos_x, pos_y, CARD_WIDHT, CARD_HEIGHT);
canvas_set_color(canvas, ColorBlack);
canvas_draw_frame(canvas, pos_x, pos_y, CARD_WIDHT, CARD_HEIGHT);
} else {
if (state == BottomCut || state == BottomAndRightCut)
canvas_draw_line(canvas, pos_x, pos_y, pos_x, pos_y + CARD_HALF_HEIGHT - 1); //half height line
if (state == BottomCut) {
canvas_draw_line(canvas, pos_x, pos_y, pos_x + CARD_WIDHT - 1, pos_y); //full width line
canvas_draw_line(canvas, pos_x + CARD_WIDHT - 1, pos_y, pos_x + CARD_WIDHT - 1,
pos_y + CARD_HALF_HEIGHT - 1); //half height line
}
if (state == BottomAndRightCut) {
canvas_draw_line(canvas, pos_x, pos_y, pos_x + CARD_HALF_WIDHT - 1, pos_y); //half width
}
if (state == RightCut) {
canvas_draw_line(canvas, pos_x, pos_y, pos_x + CARD_HALF_WIDHT - 1, pos_y); //half width
canvas_draw_line(canvas, pos_x, pos_y, pos_x, pos_y + CARD_HEIGHT - 1); //full height line
canvas_draw_line(canvas, pos_x, pos_y + CARD_HEIGHT - 1, pos_x + CARD_HALF_WIDHT - 1,
pos_y + CARD_HEIGHT - 1); //full height line
}
}
uint8_t left = pos_x + CORNER_MARGIN;
uint8_t right = (pos_x + CARD_WIDHT - CORNER_MARGIN - 7);
uint8_t top = pos_y + CORNER_MARGIN;
uint8_t bottom = (pos_y + CARD_HEIGHT - CORNER_MARGIN - 7);
for (uint8_t x = 0; x < 7; x++) {
for (uint8_t y = 0; y < 7; y++) {
if (pips[pip][x + y * 7]) {
if (state == Normal || state == BottomCut)
canvas_draw_dot(canvas, right + x + 1, top + y);
if (state == Normal || state == RightCut)
canvas_draw_dot(canvas, left + x - 1, bottom + y);
}
}
}
canvas_set_font(canvas, FontSecondary);
char drawChar[3];
if (character < 9)
snprintf(drawChar, sizeof(drawChar), "%i", character + 2);
else {
snprintf(drawChar, sizeof(drawChar), "%c", characters[character]);
}
canvas_set_font_direction(canvas, CanvasDirectionLeftToRight);
canvas_draw_str_aligned(canvas, left + 2, top + 3, AlignCenter, AlignCenter, drawChar);
canvas_set_font_direction(canvas, CanvasDirectionRightToLeft);
if (state == Normal) { //flipper crashes on non center aligned text when upside down
uint8_t margin = 9;
if (character == 8) //10 needs bigger margin
margin = 12;
canvas_draw_str_aligned(canvas, right + margin, bottom - 3, AlignCenter, AlignCenter, drawChar);
}
canvas_set_font_direction(canvas, CanvasDirectionLeftToRight);
//canvas_draw_str(canvas, left, top, drawChar );
}
void drawCardBackAt(uint8_t pos_x, uint8_t pos_y, Canvas *const canvas) {
canvas_set_color(canvas, ColorWhite);
canvas_draw_box(canvas, pos_x, pos_y, CARD_WIDHT, CARD_HEIGHT);
canvas_set_color(canvas, ColorBlack);
canvas_draw_frame(canvas, pos_x, pos_y, CARD_WIDHT, CARD_HEIGHT);
for (uint8_t x = 0; x < CARD_WIDHT - 2; x++) {
for (uint8_t y = 0; y < CARD_HEIGHT - 2; y++) {
uint8_t _x = x;
uint8_t _y = y * 2;
if (backDesign[(_x + _y) % 4]) {
canvas_draw_dot(canvas, pos_x + x + 1, pos_y + y + 1);
}
}
}
}
void generateDeck(Deck *deck_ptr) {
uint16_t counter = 0;
for (uint8_t deck = 0; deck < DECK_COUNT; deck++) {
for (uint8_t pip = 0; pip < 4; pip++) {
for (uint8_t label = 0; label < 13; label++) {
deck_ptr->cards[counter] = (Card)
{
pip, label
};
counter++;
}
}
}
}
void shuffleDeck(Deck *deck_ptr) {
srand(DWT->CYCCNT);
deck_ptr->index = 0;
int max = DECK_COUNT * 52;
for (int i = 0; i < max; i++) {
int r = i + (rand() % (max - i));
Card tmp = deck_ptr->cards[i];
deck_ptr->cards[i] = deck_ptr->cards[r];
deck_ptr->cards[r] = tmp;
}
}
uint8_t handCount(const Card cards[21], uint8_t count) {
uint8_t aceCount = 0;
uint8_t score = 0;
for (uint8_t i = 0; i < count; i++) {
if (cards[i].character == 12)
aceCount++;
else {
if (cards[i].character > 8)
score += 10;
else
score += cards[i].character + 2;
}
}
for (uint8_t i = 0; i < aceCount; i++) {
if ((score + 11) <= 21) score += 11;
else score++;
}
return score;
}