<commit_before>/* 
   SDS, a bridge single-suit double-dummy quick-trick solver.

   Copyright (C) 2015-16 by <NAME>.

   See LICENSE and README.
*/

#include <iomanip>
#include <assert.h>

#include "Trick.h"
#include "Header.h"
#include "DefList.h"
#include "MoveList.h"
#include "SimpleMoves.h"
#include "ComplexMoves.h"
#include "Twiddle.h"
#include "Dist.h"
#include "LoopHold.h"
#include "hist.h"
#include "single.h"
#include "const.h"

using namespace std;


extern SingleType * singles[14];
extern MoveList moveList;
extern vector<unsigned> holdCtr;


void MakeSimpleMoves()
{
  DefList def;
  LoopHold holding;
  for (unsigned sl = 1; sl <= 13; sl++)
  {
    cout << "\nSimple moves: " << sl << "\n";

    for (unsigned c = 0; c < SDS_NUM_SINGLES[sl]; c++)
    {
      if ((c & 0x3ffff) == 0)
      {
        cout << "Count " <<
          setw(8) << c << " (" <<
          setw(5) << fixed << setprecision(2) <<
            100. * c / SDS_NUM_SINGLES[sl] << "%)" << endl;
      }

      if (singles[sl][c].moveNo == 0)
      {
        holding.Set(sl, c);
        MakeSimpleSingleMove(sl, c, def, holding);
      }
    }
  }
}


inline bool MakeSimpleSingleMove(
  const unsigned sl,
  const unsigned c,
  DefList& def,
  LoopHold& holding)
{
  unsigned lenAce = holding.GetLength(QT_ACE);
  unsigned lenPard = holding.GetLength(QT_PARD);
  bool newFlag;

  if (lenAce == holding.GetNumTops())
  {
    unsigned r;

    if (lenPard > lenAce && holding.CashoutAceSideBlocked(def, r))
    {
      // Aceholder has blocking tops: AK / Qx / JT9 / xx.
      // Partner can cash afterwards.

      unsigned mno = moveList.AddMove(def, holding, newFlag);
      SetAllPermutations(sl, c, mno, holding, r, HIST_BLOCKED, newFlag);
    }
    else
    {
      // Aceholder has blocking tops: AK / Qxx / JT9 / xx.
      // Partner cannot cash afterwards.

      holding.CashAceShort(def, r);
      unsigned mno = moveList.AddMove(def, holding, newFlag);
      SetAllPermutations(sl, c, mno, holding, r, HIST_ACE_SHORT, newFlag);
    }
  }

  if (singles[sl][c].minLen == 0)
  {
    unsigned r;

    if (singles[sl][c].moveNo == 0)
    {
      // Partner is void.  Cash maximum from aceholder.

      holding.CashoutAce(def, r);
      unsigned mno = moveList.AddMove(def, holding, newFlag);
      SetAllPermutations(sl, c, mno, holding, r, HIST_PARD_VOID, newFlag);
    }

    // Can also make some crash positions out of this, e.g. AQ / K.

    PosType start, end;
    unsigned brank, rrank, crank, crank2, btricks, rtricks, ctricks;
    unsigned numTops = holding.GetNumTops();

    for (unsigned nMask = 1; nMask < (1u << numTops)-1u; nMask++)
    {<commit_msg>Off-by-1<commit_after>/* 
   SDS, a bridge single-suit double-dummy quick-trick solver.

   Copyright (C) 2015-16 by <NAME>.

   See LICENSE and README.
*/

#include <iomanip>
#include <assert.h>

#include "Trick.h"
#include "Header.h"
#include "DefList.h"
#include "MoveList.h"
#include "SimpleMoves.h"
#include "ComplexMoves.h"
#include "Twiddle.h"
#include "Dist.h"
#include "LoopHold.h"
#include "hist.h"
#include "single.h"
#include "const.h"

using namespace std;


extern SingleType * singles[14];
extern MoveList moveList;
extern vector<unsigned> holdCtr;


void MakeSimpleMoves()
{
  DefList def;
  LoopHold holding;
  for (unsigned sl = 1; sl <= 13; sl++)
  {
    cout << "\nSimple moves: " << sl << "\n";

    for (unsigned c = 0; c < SDS_NUM_SINGLES[sl]; c++)
    {
      if ((c & 0x3ffff) == 0)
      {
        cout << "Count " <<
          setw(8) << c << " (" <<
          setw(5) << fixed << setprecision(2) <<
            100. * c / SDS_NUM_SINGLES[sl] << "%)" << endl;
      }

      if (singles[sl][c].moveNo == 0)
      {
        holding.Set(sl, c);
        MakeSimpleSingleMove(sl, c, def, holding);
      }
    }
  }
}


inline bool MakeSimpleSingleMove(
  const unsigned sl,
  const unsigned c,
  DefList& def,
  LoopHold& holding)
{
  unsigned lenAce = holding.GetLength(QT_ACE);
  unsigned lenPard = holding.GetLength(QT_PARD);
  bool newFlag;

  if (lenAce == holding.GetNumTops())
  {
    unsigned r;

    if (lenPard > lenAce && holding.CashoutAceSideBlocked(def, r))
    {
      // Aceholder has blocking tops: AK / Qx / JT9 / xx.
      // Partner can cash afterwards.

      unsigned mno = moveList.AddMove(def, holding, newFlag);
      SetAllPermutations(sl, c, mno, holding, r, HIST_BLOCKED, newFlag);
    }
    else
    {
      // Aceholder has blocking tops: AK / Qxx / JT9 / xx.
      // Partner cannot cash afterwards.

      holding.CashAceShort(def, r);
      unsigned mno = moveList.AddMove(def, holding, newFlag);
      SetAllPermutations(sl, c, mno, holding, r, HIST_ACE_SHORT, newFlag);
    }
  }

  if (singles[sl][c].minLen == 0)
  {
    unsigned r;

    if (singles[sl][c].moveNo == 0)
    {
      // Partner is void.  Cash maximum from aceholder.

      holding.CashoutAce(def, r);
      unsigned mno = moveList.AddMove(def, holding, newFlag);
      SetAllPermutations(sl, c, mno, holding, r, HIST_PARD_VOID, newFlag);
    }

    // Can also make some crash positions out of this, e.g. AQ / K.

    PosType start, end;
    unsigned brank, rrank, crank, crank2, btricks, rtricks, ctricks;
    unsigned numTops = holding.GetNumTops();

    for (unsigned nMask = 1; nMask < (1u << numTops); nMask++)
    {
{'fraction_non_alphanumeric': 0.1430995475113122, 'fraction_numerical': 0.011312217194570135, 'mean_word_length': 2.689151599443672, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4697145', 'n_tokens_mistral': 2030, 'n_tokens_neox': 1903, 'n_words': 504}