[Home]PuertoRicoOnline/RandomBot

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

ec2-3-17-162-247.us-east-2.compute.amazonaws.com | ToothyWiki | PuertoRicoOnline | RecentChanges | Login | Webcomic
This page is read-only | View other revisions | Recently used referrers
Last edited May 13, 2005 5:28 pm (viewing revision 7, which is the newest) (diff)
Search: