Игры на TFT

21 Сен 2020
11
-1

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
1,485
524
55
Марий-Эл
Если есть бот, должен быть какой никакой ИИ.
Иначе я могу написать так, что никогда у него не выиграешь.
ИИ лучше брать из Red Alert или Command Conquer, там они неплохо написаны.
 
21 Сен 2020
11
-1
Сделаю все сам, выложу на ютюб
P.S. Если кто сделает за бесплатку, пишите сюда

Если есть бот, должен быть какой никакой ИИ.
Иначе я могу написать так, что никогда у него не выиграешь.
ИИ лучше брать из Red Alert или Command Conquer, там они неплохо написаны.
Micro pong master:
/*
  Скетч к проекту "Классический pong на oled дисплее"
  Страница проекта (схемы, описания): https://alexgyver.ru/microPong/
  Исходники на GitHub: https://github.com/AlexGyver/microPong/
  Нравится, как написан код? Поддержи автора! https://alexgyver.ru/support_alex/
  Автор: AlexGyver Technologies, 2019
  https://AlexGyver.ru/
*/

/* Некоторые новые функции сделаны каналом То Да Сё (2020)
  (https://www.youtube.com/channel/UCTDP58C52tcQs05w7efBfzg)
*/

#define GAME_SPEED 110    // стандартный период движения шарика
#define II_SPEED 175      // стандартный период движения противника
#define ALWAYS_SPEED 1    // беспеременная скорость противника ( 1 - беспеременная, 0 - переменная)
#define MY_SPEED 1        // моя скорость(в пикселях)(2 - для начинающих, 1 - для опытных)
#define RANDOM_BOUNCE 1   // отбивать шарик в случайном направлении

// пины
#define BTN_UP 4
#define BTN_DWN 3

// другие настройки
#define X_PLAYER_1 7
#define X_PLAYER_2 55
#define RACKET_LEN 5

int8_t ballPos[2];
int8_t ballSpeed[2];
uint32_t ballTimer, enemyTimer;
boolean btnFlag1, btnFlag2;
int8_t racketPos1, racketPos2 = 0;
int8_t prevRacketPos1, prevRacketPos2 = 0;
byte count2;
byte speedIncr = 0, iiIncr = 0;
byte count1;

#include <Wire.h>

void setup() {
  pinMode(BTN_UP, INPUT_PULLUP);
  pinMode(BTN_DWN, INPUT_PULLUP);
  Wire.begin();
  oledInit();
  oledClear();
  digit(0, 0, 0);
  digit(0, 20, 0);

  randomSeed(analogRead(0));
  newRound();
  redrawRacket();
  redrawRacket2();
}

void loop() {
  ballRoutine();
  buttonTick();
  enemyTick();
}

void enemyTick() {
  if (millis() - enemyTimer >= (II_SPEED - iiIncr)) {
    enemyTimer = millis();
    if (racketPos2 + RACKET_LEN / 2 > ballPos[1]) racketPos2--;
    else racketPos2++;
    racketPos2 = constrain(racketPos2, 0, 16 - RACKET_LEN);
    redrawRacket2();
  }
}

void buttonTick() {
  if (!digitalRead(BTN_DWN) && !btnFlag1) {
    btnFlag1 = true;
    racketPos1 += MY_SPEED;
    if (racketPos1 > (16 - RACKET_LEN)) racketPos1 = (16 - RACKET_LEN);
    redrawRacket();
  }
  if (digitalRead(BTN_DWN) && btnFlag1) {
    btnFlag1 = false;
  }
  if (!digitalRead(BTN_UP) && !btnFlag2) {
    btnFlag2 = true;
    racketPos1 -= MY_SPEED;
    if (racketPos1 < 0) racketPos1 = 0;
    redrawRacket();
  }
  if (digitalRead(BTN_UP) && btnFlag2) {
    btnFlag2 = false;
  }
}

void redrawRacket() {
  for (byte i = prevRacketPos1; i < prevRacketPos1 + RACKET_LEN; i++) {
    dotClear(X_PLAYER_1, i);
  }
  for (byte i = racketPos1; i < racketPos1 + RACKET_LEN; i++) {
    dotSet(X_PLAYER_1, i);
  }
  prevRacketPos1 = racketPos1;
}

