TestScoring.java package com.aza.bridge_scoring; public class TestScoring { BridgeScoring scoring; ImpTable itable = new ImpTable(); public TestScoring() { scoring = new BridgeScoring(); int cp1 = scoring.contract_points(BridgeScoring.CLUB, 3, false, false); int cp2 = scoring.contract_points(BridgeScoring.NT, 3, false, true); System.out.println("cp1: " + cp1); System.out.println("cp2: " + cp2); int op2 = scoring.overtrick_points(BridgeScoring.NT, 3, true, false, true); System.out.println("cp2: " + op2); test_4H(); test_3NT(); test_1H(); } public void test_4D() { int contract = 16; // 4D int tricks = 10; boolean doubled = false; boolean redoubled = false; boolean vuln = false; int points = scoring.calc_points(contract, tricks, doubled, redoubled, vuln); System.out.println("PIONTS: " + points); } public void test_4H() { int contract = 17; // 4H int tricks = 10; boolean doubled = false; boolean redoubled = false; boolean vuln = true; int points = scoring.calc_points(contract, tricks, doubled, redoubled, vuln); System.out.println("PIONTS: " + points); System.out.println("IMPS: " + itable.getImps(points)); } public void test_3NT() { int contract = 14; // 3NT int tricks = 10; boolean doubled = true; boolean redoubled = false; boolean vuln = true; int points = scoring.calc_points(contract, tricks, doubled, redoubled, vuln); System.out.println("PIONTS: " + points); System.out.println("IMPS: " + itable.getImps(points)); } public void test_1H() { int cl = 1; int csuit = BridgeScoring.HEART; int tricks = 9; boolean doubled = false; boolean redoubled = false; boolean vuln = false; int points = scoring.calc_points(cl, csuit, tricks, doubled, redoubled, vuln); System.out.println("PIONTS: " + points); System.out.println("IMPS: " + itable.getImps(points)); } public static void main(String[] args) { new TestScoring(); } } BridgeScoring.java package com.aza.bridge_scoring; public class BridgeScoring { // http://en.wikipedia.org/wiki/Bridge_scoring public static final int CLUB = 0; public static final int DIAM = 1; public static final int HEART = 2; public static final int SPADE = 3; public static final int NT = 4; // contract points public static final int CP_CLUB = 20; public static final int CP_DIAM = 20; public static final int CP_HEART = 30; public static final int CP_SPADE = 30; public static final int CP_NT = 30; public static final int FCP_NT = 40; // When a doubled or redoubled contract is made, a bonus is awarded to the declaring side. public static final int DOUBLE_BONUS = 50; public static final int REDOUBLE_BONUS = 100; public static final int PART_SCORE_BONUS = 50; public static final int GAME_BONUS_NOT_VULN = 300; public static final int GAME_BONUS_VULN = 500; public static final int SMALL_SLAM_BONUS_NOT_VULN = 500; public static final int SMALL_SLAM_BONUS_VULN = 750; public static final int GRAND_SLAM_BONUS_NOT_VULN = 1000; public static final int GRAND_SLAM_BONUS_VULN = 1500; // dealer N - NONE, E - NS, S - EW, W - BOTH // bids from 0 to 7x5 = 34 // c=0, d=1, h=2, s=3, nt=4 private static int getBidSuit(int bid) { return bid % 5; } private static int getBidLevel(int bid) { return bid / 5; } public BridgeScoring() { } // level 1..7 private int contract_points(int contract_suit, int level, boolean doubled, boolean redoubled) { int m = 1; if (doubled) m = 2; if (redoubled) m = 4; int cp = 0; switch (contract_suit) { case CLUB: cp = level * 20 * m; break; case DIAM: cp = level * 20 * m; break; case HEART: cp = level * 30 * m; break; case SPADE: cp = level * 30 * m; break; case NT: cp = 40 * m + (level - 1) * 30 * m; break; default: break; } return cp; } private int overtrick_points(int contract_suit, int n_overtricks, boolean doubled, boolean redoubled, boolean vuln) { int op = 0; int m = 1; if (doubled) m = 2; if (redoubled) m = 4; if(m > 1) // doubled or redoubled { if (vuln) op = n_overtricks * 100 * m; else op = n_overtricks * 50 * m; } else { if (contract_suit == CLUB || contract_suit == DIAM) op = 20 * n_overtricks; if (contract_suit == HEART || contract_suit == SPADE || contract_suit == NT) op = 30 * n_overtricks; } return op; } public int penalty_points(int n_undertricks, boolean doubled, boolean redoubled, boolean vuln) { int p = 0; int m = 1; if (doubled) m = 2; if (redoubled) m = 4; if (vuln) { //p = n_undertricks * m; if (n_undertricks >= 1) { p = 100 * m + (n_undertricks - 1) * 150 * m; } } else { if (m == 1) { p = 50 * n_undertricks; } else { int t1 = 0; int t2 = 0; int t3 = 0; int t4_and_up = 0; if (n_undertricks >= 1) t1 = 50 * m; if (n_undertricks >= 2) t2 = t1 * 2; if (n_undertricks >= 3) t3 = t1 * 2; if (n_undertricks >= 4) t4_and_up = (n_undertricks - 3) * t1 * 3; p = t1 + t2 + t3 + t4_and_up; } } return p; } public int calc_points(int contract, int tricks, boolean doubled, boolean redoubled, boolean vuln) { int c_suit = getBidSuit(contract); int c_level = contract / 5 + 1; return calc_points(c_level, c_suit, tricks, doubled, redoubled, vuln); } public int made_bonus(int contract_level, int contract_suit, boolean vuln) { int points = 0; int game_bonus = GAME_BONUS_NOT_VULN; if (vuln) game_bonus = GAME_BONUS_VULN; if ((contract_suit == CLUB || contract_suit == DIAM) && contract_level >= 5) points = game_bonus; else if ((contract_suit == HEART || contract_suit == SPADE) && contract_level >= 4) points = game_bonus; else if ((contract_suit == NT) && contract_level >= 3) points = game_bonus; else points = PART_SCORE_BONUS; return points; } public int calc_points(int contract_level, int contract_suit, int tricks, boolean doubled, boolean redoubled, boolean vuln) { //boolean made = tricks >= c_level + 6; int n_overtricks = tricks - (contract_level + 6); boolean made = n_overtricks >= 0; int points = 0; if (made) { int cp = contract_points(contract_suit, contract_level, doubled, redoubled); int op = overtrick_points(contract_suit, n_overtricks, doubled, redoubled, vuln); if (redoubled) points += REDOUBLE_BONUS; else if (doubled) points += DOUBLE_BONUS; if (contract_level == 7 && !vuln) points += GRAND_SLAM_BONUS_NOT_VULN; if (contract_level == 7 && vuln) points += GRAND_SLAM_BONUS_VULN; if (contract_level == 6 && !vuln) points += SMALL_SLAM_BONUS_NOT_VULN; if (contract_level == 6 && vuln) points += SMALL_SLAM_BONUS_VULN; int mb = made_bonus(contract_level, contract_suit, vuln); points += cp + op + mb; } else { int n_undertricks = -n_overtricks; points = - penalty_points(n_undertricks, doubled, redoubled, vuln); } return points; } } ImpTable.java package com.aza.bridge_scoring; import java.util.ArrayList; import java.util.List; public class ImpTable { public List table; public ImpTable() { table = new ArrayList(); add_entry(0, 10, 0); add_entry(20, 40, 1); add_entry(50, 80, 2); add_entry(90, 120, 3); add_entry(130, 160, 4); add_entry(170, 210, 5); add_entry(220, 260, 6); add_entry(270, 310, 7); add_entry(320, 360, 8); add_entry(370, 420, 9); add_entry(430, 490, 10); add_entry(500, 590, 11); add_entry(600, 740, 12); add_entry(750, 890, 13); add_entry(900, 1090, 14); add_entry(1100, 1290, 15); add_entry(1300, 1490, 16); add_entry(1500, 1740, 17); add_entry(1750, 1990, 18); add_entry(2000, 2240, 19); add_entry(2250, 2490, 20); add_entry(2500, 2990, 21); add_entry(3000, 3490, 22); add_entry(3500, 3990, 23); add_entry(4000, Integer.MAX_VALUE, 24); } public int getImps(int score) { int s = Math.abs(score); int imps = 0; for (int i = 0; i < table.size(); i++) { TableEntry te = table.get(i); if (s >= te.from && s <= te.to) { imps = te.imps; break; } } if (score < 0) imps = -imps; return imps; } private void add_entry(int from, int to, int imps) { TableEntry te = new TableEntry(from, to, imps); table.add(te); } static class TableEntry { public int from; public int to; public int imps; public TableEntry(int from, int to, int imps) { this.from = from; this.to = to; this.imps = imps; } } }