home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume14
/
okbridge2
/
part12
/
scoring.c
< prev
Wrap
C/C++ Source or Header
|
1993-01-27
|
10KB
|
367 lines
/* scoring.c -- scoring functions for the bridge program.
*
! Copyright (C) 1990-1992 by Matthew Clegg. All Rights Reserved
!
! OKbridge is made available as a free service to the Internet.
! Accordingly, the following restrictions are placed on its use:
!
! 1. OKbridge may not be modified in any way without the explicit
! permission of Matthew Clegg.
!
! 2. OKbridge may not be used in any way for commercial advantage.
! It may not be placed on for-profit networks or on for-profit
! computer systems. It may not be bundled as part of a package
! or service provided by a for-profit organization.
!
! If you have questions about restrictions on the use of OKbridge,
! write to mclegg@cs.ucsd.edu.
!
! DISCLAIMER: The user of OKbridge accepts full responsibility for any
! damage which may be caused by OKbridge.
*
* This file defines the functions used for computing scores.
* We provide functions for scoring according to the rules of
* rubber bridge as well as according to the rules of Chicago style
* bridge. Instead of being passed parameters, these functions
* obtain most of their information from the global variables
* defined in globals.h.
*
* I would like to thank Tom Kronmiller for supplying the code
* for scoring according to the Chicago rules. Thanks Tom!
*/
#include "types.h"
static int first_trick [] = {20, 20, 30, 30, 40};
static int subseq_tricks [] = {20, 20, 30, 30, 30};
/* All of the routines in this module use the same set of parameters:
*
* vul := a boolean flag which if true indicates that the declaring
* side was vulnerable.
* level := the level of the contract.
* suit := the trump suit (or SUIT_NOTRUMP).
* doubled := is 0 for an undoubled contract, 1 for a doubled contract,
* and 2 for a redoubled contract.
* made := If the contract was made, then the number of tricks made
* minus 6. Otherwise, the negative of the number of tricks set.
* hcp := Number of highcard points held by the declaring side.
*/
int Rubber_score_above (vul, level, suit, doubled, made)
int vul, level, suit, doubled, made;
/* Computes the above-the-line score for the current contract, assuming
the contract was made. */
{
int above = 0; /* computed above-the-line points. */
if (doubled) {
above = 100 * (made - level);
if (vul) above *= 2;
if (doubled > 1) above *= 2;
above += 50;
} else
above = subseq_tricks[suit] * (made - level);
if (level == 6)
above += vul? 750: 500;
else if (level == 7)
above += vul? 1500: 1000;
return (above);
}
int Rubber_score_below (vul, level, suit, doubled, made)
int vul, level, suit, doubled, made;
/* Computes the below-the-line score for the current contract,
* assuming the contract was made. */
{
int below = 0; /* computed below-the-line points. */
below = first_trick[suit] +
(level - 1) * subseq_tricks[suit];
if (doubled > 1)
below *= 4;
else if (doubled)
below *= 2;
return (below);
}
int Rubber_score_set (vul, level, suit, doubled, made)
int vul, level, suit, doubled, made;
/* Computes the penalty score for the current contract assuming that
* the contract was set.
*/
{
int penalty = 0; /* computed penalty points. */
int down = -made - 1;
if (doubled) {
if (vul) penalty = 200 + 300 * down;
else penalty = 100 + 200 * down;
if (doubled > 1) penalty *= 2;
} else {
if (vul) penalty = 100 + 100 * down;
else penalty = 50 + 50 * down;
}
return (penalty);
}
int Chicago_score_made (vul, level, suit, doubled, made)
int vul, level, suit, doubled, made;
/* Computes the score for the current contract under the Chicago scoring
* system, assuming that it was made.
*
* Original version by Tom Kronmiller.
*/
{
int result = 0, perTrick;
int extra = made - level;
/* How much is making the bid worth? */
perTrick = (MINOR(suit))? 20:30;
result = perTrick * level;
if (suit == SUIT_NOTRUMP) result += 10;
if (doubled > 1) result *= 4;
else if (doubled == 1) result *= 2;
/* Was it a game we made? */
if (result >= 100) result += (!vul)? 300:500;
/* else result += 50; */
/* Was it a slam we made? */
if (level == 6) result += (!vul)? 500:750;
if (level == 7) result += (!vul)? 1000:1500;
/* Were we insulted by a double? */
if (doubled > 1) result += 100;
else if (doubled == 1) result += 50;
/* How much do we get for overtricks? */
if (doubled > 1)
result += (extra * 100) * (vul? 4: 2);
else if (doubled == 1)
result += (extra * 100) * (vul? 2: 1);
else
result += extra * perTrick;
return (result);
}
int Chicago_score_set (vul, level, suit, doubled, made)
int vul, level, suit, doubled, made;
/* Computes the score for the given contract under the Chicago scoring
* system, assuming that it was set.
*
* Original version by Tom Kronmiller.
*/
{
int result = 0;
int down = -made;
if (!doubled)
{
result = 50 * down;
if (vul) result *= 2;
}
else
{
switch (down)
{
case 1:
result = (!vul)? 100:200;
break;
case 2:
result = (!vul)? 300:500;
break;
case 3:
result = (!vul)? 500:800;
break;
default:
result = 500 + (300*(down-3))
+ ((!vul)? 0:300);
break;
}
if (doubled > 1) result *= 2;
}
return (result);
}
int Duplicate_score_made (vul, level, suit, doubled, made)
int vul, level, suit, doubled, made;
/* Computes the score for the given contract under the rules of
* duplicate scoring.
*/
{
int score;
if (made == 0)
return (0);
score = Chicago_score_made (vul, level, suit, doubled, made);
if (score < 300)
score += 50;
return (score);
}
int Duplicate_score_set (vul, level, suit, doubled, made)
int vul, level, suit, doubled, made;
/* Computes the score for the given contract under the rules of
* duplicate scoring, assuming that it was set.
*/
{
return (Chicago_score_set(vul, level, suit, doubled, made));
}
static int IMP_conversion_table [] = {
20, 50, 90, 130, 170, 220, 270, 320, 370, 430,
500, 600, 750, 900, 1100, 1300, 1500, 1750, 2000, 2250,
2500, 3000, 3500, 4000, 99999};
int IMP_rating (score_diff)
int score_diff;
/* Returns the number of IMPs awarded for the given score difference. */
{
int imps = 0;
if (score_diff < 0)
return (-IMP_rating(-score_diff));
for (imps = 0; IMP_conversion_table[imps] <= score_diff; imps++);
return (imps + imps);
}
static int IMP_score_conversion (pt, highcard_points)
int pt, highcard_points;
/* Computes a 'simulated IMP' score. This score is computed by looking
up the IMP_rating of the pt score of the declaring team, and subtracting
from this the number of highcard points over 20.
*/
{
return (IMP_rating(pt) - (highcard_points - 20));
}
int Simulated_IMP_score_made (vul, level, suit, doubled, made, hcp)
int vul, level, suit, doubled, made, hcp;
/* Computes the simulated IMP score for the given contract assuming that
* it was made.
*/
{
int score;
score =
IMP_score_conversion
(Duplicate_score_made (vul, level, suit, doubled, made), hcp);
return (score);
}
int Simulated_IMP_score_set (vul, level, suit, doubled, made, hcp)
int vul, level, suit, doubled, made, hcp;
/* Computes the simulated IMP score for the given contract assuming that
* it was set.
*/
{
int score;
score =
IMP_score_conversion
(-Duplicate_score_set(vul, level, suit, doubled, made), hcp);
return (score);
}
int MIMP_scoring_vuln [] = {
-2100, -2100, -2100, -2100, -1850, -1650, -1500, -1400, -1100, -950,
-800, -750, -700, -650, -600, -450, -300, -150, -100, -50,
0, 50, 100, 150, 300, 450, 600, 650, 700, 750,
800, 950, 1100, 1400, 1500, 1650, 1850, 2100, 2100, 2100,
2100
};
int MIMP_scoring_nonvuln [] = {
-1500, -1500, -1500, -1500, -1300, -1150, -1050, -950, -800, -700,
-600, -550, -500, -450, -400, -300, -200, -150, -100, -50,
0, 50, 100, 150, 200, 300, 400, 450, 500, 550,
600, 700, 800, 950, 1050, 1150, 1300, 1500, 1500, 1500,
1500
};
int MIMP_score_conversion (score, vulnerable, highcard_points)
int score, vulnerable, highcard_points;
/* This code contributed by David Morrison. */
{
/* If you think the code calculating the score here is magic, you
* are *right*.
*/
if (vulnerable) { score -= MIMP_scoring_vuln[highcard_points]; }
else { score -= MIMP_scoring_nonvuln[highcard_points]; }
/* If I had a good description of the algorithm, and its
* justification, it would go here. For now, you'll just have to
* accept the code.
*/
if ( (score <= 600) && (score >= -600) ) {
score *= 2;
} else {
if (score > 600) {
score += 600;
} else {
score -= 600;
}
}
if (score >= 0)
score = (score + 25) / 50;
else
score = (score - 25) / 50;
return (score);
}
int MIMP_score_made (vul, level, suit, doubled, made, hcp)
int vul, level, suit, doubled, made, hcp;
/* Computes the MIMP score for the given contract assuming that
* it was made.
*
* This code contributed by David Morrison.
*/
{
int score;
score =
MIMP_score_conversion
(Duplicate_score_made (vul, level, suit, doubled, made), vul, hcp);
return (score);
}
int MIMP_score_set (vul, level, suit, doubled, made, hcp)
int vul, level, suit, doubled, made, hcp;
/* Computes the MIMP score for the given contract assuming that
* it was set.
*
* This code contributed by David Morrison.
*/
{
int score;
score =
MIMP_score_conversion
(-Duplicate_score_set(vul, level, suit, doubled, made), vul, hcp);
return (score);
}