Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions BiddingLogic/BidManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ public static void SetOptimizationParameters(string json)
public ConstructedSouthhandOutcome constructedSouthhandOutcome = ConstructedSouthhandOutcome.NotSet;

public BiddingState BiddingState { get; set; }
private bool CanSkipControlScanningFase { get; set; } = true;
public bool HasSkippedControlScanningFase { get; private set; } = false;

// Constructor used for test
public BidManager(IBidGenerator bidGenerator, Dictionary<Fase, bool> fasesWithOffset, ReverseDictionaries reverseDictionaries, RelayBidKindFunc getRelayBidKindFunc) :
Expand Down Expand Up @@ -243,6 +245,10 @@ private Bid GetNorthBid(BiddingState biddingState, Auction auction, string north
if (useSingleDummySolverDuringRelaying)
if (TryGetEndContract(southInformation, out var bid))
return bid;
if (CanSkipControlScanningFase)
if (TryGetAskQueensBid(southInformation, out var askQueensbid))
return askQueensbid;

}
}

Expand Down Expand Up @@ -326,7 +332,7 @@ bool TryGetEndContract(SouthInformation southInformation, out Bid bid)
bid = GetEndContract(possibleContracts, biddingState.CurrentBid);
if (bid != null)
{
if (biddingState.Fase == Fase.ScanningOther)
if (biddingState.Fase == Fase.ScanningOther && southInformation.SpecificControls != null)
constructedSouthhandOutcome = southInformation.SpecificControls.Count() == 1 ?
ConstructedSouthhandOutcome.SouthhandMatches : ConstructedSouthhandOutcome.MultipleMatchesFound;
biddingState.Fase = Fase.End;
Expand All @@ -338,6 +344,22 @@ bool TryGetEndContract(SouthInformation southInformation, out Bid bid)
return bid != null;
}

bool TryGetAskQueensBid(SouthInformation southInformation, out Bid askQueensbid)
{
askQueensbid = null;
if (southInformation.SpecificControls != null && southInformation.Controls.Min >= 6 && biddingState.Fase == Fase.ScanningControls)
{
askQueensbid = Bid.NextBid(Bid.NextBid(biddingState.CurrentBid));
biddingState.Fase = Fase.ScanningOther;
biddingState.RelayBidIdLastFase++;
loggerBidding.Info("Special ask for queens because controls >= 6 and controls scanning is known");
HasSkippedControlScanningFase = true;
return true;
}
return false;
}


