Permainan kartu "Bodoh" di dua M5Stack

Tujuan pelajaran


Hari ini kita akan menulis permainan kartu jaringan untuk dua pemain. Game apa yang harus ditulis? Mari kita menulis permainan kartu populer "Bodoh", yang tujuannya adalah untuk menyingkirkan semua kartu. Anda dapat mempelajari lebih lanjut tentang aturan di sini .



Gambar 1.


Sedikit teori


— RS-232, , , . "", , . RS-232, M5STACK TTL.


RS-232 "0" -3 -25 , "1" +3 +25 . RS-232 TTL "0" 0 , "1" , 3.3 5 (. 2).



2. RS-232 TTL


M5STACK / R0, R2 (RX) T0, T2 (TX) (. 3), USB . , , 0 1 .



3.


Serial Arduino IDE https://www.arduino.cc/reference/en/language/functions/communication/serial/


ASCII, : https://en.wikipedia.org/wiki/ASCII



  • M5STACK (2 .);
  • USB-C (2 .);
  • .

!


1. —


, . , MS Office Word Paint (. 4).



4. MS Office Word Paint :)


1.2.1 http://forum.m5stack.com/topic/49/lesson-1-2-1-lcd-how-to-create-image-array logo.c, .


extern unsigned char logo[];

2.


, 36 . 6 . 12 . 10 , . , 7. : ( — ; ; ; ) : , , , , . , . (. 5).



5.


define playerAmount 6


#define fullAmount 36
#define playerFieldAmount 10
#define gameFieldAmount 6

struct playCard
{
  int card;
  int suit;
  int color;
  int property = -1; // -2 not avaiable, -1 free, 0 trump, 1 player #1, 2 player #2
  int field; // + player field, - game field
};

String cards[9] = {"6", "7", "8", "9", "10", "J", "Q", "K", "A"};
char suits[4] = {3, 4, 5, 6}; // , , , 
int colors[2] = {0xe8e4, 0x00}; // red, black
playCard deckCards[fullAmount];

3.


. 1. , , (. 5.1):



5.1.


if ((opponentSteps == playerSteps) && (playerSteps == 0))
{
  deckCards[selectedCard].field = -1;
  sync();
}

. 2. , , (. 5.2) , :



5.1.


else if (opponentSteps > playerSteps)
{
  if ((((deckCards[selectedCard].card > deckCards[pfCardId].card) && (deckCards[selectedCard].suit == deckCards[pfCardId].suit)) || ((deckCards[selectedCard].suit == trumpSuit) && (deckCards[pfCardId].suit != trumpSuit))))
  {
    deckCards[selectedCard].field = -opponentSteps;
    sync();
  }
}

. 3. , , :


else if (opponentSteps == playerSteps)
{
  for (int i = 0; i < fullAmount; i++)
  {
    if ((deckCards[selectedCard].card == deckCards[i].card) && (deckCards[i].field < 0) && (deckCards[i].property != -2))
    {
      deckCards[selectedCard].field = -(playerSteps + 1);
      sync();
      break;
    }
  }
}

/. 1. , :


if (opponentSteps == playerSteps) // 
{
    for (int i = 0; i < fullAmount; i++)
    {
        if (deckCards[i].field < 0)
        {
            deckCards[i].property = -2;
        }
    }
}

/. 2. , , :


else if (opponentSteps > playerSteps) //    
{
    for (int i = 0; i < fullAmount; i++)
    {
        if ((deckCards[i].field < 0) && (deckCards[i].property != -2))
        {
            addPlayerCard(playerId, i);
        }
    }
}

4.


M5STACK, .


void drawCard(int x, int y, playCard card) {
    M5.Lcd.fillRoundRect(x, y, 30, 50, 5, 0xffff);
    M5.Lcd.drawRoundRect(x, y, 30, 50, 5, 0x00);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setTextColor(colors[card.color]);
    M5.Lcd.setCursor((x + 3), (y + 6));
    M5.Lcd.print(cards[card.card]);
    M5.Lcd.setTextSize(3);
    M5.Lcd.setCursor((x + 8), (y + 24));
    M5.Lcd.print(suits[card.suit]);
}

