ec2-3-17-162-247.us-east-2.compute.amazonaws.com | ToothyWiki | PuertoRicoOnline | RecentChanges | Login | Webcomic
A bot for qqzm's PuertoRicoOnline that does exactly what it says on the tin - takes random actions.
See PuertoRicoOnline/WritingBots for help on writing bots for PuertoRicoOnline.
- Does this really work for playing games of several of them against each other? I'd have thought they'd crash the game after 9 settler phases, since they don't check there are quarries left when they ask to take one. --AC
- True, I assume they just happen to not have had 9 settler phases when I've tested them... I've now edited it. --qqzm
function GetRandomArray(Length: Integer): array of Integer;
// Returns an array of integers (1 to length) of the specified length in random order.
var
i, j, Temp: Integer;
begin
// Set the length of the array.
SetArrayLength(Result, Length);
// Fill the array with integers.
for i:= 0 to Length - 1 do
Result[i]:= i+1;
// Randomize the array.
for i:= 0 to Length - 1 do
begin
j:= Random(Length);
Temp:= Result[i];
Result[i]:= Result[j];
Result[j]:= Temp;
end;
end;
function Build(Game: GameType; BotPlayer: Integer): String;
// Called when it's the bot's turn to build.
var
IAmBuilder, Building, i: Integer;
Order: array of Integer;
begin
Building:= 0;
// Get an array of buildings available in random order.
Order:= GetRandomArray(Game.BuildingsInBank.Count - 1);
// Work out if it was the bot who selected the builder role.
if Game.CurrentRoleChooser = BotPlayer then
IAmBuilder:= 1
else
IAmBuilder:= 0;
// Iterate through the buildings, and build the first one the bot is legally allowed to build.
for i:= 0 to Game.BuildingsInBank.Count - 2 do
if Player(Game.Players.Objects[BotPlayer]).CanBuild(Order[i], IAmBuilder) then
begin
Building:= Order[i];
Break;
end;
// Return the request for the (randomly) chosen building.
Result:= Format('builder.html?Game=%d&Player=%d&ID=&Building=%d',
[Game.GameNumber, BotPlayer, Building]);
end;
function Ship(Game: GameType; BotPlayer: Integer): String;
// Called when it's the bot's turn to Ship.
var
i, GoodsType, ShipNumber: Integer;
Order: array of Integer;
begin
GoodsType:= 0;
ShipNumber:= 0;
// Get an array of goods to try and ship in random order.
Order:= GetRandomArray(5);
with Game do
begin
// Find a good that the bot is legally allowed to ship...
for i:= 0 to 4 do
if Player(Game.Players.Objects[BotPlayer]).CanShipGood(GoodsShips, Order[i]) then
begin
GoodsType:= Order[i];
Break;
end;
// Find a ship that the bot can use to ship the selected good...
for i:= 0 to GoodsShips.Count - 1 do
if GoodsShip(GoodsShips.Objects[i]).CanShip(GoodsType) then
begin
ShipNumber:= i;
Break;
end;
end;
// Return the request to ship the chosen good in the chosen ship.
Result:= Format('captain.html?Game=%d&Player=%d&ID=&GoodsType=%d&Ship=%d',
[Game.GameNumber, BotPlayer, GoodsType, ShipNumber]);
end;
function KeepAllNext(const Game: GameType; const BotPlayer: Integer; const Order: array of Integer; var i: Integer): String;
// Returns a string to specify keeping all barrels of the next available type of good.
var
j: Integer;
begin
Result:= '';
// Find the next type of good that the bot possesses some barrels of...
while ((i < 5) and (GetBarrel(Game.GameNumber, BotPlayer, Order[i]) = 0)) do
i:= i + 1;
// Generate the string to keep all of the chosen type of good...
if i < 5 then
for j:= 1 to GetBarrel(Game.GameNumber, BotPlayer, Order[i]) do
Result:= Format('%s&%d%d=on', [Result, Order[i], j]);
end;
function Rot(Game: GameType; BotPlayer: Integer): String;
// Called when it's the bot's turn to rot barrels.
var
Order: array of Integer;
KeepString: String;
i: Integer;
begin
// Get an array of goods types in random order.
Order:= GetRandomArray(5);
KeepString:= '';
with Player(Game.Players.Objects[BotPlayer]) do
begin
i:= 0;
// If the bot has a manned large warehouse, keep 2 kinds of good...
if IsManned(LARGEWAREHOUSE) then
begin
KeepString:= KeepString + KeepAllNext(Game, BotPlayer, Order, i);
KeepString:= KeepString + KeepAllNext(Game, BotPlayer, Order, i);
end;
// If the bot has a manned small warehouse, keep 1 kind of good...
if IsManned(SMALLWAREHOUSE) then
begin
KeepString:= KeepString + KeepAllNext(Game, BotPlayer, Order, i);
end;
// Find the next type of good that the bot possesses...
while ((i < 5) and (GetBarrel(Game.GameNumber, BotPlayer, Order[i]) = 0)) do
i:= i + 1;
// Keep the default 1 of the chosen good type.
if i < 5 then
KeepString:= Format('%s&%d%d=on', [KeepString, Order[i], 1]);
end;
// Return the request to keep the selected barrels.
Result:= Format('rotting.html?Game=%d&Player=%d&ID=%s',
[Game.GameNumber, BotPlayer, KeepString]);
end;
function Craft(Game: GameType; BotPlayer: Integer): String;
// Called when it's the bot's turn to select an additional barrel to produce.
var
i, ExtraGood: Integer;
Order: array of Integer;
begin
ExtraGood:= 0;
// Get an array of goods types in random order.
Order:= GetRandomArray(5);
// Look through the random types array and select the first type that the bot produced in the current craftsman...
for i:= 0 to 4 do
if GetLastBarrel(Game.GameNumber, BotPlayer, Order[i]) > 0 then
begin
ExtraGood:= Order[i];
Break;
end;
// Return the request to produce the chosen additional barrel.
Result:= Format('craftsman.html?Game=%d&Player=%d&ExtraBarrel=%d',
[Game.GameNumber, BotPlayer, ExtraGood]);
end;
function Distribute(Game: GameType; BotPlayer: Integer): String;
// Called when it's the bot's turn to mayor.
var
Order: TStringList;
i, j: Integer;
begin
Result:= Format('mayor.html?Game=%d&Player=%d',
[Game.GameNumber, BotPlayer]);
Order:= TStringList.Create;
with Player(Game.Players.Objects[BotPlayer]) do
begin
// Go through all the plantations and buildings, and add an item to the order list for each empty colonist space...
for i:= 0 to 11 do
begin
if GetPlantation(Game.GameNumber, BotPlayer, i).ID > 0 then
begin
if GetPlantation(Game.GameNumber, BotPlayer, i).Manned then
Result:= Format('%s&p%d=on', [Result, i])
else
Order.Add('p' + IntToStr(i));
end;
if GetBuilding(Game.GameNumber, BotPlayer, i).ID > 0 then
begin
for j:= 1 to GetBuilding(Game.GameNumber, BotPlayer, i).Colonists do
Result:= Format('%s&b%d%d=on', [Result, i, j]);
for j:= GetBuilding(Game.GameNumber, BotPlayer, i).Colonists + 1 to
GetBuilding(Game.GameNumber, BotPlayer, i).ColonistSpaces do
Order.Add('b' + IntToStr(i) + IntToStr(j));
end;
end;
// Go through the spare colonists...
for i:= 1 to SpareColonists do
// ... if there are empty colonist spaces...
if Order.Count > 0 then
begin
// ... choose a random empty space to fill...
j:= Random(Order.Count);
Result:= Format('%s&%s=on', [Result, Order[j]]);
Order.Delete(j);
end;
end;
Order.Free;
end;
function Settle(Game: GameType; BotPlayer: Integer): String;
// Called when it's the bot's turn to Settle.
var
i, Plantation: Integer;
begin
with Player(Game.Players.Objects[BotPlayer]) do
// If the bot has an unmanned hacienda it hasn't used this turn, use it.
if ((IsManned(HACIENDA)) and (UsedHacienda=False)) then
begin
Result:= Format('settler.html?Game=%d&Player=%d&Plantation=-2',
[Game.GameNumber, BotPlayer]);
end
else if ((Game.CurrentRoleChooser = BotPlayer) and (PlantationType(Game.PlantationsInBank.Objects[6]).NumberBarrels > 0)) then
// ... else if the bot chose the settler and the is a quarry available ...
begin
// Take a quarry.
Result:= Format('settler.html?Game=%d&Player=%d&Plantation=6',
[Game.GameNumber, BotPlayer]);
end
else // ... else the bot doesn't have a manned hacienda or it has already used it and didn't choose the settler...
begin
Plantation:= 0;
// Choose a random plantation from those available...
for i:= 0 to Game.NumberOfPlayers do
if GetNextPlantation(Game.GameNumber, BotPlayer, i) > 0 then
begin
Plantation:= GetNextPlantation(Game.GameNumber, BotPlayer, i);
Break;
end;
Result:= Format('settler.html?Game=%d&Player=%d&Plantation=%d',
[Game.GameNumber, BotPlayer, Plantation]);
end;
end;
function Trade(Game: GameType; BotPlayer: Integer): String;
// Called when it's the bot's turn to trade.
var
i, GoodToTrade: Integer;
Order: array of Integer;
begin
GoodToTrade:= 0;
// Get an array of goods types in random order.
Order:= GetRandomArray(5);
// Find the first good in the random array the bot can legally trade...
for i:= 0 to 4 do
if Player(Game.Players.Objects[BotPlayer]).CanTradeGood(Game.TradingHouse, Order[i]) then
begin
GoodToTrade:= Order[i];
Break;
end;
// Return the request to trade the chosen good.
Result:= Format('trader.html?Game=%d&Player=%d&GoodsType=%d',
[Game.GameNumber, BotPlayer, GoodToTrade]);
end;
function TakeTurn(const Game: GameType; const BotPlayer: Integer): String;
var
Order: array of Integer;
i: Integer;
begin
// Output a line to the bot debug file...
WriteLn(Game.GameNumber, BotPlayer, 'Taking my turn...');
Result:= '';
with Game do
begin
// Check it's the bot's turn...
if CurrentPlayer = BotPlayer then
begin
// If a role has been selected, call the function that corresponds to that role...
case CurrentRole of
BUILDER: Result:= Build(Game, BotPlayer);
CAPTAIN: Result:= Ship(Game, BotPlayer);
ROTTING: Result:= Rot(Game, BotPlayer);
CRAFTSMAN: Result:= Craft(Game, BotPlayer);
MAYOR: Result:= Distribute(Game, BotPlayer);
TRADER: Result:= Trade(Game, BotPlayer);
SETTLER: Result:= Settle(Game, BotPlayer);
else // It is the bot's turn to choose a role...
begin
// Get an array of the roles in random order...
Order:= GetRandomArray(Roles.Count);
// Find the first available role in the random array...
for i:= 0 to Roles.Count - 1 do
if Role(Roles.Objects[Order[i]-1]).Available then
begin
// Request the (randomly) chosen role.
Result:= Format('role.html?Game=%d&Player=%d&ID=&Role=%d',
[Game.GameNumber, BotPlayer, Order[i]-1]);
Break;
end;
end;
end;
end;
end;
end;
begin
{}
end.
CategoryGames