single player with difficlut level balancement

This commit is contained in:
andrea
2026-03-19 20:34:16 +01:00
parent 2838b5fd14
commit 6ea443d92a
5 changed files with 50 additions and 19 deletions

View File

@@ -37,8 +37,8 @@ game_statuses game_status= TIMER;
Ball ball(4, 6); Ball ball(4, 6);
// HumanPaddle p1(1, P1_BTN_UP, P1_BTN_BOTTOM); // HumanPaddle p1(1, P1_BTN_UP, P1_BTN_BOTTOM);
// HumanPaddle p2(4, P2_BTN_UP, P2_BTN_BOTTOM); // HumanPaddle p2(4, P2_BTN_UP, P2_BTN_BOTTOM);
BotPaddle p1(1, 0, 1); BotPaddle p1(1, 0, 2);
BotPaddle p2(4, MATRIX_WIDTH-1, 1); BotPaddle p2(4, MATRIX_WIDTH-1, 2);
Engine engine(p1, p2, ball, INITIAL_BALL_DELAY); Engine engine(p1, p2, ball, INITIAL_BALL_DELAY);
Renderer renderer(p1, p2, ball, frame, matrix); Renderer renderer(p1, p2, ball, frame, matrix);
@@ -72,7 +72,7 @@ void loop() {
case RUN: case RUN:
// need_refresh= check_paddle_movements(p1, p2); // need_refresh= check_paddle_movements(p1, p2);
need_refresh= engine.control_players(); need_refresh= engine.control_players(exec_t2);
if (exec_t1 - exec_t2 > engine.ball_movement_delay()) { if (exec_t1 - exec_t2 > engine.ball_movement_delay()) {
engine.run(); engine.run();

View File

@@ -60,12 +60,29 @@ void Engine::run() {
} }
} }
bool Engine::control_players() { bool Engine::control_players(long exec_t2) {
bool need_refresh= false; bool need_refresh= false;
if (_p1.is_human()) need_refresh |= _p1.check_pad_movement(); if (_p1.is_human()) need_refresh |= _p1.check_pad_movement();
else need_refresh |= _p1.check_pad_movement(_ball); else {
uint8_t ball_delay= this -> ball_movement_delay();
long exec_t1= millis();
uint8_t skill= _p1.get_skills();
if (exec_t1 - exec_t2 > ball_delay - (skill * 10)) {
need_refresh |= _p1.check_pad_movement(_ball);
}
}
if (_p2.is_human()) need_refresh |= _p2.check_pad_movement(); if (_p2.is_human()) need_refresh |= _p2.check_pad_movement();
else need_refresh |= _p2.check_pad_movement(_ball); else {
uint8_t ball_delay= this -> ball_movement_delay();
long exec_t1= millis();
uint8_t skill= _p1.get_skills();
if (exec_t1 - exec_t2 > ball_delay - (skill * 10)) {
need_refresh |= _p2.check_pad_movement(_ball);
}
}
return need_refresh; return need_refresh;
} }

View File

@@ -26,7 +26,7 @@ class Engine {
: _p1(p_one), _p2(p_two), _ball(ball), _ball_mv_delay(ball_mv_delay) {} : _p1(p_one), _p2(p_two), _ball(ball), _ball_mv_delay(ball_mv_delay) {}
void run(); void run();
bool control_players(); bool control_players(long exec_t2);
uint8_t ball_movement_delay(); uint8_t ball_movement_delay();
EngineEvents get_event(); EngineEvents get_event();
void restart_ball(); void restart_ball();

View File

@@ -1,4 +1,5 @@
#include "paddle.h" #include "paddle.h"
#include <cstdio>
void Paddle::move_pad_up() { void Paddle::move_pad_up() {
if (_pos_y > 0) { if (_pos_y > 0) {
@@ -63,6 +64,7 @@ bool HumanPaddle::check_pad_movement() {
bool BotPaddle::check_pad_movement(Ball &ball) { bool BotPaddle::check_pad_movement(Ball &ball) {
uint8_t ball_y= ball.get_y(); uint8_t ball_y= ball.get_y();
int8_t ball_dir= ball.get_direction_x(); int8_t ball_dir= ball.get_direction_x();
int8_t ball_dir_ver= ball.get_direction_y();
// ball is moving left and pad is on right, do not move // ball is moving left and pad is on right, do not move
if (ball_dir < 0 && _pos_x > MATRIX_WIDTH / 2) return false; if (ball_dir < 0 && _pos_x > MATRIX_WIDTH / 2) return false;
@@ -74,26 +76,38 @@ bool BotPaddle::check_pad_movement(Ball &ball) {
if (ball_distance < 0) ball_distance *= -1; if (ball_distance < 0) ball_distance *= -1;
switch (this -> get_skills()) { switch (this -> get_skills()) {
case 1: case 1:
if (ball_distance > MATRIX_WIDTH / 2 - 2) return false; if (ball_distance > 2) return false;
break; break;
case 2: case 2:
if (ball_distance > MATRIX_WIDTH / 2 - 1) return false; if (ball_distance > 3) return false;
break;
case 3:
if (ball_distance > MATRIX_WIDTH / 2) return false;
break; break;
} }
// TODO BotPaddle movement logics // TODO BotPaddle movement logics
// on higher difficult level i could also check the ball direction // on higher difficult level i could also check the ball direction
// or at lover difficulty level i could also check the distance from the pad and move only when the ball si near // or at lover difficulty level i could also check the distance from the pad and move only when the ball si near
enum Movement {NONE, UP, DOWN};
for (uint8_t py= _pos_y; py < _pos_y+PADDLE_LENGTH; py++) { Movement _movment= NONE;
// don't move if ball is already centered to the pad
if (py == ball_y) continue; for (uint8_t py= _pos_y; py < _pos_y+PADDLE_LENGTH-1; py++) {
else if (_pos_y - ball_y >= 0) this -> move_pad_up(); if (_pos_y - ball_y >= 0 && ball_dir_ver < 0) {
else this -> move_pad_down(); _movment= UP;
break;
}
if (_pos_y - ball_y <= 0 && ball_dir_ver > 0) {
_movment= DOWN;
break;
}
} }
if (_movment == UP) {
this -> move_pad_up();
return true;
}
if (_movment == DOWN) {
this -> move_pad_down();
return true;
}
return false;
} }
uint8_t BotPaddle::get_skills() { uint8_t BotPaddle::get_skills() {

View File

@@ -49,7 +49,7 @@ class BotPaddle : public Paddle {
BotPaddle(uint8_t position, uint8_t pos_x, uint8_t skills) BotPaddle(uint8_t position, uint8_t pos_x, uint8_t skills)
: Paddle(position, false), _pos_x(pos_x), _skills(skills) { : Paddle(position, false), _pos_x(pos_x), _skills(skills) {
if (_skills < 1) _skills= 1; if (_skills < 1) _skills= 1;
if (_skills > 3) _skills= 3; if (_skills > 2) _skills= 2;
} }
bool check_pad_movement(Ball &ball); bool check_pad_movement(Ball &ball);
uint8_t get_skills(); uint8_t get_skills();