Beispiel #1
0
 public ResourceOrder(ResourceSale sale, Company orderCompany, double price, double timeLeft, double amount)
 {
     this.sale         = sale;
     this.orderCompany = orderCompany;
     this.price        = price;
     this.timeLeft     = timeLeft;
     this.amount       = amount;
 }
        public void PopulationBuy()
        {
            spentLast = spent;
            spent     = 0;
            buyRatio  = 0;
            foreach (var resource in main.populationDemandList)             //browse all required resources for input
            {
                double amountNeeded = resource.amount * main.population.people;
                double amountBought = 0;
                double totalOnSale  = main.TotalOnSale(resource.resource.name);
                if (totalOnSale <= 0)
                {
                    continue;
                }
                List <ResourceSale> sales = main.FindResource(resource.resource.name).sales; //get sales by resource name
                ResourceSale.OrderSalesByPrice(sales, new Location(0, 0));                   //sort by best price
                foreach (var sale in sales)                                                  //browse sales
                {
                    //if (sale.price > main.FindResource(resource.resource.name).basePrice * 5) break;
                    if (amountBought >= amountNeeded || money < 0)
                    {
                        return;
                    }
                    double buyDist = (sale.amount / totalOnSale) * Math.Pow(resource.resource.price / sale.price, 2);
                    double mult    = 1;
                    //adjust amount to buy based on how more expensive than base price, for inflation control
                    if (resource.resource.basePrice < sale.price)
                    {
                        mult *= Math.Pow(resource.resource.basePrice / sale.price, 0.5);
                    }

                    if (spentLast * 5 > money)
                    {
                        mult *= Math.Pow(money / (spentLast * 5), 2);
                    }
                    buyDist  *= mult;
                    buyRatio += mult / main.populationDemandList.Count;
                    if (buyDist > 1)
                    {
                        buyDist = 1;
                    }

                    double toBuy = 0;
                    if (amountNeeded > totalOnSale)
                    {
                        toBuy = totalOnSale * buyDist;
                    }
                    else
                    {
                        toBuy = amountNeeded * buyDist;
                    }
                    //Console.WriteLine("\ntoBuy:{0} ",toBuy);


                    if (sale.amount < toBuy)
                    {
                        toBuy = sale.amount;
                    }

                    sale.soldThisTick += toBuy;
                    sale.amount       -= toBuy;
                    money             -= toBuy * sale.price;
                    spent             += toBuy * sale.price;
                    amountBought      += toBuy;
                }
            }
        }
        public void BuyResources()
        {
            double partToBuy = 1;

            info.costToProduce = 0;
            if (info.producedPast5Turns > 0 && CompanyOutputGlobalDemand() < 0.95)
            {
                partToBuy = info.soldPast5Turns / info.producedPast5Turns;                 //calculate last turns demand
            }
            if (CompanyOutputExpectedDemand() > 0)
            {
                partToBuy = 1;
            }
            double amountStored = 0;

            if (productionRecipe.output[0].resource.sales.Find(x => x.company == this) != null)
            {
                amountStored = productionRecipe.output[0].resource.sales.Find(x => x.company == this).amount;
            }
            if (amountStored > info.soldPast5Turns && info.soldPast5Turns > 0)
            {
                partToBuy = info.soldPast5Turns / amountStored;
            }
            Console.WriteLine("amount stored: " + amountStored + " " + info.soldPast5Turns);
            if (partToBuy > 1)
            {
                partToBuy = 1;
            }
            Console.WriteLine("\ncompany demand: " + CompanyOutputDemand() + " " + this.name);

            if (productionRecipe.input.Count == 0)             //if have no inputs to produce, don't buy resources
            {
                info.actualProduction = partToBuy;
                return;
            }

            double totalAmountBought = 0, totalAmountNeeded = 0, totalPrice = 0;

            foreach (var resource in productionRecipe.input)             //browse all required resources for input
            {
                double amountNeeded = resource.amount * productionVolume * productionInput * partToBuy;
                double amountBought = 0;
                double totalOnSale  = main.TotalOnSale(resource.resource.name);
                if (totalOnSale <= 0)
                {
                    continue;
                }

                foreach (var order in resourceOrders)
                {
                    if (order.sale.resource == resource.resource)
                    {
                        PayOrder(order, ref totalPrice, ref amountBought);
                    }
                }

                List <ResourceSale> sales = new List <ResourceSale>(main.FindResource(resource.resource.name).sales); //get sales by resource name
                ResourceSale.OrderSalesByPrice(sales, location);                                                      //sort by best price
                foreach (var sale in sales)                                                                           //browse sales
                {
                    if (amountBought >= amountNeeded)
                    {
                        break;
                    }
                    double buyDist = (sale.amount / totalOnSale) * Math.Pow(resource.resource.price / sale.price, 1);

                    double toBuy = amountNeeded * buyDist;
                    if (sale.amount < toBuy)
                    {
                        toBuy = sale.amount;
                    }
                    if (toBuy > amountNeeded - amountBought)
                    {
                        toBuy = amountNeeded - amountBought;
                    }

                    PayOrder(sale.MakeOrder(toBuy, this), ref totalPrice, ref amountBought);

                    /*
                     * sale.soldThisTick += toBuy;
                     * totalPrice += toBuy * sale.price;
                     * sale.amount -= toBuy;
                     * amountBought += toBuy;
                     * TransportationCosts(sale.company, toBuy);
                     */
                }

                totalAmountBought += amountBought;
                totalAmountNeeded += amountNeeded;
            }
            resourceOrders = resourceOrders.FindAll(x => x.timeLeft > 0);

            if (totalAmountNeeded > 0)
            {
                info.inputFulfilled = (totalAmountBought / totalAmountNeeded);                 //0-1, actual company production
            }
            if (info.inputFulfilled > 1)
            {
                info.inputFulfilled = 1;
            }
            info.actualProduction = info.inputFulfilled * partToBuy;
            revenue -= totalPrice;
            if (totalAmountBought > 0 && totalPrice > 0)
            {
                info.costToProduce = totalPrice / totalAmountBought;
            }
            else if (totalPrice > 0)
            {
                info.costToProduce = totalPrice;
            }
            else
            {
                info.costToProduce = main.population.labourCost * 10;
            }
            Console.WriteLine("cost to do stuff:{0}", info.costToProduce);
        }