Bid GetRelayBid()
{
if (biddingState.CurrentBid == Bid.threeSpadeBid && biddingState.Fase != Fase.Shape && reverseDictionaries != null)
Expand Down Expand Up @@ -469,11 +491,11 @@ public void SouthBid(Auction auction, string handsString)
var lzoomOffset = nextfase switch
{
Fase.Controls => reverseDictionaries == null ? zoomOffset : biddingInformation.Shape.Value.zoomOffset,
Fase.ScanningOther => reverseDictionaries == null ? zoomOffset : biddingInformation.ControlsScanning.Value.zoomOffset,
Fase.ScanningOther => reverseDictionaries == null ? zoomOffset : HasSkippedControlScanningFase ? 0 : biddingInformation.ControlsScanning.Value.zoomOffset,
_ => 0,
};
// Check if controls and their positions are correctly evaluated.
if (nextfase == Fase.ScanningOther && reverseDictionaries != null)
if (nextfase == Fase.ScanningOther && reverseDictionaries != null && !HasSkippedControlScanningFase)
{
var controlsInSuit = Util.GetHandWithOnlyControlsAs4333(handsString, "AK");
if (!biddingInformation.ControlsScanning.Value.controls.Contains(controlsInSuit))
Expand Down
18 changes: 10 additions & 8 deletions BiddingLogic/BiddingInformation.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -52,7 +53,7 @@ public SouthInformation GetInformationFromAuction(Auction auction, string northH
var possibleControls = reverseDictionaries.ControlsOnlyAuctions[string.Join("", controls)];
southInformation.Controls = new MinMax(possibleControls.First(), possibleControls.Last());
// Special case if relayer is able figure out the position of controls
if (southInformation.ControlsScanningBidCount == 0)
if (southInformation.ControlsScanningBidCount == 0 && possibleControls.Distinct().Count() == 1)
{
var matches = GetMatchesWithNorthHand(Shape.Value.shapes, possibleControls.First(), northHand);
if (matches.Count() == 1)
Expand All @@ -68,9 +69,10 @@ public SouthInformation GetInformationFromAuction(Auction auction, string northH
throw new InvalidOperationException($"No matches found. NorthHand:{northHand}");

southInformation.SpecificControls = matches.Select(match => match.Split(',').Select(x => Regex.Replace(x, "[^AK]", "")).ToArray());
southInformation.Queens = GetQueensFromAuction(auction, reverseDictionaries, biddingState);
}

southInformation.Queens = GetQueensFromAuction(auction, reverseDictionaries, biddingState);

loggerBidding.Info($"SouthInformation. {JsonConvert.SerializeObject(southInformation)}");
return southInformation;
}
Expand Down Expand Up @@ -147,15 +149,15 @@ int GetOffsetRelayBid(Bid currentBid)
public string GetQueensFromAuction(Auction auction, ReverseDictionaries reverseDictionaries, BiddingState biddingState)
{
// Because the last shape is the one with the highest numeric value generated in ReverseDictionaries
var shapeStr = Shape.Value.shapes.Last();
var zoomOffset = ControlsScanning.Value.zoomOffset;
var lastBidScanningControl = biddingState.GetBids(Fase.ScanningControls).Last();
var queensBids = biddingState.GetBids(Fase.ScanningOther);
if (!queensBids.Any())
return null;
var shapeStr = Shape.Value.shapes.Last();
var zoomOffset = ControlsScanning.IsValueCreated ? ControlsScanning.Value.zoomOffset : 0;
var lastBidPreviousFase = auction.GetBids(Player.South).ToList().TakeWhile(bid => bid != queensBids.First()).Last();
var offsetBid = ReverseDictionaries.GetOffsetBidForQueens(shapeStr);

var queensBidsResult = GetBidsForFaseWithOffset(queensBids, offsetBid, lastBidScanningControl, zoomOffset, GetOffsetRelayBid);
if (!queensBidsResult.Any())
return null;
var queensBidsResult = GetBidsForFaseWithOffset(queensBids, offsetBid, lastBidPreviousFase, zoomOffset, GetOffsetRelayBid).ToList();
var queensAuctions = reverseDictionaries.GetQueensDictionary(shapeStr);
var bidsForFaseQueens = string.Join("", queensBidsResult);

Expand Down
44 changes: 44 additions & 0 deletions TosrIntegration.Test/DirectlyAskForQueensTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using BiddingLogic;
using Common.Test;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace TosrIntegration.Test
{
[Collection("Sequential")]

public class DirectlyAskForQueensTest : IClassFixture<BaseTestFixture>
{
private BaseTestFixture Fixture { get; }
private static readonly Logger logger = LogManager.GetCurrentClassLogger();


public DirectlyAskForQueensTest(BaseTestFixture fixture)
{
Fixture = fixture;
}

public static IEnumerable<object[]> TestCases()
{
yield return new object[] { "OneMatchFound", "AK85,K,AQ42,QJT2", "QT642,AJ54,K7,AK", "1♣1♠2♣3♦4♥5♣5♥Pass", "1♥1NT3♣4♣4NT5♦5♠" };
yield return new object[] { "MultipleMatchesFound", "KQJT43,AQ,KJ,KQJ", "A6,8752,AQ83,A64", "1♣1NT2♥3♣4♣4♥5♥6♣Pass", "1♠2♦2NT3NT4♦5♦5NT6♦" };
yield return new object[] { "OneMatchFoundPull4Di", "T3,AK532,Q2,AK85", "AKQ954,,AKJ4,Q62", "1♣1♠2♦3♣4♦5♠6♦Pass", "1♥2♣2NT3♠5♦6♣6♠" };
yield return new object[] { "MultipleMatchesFoundPull4Di", "J86,KT,AQT95,AQT", "AQ7,AJ98654,K,K4", "1♣2♣3♣4♦5♥6♥Pass", "1NT2NT3NT5♦6♦6NT" };
}

[Theory]
[MemberData(nameof(TestCases))]
public void TestAuctionsQueens(string testName, string northHand, string southHand, string expectedBidsNorth, string expectedBidsSouth)
{
SetupTest.setupTest(testName, logger);
var bidManager = new BidManager(new BidGenerator(), Fixture.fasesWithOffset, Fixture.reverseDictionaries, false);
var auction = bidManager.GetAuction(northHand, southHand);
AssertMethods.AssertAuction(expectedBidsNorth, expectedBidsSouth, auction);
}
}
}
2 changes: 1 addition & 1 deletion Wpf.Tosr/BatchBidding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ private void AddHandAndAuction(string[] board, Auction auction, int boardNumber,
AddHandPerAuction(str, strAuction);

// Start calculating hand
if (!auction.responderHasSignedOff)
if (!auction.responderHasSignedOff && !bidManager.HasSkippedControlScanningFase)
expectedSouthHands.AppendLine($"Board:{boardNumber} { bidManager.ConstructSouthHandSafe(board, auction)}");

var longestSuit = Util.GetLongestSuit(board[(int)Player.North], board[(int)Player.South]);
Expand Down
2 changes: 1 addition & 1 deletion Wpf.Tosr/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,6 @@ private async void ButtonBatchBiddingClick(object sender, EventArgs e)
{
resetEvent.WaitOne();
panelNorth.Visibility = Visibility.Hidden;
var batchBidding = new BatchBidding(reverseDictionaries, fasesWithOffset, toolStripMenuItemUseSolver.IsChecked);
toolStripStatusLabel1.Content = "Batch bidding hands...";
cancelBatchbidding.Dispose();
cancelBatchbidding = new CancellationTokenSource();
Expand All @@ -287,6 +286,7 @@ private async void ButtonBatchBiddingClick(object sender, EventArgs e)
try
{
Cursor = Cursors.Wait;
var batchBidding = new BatchBidding(reverseDictionaries, fasesWithOffset, toolStripMenuItemUseSolver.IsChecked);
await Task.Run(() =>
{
var progress = new Progress<int>(report => Dispatcher.Invoke(() => toolStripStatusLabel1.Content = $"Hands done: {report}"));
Expand Down