public static int GetChanceCard( Player player )
 {
     do {
         _chanceCard = (ChanceCards) random.Next(1, _numChanceCards + 1);
     } while ( GetOutOfJailFreeCard.ChanceOwner != null & _chanceCard == ChanceCards.GetOutOfJailCard );
     return (int)_chanceCard;
 }
 public void addPlayerDebt(Player payee, int amount)
 {
     if ((payee != null) && (!payee.Bankrupt) && (payee != _player)) {
         _playerDebt.Add(payee, amount);
         Irc.Output(Irc.getChannel(), ".newPlayerDebt " + _player.Name + " " + payee.Name + " " + amount);
     }
 }
 public static int GetCommunityChestCard( Player player )
 {
     do {
         _communityChestCard = (CommunityChestCards) random.Next(1, _numCommunityChestCards + 1);
     } while ( GetOutOfJailFreeCard.CommunityChestOwner != null & _communityChestCard == CommunityChestCards.GetOutOfJailCard );
     return (int)_communityChestCard;
 }
        public static void addPropertyDebt(Player player, TitleDeed titleDeed)
        {
            if (!hasPlayer(player)) {
                UnhandledDebt unhandledDebt = new UnhandledDebt(player);
                _unhandledDebtList.Add(player, unhandledDebt);

            }

            _unhandledDebtList[player].addPropertyDebt(titleDeed);
        }
        public static void addPlayerDebt(Player payer, Player payee, int amount)
        {
            if (!hasPlayer(payer)) {
                UnhandledDebt unhandledDebt = new UnhandledDebt(payer);
                _unhandledDebtList.Add(payer, unhandledDebt);

            }

            _unhandledDebtList[payer].addPlayerDebt(payee, amount);
        }
        public static void addTaxesDebt(Player player)
        {
            if (!hasPlayer(player)) {
                UnhandledDebt unhandledDebt = new UnhandledDebt(player);
                _unhandledDebtList.Add(player, unhandledDebt);

            }

            _unhandledDebtList[player].addTaxDebt();
        }
        public static void addCashDebt(Player player, int amount)
        {
            if (amount <= 0) {
                return;
            }

            if (!hasPlayer(player)) {
                UnhandledDebt unhandledDebt = new UnhandledDebt(player);
                _unhandledDebtList.Add(player, unhandledDebt);

            }

            _unhandledDebtList[player].addCashDebt(amount);
        }
        public static void evaluateLocation(Player player, int roll)
        {
            Tile location = _theBoard[player.Location];

            if (location == Tile.GoToJail) {
                player.sendToJail();
            } else if (location == Tile.LuxuryTax) {
                player.payFlatFee((int)Amounts.LuxuryTax);
            } else if (location == Tile.IncomeTax) {
                UnhandledDebtList.addTaxesDebt(player);
            } else if (location == Tile.Chance) {
                int ChestCard = Card.GetChanceCard(player);
                Irc.Output(Irc.getChannel(), ".chance " + player.Name + " " + ChestCard.ToString());
                Card.RunChanceCard(player);
            } else if (location == Tile.CommunityChest) {
                int card = Card.GetCommunityChestCard(player);
                Irc.Output(Irc.getChannel(), ".communityChest " + player.Name + " " + card.ToString());
                Card.RunCommunityChestCard(player);
            } else if ((location == Tile.FreeParking) || (location == Tile.Jail) || (location == Tile.Go)) {
                return;
            } else {
                TitleDeed titleDeed = Property.getTitleDeed(location);
                if (titleDeed != null) {
                    Player owner = titleDeed.Owner;

                    if (owner == null) {
                        Irc.Output(Irc.getChannel(), ".offer " + player.Name + " " + (int)titleDeed.Name + " " + titleDeed.Cost);
                    } else if (owner != player) {
                        int rent = titleDeed.getRent(roll);
                        if (rent != 0) {
                            player.payPlayer(rent, owner);
                        }
                    }
                }
            }
        }
        public static void remove(Player player)
        {
            if (hasPlayer(player)) {
                _unhandledDebtList.Remove(player);
            }

            foreach (UnhandledDebt unhandledDebt in _unhandledDebtList.Values) {
                if (unhandledDebt.hasPlayerDebt(player)) {
                    unhandledDebt.removePlayerDebt(player);
                }
            }
        }
        public static int ownedInSet(Player player, Set set)
        {
            if (player == null) {
                return 0;
            }

            if (_set.ContainsKey(set)) {
                int sum = 0;
                LinkedList<TitleDeed> titleDeedList = _set[set];

                foreach (TitleDeed titleDeed in titleDeedList) {
                    if (titleDeed.Owner == player) {
                        sum++;
                    }
                }

                return sum;
            } else {
                return 0;
            }
        }
        public static bool hasFullSet(Player player, Set set)
        {
            if (player == null) {
                return false;
            }

            if (_set.ContainsKey(set)) {
                LinkedList<TitleDeed> titleDeedList = _set[set];

                foreach (TitleDeed titleDeed in titleDeedList) {
                    if (titleDeed.Owner != player) {
                        return false;
                    }
                }

                return true;
            } else {
                return false;
            }
        }
        private void payPlayer(Player payer, string command)
        {
            if (command.Length > 11) {
                string playerName = command.Substring(11);

                if (!isValidPlayer(playerName)) {
                    Irc.Output(Irc.getChannel(), ".fail " + payer.Name + " invalid command.");
                    return;
                }

                Player payee = _players[playerName];

                UnhandledDebt unhandledDebt = UnhandledDebtList.getUnhandledDebt(payer);
                if (unhandledDebt == null) {
                    return;
                }

                if (!unhandledDebt.hasPlayerDebt(payee)) {
                    Irc.Output(Irc.getChannel(), ".fail " + payer.Name + " you don't have debt to " + payee + ".");
                    return;
                }

                unhandledDebt.payPlayerDebt(payee);
                resolvedDebt(payee);

            } else {
                Irc.Output(Irc.getChannel(), ".fail " + payer.Name + " invalid command.");
            }
        }
        public static void RunChanceCard( Player player )
        {
            int location = 0;
            int move = 0;

            switch ( _chanceCard ) {
                case ChanceCards.AdvanceGo: player.moveAndEval(Move.Absolute, (int) Tile.Go); break;
                case ChanceCards.AdvanceBoardWalk: player.moveAndEval(Move.Absolute, (int) Tile.Boardwalk); break;
                case ChanceCards.AdvanceIllinoisAve: player.moveAndEval(Move.Absolute, (int) Tile.IllinoisAvenue); break;
                case ChanceCards.AdvanceNearestRailroad: {
                        location = player.Location;
                        location %= 10;

                        if ( location < 5 ) {
                            move = 5 - location;
                        } else {
                            move = 15 - location;
                        }

                        player.simpleMove(Move.Relative, move);

                        TitleDeed titleDeed = Property.getTitleDeed((Tile) player.Location);
                        Player railroadOwner = titleDeed.Owner;
                        if ( ( railroadOwner != player ) && ( railroadOwner != null ) ) {
                            //for RailRoad the parameter passed to getRent is ignored
                            player.payPlayer(( (Railroad) titleDeed ).getRent(-1) * 2, railroadOwner);
                        } else if ( railroadOwner == null ) {
                            Irc.Output(Irc.getChannel(), ".offer " + player.Name + " " + (int) titleDeed.Name + " " + titleDeed.Cost);
                        }
                    }; break;
                case ChanceCards.AdvanceNearestRailroad2: {
                        location = player.Location;
                        location %= 10;

                        if ( location < 5 ) {
                            move = 5 - location;
                        } else {
                            move = 15 - location;
                        }

                        player.simpleMove(Move.Relative, move);

                        TitleDeed titleDeed = Property.getTitleDeed((Tile) player.Location);
                        Player railroadOwner = titleDeed.Owner;
                        if ( ( railroadOwner != player ) && ( railroadOwner != null ) ) {
                            //for RailRoad the parameter passed to getRent is ignored
                            player.payPlayer(( (Railroad) titleDeed ).getRent(-1) * 2, railroadOwner);
                        } else if ( railroadOwner == null ) {
                            Irc.Output(Irc.getChannel(), ".offer " + player.Name + " " + (int) titleDeed.Name + " " + titleDeed.Cost);
                        }
                    }; break;
                case ChanceCards.AdvanceNearestUtility: {
                        if ( ( player.Location < (int) Tile.ElectricCompany ) || ( player.Location >= (int) Tile.WaterWorks ) ) {
                            player.simpleMove(Move.Absolute, (int) Tile.ElectricCompany);
                        } else {
                            player.simpleMove(Move.Absolute, (int) Tile.WaterWorks);
                        }

                        TitleDeed titleDeed = Property.getTitleDeed((Tile) player.Location);
                        Player utilityOwner = titleDeed.Owner;
                        if ( ( utilityOwner != player ) && ( utilityOwner != null ) ) {
                            int die1, die2;
                            die1 = Die.Roll();
                            die2 = Die.Roll();

                            player.payPlayer(( (Utility) titleDeed ).getRent(( die1 + die2 ) * 10), utilityOwner);
                        } else if ( utilityOwner == null ) {
                            Irc.Output(Irc.getChannel(), ".offer " + player.Name + " " + (int) titleDeed.Name + " " + titleDeed.Cost);
                        }
                    }; break;
                case ChanceCards.AdvanceStCharles: player.moveAndEval(Move.Absolute, (int) Tile.StCharlesPlace); break;
                case ChanceCards.Back3: player.moveAndEval(Move.Relative, -3); break;
                case ChanceCards.BankDivident: player.addCash(50); break;
                case ChanceCards.BuildingAndLoanMatures: player.addCash(150); break;
                case ChanceCards.ChairmanOfBoard: {
                    foreach ( Player otherPlayer in _players ) {
                        if ( otherPlayer != player ) {
                            if ( !otherPlayer.Bankrupt && !player.Bankrupt) {
                                player.payPlayer(50, otherPlayer);
                            }
                        }
                    }
                }; break;
                case ChanceCards.GeneralRepairs: {
                    player.payFlatFee(player.Hotels * 100 + player.Houses * 25);
                } break;
                case ChanceCards.GetOutOfJailCard: GetOutOfJailFreeCard.ChanceOwner = player; break;
                case ChanceCards.JailNoGo: player.sendToJail(); break;
                case ChanceCards.PoorTax: player.payFlatFee(15); break;
                case ChanceCards.RideOnReading: player.moveAndEval(Move.Absolute, (int)Tile.ReadingRailroad); break;
            }
        }
 private void purchase(Player player, TitleDeed titleDeed)
 {
     if (titleDeed == null) {
         Irc.Output(Irc.getChannel(), ".fail " + player.Name + " Unpurchaseable property.");
     } else if (titleDeed.Owner != null) {
         if (titleDeed.Owner == player) {
             Irc.Output(Irc.getChannel(), ".fail " + player.Name + " You already own " + titleDeed.Name + ".");
         } else {
             Irc.Output(Irc.getChannel(), ".fail " + player.Name + " " + titleDeed.Owner.Name + " already owns " + titleDeed.Name + ".");
         }
     } else {
         if (player.Cash >= titleDeed.Cost) {
             player.payFlatFee(titleDeed.Cost);
             player.addTitleDeed(titleDeed);
             titleDeed.Owner = player;
         } else {
             Irc.Output(Irc.getChannel(), ".fail " + player.Name + " insufficient funds");
         }
     }
 }
        private void unmortgage(Player player, string command)
        {
            if (command.Length > 12) {
                int tileIndex = atoi(command.Substring(12));
                Tile tile = Board.getTile(tileIndex);
                TitleDeed titleDeed = Property.getTitleDeed(tile);
                if ((titleDeed != null) && (titleDeed.Owner == player) && (titleDeed.Mortgaged)) {
                    UnhandledDebt unhandledDebt = UnhandledDebtList.getUnhandledDebt(player);

                    if (unhandledDebt == null) {
                        titleDeed.unmortgage();
                    } else {
                        if (unhandledDebt.hasPropertyDebt(tile)) {
                            titleDeed.unmortgage();

                            if (!titleDeed.Mortgaged) {
                                unhandledDebt.removePropertyDebt(tile);
                            }

                            resolvedDebt(player);
                        } else {
                            Irc.Output(Irc.getChannel(), ".fail " + player.Name + " you need to resolve your debt.");
                        }
                    }
                } else {
                    Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
                }
            } else {
                Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
            }
        }
 public void payPlayer(int amount, Player payee)
 {
     if (amount <= _cash) {
         payFlatFee(amount);
         payee.addCash(amount);
     } else if (amount > networthCash()) {
         declareBankruptcy(payee);
     } else {
         UnhandledDebtList.addPlayerDebt(this, payee, amount);
     }
 }
        public void tellInventory(Player player)
        {
            string output = ".inventory " + player.Name + " " + _name + " " + _cash;

            foreach (TitleDeed titleDeed in _inventory.Values) {
                output += " " + (int)titleDeed.Name;

                if (titleDeed.Mortgaged) {
                    output += "m";
                }

            }

            Irc.Output(Irc.getChannel(), output);
        }
        public void declareBankruptcy(Player bankrupter)
        {
            if (bankrupter == null) {
                foreach (TitleDeed titleDeed in _inventory.Values) {
                    titleDeed.reset();
                }
                if ( hasChanceOutOfJailFreeCard() ) {
                    releaseChanceOutOfJailCard();
                }

                if ( hasChanceOutOfJailFreeCard() ) {
                    releaseCommunityChestOutOfJailCard();
                }

                Irc.Output(Irc.getChannel(), ".bankrupt " + _name);
            } else {
                if ( hasChanceOutOfJailFreeCard() ) {
                    GetOutOfJailFreeCard.ChanceOwner = bankrupter;
                }

                if ( hasCommunityChestOutOfJailFreeCard() ) {
                    GetOutOfJailFreeCard.CommunityChestOwner = bankrupter;
                }

                Irc.Output(Irc.getChannel(), ".bankrupt " + _name + " " + bankrupter.Name);
                payPlayer(_cash, bankrupter);
                bankrupter.inheritInventory(_inventory);
            }
            _isBankrupt = true;
            _inventory.Clear();
            UnhandledDebtList.remove(this);
        }
        private void viewInventory(Player requester, string command)
        {
            if (command.Length > 11) {
                string playerName = command.Substring(11);

                if (!isValidPlayer(playerName)) {
                    Irc.Output(Irc.getChannel(), ".fail " + requester.Name);
                    return;
                }

                Player requestee = _players[playerName];
                requestee.tellInventory(requester);
            } else {
                Irc.Output(Irc.getChannel(), ".fail " + requester.Name + " invalid command.");
            }
        }
 private void upgrade(Player player, string command)
 {
     if (command.Length > 9) {
         int tileIndex = atoi(command.Substring(9));
         Tile tile = Board.getTile(tileIndex);
         TitleDeed titleDeed = Property.getTitleDeed(tile);
         if ((titleDeed != null) && (titleDeed.Owner == player)) {
             titleDeed.upgrade();
         } else {
             Irc.Output(Irc.getChannel(), ".fail " + player.Name + " you can't upgrade specified tile.");
         }
     } else {
         Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
     }
 }
 public static int totalDebt(Player player)
 {
     if (hasPlayer(player)) {
         return _unhandledDebtList[player].totalDebt();
     } else {
         return 0;
     }
 }
        private void payTaxes(Player player, Amounts fee)
        {
            if ((player != _activePlayer.Player) || ((fee != Amounts.IncomeTaxPercent) && (fee != Amounts.IncomeTaxFlat))) {
                return;
            }

            UnhandledDebt unhandledDebt = UnhandledDebtList.getUnhandledDebt(player);

            if ((unhandledDebt == null) || (!unhandledDebt.IncomeTax)) {
                return;
            } else {
                unhandledDebt.payTaxDebt(fee);
            }

            resolvedDebt(player);
        }
 public static bool hasPlayer(Player player)
 {
     return _unhandledDebtList.ContainsKey(player);
 }
        private void resolvedDebt(Player player)
        {
            UnhandledDebt unhandledDebt = UnhandledDebtList.getUnhandledDebt(player);

            if (unhandledDebt != null && !unhandledDebt.hasDebt()) {
                UnhandledDebtList.remove(player);
            }

            if (UnhandledDebtList.Count == 0) {
                if (player.Bankrupt) {
                    killPlayer(player);
                } else if (_activePlayer.EndedTurn) {
                    setNextPlayer();
                }
            }
        }
 public static void RunCommunityChestCard( Player player )
 {
     //the number is generated in the Get function
     switch ( _communityChestCard ) {
         case CommunityChestCards.AdvanceGo: player.moveAndEval(Move.Absolute, (int) Tile.Go); break;
         case CommunityChestCards.BankError: player.addCash(200); break;
         case CommunityChestCards.LifeInsuranceMatures: player.addCash(100); break;
         case CommunityChestCards.DoctorFee: player.payFlatFee(50); break;
         case CommunityChestCards.FromSaleOfStock: player.addCash(45); break;
         case CommunityChestCards.GetOutOfJailCard: GetOutOfJailFreeCard.CommunityChestOwner = player; break;
         case CommunityChestCards.GoJailNoCollect: player.sendToJail(); break;
         case CommunityChestCards.GrandOperaOpening: {
             foreach ( Player otherPlayer in _players ) {
                 if ( otherPlayer != player ) {
                     if ( !otherPlayer.Bankrupt && !player.Bankrupt) {
                         otherPlayer.payPlayer(50, player);
                     }
                 }
             }
         }; break;
         case CommunityChestCards.IncomeTaxRefund: player.addCash(20); break;
         case CommunityChestCards.Inherit: player.addCash(100); break;
         case CommunityChestCards.PayHospital: player.payFlatFee(100); break;
         case CommunityChestCards.ReceiveForServices: player.addCash(25); break;
         case CommunityChestCards.SchoolTax: player.payFlatFee(150); break;
         case CommunityChestCards.SecondPrizeBeautyContest: player.addCash(10); break;
         case CommunityChestCards.StreetRepairs: {
             player.payFlatFee(player.Hotels * 115 + player.Houses * 40);
         }; break;
         case CommunityChestCards.XMASFundMatures: player.addCash(100); break;
     }
 }
        private void payPropertyDebt(Player player, string command)
        {
            if (command.Length > 17) {
                int tileIndex = atoi(command.Substring(17));
                Tile tile = Board.getTile(tileIndex);
                TitleDeed titleDeed = Property.getTitleDeed(tile);
                if ((titleDeed != null) && (titleDeed.Owner == player)) {
                    UnhandledDebt unhandledDebt = UnhandledDebtList.getUnhandledDebt(player);

                    if (unhandledDebt != null) {

                        if (unhandledDebt.hasPropertyDebt(tile)) {
                            unhandledDebt.payPropertyDebt(tile);
                        }

                        resolvedDebt(player);
                    }
                } else {
                    Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
                }
            } else {
                Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
            }
        }
 public static UnhandledDebt getUnhandledDebt(Player player)
 {
     if (hasPlayer(player)) {
         return _unhandledDebtList[player];
     } else {
         return null;
     }
 }
 private void mortgage(Player player, string command)
 {
     if (command.Length > 10) {
         int tileIndex = atoi(command.Substring(10));
         Tile tile = Board.getTile(tileIndex);
         TitleDeed titleDeed = Property.getTitleDeed(tile);
         if ((titleDeed != null) && (titleDeed.Owner == player) && (!titleDeed.Mortgaged)) {
             titleDeed.mortgage();
         } else {
             Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
         }
     } else {
         Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
     }
 }
 public void reset()
 {
     _level = Level.Default;
     _isMortgaged = false;
     _owner = null;
 }
        private void payCashDebt(Player player)
        {
            if (player == null) {
                return;
            }

            UnhandledDebt unhandledDebt = UnhandledDebtList.getUnhandledDebt(player);

            if ((unhandledDebt == null) || (!unhandledDebt.hasCashDebt())) {
                Irc.Output(Irc.getChannel(), ".fail " + player.Name + " invalid command.");
                return;
            } if (player.Cash < unhandledDebt.CashDebt) {
                Irc.Output(Irc.getChannel(), ".fail " + player.Name + " insufficient funds to pay debt.");
                return;
            }

            unhandledDebt.payCashDebt();
            resolvedDebt(player);

            if ((!unhandledDebt.hasCashDebt()) && (player == _activePlayer.Player) && (_activePlayer.Frozen)) {
                int roll = _activePlayer.unfreeze();
                movePlayer(player.Name, Move.Relative, roll);
            }
        }