void drawEmptyCard(int x, int y) {
  M5.Lcd.fillRect(x, y, 30, 50, 0x2589);
  M5.Lcd.drawRoundRect(x, y, 30, 50, 5, 0x00);
}

Windows: Alt 3 6, .

5.


void drawSelect(playCard card) {
    int n = card.field - 1;
    int x = 10 + (n * 30);
    int y = (yPlayerField - 10);
    drawEmptyCard(x, yPlayerField);
    drawCard(x, y, card);
}

void clearSelect(playCard card) {
    int n = card.field - 1;
    int x = 10 + (n * 30);
    int y = (yPlayerField - 10);
    M5.Lcd.fillRect(x, y, 30, 50, 0x2589);
    drawCard(x, yPlayerField, card);
}

6.


void drawGameTable() {
    M5.Lcd.fillScreen(0x2589); // green table
    drawAllFields();
}

void drawMenu() {
    M5.Lcd.fillRect(0, 0, 320, 20, 0x00); // score bar
    M5.Lcd.fillRect(0, 220, 320, 20, 0x00); // menu bar
    /* menu buttons */
    M5.Lcd.setTextSize(2);
    M5.Lcd.setTextColor(0x7bef);
    M5.Lcd.setCursor(62, 223);
    M5.Lcd.print("G");
    M5.Lcd.setCursor(155, 223);
    M5.Lcd.print("A");
    M5.Lcd.setCursor(247, 223);
    M5.Lcd.print("S");
}

7.


void updateGraphics() {
    drawGameTable();
    drawMenu();
    drawPlayerId();
    drawRest();
    for (int i = 0; i < fullAmount; i++)
    {
        if (deckCards[i].property == playerId)
        {
            if (deckCards[i].field > 0) // if in the hands of
                drawPlayerCard(deckCards[i]); 
            else // if in the playing field
                drawPlPfCard(deckCards[i]); 
        }
        else if (deckCards[i].property == getOpponentId())
        {
            if (deckCards[i].field < 0)
                drawOpPfCard(deckCards[i]); // draw opponent's cards in the playing field
        }
        else if (deckCards[i].property == 0)
        {
            drawTrumpCard(deckCards[i]);
        }
    }
}

(, drawPlayerId()) ;)

8. /



5.3


. , . , true false.


bool serialWriteStr(String str) {
    Serial.print(str);
    Serial.print('\n');
    String input = serialReadStr(); 
    if (input != "")
    {
        if (input[0] == (char)0x04) return true;
    }
    return false;
}

timeout (3000 ) , . .


String serialReadStr() {
    String buf = "";
    long timeout = 3000;
    long previousMillis = millis();
    while (true)
    {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis > timeout) break;
        if (Serial.available() > 0)
        {
            char chr = (char)Serial.read();
            if ((chr != (char)0x16) && (chr != (char)0x04) && (buf == "")) // clear trash
            {
                Serial.read();
            }
            else
            {
                if (chr == '\n')
                    break;
                else
                    buf += chr;
            }  
        }
    }   
    if (buf != "")
    {
        Serial.print((char)0x04);
        Serial.print('\n');
    }
    return buf;
}

9.


, , (. 6). , , . (parseString), , ( Split JS).



6.


bool serialRecivePacket() {
    String input = serialReadStr(); 
    if (input.length() > 0)
    {
        if ((char)input[0] == (char)0x16) 
        {
            input[0] = ' ';
            char groupType = ((parseString(0, (char)0x1d, input)).toInt()) + '0';
            String groupData = parseString(1, (char)0x1d, input);
            int groupDataLenmo = (groupData.length() - 1);
            if (groupData[groupDataLenmo] == (char)0x03)  
            {
                groupData[groupDataLenmo] = ' '; 
                if (groupType == (char)0x31) updateReciveDeckCards(groupData); 
                else if (groupType == (char)0x32) playerId = 2; 
                return true;
            }
        }
    return false;
    }
}

