home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume14 / okbridge2 / part12 / scoring.c < prev   
C/C++ Source or Header  |  1993-01-27  |  10KB  |  367 lines

  1. /* scoring.c -- scoring functions for the bridge program.
  2.  *
  3.  ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  4.  ! 
  5.  ! OKbridge is made available as a free service to the Internet.
  6.  ! Accordingly, the following restrictions are placed on its use:
  7.  ! 
  8.  ! 1.  OKbridge may not be modified in any way without the explicit 
  9.  !     permission of Matthew Clegg.  
  10.  ! 
  11.  ! 2.  OKbridge may not be used in any way for commercial advantage.
  12.  !     It may not be placed on for-profit networks or on for-profit
  13.  !     computer systems.  It may not be bundled as part of a package
  14.  !     or service provided by a for-profit organization.
  15.  ! 
  16.  ! If you have questions about restrictions on the use of OKbridge,
  17.  ! write to mclegg@cs.ucsd.edu.
  18.  ! 
  19.  ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  20.  ! damage which may be caused by OKbridge.
  21.  *
  22.  * This file defines the functions used for computing scores.
  23.  * We provide functions for scoring according to the rules of
  24.  * rubber bridge as well as according to the rules of Chicago style
  25.  * bridge.  Instead of being passed parameters, these functions
  26.  * obtain most of their information from the global variables
  27.  * defined in globals.h.
  28.  *
  29.  * I would like to thank Tom Kronmiller for supplying the code
  30.  * for scoring according to the Chicago rules.  Thanks Tom!
  31.  */
  32.  
  33. #include "types.h"
  34.  
  35. static int  first_trick   [] = {20, 20, 30, 30, 40};
  36. static int  subseq_tricks [] = {20, 20, 30, 30, 30};
  37.  
  38.  
  39. /*  All of the routines in this module use the same set of parameters:
  40.  *  
  41.  *  vul     := a boolean flag which if true indicates that the declaring
  42.  *             side was vulnerable.
  43.  *  level   := the level of the contract.
  44.  *  suit    := the trump suit (or SUIT_NOTRUMP).
  45.  *  doubled := is 0 for an undoubled contract, 1 for a doubled contract,
  46.  *             and 2 for a redoubled contract.
  47.  *  made    := If the contract was made, then the number of tricks made
  48.  *             minus 6.  Otherwise, the negative of the number of tricks set.
  49.  *  hcp     := Number of highcard points held by the declaring side.
  50.  */
  51.  
  52. int Rubber_score_above (vul, level, suit, doubled, made)
  53.      int vul, level, suit, doubled, made;
  54. /* Computes the above-the-line score for the current contract, assuming
  55.    the contract was made. */
  56. {
  57.   int above = 0;  /* computed above-the-line points. */
  58.  
  59.   if (doubled) {
  60.     above = 100 * (made - level);
  61.     if (vul)         above *= 2;
  62.     if (doubled > 1) above *= 2;
  63.     above += 50;
  64.   } else
  65.     above = subseq_tricks[suit] * (made - level);
  66.  
  67.   if (level == 6)
  68.     above += vul? 750: 500;
  69.   else if (level == 7)
  70.     above += vul? 1500: 1000;
  71.   return (above);
  72.     
  73. }
  74.  
  75. int Rubber_score_below (vul, level, suit, doubled, made)
  76.      int vul, level, suit, doubled, made;
  77. /* Computes the below-the-line score for the current contract,
  78.  * assuming the contract was made. */
  79. {
  80.   int below = 0;  /* computed below-the-line points. */
  81.  
  82.   below  = first_trick[suit] + 
  83.     (level - 1) * subseq_tricks[suit];
  84.   if (doubled > 1)
  85.     below *= 4;
  86.   else if (doubled)
  87.     below *= 2;
  88.   return (below);
  89. }
  90.  
  91.  
  92. int Rubber_score_set (vul, level, suit, doubled, made)
  93.      int vul, level, suit, doubled, made;
  94. /* Computes the penalty score for the current contract assuming that
  95.  * the contract was set.  
  96.  */
  97. {
  98.   int penalty = 0;  /* computed penalty points. */
  99.   int down = -made - 1;
  100.  
  101.   if (doubled) {
  102.     if (vul) penalty = 200 + 300 * down;
  103.     else     penalty = 100 + 200 * down;
  104.     if (doubled > 1) penalty *= 2;
  105.   } else {
  106.     if (vul) penalty = 100 + 100 * down;
  107.     else     penalty =  50 +  50 * down;
  108.   }
  109.   return (penalty);
  110. }
  111.  
  112.  
  113. int Chicago_score_made (vul, level, suit, doubled, made)
  114.      int vul, level, suit, doubled, made;
  115. /* Computes the score for the current contract under the Chicago scoring
  116.  * system, assuming that it was made.
  117.  *
  118.  * Original version by Tom Kronmiller.
  119.  */
  120. {
  121.     int result = 0, perTrick;
  122.     int extra = made - level;
  123.  
  124.     /* How much is making the bid worth? */
  125.     perTrick = (MINOR(suit))? 20:30;
  126.     result = perTrick * level;
  127.     if (suit == SUIT_NOTRUMP)    result += 10;
  128.     if (doubled > 1)                result *= 4;
  129.     else if (doubled == 1)          result *= 2;
  130.       
  131.     /* Was it a game we made? */
  132.     if (result >= 100)        result += (!vul)? 300:500;
  133. /*    else                    result += 50; */
  134.  
  135.     /* Was it a slam we made? */
  136.     if (level == 6)        result += (!vul)? 500:750;
  137.     if (level == 7)        result += (!vul)? 1000:1500;
  138.  
  139.     /* Were we insulted by a double? */
  140.     if (doubled > 1)                  result += 100;
  141.     else if (doubled == 1)            result += 50;
  142.  
  143.     /* How much do we get for overtricks? */
  144.     if (doubled > 1)
  145.             result += (extra * 100) * (vul? 4: 2);
  146.     else if (doubled == 1)
  147.             result += (extra * 100) * (vul? 2: 1);
  148.     else
  149.         result += extra * perTrick;
  150.  
  151.     return (result);
  152. }
  153.  
  154.  
  155. int Chicago_score_set (vul, level, suit, doubled, made)
  156.      int vul, level, suit, doubled, made;
  157. /* Computes the score for the given contract under the Chicago scoring
  158.  * system, assuming that it was set.
  159.  *
  160.  * Original version by Tom Kronmiller.
  161.  */
  162. {
  163.     int result = 0;
  164.     int down =  -made;
  165.  
  166.     if (!doubled)
  167.     {
  168.         result = 50 * down;
  169.         if (vul) result *= 2;
  170.     }
  171.     else
  172.     {
  173.         switch (down)
  174.         {
  175.             case 1:
  176.                 result = (!vul)? 100:200;
  177.                 break;
  178.             case 2:
  179.                 result = (!vul)? 300:500;
  180.                 break;
  181.             case 3:
  182.                 result = (!vul)? 500:800;
  183.                 break;
  184.             default:
  185.                 result = 500 + (300*(down-3)) 
  186.                   + ((!vul)? 0:300);
  187.                 break;
  188.         }
  189.         if (doubled > 1) result *= 2;
  190.     }
  191.     return (result);
  192. }
  193.  
  194. int Duplicate_score_made (vul, level, suit, doubled, made)
  195.      int vul, level, suit, doubled, made;
  196. /* Computes the score for the given contract under the rules of
  197.  * duplicate scoring. 
  198.  */
  199. {
  200.     int score;
  201.  
  202.     if (made == 0)
  203.       return (0);
  204.  
  205.     score = Chicago_score_made (vul, level, suit, doubled, made);
  206.     if (score < 300)
  207.         score += 50;
  208.     return (score);
  209.     
  210. }
  211.  
  212. int Duplicate_score_set (vul, level, suit, doubled, made)
  213.      int vul, level, suit, doubled, made;
  214. /* Computes the score for the given contract under the rules of
  215.  * duplicate scoring, assuming that it was set.
  216.  */
  217. {
  218.   return (Chicago_score_set(vul, level, suit, doubled, made));
  219. }
  220.  
  221.  
  222. static int IMP_conversion_table [] = {
  223.     20,   50,   90,  130,  170,  220,  270,  320,  370,  430, 
  224.    500,  600,  750,  900, 1100, 1300, 1500, 1750, 2000, 2250,
  225.   2500, 3000, 3500, 4000, 99999};
  226.  
  227. int IMP_rating (score_diff)
  228.      int score_diff;
  229. /* Returns the number of IMPs awarded for the given score difference. */
  230. {
  231.   int imps = 0;
  232.  
  233.   if (score_diff < 0)
  234.     return (-IMP_rating(-score_diff));
  235.  
  236.   for (imps = 0; IMP_conversion_table[imps] <= score_diff; imps++);
  237.   return (imps + imps);
  238. }
  239.  
  240. static int IMP_score_conversion (pt, highcard_points)
  241.      int pt, highcard_points;
  242. /* Computes a 'simulated IMP' score.  This score is computed by looking
  243.    up the IMP_rating of the pt score of the declaring team, and subtracting
  244.    from this the number of highcard points over 20.
  245. */
  246. {
  247.   return (IMP_rating(pt) - (highcard_points - 20));
  248. }
  249.  
  250. int Simulated_IMP_score_made (vul, level, suit, doubled, made, hcp)
  251.      int vul, level, suit, doubled, made, hcp;
  252. /* Computes the simulated IMP score for the given contract assuming that 
  253.  * it was made.
  254.  */
  255. {
  256.     int score;
  257.  
  258.     score =
  259.       IMP_score_conversion
  260.         (Duplicate_score_made (vul, level, suit, doubled, made), hcp);
  261.  
  262.     return (score);
  263.     
  264. }
  265.  
  266. int Simulated_IMP_score_set (vul, level, suit, doubled, made, hcp)
  267.      int vul, level, suit, doubled, made, hcp;
  268. /* Computes the simulated IMP score for the given contract assuming that 
  269.  * it was set.
  270.  */
  271. {
  272.     int score;
  273.  
  274.     score =
  275.       IMP_score_conversion
  276.         (-Duplicate_score_set(vul, level, suit, doubled, made), hcp);
  277.  
  278.     return (score);
  279. }
  280.  
  281. int MIMP_scoring_vuln [] = {
  282.     -2100, -2100, -2100, -2100, -1850, -1650, -1500, -1400, -1100, -950,
  283.     -800, -750, -700, -650, -600, -450, -300, -150, -100, -50,
  284.     0, 50, 100, 150, 300, 450, 600, 650, 700, 750,
  285.     800, 950, 1100, 1400, 1500, 1650, 1850, 2100, 2100, 2100,
  286.     2100
  287. };
  288.  
  289. int MIMP_scoring_nonvuln [] = {
  290.     -1500, -1500, -1500, -1500, -1300, -1150, -1050, -950, -800, -700,
  291.     -600, -550, -500, -450, -400, -300, -200, -150, -100, -50,
  292.     0, 50, 100, 150, 200, 300, 400, 450, 500, 550,
  293.     600, 700, 800, 950, 1050, 1150, 1300, 1500, 1500, 1500,
  294.     1500
  295. };
  296.  
  297. int MIMP_score_conversion (score, vulnerable, highcard_points)
  298.      int score, vulnerable, highcard_points;
  299. /* This code contributed by David Morrison. */
  300. {
  301.     /* If you think the code calculating the score here is magic, you
  302.      * are *right*.
  303.      */
  304.  
  305.     if (vulnerable) { score -= MIMP_scoring_vuln[highcard_points]; }
  306.     else { score -= MIMP_scoring_nonvuln[highcard_points]; }
  307.  
  308.     /* If I had a good description of the algorithm, and its
  309.      * justification, it would go here.  For now, you'll just have to
  310.      * accept the code.
  311.      */
  312.  
  313.     if ( (score <= 600) && (score >= -600) ) {
  314.         score *= 2;
  315.     } else {
  316.     if (score > 600) {
  317.         score += 600;
  318.     } else {
  319.         score -= 600;
  320.     }
  321.     }
  322.  
  323.     if (score >= 0)
  324.       score = (score + 25) / 50;
  325.     else
  326.       score = (score - 25) / 50;
  327.  
  328.     return (score);
  329.  
  330. }
  331.  
  332. int MIMP_score_made (vul, level, suit, doubled, made, hcp)
  333.      int vul, level, suit, doubled, made, hcp;
  334. /* Computes the MIMP score for the given contract assuming that 
  335.  * it was made.
  336.  *
  337.  * This code contributed by David Morrison.
  338.  */
  339. {
  340.   int score;
  341.  
  342.   score =
  343.     MIMP_score_conversion
  344.       (Duplicate_score_made (vul, level, suit, doubled, made), vul, hcp);
  345.  
  346.   return (score);
  347.     
  348. }
  349.  
  350. int MIMP_score_set (vul, level, suit, doubled, made, hcp)
  351.      int vul, level, suit, doubled, made, hcp;
  352. /* Computes the MIMP score for the given contract assuming that 
  353.  * it was set.
  354.  *
  355.  * This code contributed by David Morrison.
  356.  */
  357. {
  358.   int score;
  359.  
  360.   score =
  361.     MIMP_score_conversion
  362.       (-Duplicate_score_set(vul, level, suit, doubled, made), vul, hcp);
  363.   
  364.   return (score);
  365. }
  366.  
  367.