//  rank points are used to sort players
        public decimal RankPoints( NFLPlayer player, NFLGame game, NflTeam opponent )
        {
            decimal points = 0;

             #region  short cut

             if (RankMaster.Contains(player.PlayerCode))
             {
            var rankedPlayer = (NFLPlayer) RankMaster[player.PlayerCode];
            return rankedPlayer.Points;
             }
             #endregion

             #region  Get the average output for the last 3 games

             //  Always start with the Average points in their last 3 games, if 0 and QB use 14
             if (game != null)
             {
            if (player.PlayerRole.Equals(Constants.K_ROLE_STARTER))
            {
               var avgPoints = AveragePoints(player);

               //  Rookies and injured players may not have played in the last 3 games
               if ( player.PlayerCat.Equals( "1" ) )
               {
                  if (avgPoints.Equals( 0.0M )) avgPoints = 14.0M;  // avergage for a QB
               }
               if ( player.PlayerCat.Equals( "2" ) )
               {
                  if ( avgPoints.Equals( 0.0M ) ) avgPoints = 8.0M;  // avergage for a RB
               }
               if ( player.PlayerCat.Equals( "3" ) )
               {
                  if ( avgPoints.Equals( 0.0M ) ) avgPoints = 6.0M;  // avergage for a RB
               }
               else if ( player.PlayerCat.Equals( "4" ))
               {
                  if (avgPoints.Equals( 0.0M )) avgPoints = 6.0M;  // avergage day for a PK
               }
               points += avgPoints;
            }
             }

             #endregion

             #region  Consider the likely result

             decimal spreadModifier = 1;  //  no modification

             if ( IncludeSpread )
             {
            if (game != null) spreadModifier = PlayerSpread( game.GetSpread(), game.IsHome( player.CurrTeam.TeamCode ) ) / 1;

            points *= spreadModifier;
             }

             #endregion

             #region  factor in the quality of the opponent

             if ( IncludeRatingModifier )
             {
            if ( opponent != null )
            {
               var oppRating = player.OpponentRating( opponent.Ratings );
               var ratingModifier = RatingModifier( oppRating );
               points *= ratingModifier;
            }
             }

             #endregion

             player.Points = points;
             RankMaster.Add(player.PlayerCode, player); //  save points for later

            #if DEBUG
             //  verbose audit trail of the calculations
             //Utility.Announce( string.Format(
             //   "{0,-16} has {1,4:#0.#} r pts- spr {2,4:#0.#} avgFP last 3 {3,4:##.#} rating mod {4,4:#0.#} {5}",
             //   player.PlayerNameShort, points, spreadModifier, avgPoints, ratingModifier, oppRating ) );
            #endif
             return points;
        }
        private DataTable BuildTable()
        {
            var dt = new DataTable();
             var cols = dt.Columns;
             cols.Add( "SLOT", typeof( String ) );
             cols.Add( "PLAYER", typeof( String ) );
             cols.Add( "TEAM", typeof( String ) );
             cols.Add( "FTEAM", typeof( String ) );
             cols.Add( "POS", typeof( String ) );
             cols.Add( "PTS", typeof( Int16 ) );
             cols.Add( "UNIT", typeof( String ) );
             cols.Add( "ROLE", typeof( String ) );
             cols.Add( "GAME", typeof( String ) );
             cols.Add( "OPPRATE", typeof( String ) );
             cols.Add( "SPREAD", typeof( Decimal ) );
             cols.Add( "TOTAL", typeof( Decimal ) );
             cols.Add( "BOOKIE", typeof( String ) );
             cols.Add( "ACTUAL", typeof( Int16 ) );

             PgmList = PgmDao.GetWeek( Season, Week );
             var week = Scorer.Week;

             foreach ( var pgm in PgmList )
             {
            var p = new NFLPlayer( pgm.PlayerId );

            if ( !string.IsNullOrEmpty( TeamFilter ) )
            {
               if ( p.TeamCode != TeamFilter )
                  continue;
            }

            if ( !string.IsNullOrEmpty( CategoryFilter ) )
            {
               if ( p.PlayerCat != CategoryFilter )
                  continue;
            }

            p.LoadOwner( League );
            var dr = dt.NewRow();

            var game = new NFLGame( pgm.GameKey );
            p.LoadProjections( pgm );

            var opponent = p.CurrTeam.OpponentFor( Season, Int32.Parse( Week ) );
            //  player actually available
            dr[ "PLAYER" ] = p.Url( p.PlayerName, forceReport: false );
            dr[ "TEAM" ] = p.CurrTeam.TeamCode;
            dr[ "FTEAM" ] = p.Owner;
            dr[ "ROLE" ] = p.PlayerRole;
            dr[ "POS" ] = p.PlayerPos;

            dr[ "PTS" ] = Scorer.RatePlayer( p, week );
            dr[ "UNIT" ] = game.ProjectionLink();
            dr[ "GAME" ] = string.Format( "{0} {1} {2}",
                                       game.GameDay(), game.Hour, game.OpponentOut( p.CurrTeam.TeamCode ) );
            dr[ "SPREAD" ] = game.GetSpread();
            dr[ "TOTAL" ] = game.Total;
            game.CalculateSpreadResult();
            dr[ "BOOKIE" ] = game.BookieTip.PredictedScore();

            if ( opponent != null )
               dr[ "OPPRATE" ] = opponent.Ratings;

            //if ( game.Played() )
            //	dr[ "ACTUAL" ] = ActualPoints( p );
            dt.Rows.Add( dr );
             }
             dt.DefaultView.Sort = "PTS DESC";
             return dt;
        }