我试图返回一个函数的值来告诉我一个位置是否有该位置的熔岩或水.
问题是即使它有熔岩或水,它仍然会返回真实.水,熔岩和苍蝇的值来自玩家生物的列表.如果该生物具有水,熔岩或能够飞行的能力,那就是它.我只是将它们标记为真/假.位置是TPOINT.它将所有这些加载到一个函数中,只要函数CheckLocation返回true然后它的ok位置
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;
Run Code Online (Sandbox Code Playgroud)
在运行时,我检查WaterLocations中的值
[0] x47
[1] y47
[2] x58
[3] y58
Run Code Online (Sandbox Code Playgroud)
Position.x和Position.y的值是(4,7)因此它应该返回false原因x47在列表中.
就像@SertacAkyuz所说,问题是你的使用IndexOfName().你需要IndexOf()改用.
您的CheckLocation()函数还有另一个错误.您忽略除了以外的所有输入参数canfly.如果canwater或canlava为True,您的函数将在任何水/熔岩位置返回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;
Run Code Online (Sandbox Code Playgroud)
.
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;
Run Code Online (Sandbox Code Playgroud)
话虽如此,我同意@sarnold你的坐标系需要一些调整.只要您的x/y坐标都是单个数字,它就可以了.但如果它们是多位数,它将无法工作.至少,你应该在Y坐标前面添加前缀,例如:
[0] x4y7
[1] x5y8
loc := Format('x%dy%d', [Position.X, Position.Y]);
Run Code Online (Sandbox Code Playgroud)
就个人而言,我根本不会使用a TStrings来保存这样的整数值.我会用TList的TPoint情况相反,如:
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;
Run Code Online (Sandbox Code Playgroud)
.
if (not canwater) and (FindLocation(FGamePlay.waterLocations, Position) <> -1) then
begin
Showmessage('Cant move there due to water');
Result := False;
Exit;
end;
Run Code Online (Sandbox Code Playgroud)
或者,如果您使用的是支持泛型的现代Delphi版本,则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;
Run Code Online (Sandbox Code Playgroud)
.
if (not canwater) and (FindLocation(FGamePlay.waterLocations, Position) <> -1) then
begin
Showmessage('Cant move there due to water');
Result := False;
Exit;
end;
Run Code Online (Sandbox Code Playgroud)
或者甚至是TDictionary存储任何给定X/Y坐标指定的位置类型的单个:
type
locType = (locLand, locWater, locLava, locSnow);
locations: TDictionary<TPoint, locType>;
Run Code Online (Sandbox Code Playgroud)
.
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;
Run Code Online (Sandbox Code Playgroud)