2012-07-06 89 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