class Food {
public:
Food() {}
Food(COORD _cd) : cd(_cd) {}
COORD cd;
};
class SnakeNode {
public:
SnakeNode() : Prev(0), Next(0) { cd.X = cd.Y = 0; }
SnakeNode(COORD _cd) : cd(_cd), Prev(0), Next(0) {}
SnakeNode(int x, int y) : Prev(0), Next(0) { cd.X = x; cd.Y = y; }
COORD cd;
SnakeNode* Prev;
SnakeNode* Next;
};
class Snake {
public:
Snake() { Initialize(); }
~Snake() { Destroy(); }
void Initialize() {
Score = 0; Length = 3; Type = dtLeft; Speed = 1000;
SnakeNode* n1 = new SnakeNode(GAME_WIDTH/2, GAME_HEIGHT/2);
SnakeNode* n2 = new SnakeNode(n1->cd.X+1, n1->cd.Y);
SnakeNode* n3 = new SnakeNode(n1->cd.X+2, n1->cd.Y);
n1->Next = n2; n2->Next = n3;
n3->Prev = n2; n2->Prev = n1;
Head = n1; Tail = n3;
}
void Destroy() {
SnakeNode* p = Head->Next;
while (p) { SnakeNode* nxt = p->Next; delete p; p = nxt; }
if (Head) { delete Head; Head = Tail = 0; }
}
int Insert(int x, int y) { // 頭插法增長
SnakeNode* n = new SnakeNode(x, y);
n->Next = Head; Head->Prev = n; Head = n;
return ++Length;
}
COORD Pop() { // 尾刪法移動
COORD cd = Tail->cd;
Tail = Tail->Prev;
delete Tail->Next;
Tail->Next = 0;
return cd;
}
int Length; DIRECTIONTYPE Type; SnakeNode *Head, *Tail;
int Speed; Food food; int Score;
};
static void SnakeMove(Snake& sn) {
COORD cdNew;
switch (sn.Type) {
case dtTop: cdNew = sn.Head->cd; cdNew.Y--; break;
case dtRight: cdNew = sn.Head->cd; cdNew.X++; break;
case dtBottom: cdNew = sn.Head->cd; cdNew.Y++; break;
case dtLeft: cdNew = sn.Head->cd; cdNew.X--; break;
}
// 邊界檢測、撞身檢測、吃食物判斷、頭插/尾刪...
if (cdNew.X < 0 || cdNew.X >= GAME_WIDTH || ...) { /* Game Over */ }
if (cdNew == sn.food.cd) { sn.Insert(cdNew.X, cdNew.Y); /* 重生食物 */ }
else { sn.Insert(cdNew.X, cdNew.Y); sn.Pop(); }
}
(完整邊界、碰撞、得分、食物重生邏輯請參考源碼倉庫)