Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 蛇游戏应该使用什么数据结构?_Delphi_Data Structures - Fatal编程技术网

Delphi 蛇游戏应该使用什么数据结构?

Delphi 蛇游戏应该使用什么数据结构?,delphi,data-structures,Delphi,Data Structures,我有一些家庭作业要交给学校,我必须用德尔福制作一个像诺基亚一样的蛇游戏。我不知道哪种解决方案是最好的。我希望我的snake是一个类,主体是一个点数组(父类)或点的链接列表。最好的是什么?数组还是链表?以下是一些不错的起点……因为我不想做你的家庭作业: 如果在编程过程中出现错误,请随时提出新问题。链表更好。(每个节点可以指向上一个和下一个节点)将节点添加到链接列表的末尾更容易 如果您使用一个数组,您可能需要调整它的大小,或者将它初始化为最大可能的蛇形长度,这样可能会浪费内存 更新 本文讨论了D

我有一些家庭作业要交给学校,我必须用德尔福制作一个像诺基亚一样的蛇游戏。我不知道哪种解决方案是最好的。我希望我的snake是一个类,主体是一个点数组(父类)或点的链接列表。最好的是什么?数组还是链表?

以下是一些不错的起点……因为我不想做你的家庭作业:

如果在编程过程中出现错误,请随时提出新问题。

链表更好。(每个节点可以指向上一个和下一个节点)将节点添加到链接列表的末尾更容易

如果您使用一个数组,您可能需要调整它的大小,或者将它初始化为最大可能的蛇形长度,这样可能会浪费内存

更新
本文讨论了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实现中使用了一些不同的东西。我们的想法是,你要去商店

  • 蛇头的位置
  • 蛇的长度
  • 蛇头的方向
  • “弯曲”对象的数组,其中弯曲包括方向(左或右)和偏移(例如(左,3),当蛇的第三个位置有左弯曲时)
  • 这是一个非常有效的解决方案,不像一个简单的数组那样是一个愚蠢的解决方案,可以很容易地用来绘制“更喜欢”的蛇,例如圆角蛇。

    您可以使用。详细说明:

    获得一个数组,足够容纳最大数量的蛇。建立两个指针,一个用于头部,一个用于尾部


    一开始,尾巴在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字段,也不能让数组变长。我总是喜欢家庭作业之类的问题。很想知道什么学校和班级。。排队怎么样?这显然是一个数据结构,如果你想创建圆角,你可以在渲染部分这样做,游戏逻辑可以保持沉默。