Skip to content

Commit

Permalink
Implemented check final contract
Browse files Browse the repository at this point in the history
  • Loading branch information
ThorvaldAagaard committed Jun 3, 2024
1 parent a77507d commit 87612d3
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 14 deletions.
75 changes: 65 additions & 10 deletions src/bots.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from objects import BidResp, CandidateBid, Card, CardResp, CandidateCard
from bidding import bidding
from collections import defaultdict

import carding
from util import hand_to_str, expected_tricks_sd, p_defeat_contract, follow_suit, calculate_seed, get_play_status
Expand Down Expand Up @@ -243,17 +244,71 @@ def bid(self, auction):

#print("self.models.check_final_contract", self.models.check_final_contract)
#print("candidates[0].bid", candidates[0].bid)
if self.models.check_final_contract:
if candidates[0].bid == "PASS" and len(samples) > 0:
if len(auction) > 4 and self.models.check_final_contract and (passout or auction[-2] != "PASS"):
# We will avoid rescuing if we have a score of 500 or more
if candidates[0].bid == "PASS" and len(samples) > 0 and candidates[0].expected_score < 500:
# We need to find a sample or two from the bidding
print(samples[0].split(" ")[0])
X = self.get_binary_contract(self.seat, self.vuln, self.hand_str, samples[0].split(" ")[0])
contract_id, doubled, tricks = self.models.contract_model.model[0](X)
contract = bidding.ID2BID[contract_id] + ("X" if doubled else "")
result = {"contract": contract,
"tricks": tricks}
print(result)

alternatives = {}
current_contract = bidding.get_contract(auction)[0:2]
if self.verbose:
print("current_contract", current_contract)
for i in range(len(samples)):
if self.verbose:
print(samples[i].split(" ")[(self.seat + 2) % 4])
X = self.get_binary_contract(self.seat, self.vuln, self.hand_str, samples[i].split(" ")[(self.seat + 2) % 4])
contract_id, doubled, tricks = self.models.contract_model.model[0](X)
contract = bidding.ID2BID[contract_id] + ("X" if doubled else "")
if current_contract == contract:
if self.verbose:
print("Contract bid, stopping rescue")
break

# if the contract is in candidates we assume previous calculations are right and we stop
for c in candidates:
if c.bid == contract:
if self.verbose:
print("Contract found in candidates, stopping rescue")
break
# Skip invalid bids
if bidding.can_bid(contract, auction):
result = {"contract": contract, "tricks": tricks}
score = scoring.score(contract, self.vuln, tricks)
if self.verbose:
print(result, score)
if contract not in alternatives:
alternatives[contract] = []
alternatives[contract].append({"score": score, "tricks": tricks})

if len(alternatives) > 0:
# Initialize dictionaries to store counts and total scores
contract_counts = defaultdict(int)
contract_total_scores = defaultdict(int)

# Iterate through the alternatives dictionary to populate counts and total scores
for contract, entries in alternatives.items():
for entry in entries:
score = entry["score"]

contract_counts[contract] += 1
contract_total_scores[contract] += score

# Calculate the average scores
contract_average_scores = {contract: contract_total_scores[contract] / contract_counts[contract]
for contract in contract_counts}

# Print the results
if self.verbose:
print("Contract Counts:", dict(contract_counts))
print("Contract Average Scores:", contract_average_scores)
# Find the contract with the highest count
max_count_contract = max(contract_counts, key=contract_counts.get)
# Unless we gain 300 we will not override BEN
if contract_average_scores[max_count_contract] > candidates[0].expected_score + 250:
candidatebid = CandidateBid(bid=max_count_contract, insta_score=-1,
expected_score=contract_average_scores[max_count_contract], adjust=0)
candidates.insert(0, candidatebid)
who = "Rescue"
print(f"Rescuing {current_contract} {max_count_contract}")
# We return the bid with the highest expected score or highest adjusted score

return BidResp(bid=candidates[0].bid, candidates=candidates, samples=samples[:self.sample_hands_for_review], shape=p_shp, hcp=p_hcp, who=who, quality=good_quality)
Expand Down
4 changes: 2 additions & 2 deletions src/config/default_api.conf
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use_biddingquality = True
# Upvote the samples that matches the bidding best
use_probability = False
# Before the final pass validate the contract with a neural network
check_final_contract = False
check_final_contract = True

[adjustments]
# Are adjustments enabled
Expand Down Expand Up @@ -172,4 +172,4 @@ sample_hands_opening_lead = 200
# Max number of samples to include when reviewing a board
sample_hands_for_review = 20
# If probability for a bid is below this, then drop the sample
exclude_samples = 0.001
exclude_samples = 0.07
1 change: 1 addition & 0 deletions src/frontend/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ <h1>Enter Board information</h1>
if (tokenKey && !tokens[0].startsWith("[")) {
if (tokenKey === 'Auction') {
line = line.replace(/Pass/g,"P").trim()
line = line.replace(/PASS/g,"P").trim()
line = line.replace(/NT/g,"N")
line = line.replace(/ =\d+=/, '');
line = line.replace(/\s/g,"-")
Expand Down
11 changes: 9 additions & 2 deletions src/sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def sample_cards_auction(self, auction, nesw_i, hand_str, vuln, n_samples, rng,
n_samples = lho_pard_rho.shape[0]

if self.verbose:
print(f"n_samples {n_samples} matching bidding info")
print(f"n_samples {n_samples} from bidding info")
print("n_steps", n_steps)
if (models.model_version == 0 or models.ns == -1):
index = 0
Expand Down Expand Up @@ -321,11 +321,18 @@ def sample_cards_auction(self, auction, nesw_i, hand_str, vuln, n_samples, rng,
for i in range(n_steps):
if lho_actual_bids[i] not in (bidding.BID2ID['PAD_START'], bidding.BID2ID['PAD_END']):
min_scores_lho = np.minimum(min_scores_lho, lho_sample_bids[:, i, lho_actual_bids[i]])
#print(lho_actual_bids[i])
if (lho_actual_bids[i] == 31):
for j in range(n_samples):
if (lho_sample_bids[j, i, lho_actual_bids[i]] >0.3):
print(hand_to_str(lho_pard_rho[j, 0:1, :]))
print(lho_sample_bids[j, i, lho_actual_bids[i]])

if pard_actual_bids[i] not in (bidding.BID2ID['PAD_START'], bidding.BID2ID['PAD_END']):
min_scores_partner = np.minimum(min_scores_partner, pard_sample_bids[:, i, pard_actual_bids[i]])
if rho_actual_bids[i] not in (bidding.BID2ID['PAD_START'], bidding.BID2ID['PAD_END']):
min_scores_rho = np.minimum(min_scores_rho, rho_sample_bids[:, i, rho_actual_bids[i]])

if self.use_distance:
# Initialize an array to store distances
distances = np.zeros(n_samples)
Expand Down

0 comments on commit 87612d3

Please sign in to comment.