Initial CST-Agent: portable Linux/Termux/Windows coding agent.

Vendored sashidown, OpenAI-compatible env (OPENAI_*), and bootstrap scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-09-07 22:42:32 +08:00
co-authored by Cursor
commit 1f1fcba7ad
75 changed files with 14940 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
CXX = g++
CXXFLAGS = -O2 -std=c++17 -Wall -Wextra
snake: snake.cpp
$(CXX) $(CXXFLAGS) -o snake snake.cpp
clean:
rm -f snake
.PHONY: clean
+51
View File
@@ -0,0 +1,51 @@
# Snake Game
A classic terminal-based Snake game written in C++17.
## Features
- Smooth snake movement using POSIX terminal I/O
- WASD or Arrow keys for movement
- Food spawning and snake growth
- Wall and self-collision detection
- Score tracking
- Pause functionality (P key)
- Clean terminal rendering
## Build
```bash
make
```
This compiles `snake.cpp` with optimization level O2 and C++17 standard.
## Run
```bash
./snake
```
## Controls
| Key | Action |
|-----|--------|
| W / ↑ | Move Up |
| S / ↓ | Move Down |
| A / ← | Move Left |
| D / → | Move Right |
| P | Pause/Resume |
| Q | Quit |
## Game Rules
- Eat the `*` food to grow and score points (+10 per food)
- Avoid hitting the walls `#`
- Avoid colliding with your own body `o`
- The snake moves continuously
## Requirements
- GCC/G++ with C++17 support
- POSIX-compliant system (Linux, macOS)
- Terminal with ANSI escape support
+10
View File
@@ -0,0 +1,10 @@
Write a complete C++ terminal Snake game in this workspace.
Requirements:
1. Single file `snake.cpp` (C++17 ok). Use POSIX terminal I/O: raw mode or ncurses; WASD or arrow keys; quit with `q`.
2. Features: moving snake, food, grow on eat, wall or self collision ends game, score printed, board roughly 20x20 or similar.
3. `Makefile` with target `snake` that runs `g++ -O2 -o snake snake.cpp` (link `-lncurses` only if you use ncurses).
4. After writing, run `make` to verify it compiles. Do not need an interactive play session.
5. Brief README.md with how to build and run.
Use write_file / run_shell tools. Prefer implementing yourself rather than downloading.
+224
View File
@@ -0,0 +1,224 @@
#include <iostream>
#include <vector>
#include <deque>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <chrono>
#include <thread>
#include <conio.h>
// Game constants
constexpr int BOARD_WIDTH = 20;
constexpr int BOARD_HEIGHT = 15;
constexpr char WALL = '#';
constexpr char SNAKE_BODY = 'o';
constexpr char SNAKE_HEAD = 'O';
constexpr char FOOD = '*';
constexpr char EMPTY = ' ';
// Directions
enum class Direction { UP, DOWN, LEFT, RIGHT };
struct Position {
int x, y;
bool operator==(const Position& other) const {
return x == other.x && y == other.y;
}
};
struct GameState {
std::deque<Position> snake;
Position food;
Direction dir;
Direction next_dir;
int score;
bool game_over;
bool paused;
};
char board[BOARD_HEIGHT][BOARD_WIDTH + 1];
void place_food(GameState& state);
void init_board() {
for (int y = 0; y < BOARD_HEIGHT; y++) {
for (int x = 0; x < BOARD_WIDTH; x++) {
if (y == 0 || y == BOARD_HEIGHT - 1 || x == 0 || x == BOARD_WIDTH - 1) {
board[y][x] = WALL;
} else {
board[y][x] = EMPTY;
}
}
board[y][BOARD_WIDTH] = '\0';
}
}
void init_game(GameState& state) {
Position head = {BOARD_WIDTH / 2, BOARD_HEIGHT / 2};
state.snake = {head, {head.x - 1, head.y}, {head.x - 2, head.y}};
state.dir = Direction::RIGHT;
state.next_dir = Direction::RIGHT;
state.score = 0;
state.game_over = false;
state.paused = false;
place_food(state);
}
void place_food(GameState& state) {
Position pos;
bool on_snake;
do {
on_snake = false;
pos.x = 1 + std::rand() % (BOARD_WIDTH - 2);
pos.y = 1 + std::rand() % (BOARD_HEIGHT - 2);
for (const auto& segment : state.snake) {
if (segment == pos) {
on_snake = true;
break;
}
}
} while (on_snake);
state.food = pos;
}
void render(const GameState& state) {
system("cls"); // Windows clear screen
init_board();
board[state.food.y][state.food.x] = FOOD;
for (size_t i = 0; i < state.snake.size(); i++) {
const auto& segment = state.snake[i];
board[segment.y][segment.x] = (i == 0) ? SNAKE_HEAD : SNAKE_BODY;
}
std::cout << "=== SNAKE GAME ===\n";
std::cout << "Score: " << state.score << "\n";
std::cout << "Controls: WASD/Arrows to move, Q to quit, P to pause\n";
std::cout << "==================\n";
for (int y = 0; y < BOARD_HEIGHT; y++) {
std::cout << board[y] << "\n";
}
if (state.game_over) {
std::cout << "\n=== GAME OVER! ===\n";
std::cout << "Final Score: " << state.score << "\n";
std::cout << "Press R to restart or Q to quit.\n";
} else if (state.paused) {
std::cout << "\n=== PAUSED ===\n";
std::cout << "Press P to continue.\n";
}
}
bool kbhit() {
return _kbhit() != 0;
}
char get_char() {
return _getch();
}
void update_direction(GameState& state, Direction new_dir) {
Direction opposite = Direction::UP;
switch (state.dir) {
case Direction::UP: opposite = Direction::DOWN; break;
case Direction::DOWN: opposite = Direction::UP; break;
case Direction::LEFT: opposite = Direction::RIGHT; break;
case Direction::RIGHT: opposite = Direction::LEFT; break;
}
if (new_dir != opposite) {
state.next_dir = new_dir;
}
}
bool move_snake(GameState& state) {
state.dir = state.next_dir;
Position head = state.snake.front();
switch (state.dir) {
case Direction::UP: head.y--; break;
case Direction::DOWN: head.y++; break;
case Direction::LEFT: head.x--; break;
case Direction::RIGHT: head.x++; break;
}
// Check wall collision
if (head.x <= 0 || head.x >= BOARD_WIDTH - 1 ||
head.y <= 0 || head.y >= BOARD_HEIGHT - 1) {
return false;
}
// Check self collision (skip tail as it will move)
for (size_t i = 0; i < state.snake.size() - 1; i++) {
if (state.snake[i] == head) {
return false;
}
}
state.snake.push_front(head);
// Check food
if (head == state.food) {
state.score += 10;
place_food(state);
} else {
state.snake.pop_back();
}
return true;
}
void handle_input(GameState& state) {
if (kbhit()) {
char c = get_char();
if (state.game_over) {
if (c == 'r' || c == 'R') {
init_game(state);
}
return;
}
if (state.paused) {
if (c == 'p' || c == 'P') {
state.paused = false;
}
return;
}
switch (c) {
case 'w': case 'W': case 72: update_direction(state, Direction::UP); break;
case 's': case 'S': case 80: update_direction(state, Direction::DOWN); break;
case 'a': case 'A': case 75: update_direction(state, Direction::LEFT); break;
case 'd': case 'D': case 77: update_direction(state, Direction::RIGHT); break;
case 'q': case 'Q': state.game_over = true; state.score = -1; break;
case 'p': case 'P': state.paused = true; break;
}
}
}
int main() {
std::srand(static_cast<unsigned>(std::time(nullptr)));
GameState state;
init_game(state);
while (true) {
render(state);
if (!state.game_over && !state.paused) {
if (!move_snake(state)) {
state.game_over = true;
}
}
handle_input();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return 0;
}