String parseString(int idSeparator, char separator, String str) { // like split JS
    String output = "";
    int separatorCout = 0;
    for (int i = 0; i < str.length(); i++)
    {
        if ((char)str[i] == separator)
        {
            separatorCout++;
        }
        else
        {
            if (separatorCout == idSeparator)
        {
            output += (char)str[i];
        }
        else if (separatorCout > idSeparator)
        {
            break;
        }
    }
    return output;
}

parseString:
parseString(1, ':', "cat:Bob,Jack:dog:Martin,Kelvin"); -----> Bob,Jack

parseString(0, ',', "Bob,Jack"); -----> Bob

parseString(1, ',', "Bob,Jack"); -----> Jack


10.


, , , , " !" (. 7). - . , " !" 2.



7.

void handshakePlayerId() {
long tpid = random(10, 1001) * 10;
long previousMillis = millis();
while (!serialRecivePacket())
{
unsigned long currentMillis = millis();
if (currentMillis — previousMillis > tpid) break;
}
while (!serialSendPlayerTId());
}


bool serialSendPlayerTId() {
    String str = "";
    str += (char)0x16; 
    str += (char)0x32; // type "player id selector"
    str += (char)0x1d;
    str += (char)0x03; 
    return serialWriteStr(str);
}

11.


bool serialSendDeckCards() {
    String str = "";
    str += (char)0x16; 
    str += (char)0x31; // type "card transfer flag"
    str += (char)0x1d; 
    for (int i = 0; i < fullAmount; i++)
    {
        str += (char)0x1e; 
        str += deckCards[i].card;
        str += (char)0x1f; 
        str += deckCards[i].suit;
        str += (char)0x1f;
        str += deckCards[i].color;
        str += (char)0x1f;
        str += deckCards[i].property;
        str += (char)0x1f;
        str += deckCards[i].field;
    }
    str += (char)0x03; 
    return serialWriteStr(str);
}

void updateReciveDeckCards(String groupData) {
    for (int i = 0; i < fullAmount; i++)
    {
        /* update new card */
        String record = parseString(i, (char)0x1e, groupData);
        deckCards[i].card = (int8_t)(parseString(0, (char)0x1f, record).toInt());
        deckCards[i].suit = (int8_t)(parseString(1, (char)0x1f, record).toInt());
        deckCards[i].color = (int8_t)(parseString(2, (char)0x1f, record).toInt());
        deckCards[i].property = (int8_t)(parseString(3, (char)0x1f, record).toInt());
        deckCards[i].field = (int8_t)(parseString(4, (char)0x1f, record).toInt());
    }
    getTrumpCard();
    updateGraphics();
    checkWinner();
}

(, getTrumpCard()) ;)

12.


. . loop(). . .


void sync(bool auto_ = false) {
    if (queue != playerId) 
    {
        while (!serialRecivePacket());
        queue = playerId;
    }
    else
    {
        if (!auto_)
        {
          while (!serialSendDeckCards());
          updateGraphics();
          checkWinner();
          queue = getOpponentId();
        }
    }
}

13. ?


whoWin() , -1, .
, , . 10 (playerFieldAmount) , .


int whoWin() {
    int opponentId = getOpponentId();
    int playerAmount_ = getAmount(playerId);
    int opponentAmount = getAmount(opponentId);
    if ((playerAmount_ == 0) || (opponentAmount >= playerFieldAmount)) return playerId;
    if ((opponentAmount == 0) || (playerAmount_ >= playerFieldAmount)) return opponentId;
    return -1; 
}

void checkWinner() {
    int winner = whoWin();
    if (winner != -1) drawWinnerShow(winner);
}

14.


: , beta-, . !

Arduino IDE .


15.


(. 5.1). (. 8). ! (. 8.1).



8.



8.1. !


\


M5Stack


All Articles