Repository navigation
Expand file tree
/
Copy pathsnake.cpp
More file actions
74 lines (60 loc) · 2.2 KB
/
Copy pathsnake.cpp
File metadata and controls
74 lines (60 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Snake 实体实现:纯几何领域对象,不做任何 IO/渲染。
// 越界与规则判定属于 GameState,本类只管身体队列与朝向。
#include "core/snake.hpp"
#include <cstddef>
namespace snake::core {
// 初始长度由实现决定:本实现为 1(仅蛇头)。
Snake::Snake(Position head, Direction facing)
: body_{head}, facing_{facing} {}
Position Snake::head() const noexcept {
return body_.front();
}
Direction Snake::facing() const noexcept {
return facing_;
}
std::size_t Snake::length() const noexcept {
return body_.size();
}
const std::deque<Position>& Snake::body() const noexcept {
return body_;
}
// 遍历身体判定占据:长度通常 ≤ 数百,线性扫描足够。
bool Snake::occupies(Position p) const noexcept {
for (const Position& seg : body_) {
if (seg == p) return true;
}
return false;
}
// 绝对方向控制:与当前朝向相反(180° 掉头)直接拒绝,不改变状态。
bool Snake::turn(Direction d) noexcept {
if (d == opposite(facing_)) return false;
facing_ = d;
return true;
}
// 头按 facing_ 前进一步;若无待生效生长则弹出尾部(保持长度不变)。
// 不做边界/自碰检查——那属于 GameState 的职责(单一职责)。
void Snake::move() noexcept {
body_.push_front(head().advanced(facing_));
if (pending_growth_) {
pending_growth_ = false;
} else {
body_.pop_back();
}
}
// 标记一次生长:下一次 move 时保留尾部(长度 +1),随后标志被消费。
void Snake::grow() noexcept {
pending_growth_ = true;
}
// 预判下一步是否会咬到自己。
// 细节:未处于生长(pending_growth_ == false)时,下一步尾部会弹走,
// 因此走入当前尾格不算自碰,扫描时排除尾格;生长中则尾部保留、须计入。
std::optional<Position> Snake::self_collision_next() const noexcept {
const Position next = head().advanced(facing_);
const std::size_t scanned =
pending_growth_ ? body_.size() : body_.size() - 1;
for (std::size_t i = 0; i < scanned; ++i) {
if (body_[i] == next) return next;
}
return std::nullopt;
}
} // namespace snake::core