就像@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;
.
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]);
就个人而言,我根本不会使用 aTStrings
来保存这样的整数值。我会改用TList
ofTPoint
实例,例如:
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;
或者,如果您使用的是支持泛型的现代 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;
.
if (not canwater) and (FindLocation(FGamePlay.waterLocations, Position) <> -1) then
begin
Showmessage('Cant move there due to water');
Result := False;
Exit;
end;
甚至是TDictionary
存储任何给定 X/Y 坐标指定的位置类型的单个:
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;