void redrawRacket2() {
  for (byte i = prevRacketPos2; i < prevRacketPos2 + RACKET_LEN; i++) {
    dotClear(X_PLAYER_2, i);
  }
  for (byte i = racketPos2; i < racketPos2 + RACKET_LEN; i++) {
    dotSet(X_PLAYER_2, i);
  }
  prevRacketPos2 = racketPos2;
}

void ballRoutine() {
  if (millis() - ballTimer >= (GAME_SPEED - speedIncr)) {
    ballTimer = millis();
    int8_t prevPos[2];
    for (byte i = 0; i < 2; i++) {
      prevPos[i] = ballPos[i];
      ballPos[i] += ballSpeed[i];
    }

    if (ballPos[0] < X_PLAYER_1) {
      if (!(prevPos[1] >= racketPos1 && prevPos[1] <= (racketPos1 + RACKET_LEN))) {
        count2++;
        if (count2 > 9) {
          digit(count2 / 10, 20, 0);
          digit(count2 % 10, 20, 1);
        } else {
          digit(count2, 20, 0);
        }

        delay(1000);
        newRound();
        dotClear(prevPos[0], prevPos[1]);
        return;
      } else {
        ballPos[0] = prevPos[0];
        ballSpeed[0] = -ballSpeed[0];
        if (RANDOM_BOUNCE) ballSpeed[1] *= (random(0, 2)) ? 1 : -1;
      }
    }
    if (ballPos[1] < 0) {
      ballPos[1] = -ballPos[1];
      ballSpeed[1] = -ballSpeed[1];
    }

    if (ballPos[0] > X_PLAYER_2) {
      if (!(prevPos[1] >= racketPos2 && prevPos[1] <= (racketPos2 + RACKET_LEN))) {
        count1++;
        if (count1 > 9) {
          digit(count1 / 10, 0, 0);
          digit(count1 % 10, 0, 1);
        } else {
          digit(count1, 0, 0);
        }

        delay(1000);
        newRound();
        dotClear(prevPos[0], prevPos[1]);
        return;
      } else {
        ballPos[0] = prevPos[0];
        ballSpeed[0] = -ballSpeed[0];
        if (RANDOM_BOUNCE) ballSpeed[1] *= (random(0, 2)) ? 1 : -1;
      }
    }
    if (ballPos[1] > 15) {
      ballPos[1] = 15;
      ballSpeed[1] = -ballSpeed[1];
    }

    dotClear(prevPos[0], prevPos[1]);
    dotSet(ballPos[0], ballPos[1]);
  }
}

void newRound() {
  randomSeed(millis());
  ballPos[0] = X_PLAYER_1 + 1;
  racketPos1 = random(0, 16 - RACKET_LEN);
  ballPos[1] = racketPos1 + RACKET_LEN / 2;
  ballSpeed[0] = 2;
  ballSpeed[1] = (random(0, 2)) ? 1 : -1;
  //racketPos2 = 8;
  redrawRacket();
  redrawRacket2();
  if (ALWAYS_SPEED == 1) {
    if (count1 >= 10) {
      speedIncr = 10;
      iiIncr = 20;
    }
    if (count1 >= 20) {
      speedIncr = 20;
      iiIncr = 50;
    }
    if (count1 >= 30) {
      speedIncr = 35;
      iiIncr = 75;
    }
  }
}
Micro pong master:
void enemyTick() {
  if (millis() - enemyTimer >= (II_SPEED - iiIncr)) {
    enemyTimer = millis();
    if (racketPos2 + RACKET_LEN / 2 > ballPos[1]) racketPos2--;
    else racketPos2++;
    racketPos2 = constrain(racketPos2, 0, 16 - RACKET_LEN);
    redrawRacket2();
  }
}
Весь "ИИ"(это вовсе не ИИ)
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
1,485
524
55
Марий-Эл
Ну вот видишь, затравка есть.
Так что дерзай.
Надеюсь лет через 5 в мире появится новый крутой программист.
Главное не бросай и добивайся своего.
 
  • Лойс +1
Реакции: То да сё