Files
roro9stack/lib/games/src/pong.h
T
twislaandClaude Opus 5.5 68d50b320f Games: Pong, Snake and Tetris as seeded state machines, and a tune
The rules of the three Games (issue #101), with no screen and no
keyboard in them: time and keys go in, the new state and what happened
come out, and a seed decides the dice. With a player for a tune a note
at a time, and Korobeiniki's notes. Host-tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
2026-10-13 22:59:05 +02:00

56 lines
2.1 KiB
C++

#pragma once
#include <cstdint>
#include "game_rng.h"
namespace roro::games {
// Pong against the device (issue #101): the player's paddle on the left, the device's on the
// right, first to 7. The ball goes faster with each return, and the device's paddle only moves so
// fast: a steep, fast ball gets past it. Lengths are pixels of the 240 x 122 field, times seconds.
class Pong {
public:
static constexpr float kWidth = 240, kHeight = 122;
static constexpr float kPaddleH = 24, kPaddleW = 3, kMargin = 6, kBall = 4;
static constexpr float kPlayerSpeed = 150, kDeviceSpeed = 88;
static constexpr float kServeSpeed = 110, kMaxSpeed = 270, kFaster = 1.06f;
static constexpr float kServePause = 0.8f;
static constexpr int kWinScore = 7;
enum Event : uint8_t { Wall = 1, Hit = 2, Point = 4, Over = 8 };
enum class Phase : uint8_t { Serve, Play, Over };
explicit Pong(uint32_t seed) : rng_(seed) { start(); }
void start();
// `seconds` later, with the player's paddle asked up (-1), down (1) or left alone (0).
// What happened, as Events.
uint8_t step(float seconds, int move);
Phase phase() const { return phase_; }
float ballX() const { return x_; }
float ballY() const { return y_; }
float speed() const { return speed_; }
float playerY() const { return player_; } // the paddle's middle
float deviceY() const { return device_; }
int playerScore() const { return playerScore_; }
int deviceScore() const { return deviceScore_; }
bool playerWon() const { return playerScore_ >= kWinScore; }
int rally() const { return rally_; } // the player's returns since the serve
int longestRally() const { return longest_; } // in this game
private:
uint8_t tick(float dt, int move);
void serve(bool toPlayer);
bool meets(float paddleY) const;
void bounceOff(float paddleY, bool toRight);
Rng rng_;
Phase phase_ = Phase::Serve;
float x_ = 0, y_ = 0, vx_ = 0, vy_ = 0, speed_ = 0;
float player_ = 0, device_ = 0, wait_ = 0;
int playerScore_ = 0, deviceScore_ = 0, rally_ = 0, longest_ = 0;
};
} // namespace roro::games