2012-07-06 88 views
-1

我想返回一个函数的值来告诉我,如果某个位置在该位置有熔岩或水。结果总是正确的?

问题是即使它有熔岩或水,它仍然会返回true。 水,熔岩和苍蝇的值来自玩家生物的列表。如果这个生物具有水,熔岩或能飞的能力,那就是了。我只是相应地将它们标记为真/假。位置是一个TPOINT。它加载到所有这些功能只要功能CheckLocation返回true,则其确定位置

if FMyPlayers.Player[i].Values['water']='yes' then 
     canwater := true; 
    if FMyPlayers.Player[i].Values['Lava']='yes' then 
     canlava := true; 
    if FMyPlayers.Player[i].Values['fly']='yes' then 
     canfly := true; 
    cansnow := true; 
    if checkLocation(position,cansnow,canlava,canwater,canfly) = False then 
     exit; 

function TBaseGameForm.checkLocation(position :Tpoint;Cansnow,canlava,canwater,canfly:bool):Bool; 
begin 
RESULT := True; 
if canfly = true then 
    RESULT := true 
else begin 
    if FGamePlay.waterLocations.IndexOfName('x'+inttostr(Position.x)+inttostr(Position.Y)) <> -1 then begin //Check location 
    Showmessage('Cant move there due to water'); 
    RESULT := FALSE; 
    end; 
    if FGamePlay.LavaLocations.IndexOfName('x'+inttostr(Position.x)+inttostr(Position.Y)) <> -1 then begin //Check location 
    Showmessage('Cant move there due to lava'); 
    RESULT := False; 
    end; 
    end; 
end; 

运行当我检查在WaterLocations

[0] x47 
[1] y47 
[2] x58 
[3] y58 

Position.x的价值和价值观Position.y是(4,7)因此它应该返回false,因为x47在列表中。

+1

我不熟悉delphi/Pascal,但是大写有什么意义? ('True'与'true','FALSE'与'False') – chandsie 2012-07-06 00:39:55

+2

您的列表必须包含'Index ='('x47')'x47 = ...'条目才能返回'-1 '(假设NameValueSeparator是'=')。如果不是这样,只需使用'IndexOf'。 – 2012-07-06 00:41:02

+4

'(22,22)'和'(222,2)'位置会发生什么?我认为你的位置存储需要改进... – sarnold 2012-07-06 00:45:33

回答

8

像@SertacAkyuz说的,问题是您使用IndexOfName()。您需要改用IndexOf()

您的CheckLocation()函数中存在另一个错误。您忽略了除canfly以外的所有输入参数。如果canwatercanlava为真,则您的函数将在任何水/熔岩位置返回False。您需要检查该位置是否与玩家的能力匹配。如果canwater为真,则不需要检查该位置是否是水。与熔岩一样。

试试这个:

canwater := (FMyPlayers.Player[i].Values['water'] = 'yes'); 
canlava := (FMyPlayers.Player[i].Values['Lava'] = 'yes'); 
canfly := (FMyPlayers.Player[i].Values['fly'] = 'yes'); 
cansnow := true; 
if not CheckLocation(position, cansnow, canlava, canwater, canfly) then 
    Exit; 

function TBaseGameForm.CheckLocation(position: TPoint; cansnow, canlava, canwater, canfly: Boolean): Boolean; 
var 
    loc: String; 
begin 
    Result := True; 
    if (not canfly) and ((not canwater) or (not canlava)) then 
    begin 
    loc := Format('x%d%d', [Position.X, Position.Y]); 

    if (not canwater) and (FGamePlay.waterLocations.IndexOf(loc) <> -1) then 
    begin 
     Showmessage('Cant move there due to water'); 
     Result := False; 
     Exit; 
    end; 

    if (not canlava) and (FGamePlay.LavaLocations.IndexOf(loc) <> -1) then 
    begin 
     Showmessage('Cant move there due to lava'); 
     Result := False; 
     Exit; 
    end; 
    end; 
end; 

这样说,我同意@sarnold,你的坐标系统需要一些调整。只要你的x/y坐标都是单个数字就可以了。但是,如果它们是多位数字,它将不起作用。最起码,你应该前缀Y坐标,如:

[0] x4y7 
[1] x5y8 

loc := Format('x%dy%d', [Position.X, Position.Y]); 

就个人而言,我不会用一个TStrings持有整数值是这样的。我会用TPointTList一个实例来代替,例如:

waterLocations: TList; 

function FindLocation(List: TList; Position: TPoint): Integer; 
begin 
    for Result := 0 to List.Coun-1 do 
    begin 
    with PPoint(List[Result])^ do 
    begin 
     if (X = Position X) and (Y = Position.Y) then Exit; 
    end; 
    end; 
    Result := -1; 
end; 

if (not canwater) and (FindLocation(FGamePlay.waterLocations, Position) <> -1) then 
begin 
    Showmessage('Cant move there due to water'); 
    Result := False; 
    Exit; 
end; 

或者,如果您使用的是支持泛型现代德尔福版本,一个TList<TPoint>

waterLocations: TList<TPoint>; 

function FindLocation(List: TList<TPoint>; Position: TPoint): Integer; 
begin 
    for Result := 0 to List.Coun-1 do 
    begin 
    with List[Result] do 
    begin 
     if (X = Position X) and (Y = Position.Y) then Exit; 
    end; 
    end; 
    Result := -1; 
end; 

if (not canwater) and (FindLocation(FGamePlay.waterLocations, Position) <> -1) then 
begin 
    Showmessage('Cant move there due to water'); 
    Result := False; 
    Exit; 
end; 

甚至存储任何给定的X/Y坐标指定位置的类型的单个TDictionary

type 
    locType = (locLand, locWater, locLava, locSnow); 

locations: TDictionary<TPoint, locType>; 

function TBaseGameForm.CheckLocation(position: TPoint; cansnow, canlava, canwater, canfly: Boolean): Boolean; 
var 
    loc: locType; 
begin 
    Result := True; 
    if not canfly then 
    begin 
    locations.TryGetValue(Position, loc); 
    case loc of 
     locWater: begin 
     if not canwater then 
     begin 
      Showmessage('Cant move there due to water'); 
      Result := False; 
     end; 
     end; 
     locLava: begin 
     if not canlava then 
     begin 
      Showmessage('Cant move there due to lava'); 
      Result := False; 
      Exit; 
     end; 
     end; 
    end; 
    end; 
end; 
+0

谢谢,我会试试,目前在工作中,所以只需要快速查看一下:D – 2012-07-06 01:47:22

+1

+1为扩展答案 – 2012-07-06 11:23:59

+0

谢谢这是非常清晰,效果很好。 – 2012-07-08 19:25:22