Delphi 蛇游戏应该使用什么数据结构?
我有一些家庭作业要交给学校,我必须用德尔福制作一个像诺基亚一样的蛇游戏。我不知道哪种解决方案是最好的。我希望我的snake是一个类,主体是一个点数组(父类)或点的链接列表。最好的是什么?数组还是链表?以下是一些不错的起点……因为我不想做你的家庭作业: 如果在编程过程中出现错误,请随时提出新问题。链表更好。(每个节点可以指向上一个和下一个节点)将节点添加到链接列表的末尾更容易 如果您使用一个数组,您可能需要调整它的大小,或者将它初始化为最大可能的蛇形长度,这样可能会浪费内存 更新Delphi 蛇游戏应该使用什么数据结构?,delphi,data-structures,Delphi,Data Structures,我有一些家庭作业要交给学校,我必须用德尔福制作一个像诺基亚一样的蛇游戏。我不知道哪种解决方案是最好的。我希望我的snake是一个类,主体是一个点数组(父类)或点的链接列表。最好的是什么?数组还是链表?以下是一些不错的起点……因为我不想做你的家庭作业: 如果在编程过程中出现错误,请随时提出新问题。链表更好。(每个节点可以指向上一个和下一个节点)将节点添加到链接列表的末尾更容易 如果您使用一个数组,您可能需要调整它的大小,或者将它初始化为最大可能的蛇形长度,这样可能会浪费内存 更新 本文讨论了D
本文讨论了Delph中的指针,甚至建议在Delphi中使用一个简单的节点定义,我会使用TQueue,它是在Contnrs单元中定义的。 你可以“推”你的新坐标到它(蛇头),当你的最大蛇大小达到你只需要调用“弹出”来释放蛇尾
lp := new(PPoint);
lp^.X := x;
lp^.X := y;
Body.Push(lp);
if Body.count > iSnakeLength then
Dispose(Body.Pop); // Free the last TCoord that is pop'ed.
然后,你需要做的就是画出TObjectQueue中的内容。要访问TQueue的列表,必须公开属性列表。。。要做到这一点,只需像这样定义蛇身类
TSnakeBody = class(TObjectQueue)
public
property List; //Expose the list
end;
我有一个非常古老的turbopascal snake程序。它对主体使用数组
const MaxBodyLength = 100;
type
TSnake = record
Dir : (nord,sud,est,oest);
Head : tpoint;
BodyLength : integer;
Body : array[1..MaxBodyLength] of tPoint;
Tail : tpoint;
end;
var
Snake : TSnake;
Fruit : tPoint;
还有移动蛇的密码
procedure Slither;
var i : integer;
npos,lpos : tPoint;
hasEaten:boolean;
begin
npos:=Snake.Head;
lpos:=Snake.Tail;
case Snake.dir of
East : inc(npos.x);
West : dec(npos.x);
South : inc(npos.y);
North : dec(npos.y);
end;
hasEaten:=(npos.x=fruit.x) and (npos.y=fruit.y);
if hasEaten then
inc(Snake.BodyLength)
else
Snake.Tail:=Snake.Body[Snake.BodyLength];
for i:=Snake.BodyLength downto 2 do
Snake.Body[i]:=Snake.Body[i-1];
Snake.Body[1]:=Snake.Head;
if not hasEaten then
Snake.Head:=npos;
writeP(idHead,Snake.Head);
writeP(idBody,Snake.Body[1]);
if not hasEaten then
begin
writeP(idTail,Snake.Tail);
writeP(idResidual,lPos);
end;
if hasEaten then
NewFruit;
end;
一个简单的解决方案是制作一个类型为[horizontal][vertical]的数组,这样屏幕上的每个坐标都有一个项目。每种类型可以是蛇的方向、食物、毒药、墙或空。这意味着您只需要记住蛇的头部和尾部位置,以及食物和毒物的计数,数组描述了屏幕的外观 这就省去了处理蛇元素的麻烦,并且可以很容易地在屏幕上定位新的食物或有毒物品,确保你不会把它放在已经被占用的地方
当需要移除蛇的尾巴元素时,使用direction:=array[tailx,taily]获取尾巴的方向;然后将数组[tailx,taily]:=empty。然后,根据方向更新tailx和taily。就是这样。我在Snake实现中使用了一些不同的东西。我们的想法是,你要去商店
一开始,尾巴在1号牢房,头在3号牢房。当蛇移动时,将头部指针向右移动并写入新坐标。然后,如果没有食物吃,也将尾部指针向右移动。如果任何一个指针试图超出数组的最右端,请将其换行到开头。我不希望任何人做我的作业。。我只是想听听关于数组或linkedlist的建议。既然这是家庭作业,任何使用指针的练习都会很有帮助。@skamradt建议你把这当作另一个问题来问。您没有指定什么语言。我通常不在Pascal(Delphi)中编码,但我认为它与C++不同,它隐藏了pointers@Andrew,您仍然可以在Delphi中使用指针。它们不是隐藏的,只是隐含在类实例中。@skamradt-有趣-添加了一个链接,指向一篇可能有用的文章。Delphi比我意识到的更通用(我通常用C++或java代码,C++是一个更遥远的内存)。Pascal(和因此Delphi)一直支持指针。我记得1984年写的链表!从队列中弹出将删除head元素,而不是tail元素。在蛇游戏的哪个版本中,蛇的最大长度是多少?它应该保持增长——这是游戏的挑战。如果需要获取队列的内部内容,那么队列不是正确的数据结构。使用普通列表代替。另外,我不确定这是否是
New
的有效语法。队列是一种先进先出(FIFO)数据结构,与Rob所说的添加到集合中的后进先出(LIFO)堆栈不同。使用Delphi的TQueue(而不是TStack),弹出删除输入的第一个数据。所以你推着头,弹着尾巴。。。在我的蛇版本中,你必须吃蛇的东西才能让它生长。绘制蛇需要获取队列的内部内容。我相当确定这不是Turbo Pascal。记录的数组长度由记录的成员定义?这是不允许的。记录的大小在编译时是固定的。你不能增加BodyLength字段,也不能让数组变长。我总是喜欢家庭作业之类的问题。很想知道什么学校和班级。。排队怎么样?这显然是一个数据结构,如果你想创建圆角,你可以在渲染部分这样做,游戏逻辑可以保持沉默。