#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include "dump.h"
string PrintSuit(const unsigned short suitCode);
string PrintSuit(
const unsigned short suitCode,
const char leastWin);
string PrintDeal(
const unsigned short ranks[][DDS_SUITS],
const int spacing);
string RankToDiagrams(
const unsigned short ranks[DDS_HANDS][DDS_SUITS],
const nodeCardsType& node);
string WinnersToText(const unsigned short winRanks[]);
string NodeToText(const nodeCardsType& node);
string FullNodeToText(const nodeCardsType& node);
string PosToText(
const pos& tpos,
const int target,
const int depth);
string TopMove(
const bool val,
const moveType& bestMove);
string DumpTopHeader(
const ThreadData& thrd,
const int tricks,
const int lower,
const int upper,
const int printMode);
string PrintSuit(const unsigned short suitCode)
{
if (! suitCode)
return "--";
string st;
for (int r = 14; r >= 2; r--)
if ((suitCode & bitMapRank[r]))
st += static_cast<char>(cardRank[r]);
return st;
}
string PrintSuit(
const unsigned short suitCode,
const char leastWin)
{
if (! suitCode)
return "--";
string st;
for (int r = 14; r >= 2; r--)
{
if ((suitCode & bitMapRank[r]))
{
if (r >= 15 - leastWin)
st += static_cast<char>(cardRank[r]);
else
st += "x";
}
}
return st;
}
string PrintDeal(
const unsigned short ranks[][DDS_SUITS],
const int spacing)
{
stringstream ss;
for (int s = 0; s < DDS_SUITS; s++)
{
ss << setw(spacing) << "" <<
cardSuit[s] << " " <<
PrintSuit(ranks[0][s]) << "\n";
}
for (int s = 0; s < DDS_SUITS; s++)
{
ss << cardSuit[s] << " " <<
setw(2*spacing - 2) << left << PrintSuit(ranks[3][s]) <<
cardSuit[s] << " " <<
PrintSuit(ranks[1][s]) << "\n";
}
for (int s = 0; s < DDS_SUITS; s++)
{
ss << setw(spacing) << "" <<
cardSuit[s] << " " <<
PrintSuit(ranks[2][s]) << "\n";
}
return ss.str() + "\n";
}
string RankToDiagrams(
const unsigned short ranks[DDS_HANDS][DDS_SUITS],
const nodeCardsType& node)
{
stringstream ss;
for (int s = 0; s < DDS_SUITS; s++)
{
ss << setw(12) << left <<
(s == 0 ? "Sought" : "") <<
cardSuit[s] << " " << setw(20) << PrintSuit(ranks[0][s]) << "| " <<
setw(12) << (s == 0 ? "Found" : "") <<
cardSuit[s] << " " <<
PrintSuit(ranks[0][s], node.leastWin[s]) << "\n";
}
for (int s = 0; s < DDS_SUITS; s++)
{
ss <<
cardSuit[s] << " " << setw(22) << left << PrintSuit(ranks[3][s]) <<
cardSuit[s] << " " << setw(8) << PrintSuit(ranks[1][s]) << "| " <<
cardSuit[s] << " " <<
setw(22) << PrintSuit(ranks[3][s], node.leastWin[s]) <<
cardSuit[s] << " " <<
PrintSuit(ranks[1][s], node.leastWin[s]) << "\n";
}
for (int s = 0; s < DDS_SUITS; s++)
{
ss << setw(12) << left << "" <<
cardSuit[s] << " " << setw(20) << PrintSuit(ranks[0][s]) << "| " <<
setw(12) << "" << cardSuit[s] << " " <<
PrintSuit(ranks[0][s], node.leastWin[s]) << "\n";
}
return ss.str();
}
string WinnersToText(const unsigned short ourWinRanks[])
{
stringstream ss;
for (int s = 0; s < DDS_SUITS; s++)
ss << cardSuit[s] << " " << PrintSuit(ourWinRanks[s]) << "\n";
return ss.str();
}
string NodeToText(const nodeCardsType& node)
{
stringstream ss;
ss << setw(16) << left << "Address" <<
static_cast<void const *>(&node) << "\n";
ss << setw(16) << left << "Bounds" <<
static_cast<int>(node.lbound) << " to " <<
static_cast<int>(node.ubound) << " tricks\n";
ss << setw(16) << left << "Best move" <<
cardSuit[ static_cast<int>(node.bestMoveSuit) ] <<
cardRank[ static_cast<int>(node.bestMoveRank) ] << "\n";
return ss.str();
}
string FullNodeToText(const nodeCardsType& node)
{
stringstream ss;
vector<int> v(DDS_SUITS);
for (unsigned i = 0; i < DDS_SUITS; i++)
v[i] = 15 - static_cast<int>(node.leastWin[i]);
ss << setw(16) << left << "Lowest used" <<
cardSuit[0] << cardRank[v[0]] << ", " <<
cardSuit[1] << cardRank[v[1]] << ", " <<
cardSuit[2] << cardRank[v[2]] << ", " <<
cardSuit[3] << cardRank[v[3]] << "\n";
return NodeToText(node) + ss.str();
}
string PosToText(
const pos& tpos,
const int target,
const int depth)
{
stringstream ss;
ss << setw(16) << left << "Target" << target << "\n";
ss << setw(16) << "Depth" << depth << "\n";
ss << setw(16) << "tricksMAX" << tpos.tricksMAX << "\n";
ss << setw(16) << "First hand" << cardHand[tpos.first[depth]] << "\n";
ss << setw(16) << "Next first" << cardHand[tpos.first[depth - 1]] << "\n";
return ss.str();
}
string DumpTopHeader(
const ThreadData& thrd,
const int tricks,
const int lower,
const int upper,
const int printMode)
{
string stext;
if (printMode == 0)
{
stext = "Single target " + to_string(tricks) + ", " + "achieved";
}
else if (printMode == 1)
{
stext = "Loop target " + to_string(tricks) + ", " +
"bounds " + to_string(lower) + " .. " + to_string(upper) + ", " +
TopMove(thrd.val, thrd.bestMove[thrd.iniDepth]) + "";
}
else if (printMode == 2)
{
stext = "Loop for cards with score " + to_string(tricks) + ", " +
TopMove(thrd.val, thrd.bestMove[thrd.iniDepth]);
}
return stext + "\n" + string(stext.size(), '-') + "\n";
}
string TopMove(
const bool val,
const moveType& bestMove)
{
if (val)
{
stringstream ss;
ss << "achieved with move " <<
cardSuit[ bestMove.suit ] <<
cardRank[ bestMove.rank ];
return ss.str();
}
else
return "failed";
}
int DumpInput(
const int errCode,
const deal& dl,
const int target,
const int solutions,
const int mode)
{
#ifndef DDS_NO_DUMP_ON_ERROR
ofstream fout;
fout.open("dump.txt");
fout << "Error code=" << errCode << "\n\n";
fout << "Deal data:\n";
fout << "trump=";
if (dl.trump == DDS_NOTRUMP)
fout << "N\n";
else
fout << cardSuit[dl.trump] << "\n";
fout << "first=" << cardHand[dl.first] << "\n";
unsigned short ranks[4][4];
for (int k = 0; k <= 2; k++)
if (dl.currentTrickRank[k] != 0)
{
fout << "index=" << k <<
" currentTrickSuit=" << cardSuit[dl.currentTrickSuit[k]] <<
" currentTrickRank= " << cardRank[dl.currentTrickRank[k]] << "\n";
}
for (int h = 0; h < DDS_HANDS; h++)
for (int s = 0; s < DDS_SUITS; s++)
{
fout << "index1=" << h << " index2=" << s <<
" remainCards=" << dl.remainCards[h][s] << "\n";
ranks[h][s] = static_cast<unsigned short>
(dl.remainCards[h][s] >> 2);
}
fout << "\ntarget=" << target << "\n";
fout << "solutions=" << solutions << "\n";
fout << "mode=" << mode << "\n\n\n";
fout << PrintDeal(ranks, 8);
fout.close();
#endif
return 0;
}
void DumpRetrieved(
ofstream& fout,
const pos& tpos,
const nodeCardsType& node,
const int target,
const int depth)
{
fout << "Retrieved entry\n";
fout << string(15, '-') << "\n";
fout << PosToText(tpos, target, depth) << "\n";
fout << FullNodeToText(node) << "\n";
fout << RankToDiagrams(tpos.rankInSuit, node) << "\n";
}
void DumpStored(
ofstream& fout,
const pos& tpos,
const Moves& moves,
const nodeCardsType& node,
const int target,
const int depth)
{
fout << "Stored entry\n";
fout << string(12, '-') << "\n";
fout << PosToText(tpos, target, depth) << "\n";
fout << NodeToText(node);
fout << moves.TrickToText((depth >> 2) + 1) << "\n";
fout << PrintDeal(tpos.rankInSuit, 16);
}
void DumpTopLevel(
ofstream& fout,
const ThreadData& thrd,
const int tricks,
const int lower,
const int upper,
const int printMode)
{
const pos& tpos = thrd.lookAheadPos;
fout << DumpTopHeader(thrd, tricks, lower, upper, printMode) << "\n";
fout << PrintDeal(tpos.rankInSuit, 16);
fout << WinnersToText(tpos.winRanks[thrd.iniDepth]) << "\n";
fout << thrd.nodes << " AB nodes, " <<
thrd.trickNodes << " trick nodes\n\n";
}