예제 #1
0
        public static List <Balance> GetBalanceLine(CountryContext db, int countryId, DateTime date, bool xLine)
        {
            var start = xLine ? countryId - countryId % 10 : countryId / 10 * 10;
            var end   = start + (xLine ? 9 : 90);
            var step  = xLine ? 1 : 10;

            var ids = new List <int>();

            for (var i = start; i <= end; i += step)
            {
                if (i == countryId)
                {
                    continue;
                }
                ids.Add(i);
            }

            return(db.Transactions
                   .Where(x => (ids.Contains(x.Sender.Id) || ids.Contains(x.Recipient.Id)) && x.Date < date)
                   .Select(x => new Balance {
                Coin = x.Coin, Count = x.Count * (ids.Contains(x.Recipient.Id) ? 1 : -1)
            })
                   .GroupBy(x => x.Coin)
                   .Select(x => new Balance
            {
                Coin = x.Key,
                Count = x.Sum(s => s.Count)
            }).Where(b => b.Count > 0).ToList());
        }
예제 #2
0
        private static void CreateWorld(CountryContext db)
        {
            var countries = new List <Country>();

            for (var i = 0; i < 100; i++)
            {
                countries.Add(new Country {
                    Id = i, Name = i.ToString()
                });
            }

            db.Countries.AddRange(countries);

            foreach (var country in countries)
            {
                if ((country.Id + 1) % 10 == 0)
                {
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id - 9));
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id - 1));
                }
                else if (country.Id % 10 == 0)
                {
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id + 9));
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id + 1));
                }
                else
                {
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id + 1));
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id - 1));
                }

                if (country.Id >= 90)
                {
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id - 90));
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id - 10));
                }
                else if (country.Id < 10)
                {
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id + 90));
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id + 10));
                }
                else
                {
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id + 10));
                    country.Neighbors.Add(countries.First(x => x.Id == country.Id - 10));
                }

                db.Coins.Add(new Coin {
                    Id = country.Id, Country = country
                });

                db.SaveChanges();
            }
        }
예제 #3
0
 public static List <Balance> GetBalance(CountryContext db, int countryId, DateTime date)
 {
     return(db.Transactions
            .Where(x => (x.Sender.Id == countryId || x.Recipient.Id == countryId) && x.Date < date)
            .Select(x => new Balance {
         Coin = x.Coin, Count = x.Count * (x.Recipient.Id == countryId ? 1 : -1)
     })
            .GroupBy(x => x.Coin)
            .Select(x => new Balance
     {
         Coin = x.Key,
         Count = x.Sum(s => s.Count)
     }).Where(b => b.Count > 0).ToList());
 }
예제 #4
0
        public static void CreateCoins(CountryContext db, DateTime dateTime, int countCoins)
        {
            var transactions = new List <Transaction>();

            foreach (var country in db.Countries.ToList())
            {
                transactions.Add(new Transaction
                {
                    Coin      = db.Coins.First(x => x.Country.Id == country.Id),
                    Recipient = country,
                    Sender    = null,
                    Date      = dateTime.AddMonths(-1),
                    Count     = countCoins
                });
            }

            db.Transactions.AddRange(transactions);
            db.SaveChanges();
        }
예제 #5
0
        private static void Main()
        {
            using (var db = new CountryContext())
            {
                CreateWorld(db);
                bool isFull;
                var  currentDate = Convert.ToDateTime("01/01/2020");
                var  countries   = db.Countries.ToList();
                do
                {
                    isFull = true;
                    //каждый год создаем монеты
                    if (currentDate.DayOfYear == 1)
                    {
                        CreateCoins(db, currentDate, 20);
                        Console.WriteLine("**********************************************************");
                    }

                    var newAllTransactions = new List <Transaction>();

                    foreach (var country in countries)
                    {
                        var newCountryTransactions = new List <Transaction>();
                        var balanceCountry         = GetBalance(db, country.Id, currentDate);

                        if (balanceCountry.Count() < 100)
                        {
                            isFull = false;
                        }

                        //var balanceLineX = GetBalanceLine(db, country.Id, currentDate, true);
                        //var balanceLineY = GetBalanceLine(db, country.Id, currentDate, false);

                        //var forLineX = balanceCountry.Where(x => (x.Count > 1||x.Coin.Country.Id==country.Id)).OrderByDescending(o => o.Count).Select(x => x.Coin).ToList();
                        //    //.Except(balanceLineX.Where(x => x.Count > 8).Select(x => x.Coin)).ToList();

                        //var forLineY = balanceCountry.Where(x => (x.Count > 1 || x.Coin.Country.Id == country.Id)).OrderByDescending(o=>o.Count).Select(x => x.Coin).ToList();
                        //    //.Except(balanceLineY.Where(x => x.Count > 8).Select(x => x.Coin)).ToList();

                        ////торгуем монетами нужными только по горизонтали
                        //var forOnlyX = forLineX.Except(forLineY).ToList();
                        //newCountryTransactions.AddRange(Trade(country,
                        //    country.Neighbors.Where(n => Math.Abs(n.Id - country.Id) < 10).ToList(), balanceCountry,
                        //    forOnlyX, newCountryTransactions.Sum(x => x.Count),
                        //    currentDate));

                        ////торгуем монетами нужными только по вертикали
                        //var forOnlyY = forLineY.Except(forLineX).ToList();
                        //newCountryTransactions.AddRange(Trade(country,
                        //    country.Neighbors.Where(n => Math.Abs(n.Id - country.Id) >= 10).ToList(),
                        //    balanceCountry,
                        //    forOnlyY, newCountryTransactions.Sum(x => x.Count),
                        //    currentDate));

                        //распределяем оставшиеся монеты по всем
                        var forAllOther = balanceCountry.Where(x => (x.Count > 1 || x.Coin.Country.Id == country.Id))
                                          .OrderByDescending(o => o.Count).Select(x => x.Coin).ToList();

                        newCountryTransactions.AddRange(Trade(country, country.Neighbors.ToList(), balanceCountry,
                                                              forAllOther, newCountryTransactions.Sum(x => x.Count),
                                                              currentDate));

                        newAllTransactions.AddRange(newCountryTransactions);
                    }

                    //TODO: bulkinsert
                    db.Transactions.AddRange(newAllTransactions.Where(x => x.Count > 0));
                    db.SaveChanges();

                    //Отчет по стране
                    foreach (var country in countries)
                    {
                        var balanceCountryStart = GetBalance(db, country.Id, currentDate);
                        var balanceCountryEnd   = GetBalance(db, country.Id, currentDate.AddMonths(1));

                        var tradeIn  = newAllTransactions.Where(x => x.Recipient.Id == country.Id).Sum(s => s.Count);
                        var tradeOut = newAllTransactions.Where(x => x.Sender.Id == country.Id).Sum(s => s.Count);

                        Console.WriteLine("*******************************" +
                                          $"\r\n{currentDate} \r\n" +
                                          $"Country = {country.Id} \r\n" +
                                          $"Balance start = {balanceCountryStart.Sum(x => x.Count)}\r\n" +
                                          $"TradeOut = {tradeOut}\r\n" +
                                          $"TradeIn = {tradeIn}\r\n" +
                                          $"Balance end = {balanceCountryEnd.Sum(x => x.Count)}");
                        foreach (var balance in balanceCountryEnd.OrderBy(x => x.Coin.Id))
                        {
                            Console.WriteLine($"Coin({balance.Coin.Country.Id}) = {balance.Count}");
                        }
                    }

                    currentDate = currentDate.AddMonths(1);
                } while (!isFull);
            }

            Console.Read();
        }