Texas holdem straight check values - c++

I'm have a small issue with evaluating a straight in a seven card hand, where you want to get the highest 5 card straight.
I can get highest 5 card straight as long as there is not a pair in the hand so for example:
Hole cards: 2h,3d
community cards:4h, 5s, 6s, 8d, 9d,
Output: 2h,3d,4h,5s,6s
Because there is no pair within the straight it counts and outputs just fine.
The problem occurs when there is a pair within the straight
for example:
Hole cards: 2h, 3d,
community cards: 4h, 4c, 5s, 6s, 8d
Output: 2h,3d,4h,4c,5s
So it is counting the pair in the straight, I need a way to skip past one of the paired cards and select only one. This happens with 3 of a kind as well.
It makes complete sense to me why it is doing this, but for the life of me I can't think of a way to fix it.
Here is the function:
bool Player::checkForStraight()
{
//Loops through the ranks from greatest to least 0 is NONE is the enum class
for (int i = FACES; i >= 1; i--)
{
//Checks to see if a straight exists (_checkNumfaces is an array[13] to
//hold the amount of each card
if ((_checkNumFaces[i - 1] >= 1) && (_checkNumFaces[i - 2] >= 1) &&
(_checkNumFaces[i - 3] >= 1) && (_checkNumFaces[i - 4] >= 1) &&
(_checkNumFaces[i - 5] >= 1))
{
//If a straight exists loop through the cards(sorted in another
//function from lowest to highest
for (int j = 6; j >= 0; j--)
{
//if the face matches the enum value of i then we have a
//straight there down because I checked if the straight
//existed already
if ((*p_playerHand[j])->face == (Face)(i))
{
//PlayerHighCards out of the seven
p_playerHighFive[4] = p_playerHand[j];
p_playerHighFive[3] = p_playerHand[j - 1];
p_playerHighFive[2] = p_playerHand[j - 2];
p_playerHighFive[1] = p_playerHand[j - 3];
p_playerHighFive[0] = p_playerHand[j - 4];
return true;
}
}
}
}
return false;
}
Sorry about the shoddy formatting at the bottom but its only curly braces and they are fine in my code.
I know how to check for A,2,3,4,5 straight I just havnt coded yet, I am just really stumped on how to move past one of the pairs that I was on about. Its not just pairs, this occurs with 3 of a kind as well (so if there's 3 of a kind in the straight) or more than one pair for that matter so 2 pairs. Doesn't happen outside of this because there's not physically enough cards to be concerned about it.
Sorry if my code is not that elegant and if there's a better way then let me know. I havnt learned templates or the stl yet as I have only just started the language so a solution not using these would be great.
I tried to be as descriptive as possible but, I'm new to this so if you have any questions just ask:)
Here is the function for counting the different cards in the deck
void Player::countNumFaces(const int& size)
{
for (int i = 0; i < (size); i++)
{
switch((*p_playerHand[i])->face)
{
case Face::NONE: std::cout << "Joker" << std::endl;
case Face::TWO: _checkNumFaces[0] ++; break;
case Face::THREE: _checkNumFaces[1] ++; break;
case Face::FOUR: _checkNumFaces[2] ++; break;
case Face::FIVE: _checkNumFaces[3] ++; break;
case Face::SIX: _checkNumFaces[4] ++; break;
case Face::SEVEN: _checkNumFaces[5] ++; break;
case Face::EIGHT: _checkNumFaces[6] ++; break;
case Face::NINE: _checkNumFaces[7] ++; break;
case Face::TEN: _checkNumFaces[8] ++; break;
case Face::JACK: _checkNumFaces[9] ++; break;
case Face::QUEEN: _checkNumFaces[10] ++; break;
case Face::KING: _checkNumFaces[11] ++; break;
case Face::ACE: _checkNumFaces[12] ++; break;
}
}
std::cout << "| 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 | 10 || J || Q || K || A |" << std::endl; //Print for testing
for (int i = 0; i < FACES; i++) { std::cout << "| " << _checkNumFaces[i] << " |"; } //Print for testing
}

Instead of
p_playerHighFive[4] = p_playerHand[j];
p_playerHighFive[3] = p_playerHand[j - 1];
p_playerHighFive[2] = p_playerHand[j - 2];
p_playerHighFive[1] = p_playerHand[j - 3];
p_playerHighFive[0] = p_playerHand[j - 4];
return true;
try
int k = 4;
int l = 0;
p_playerHighFive[k] = p_playerHand[j-l];
k--;
l++;
while(k>=0)
{
if( isSameValue(p_playerHighFive[k+1], p_playerHand[j-l]) ) //check if card has same value
{
l++;
continue;
}
p_playerHighFive[k] = p_playerHand[j-l];
k--;
l++;
}

Related

While Loop in For Loop

I'm trying to count the cats and dogs in a string. So,
for example:
if the string is "cc+dd-cd",:
I want to count 2 positive cats, 2 positive dogs, 1 negative cat, 1 negative dog (yes I know this is a weird way to count, but it's part of my assignment).
I thought about doing a for loop where I iterated over the string, then nested inside the for loop, I'd have a while loop that would run until a '-', then run until a '+' or the end. I started the code, and without even getting that far into it, it created an infinite loop.
Question: How can I fix it?
Thanks!
string animalparkString = "cc+dd-cd"
for (int k = 0; k != animalparkString.size(); k++)
{
while (k != '-'){
pdc = pdc + 1; //positive dog count
pcc = pcc + 1; //positive cat count
}
while (k != '+') {
ndc = ndc + 1;
ncc = ncc + 1;
}
}
The immediate issue is that the while loops check k's value, but don't modify it. So once you entered one of them you'll be stuck there infinitely as k doesn't change inside the loop's body.
I wouldn't bother with nested loops - I'd just go over the entire string in one loop, and evaluate each character in its turn. A neat way to accomplish this is to keep a state of whether you're adding or subtracting (according to whether you last encountered a + or a - sign:
bool positive = true;
string animalparkString = "cc+dd-cd";
for (int k = 0; k < animalparkString.size(); k++) {
char ch = animalparkString[k];
switch (ch) {
case '+':
positive = true;
break;
case '-':
positive = false;
break;
case 'c':
if (positive) {
pcc++;
} else {
ncc++
}
break;
case 'd':
if (positive) {
pdc++;
} else {
ndc++
}
break;
}
}
This post describes iterating all characters is a string.
This is a simple solution using modern C++:
int sign = 1;
int dogs_count = 0, cats_count = 0;
std::string animalparkString = "-cccccc+dddd-cd";
for (const char& ch : animalparkString)
{
switch (ch) {
case '+':
sign = 1;
continue;
case '-':
sign = -1;
continue;
case 'c':
cats_count += sign;
continue;
case 'd':
dogs_count += sign;
continue;
}
}
std::cout <<"dogs: " << dogs_count << " cats: " <<cats_count;
A couple of suggestions to help you get started:
1. Use online c++ compilers to quickly test code
2. If your code doesn't behave as expected, use step-by-step debugging in your IDE or print our variables as you go using std::cout
3. Explicitly stating namespace is considered good practice. i.e:
// preferable:
std::string myString;
// avoid:
using namespace std;
string myString
To make your code work without too many changes , you can simply replace the while() condition with an if(). Moreover, instead of checking the iterator value k, you should compare the kth string element animalparkString[k].
Then you might start wondering if the code you wrote is actually doing what you expect. Possible questions you could try to answer is "how do I distinguish between positive or negative counts" and, then, "how do I distinguish between cats and dogs "? You will probably need to check also for cs and ds, not only for the operation sign!
string animalparkString = "cc+dd-cd"
for (int k = 0; k != animalparkString.size(); k++)
{
if(animalparkStrink[k] != '-'){
// Now you know, there will be a pos count. Dog or Cat?
}
if(animalparkString[k] != '+') {
// Now you know, there will be a neg count. Dog or Cat?
}
}
Note that if you write while( k != '-'), it will always evaluate true and, therefore, you will be stuck there. If it is the first time working with for-loops, consider printing the iterator value, to understand when and where you are stuck.
string animalparkString = "cc+dd-cd"
for (int k = 0; k != animalparkString.size(); k++)
{
std::cout << "for-loop iteration number: " << k << std::endl;
if(animalparkStrink[k] != '-'){
// Now you know, there will be a pos count. Dog or Cat?
}
if(animalparkString[k] != '+') {
// Now you know, there will be a neg count. Dog or Cat?
}
}
for and while together approach is unnecessarily complicated. Here's a simpler solution:
#include <concepts>
#include <iostream>
int main() {
auto const& str{"cc+dd-cd"};
std::boolean auto isPositive = 1;
std::integral auto pdc{0}, pcc{0}, ndc{0}, ncc{0};
for (char const ch : str) {
switch (ch) {
case 'c': {
pcc += isPositive;
ncc += !isPositive;
break;
}
case 'd': {
pdc += isPositive;
ndc += !isPositive;
break;
}
case '+': {
isPositive = true;
break;
}
case '-': {
isPositive = false;
break;
}
}
}
std::cout << "pcc: " << pcc << '\n'
<< "ncc: " << ncc << '\n'
<< "pdc: " << pdc << '\n'
<< "ndc: " << ndc << '\n';
}
LIVE

Recursion not going back looking for different path

I am trying to write a backtracking algorithm for harmonious graph coloring (no adjacent colors can be the same, and also each pair of colors can appear only once).
This is the backtracking function:
void Graph::colorBacktrack(int a, int b) {
print();
for (int i = 1; i <= colors; i++) //assigning colors until match
{
elems[a][b] = i; //color
if (check(a, b)) break; //if it's alright break
if (i == colors) // if all the colors have been used -
return; //return one stack back and look again
}
int nextA;
int nextB = b;
if (a < size - 1 ) nextA = a + 1;
else {
nextA = 0;
nextB = b + 1;
}
if (a == size && b == size - 1) //when array is complete - cout finished
{
cout << endl << endl << "Finished" << endl << endl;
}
colorBacktrack(nextA, nextB); //go to next node when everything is fine
}
checking is working properly and all the other things. The problem is that the output is wrong - at the end it shows something like this:
1 4 2 6
2 5 7 8
3 6 4 8
<--- this is wrong
1 7 3 0
<--- this is also wrong
So when it cannot find a solution in current tree it just ends everything instead of going up. Why is it happening?

C++ Darts Game: Loop does not exit second time round

I am currently coding a simulator for a game (or multiple games) of 501 darts in C++ and have run into a problem in my code.
The purpose of this region is to simulate 10,000 matches of world championship final darts between two players. One match consists of two players playing the best of 13 sets (first to 7), a set being the best of 5 games (first to 3). In each game both players start at a score of 501 and try to reduce their score to 0 before the other player. I am simulating 10,000 of these matches in order to gain the frequency of each possible result between the two players.
My players are declared in a class with their skill attributes and score count etc, with a method throw_quick_set(); which simulates the player throwing a set of 3 darts for their turn before the other player steps up to do the same.
My problem is, after the first match is won (the program sees a player with 7 sets) - the second match goes on forever with a player winning an infinite amount of sets. I see this because of the output phrases I included when a player wins a game or set when I noticed something was going wrong.
Perhaps someone can help me spot the error in my code, I've been staring at it so long I probably wouldn't notice it even if it was staring me in the face.
Thanks for your time!
int results[14] = {0}; //Stores counters for each of 14 possible outcomes
for (int gameNum = 0; gameNum < 10000; gameNum++)
{
// Calculate results of 10,000 full world championship finals.
// Final is thirteen sets - each set is a best of 5 games.
int sidSetWins = 0, joeSetWins = 0;
int sidGWins = 0, joeGWins = 0;
do
{ // Play best of 13 sets
do
{ // Play best of 5 games
do
{ // Play single game
if (currTurn == sid)
{
Sid.throw_quick_set(); // Throws a set of three
currTurn = joe;
}
else if (currTurn == joe)
{
Joe.throw_quick_set(); // Throws a set of three
currTurn = sid;
}
}
while ((Sid.score != 0) && (Joe.score != 0));
if (Sid.score == 0)
{
sidGWins++;
cout << "Sid wins game" << endl;
Sid.score = 501;
Joe.score = 501;
}
else if (Joe.score == 0)
{
joeGWins++;
cout << "Joe wins game" << endl;
Sid.score = 501;
Joe.score = 501;
}
Sleep(1000);
}
while ((joeGWins < 3) && (sidGWins < 3));
if (joeGWins == 3)
{
joeSetWins++;
cout << "Joe wins set" << endl;
sidGWins = 0;
joeGWins = 0; // Reset for each set
}
else if (sidGWins == 3)
{
sidSetWins++;
cout << "Sid wins set" << endl;
sidGWins = 0;
joeGWins = 0; // Reset for each set
}
Sleep(1000);
}
while ((sidSetWins < 7) && (joeSetWins < 7));
if ((gameNum%1000) == 0)
{
cout << "SidSets " << sidSetWins << endl;
cout << "JoeSets " << joeSetWins << endl;
sidSetWins = 0;
joeSetWins = 0; // Reset for each match
}
EDIT: Here's the class method throw_live_set(); also, if that helps you.
int Darts_501::throw_quick_set()
{ // Used for quick games with no commentary - for average calculations
darts = 0;
int startScore = score;
quickGame = true; // Disable commentary
do
{
if (score>=100)
curr_state = fast;
else if (score > 50)
curr_state = slow;
else if ((score <= 50) && (score > 1))
curr_state = focus;
else if ((score == 1) || (score < 0))
curr_state = bust;
else
curr_state = out;
switch (curr_state)
{
case fast:
score -= throw_treble(20, trebPerc);
break;
case slow:
score -= throw_single(20);
break;
case focus:
if (score == 50)
score -= throw_bull(bullPerc);
else if ((score != 0) && (score%2 == 0))
score -= throw_double(score/2); // If score is even, look to hit the double of half that value
else if ((score != 0) && (score%2 != 0))
score -= throw_setup(score); // If odd, look to set-up a good double score (strategic)
break;
case bust:
score = startScore;
break;
case out: score = 0;;
}
darts++;
} while ((darts < 3) &&
(curr_state != out) &&
(curr_state != bust));
return 0;
}

How to optimize Knight's tour algorithm?

I code the Knight's tour algorithm in c++ using Backtracking method.
But it seems too slow or stuck in infinite loop for n > 7 (bigger than 7 by 7 chessboard).
The question is: What is the Time complexity for this algorithm and how can I optimize it?!
The Knight's Tour problem can be stated as follows:
Given a chess board with n × n squares, find a path for the knight that visits every square exactly once.
Here is my code:
#include <iostream>
#include <iomanip>
using namespace std;
int counter = 1;
class horse {
public:
horse(int);
bool backtrack(int, int);
void print();
private:
int size;
int arr[8][8];
void mark(int &);
void unmark(int &);
bool unvisited(int &);
};
horse::horse(int s) {
int i, j;
size = s;
for (i = 0; i <= s - 1; i++)
for (j = 0; j <= s - 1; j++)
arr[i][j] = 0;
}
void horse::mark(int &val) {
val = counter;
counter++;
}
void horse::unmark(int &val) {
val = 0;
counter--;
}
void horse::print() {
cout << "\n - - - - - - - - - - - - - - - - - -\n";
for (int i = 0; i <= size - 1; i++) {
cout << "| ";
for (int j = 0; j <= size - 1; j++)
cout << setw(2) << setfill ('0') << arr[i][j] << " | ";
cout << "\n - - - - - - - - - - - - - - - - - -\n";
}
}
bool horse::backtrack(int x, int y) {
if (counter > (size * size))
return true;
if (unvisited(arr[x][y])) {
if ((x - 2 >= 0) && (y + 1 <= (size - 1))) {
mark(arr[x][y]);
if (backtrack(x - 2, y + 1))
return true;
else
unmark(arr[x][y]);
}
if ((x - 2 >= 0) && (y - 1 >= 0)) {
mark(arr[x][y]);
if (backtrack(x - 2, y - 1))
return true;
else
unmark(arr[x][y]);
}
if ((x - 1 >= 0) && (y + 2 <= (size - 1))) {
mark(arr[x][y]);
if (backtrack(x - 1, y + 2))
return true;
else
unmark(arr[x][y]);
}
if ((x - 1 >= 0) && (y - 2 >= 0)) {
mark(arr[x][y]);
if (backtrack(x - 1, y - 2))
return true;
else
unmark(arr[x][y]);
}
if ((x + 2 <= (size - 1)) && (y + 1 <= (size - 1))) {
mark(arr[x][y]);
if (backtrack(x + 2, y + 1))
return true;
else
unmark(arr[x][y]);
}
if ((x + 2 <= (size - 1)) && (y - 1 >= 0)) {
mark(arr[x][y]);
if (backtrack(x + 2, y - 1))
return true;
else
unmark(arr[x][y]);
}
if ((x + 1 <= (size - 1)) && (y + 2 <= (size - 1))) {
mark(arr[x][y]);
if (backtrack(x + 1, y + 2))
return true;
else
unmark(arr[x][y]);
}
if ((x + 1 <= (size - 1)) && (y - 2 >= 0)) {
mark(arr[x][y]);
if (backtrack(x + 1, y - 2))
return true;
else
unmark(arr[x][y]);
}
}
return false;
}
bool horse::unvisited(int &val) {
if (val == 0)
return 1;
else
return 0;
}
int main() {
horse example(7);
if (example.backtrack(0, 0)) {
cout << " >>> Successful! <<< " << endl;
example.print();
} else
cout << " >>> Not possible! <<< " << endl;
}
output for the example (n = 7) above is like this:
Since at each step you have 8 possibilities to check and this has to be done for each cell (minus the last one) the time complexity of this algorithm is O(8^(n^2-1)) = O(8^(n^2)) where n is the number of squares on the edges of the checkboard. To be precise this is the worst case time complexity (time taken to explore all the possibilities if none is found or if it is the last one).
As for the optimizations there can be 2 types of improvements:
Implementation improvements
You're calculating x-2, x-1, x+1, x+2 and the same for y at least the double of the times.
I can suggest to rewrite things like this:
int sm1 = size - 1;
int xm2 = x - 2;
int yp1 = y + 1;
if((xm2 >= 0) && (yp1 <= (sm1))){
mark(arr[x][y]);
if(backtrack(xm2, yp1))
return true;
else
unmark(arr[x][y]);
}
int ym1 = y-1;
if((xm2 >= 0) && (ym1 >= 0)){
mark(arr[x][y]);
if(backtrack(xm2, ym1))
return true;
else
unmark(arr[x][y]);
}
note the reusing of precalculated values also in subsequent blocks.
I've found this to be more effective than what I was especting; meaning that variable assignment and recall is faster than doing the operation again.
Also consider saving sm1 = s - 1; and area = s * s; in the constructor instead of calculating each time.
However this (being an implementation improvement and not an algorithm improvement) will not change the time complexity order but only divide the time by a certain factor.
I mean time complexity O(8^(n^2)) = k*8^(n^2) and the difference will be in a lower k factor.
Algorithm improvements
I can think this:
for each tour starting on in a cell in the diagonals (like starting in (0,0) as in your example) you can consider only the first moves being on one of the two half checkboards created by the diagonal.
This is beacouse of the simmetry or it exists 2 simmetric solutions or none.
This gives O(4*8^(n^2-2)) for that cases but the same remains for non simmetric ones.
Note that again O(4*8^(n^2-2)) = O(8^(n^2))
try to interrupt the rush early if some global condition suggests that a solution is impossible given the current markings.
for example the horse cannot jump two bulk columns or rows so if you have two bulk marked columns (or rows) and unmarked cells on both sides you're sure that there will be no solution. Consider that this can be checked in O(n) if you mantain number of marked cells per col/row updated. Then if you check this after each marking you're adding O(n*8^(n^2)) time that is not bad if n < = 8. Workaround is simply not to check alwais but maybe every n/8 markings (checking counter % 8 == 4 for example or better counter > 2*n && counter % 8 == 4
find other ideas to cleverly interrupt the search early but remember that the backtrack algorithm with 8 options will always have its nature of being O(8^(2^n)).
Bye
Here is my 2 cents. I started with the basic backtracking algorithm. It was waiting indefinitely for n > 7 as you mentioned. I implemented warnsdorff rule and it works like a magic and gives result in less than a second for boards of sizes till n = 31. For n >31, it was giving stackoverflow error as recursion depth exceeded the limit. I could find a better discussion here which talks about problems with warnsdorff rule and possible further optimizations.
Just for the reference, I am providing my python implementation of Knight's Tour problem with warnsdorff optimization
def isValidMove(grid, x, y):
maxL = len(grid)-1
if x maxL or y maxL or grid[x][y] > -1 :
return False
return True
def getValidMoves(grid, x, y, validMoves):
return [ (i,j) for i,j in validMoves if isValidMove(grid, x+i, y+j) ]
def movesSortedbyNumNextValidMoves(grid, x, y, legalMoves):
nextValidMoves = [ (i,j) for i,j in getValidMoves(grid,x,y,legalMoves) ]
# find the number of valid moves for each of the possible valid mode from x,y
withNumNextValidMoves = [ (len(getValidMoves(grid,x+i,y+j,legalMoves)),i,j) for i,j in nextValidMoves]
# sort based on the number so that the one with smallest number of valid moves comes on the top
return [ (t[1],t[2]) for t in sorted(withNumNextValidMoves) ]
def _solveKnightsTour(grid, x, y, num, legalMoves):
if num == pow(len(grid),2):
return True
for i,j in movesSortedbyNumNextValidMoves(grid,x,y,legalMoves):
#For testing the advantage of warnsdorff heuristics, comment the above line and uncomment the below line
#for i,j in getValidMoves(grid,x,y,legalMoves):
xN,yN = x+i,y+j
if isValidMove(grid,xN,yN):
grid[xN][yN] = num
if _solveKnightsTour(grid, xN, yN, num+1, legalMoves):
return True
grid[xN][yN] = -2
return False
def solveKnightsTour(gridSize, startX=0, startY=0):
legalMoves = [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]
#Initializing the grid
grid = [ x[:] for x in [[-1]*gridSize]*gridSize ]
grid[startX][startY] = 0
if _solveKnightsTour(grid,startX,startY,1,legalMoves):
for row in grid:
print ' '.join(str(e) for e in row)
else:
print 'Could not solve the problem..'
Examine your algorithm. At each depth of recursion, you examine each of 8 possible moves, checking which are on the board, and then recursively process that position. What mathematical formula best describes this expansion?
You have a fixed board size, int[8][8], maybe you should make it dynamic,
class horse
{
...
int** board; //[s][s];
...
};
horse::horse(int s)
{
int i, j;
size = s;
board = (int**)malloc(sizeof(int*)*size);
for(i = 0; i < size; i++)
{
board[i] = (int*)malloc(sizeof(int)*size);
for(j = 0; j < size; j++)
{
board[i][j] = 0;
}
}
}
Changing your tests a little by adding a function to check that a board move is legal,
bool canmove(int mx, int my)
{
if( (mx>=0) && (mx<size) && (my>=0) && (my<size) ) return true;
return false;
}
Note that the mark() and unmark() are very repetitive, you really only need to mark() the board, check all legal moves, then unmark() the location if none of the backtrack() return true,
And rewriting the function makes everything a bit clearer,
bool horse::backtrack(int x, int y)
{
if(counter > (size * size))
return true;
if(unvisited(board[x][y]))
{
mark(board[x][y]);
if( canmove(x-2,y+1) )
{
if(backtrack(x-2, y+1)) return true;
}
if( canmove(x-2,y-1) )
{
if(backtrack(x-2, y-1)) return true;
}
if( canmove(x-1,y+2) )
{
if(backtrack(x-1, y+2)) return true;
}
if( canmove(x-1,y-2) )
{
if(backtrack(x-1, y-2)) return true;
}
if( canmove(x+2,y+1) )
{
if(backtrack(x+2, y+1)) return true;
}
if( canmove(x+2,y-1) )
{
if(backtrack(x+2, y-1)) return true;
}
if( canmove(x+1,y+2) )
{
if(backtrack(x+1, y+2)) return true;
}
if( canmove(x+1,y-2) )
{
if(backtrack(x+1, y-2)) return true;
}
unmark(board[x][y]);
}
return false;
}
Now, think about how deep the recursion must be to visit every [x][y]? Fairly deep, huh?
So, you might want to think about a strategy that would be more efficient. Adding these two printouts to the board display should show you how many backtrack steps occured,
int counter = 1; int stepcount=0;
...
void horse::print()
{
cout<< "counter: "<<counter<<endl;
cout<< "stepcount: "<<stepcount<<endl;
...
bool horse::backtrack(int x, int y)
{
stepcount++;
...
Here is the costs for 5x5, 6x6, 7x6,
./knightstour 5
>>> Successful! <<<
counter: 26
stepcount: 253283
./knightstour 6
>>> Successful! <<<
counter: 37
stepcount: 126229019
./knightstour 7
>>> Successful! <<<
counter: 50
stepcount: 56342
Why did it take fewer steps for 7 than 5? Think about the ordering of the moves in the backtrack - if you change the order, would the steps change? What if you made a list of the possible moves [ {1,2},{-1,2},{1,-2},{-1,-2},{2,1},{2,1},{2,1},{2,1} ], and processed them in a different order? We can make reordering the moves easier,
int moves[ ] =
{ -2,+1, -2,-1, -1,+2, -1,-2, +2,+1, +2,-1, +1,+2, +1,-2 };
...
for(int mdx=0;mdx<8*2;mdx+=2)
{
if( canmove(x+moves[mdx],y+moves[mdx+1]) )
{
if(backtrack(x+moves[mdx], y+moves[mdx+1])) return true;
}
}
Changing the original move sequence to this one, and running for 7x7 gives different result,
{ +2,+1, +2,-1, +1,+2, +1,-2, -2,+1, -2,-1, -1,+2, -1,-2 };
./knightstour 7
>>> Successful! <<<
counter: 50
stepcount: -556153603 //sheesh, overflow!
But your original question was,
The question is: What is the Time complexity for this algorithm and how can I optimize it?!
The backtracking algorithm is approximately 8^(n^2), though it may find the answer after as few as n^2 moves. I'll let you convert that to O() complexity metric.
I think this guides you to the answer, without telling you the answer.
this is a new solution:
in this method, using the deadlock probability prediction at the next movement of the knight in the chessboard, a movement will be chose that it’s tending to the deadlock probability is less than the other ones, we know at the first step this deadlock probability is zero for every cells and it will be changed gradually. The knight in the chessboard has between 2 and 8 moves, so each cells has predetermined value for next move.
Selecting the cells that have less available movement is best choice because it will tend to the deadlock in the future unless it is filled. There is an inverse relationship between allowed movement number and reach an impasse.
the outer cells is in the highest priority, As regards in a knight's tour problem the knight has to cross a cell only once, these value will be changed gradually in future travels.
Then in the next step a cell will be chose that has these conditions
The number of its adjacent empty cells is less than others, or in the other words the probability to be filled is more
After selecting, the adjacent houses doesn’t going to deadlock
you can read my full article about this problem here
Knight tour problem article
and you can find the full source from here
Full Source in GitHub
I hope it will be useful

Game of life does not print correctly C++

I have some code for the game of life that takes the users input and displays that input as to which cells they entered as alive, but it always prints a row of four * no matter what. I've messed around with changing things a lot of different ways, but it either still prints the same thing, or doesn't display anything at all. I've done searching around multiple forums and websites, but every code i find is done completely different, which is something i would expect (including code from stackoverflow).
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;
#include <memory.h>
int main ()
{
const long MaxCols (10);
const long MaxRows (10);
const time_t WaitTime (3);
bool Board [MaxRows + 2] [MaxCols + 2];
long CurrCol;
long CurrRow;
time_t StopTime;
long Generation;
long OriginalArray[MaxRows][MaxCols];
long NewArray[MaxRows][MaxCols];
long Neighbors;
do
{
cout << "Enter a row and col for the living cell: ";
cin >> CurrRow >> CurrCol;
} while (CurrRow != 0 && CurrCol != 0);
for (Generation = 1; ; Generation++)
{
//Display the current generation on the board
system("cls");
cout << "\tCurrent Generation: " << Generation << endl;
for (CurrRow = 1; CurrRow <= MaxRows; CurrRow++)
{
for (CurrCol = 1; CurrCol <= MaxCols; CurrCol++)
cout << (Board [CurrRow + 2] [CurrCol + 2] ? ' ' : '*');
cout << endl;
}
//Loop to determine nieghbors
for(CurrRow=1; CurrRow <= MaxRows + 2; CurrRow++)
{
cout << endl;
for (CurrCol = 1; CurrCol <= MaxCols + 2; CurrCol++)
{
if (OriginalArray[CurrRow][CurrCol] == '*')
{
Neighbors = (OriginalArray, CurrRow, CurrCol);
if (Neighbors != 3 || Neighbors != 4 )
NewArray[CurrRow][CurrCol] = ' ';
else
NewArray[CurrRow][CurrCol] = '*';
}
else
{
Neighbors = (OriginalArray, CurrRow, CurrCol);
if (Neighbors != 2 || Neighbors != 3 )
NewArray[CurrRow][CurrCol] = ' ';
else
NewArray[CurrRow][CurrCol] = '*';
}
cout << "Touch any key to halt the program";
StopTime = time(0) + WaitTime; // time(0) gives the number of seconds since Jan 1, 1970
while (time (0) < StopTime) // keep looping until the current time catches the stop time
if (_kbhit()) //true if the user has hit a key, false if not hit a key
{
cout << "\nBye" << endl;
exit(0);
}
else;
}
}
}
}
Messing around is no way to debug a program. When it doesn't behave as you expect your first step should be to try to understand why. By making what, at your level of experience, will basically be random changes to your code you will just make things worse. As Oli mentioned a debugger is the best tool for this. You should learn how to use yours.
Looking at the code there are probably lots of errors but one error jumps out at me which is this
Neighbors = (OriginalArray, CurrRow, CurrCol);
I've no idea why you think this will count the number of neighbours but trust me it doesn't. I suppose you took a guess and then when the compiler didn't complain you assumed the guess was right. I'm afraid not.
So that's the bit to concentrate on first. You need some new code to count the number of live neighbours. Have a think about that.
There's no code above to enter values into Board. Here some code to do that. It's correct as far as it goes, but that doesn't mean it will work with the rest of your code which needs a lot of work.
// baord uses false for dead cells and true for living cells
bool Board [MaxRows + 2] [MaxCols + 2];
// initially make the whole board dead
for (int i = 0; i < MaxRows + 2; ++i)
for (int j = 0; j < MaxCols + 2; ++j)
Baord[i][j] = false;
// now ask the user for some live cells
for (;;)
{
cout << "Enter a row and col for the living cell (0 0 to quit): ";
int i, j;
cin >> i >> j;
if (i == 0 && j == 0)
break; // user entered 0 0 so quit loop
Board[i][j] = true; // set position i,j to live
}
The two parts that were missing from your code were initially setting the whole Board to dead, and secondly once you have got the coordinates for a live cell from the user you did nothing to set that cell to live.
One other thing that's confusing me about your code is that you have different size boards
bool Board [MaxRows + 2] [MaxCols + 2];
long OriginalArray[MaxRows][MaxCols];
long NewArray[MaxRows][MaxCols];
Why does Board have + 2 and the others don't. That makes no sense to me.