CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Jun 2022
    Posts
    5

    Lightbulb help with hobby programming in C++

    I am posting the C++ code I worked on . It is working, but with some glitch, and with slow execution. I need help with code optimization. Thanks.

    Code:
    // Program for finding max movement possible of a knight on Chess board. 
    // A random location is allocated as starting point and with pressing any key (other than
    // return), the program shows the next move of knight. This continues untill user press ENTER 
    //key or no further move is possible on unlanded position.
    
    
    #include<iostream>
    #include<vector>
    #include<time.h>
    #include<conio.h>
    #define f(i,n) for (auto i=0;i<n;i++)
    using namespace std;
    char a[8][8]
    {{'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},};
    int l=0,m=0,count=0;
    void disp(int i,int j)
    {
    	system("cls");
    	a[l+i][m+j]='X';
    	count++;
    	l+=i;
    	m+=j;
    	f(i,8)
    	{
    		f(j,8)
    		cout<<a[i][j]<<" ";
    		cout<<endl;
    	}
    	cout<<"\n\nMoved to ("<<m+1<<','<<l+1<<')'<<endl;
    	cout<<"\nToatl moves : "<<count<<endl;
    }
    int main()
    {
    	srand(time(0));
    	int k=0;
    	vector <int>v;
    	bool b[8]={0};
    	int count =0,q=0;
    //	cout<<"A random number :"<<rand()<<endl;
    	int i=rand()%8;
    	int j=rand()%8;
    	a[i][j]='X';
    	disp(i,j);
    	char g='a';
    	do
    	{
    		if(i+2<8)
    		{
    			if(j+1<8 && a[i+2][j+1]=='O')
    			b[0]=1;
    			if (j-1>=0 && a[i+2][j-1]=='O')
    			b[1]=1;
    		}
    		if(i-2>=0)
    		{
    			if(j+1<8 && a[i-2][j+1]=='O')
    			b[2]=1;
    			if (j-1>=0 && a[i-2][j-1]=='O')
    			b[3]=1;
    		}
    		if(j-2>=0)
    		{
    			if(i+1<8 && a[j-2][i+1]=='O')
    			b[4]=1;
    			if (i-1>=0 && a[j-2][i-1]=='O')
    			b[5]=1;
    		}
    		if(j+2<8)
    		{
    			if(i+1<8 && a[j+2][i+1]=='O')
    			b[6]=1;
    			if (i-1>=0 && a[j+2][i-1]=='O')
    			b[7]=1;
    		}
    		f(i,8)if(b[i])v.push_back(i);
    		//	if(v.size()==0)cout<<"Empty moves...\n\n";
    		k=rand()%(v.size());
    		switch(v[k])
    		{
    			case 0: disp(2,1);i+=2;j+=1;break;
    			case 1: disp(2,-1);i+=2;j-=1;break;
    			case 2: disp(-2,1);i-=2;j+=1;break;
    			case 3: disp(-2,-1);i-=2;j-=1;break;
    			case 4: disp(1,-2);i+=1;j-=2;break;
    			case 5: disp(-1,-2);i-=1;j-=2;break;
    			case 6: disp(1,2);i+=1;j+=2;break;
    			default: disp(-1,2);i-=1;j+=2;break;
    			
    		}
    		f(i,8)b[i]=0;
    		v.clear();
    		g=getch();
    		//else cout<<" Further movement not possible.\n\nTotal movements : "<<count<<endl;
    	}while(g!=13 && v.empty()
    	);
    	
    	return 0;
    }

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,248

    Re: help with hobby programming in C++

    1. What task are you trying to solve with this code?
    2. Define "with some glitch".
    Victor Nijegorodov

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,631

    Re: help with hobby programming in C++

    There are various issues with variables being defined at global or function level and then at local scope level.

    As a start, this revised c++ code compiles cleanly. If it now doesn't work as expected, then I suggest you use the debugger to trace through the code to see where it's execution deviates from that expected from the design.

    It is also confusing, and not exactly good practice to have a function perform more actions than it's name might imply. so a function called disp() it would not be expected to change data.

    Also, there is no checking for -ve coordinates or co-ordinates outside of the array bounds (0 to 7). eg if the first value of k is 5, then the co-ords are then -1 and -2! so you have a[-1][-2] = 'X' - which is not what you want as this is outside of the bounds of the array!

    Code:
    #include <iostream>
    #include <vector>
    #include <random>
    #include <conio.h>
    
    #define f(z,n) for (auto z=0;z<n;z++)
    
    char a[8][8]
    { {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',}, };
    
    int l = 0, m = 0, count = 0;
    std::mt19937 rng(std::random_device {}());
    
    void disp(int i, int j) {
    	//system("cls");
    	a[l + i][m + j] = 'X';
    	++count;
    	l += i;
    	m += j;
    
    	f(i1, 8) {
    		f(j1, 8)
    			std::cout << a[i1][j1] << " ";
    
    		std::cout << '\n';
    	}
    
    	std::cout << "\n\nMoved to (" << m + 1 << ',' << l + 1 << ')' << '\n';
    	std::cout << "\nTotal moves : " << count << '\n';
    }
    
    int main() {
    	std::uniform_int_distribution<int> loc(0, 7);
    	std::vector<int> v;
    	bool b[8] { 0 };
    	int i = loc(rng);
    	int j = loc(rng);
    
    	a[i][j] = 'X';
    	disp(i, j);
    	int g = 'a';
    
    	do {
    		if (i + 2 < 8) {
    			if (j + 1 < 8 && a[i + 2][j + 1] == 'O')
    				b[0] = 1;
    
    			if (j - 1 >= 0 && a[i + 2][j - 1] == 'O')
    				b[1] = 1;
    		}
    
    		if (i - 2 >= 0) {
    			if (j + 1 < 8 && a[i - 2][j + 1] == 'O')
    				b[2] = 1;
    
    			if (j - 1 >= 0 && a[i - 2][j - 1] == 'O')
    				b[3] = 1;
    		}
    
    		if (j - 2 >= 0) {
    			if (i + 1 < 8 && a[j - 2][i + 1] == 'O')
    				b[4] = 1;
    
    			if (i - 1 >= 0 && a[j - 2][i - 1] == 'O')
    				b[5] = 1;
    		}
    
    		if (j + 2 < 8) {
    			if (i + 1 < 8 && a[j + 2][i + 1] == 'O')
    				b[6] = 1;
    
    			if (i - 1 >= 0 && a[j + 2][i - 1] == 'O')
    				b[7] = 1;
    		}
    		f(i1, 8)
    			if (b[i1])
    				v.push_back(i1);
    
    		const int k = (std::uniform_int_distribution<int>(0, 7))(rng);
    
    		switch (v[k]) {
    		case 0: disp(2, 1); i += 2; j += 1; break;
    		case 1: disp(2, -1); i += 2; j -= 1; break;
    		case 2: disp(-2, 1); i -= 2; j += 1; break;
    		case 3: disp(-2, -1); i -= 2; j -= 1; break;
    		case 4: disp(1, -2); i += 1; j -= 2; break;
    		case 5: disp(-1, -2); i -= 1; j -= 2; break;
    		case 6: disp(1, 2); i += 1; j += 2; break;
    		default: disp(-1, 2); i -= 1; j += 2; break;
    		}
    
    		f(i1, 8)
    			b[i1] = 0;
    
    		v.clear();
    		g = _getch();
    		//else cout<<" Further movement not possible.\n\nTotal movements : "<<count<<endl;
    	} while (g != 13 && v.empty());
    }
    Last edited by 2kaud; June 12th, 2022 at 11:02 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.2.4)

  4. #4
    Join Date
    Jun 2022
    Posts
    5

    Resolved Re: help with hobby programming in C++

    Thank you for replying.

    But same problem persists with your code as well as I tried it. As mentioned in the comments in code itself, this program counts the maximum number of move possible for a knight on a chess board without stepping on already visited locations on board. Hence the maximum possible moves can not be more than 64. This is the problem. The program is visiting already visited spots and counts it as next move, which is prohibited ,
    if(j+1<8 && a[i+2][j+1]=='O')
    I found my code running faster without using
    system("cls")
    . Although it's faster now but I am still looking for an alternative to this effect though standard libraries header file commands.

  5. #5
    Join Date
    Jun 2022
    Posts
    5

    Re: help with hobby programming in C++

    Thank you for the reply.

    1. There is no task. I am just beginner, and trying to learn through book exercise problems.

    2. As you might have understood from the comments in code, I a trying to get maximum possible moves for a knight without visiting its previous locations on a chess board. Now the glitch part, on running the code , it's count of maximum moves goes beyond 64, which shouldn't happen (max non repetitive moves on a chess board).

  6. #6
    Join Date
    Jun 2022
    Posts
    5

    Re: help with hobby programming in C++

    Quote Originally Posted by 2kaud View Post
    Also, there is no checking for -ve coordinates or co-ordinates outside of the array bounds (0 to 7). eg if the first value of k is 5, then the co-ords are then -1 and -2! so you have a[-1][-2] = 'X' - which is not what you want as this is outside of the bounds of the array!
    There is a check for that as well. From code itself, the value of k=5 is only possible if some conditions are met, which in this case is from this part of the code :
    Code:
    if(j-2>=0)
    		{
    			if(i+1<8 && a[j-2][i+1]=='O')
    			b[4]=1;
    			if (i-1>=0 && a[j-2][i-1]=='O')
    			b[5]=1;
    So the value of k=5 is only possible if
    Code:
     (j-2>=0)
    and
    Code:
    if (i-1>=0 && a[j-2][i-1]=='O')

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,631

    Re: help with hobby programming in C++

    Then you need to use the debugger to trace through the code to see where is the issue.

    When I ran the code, I was getting -ve values for moved to in disp().

    Code:
    Moved to (11,1)
    
    Total moves : 3
    O O O O O O O O
    O O X O O O O O
    X O O O O O X O
    O O O O O O O O
    O O O O O O O O
    O O O O O O O O
    O O O O O O O O
    O O O O O O O O
    
    
    Moved to (10,-1)
    Last edited by 2kaud; June 12th, 2022 at 11:03 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.2.4)

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,631

    Re: help with hobby programming in C++

    The program is visiting already visited spots and counts it as next move
    You need to maintain a container of already visited locations. I'd suggest a std::unordered_set

    https://cplusplus.com/reference/unor...unordered_set/

    insert only works if the value to be inserted doesn't already exist and it's easy to determine if an insert worked/failed or if a value already exists or not.

    If you have a struct for the position

    Code:
    struct Pos {
        int i;
        int j;
    };
    then you could have for the unordered_set

    Code:
    std::unordered_set<Pos> used;
    So every move is inserted into this and if the insert failed then you know it's a duplicate.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.2.4)

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,631

    Re: help with hobby programming in C++

    As an example of using std::unordered_set consider:

    Code:
    #include <iostream>
    #include <unordered_set>
    
    struct Pos {
    	int i {};
    	int j {};
    
    	Pos(int i_, int j_) : i(i_), j(j_) {}
    };
    
    struct Hash {
    	size_t operator()(const Pos& p) const {
    		return p.i * 100 + p.j;
    	}
    };
    
    struct Equal {
    	bool operator()(const Pos& e1, const Pos& e2) const {
    		return e1.i == e2.i && e1.j == e2.j;
    	}
    };
    
    using Used = std::unordered_set<Pos, Hash, Equal>;
    
    bool insert(Used& used, int x, int y) {
    	if (!used.emplace(x, y).second) {
    		std::cout << '(' << x << ", " << y << ") already exists\n";
    		return false;
    	}
    
    	return true;
    }
    
    int main() {
    	Used used;
    
    	insert(used, 1, 2);
    	insert(used, 2, 3);
    	insert(used, 1, 2);
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.2.4)

  10. #10
    Join Date
    Jun 2022
    Posts
    5

    Re: help with hobby programming in C++

    Quote Originally Posted by 2kaud View Post
    Then you need to use the debugger to trace through the code to see where is the issue.

    When I ran the code, I was getting -ve values for moved to in disp().

    Code:
    Moved to (11,1)
    
    Total moves : 3
    O O O O O O O O
    O O X O O O O O
    X O O O O O X O
    O O O O O O O O
    O O O O O O O O
    O O O O O O O O
    O O O O O O O O
    O O O O O O O O
    
    
    Moved to (10,-1)
    As I see it, the code is too much altered. It's not only giving -ve coordinates, but out of bound too. None of the values for i,j in a[i][j] can be less than 0, or more than 7, but your initial coordiantes are (11,1), which can't be on a board.

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,631

    Re: help with hobby programming in C++

    Sorry my bad - I blame not enough coffee! When I was going through the original code I misread one line and used 8 instead of v.size() - 1.

    I've also changed in main re detecting no move possible and removed b array. Try this:

    Code:
    #include <iostream>
    #include <vector>
    #include <random>
    #include <conio.h>
    
    #define f(z,n) for (auto z=0;z<n;z++)
    
    char a[8][8]
    { {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',},
    {'O','O','O','O','O','O','O','O',}, };
    
    int l = 0, m = 0, count = 0;
    std::mt19937 rng(std::random_device {}());
    
    void disp(int i, int j) {
    	//system("cls");
    	a[l + i][m + j] = 'X';
    	++count;
    	l += i;
    	m += j;
    
    	f(i1, 8) {
    		f(j1, 8)
    			std::cout << a[i1][j1] << " ";
    
    		std::cout << '\n';
    	}
    
    	std::cout << "\n\nMoved to (" << m + 1 << ',' << l + 1 << ')' << '\n';
    	std::cout << "\nTotal moves : " << count << '\n';
    }
    
    int main() {
    	std::uniform_int_distribution<int> loc(0, 7);
    	int i = loc(rng);
    	int j = loc(rng);
    	std::vector<int> v;
    
    	disp(i, j);
    
    	do {
    		v.clear();
    
    		if (i + 2 < 8) {
    			if (j + 1 < 8 && a[i + 2][j + 1] == 'O')
    				v.push_back(0);
    
    			if (j - 1 >= 0 && a[i + 2][j - 1] == 'O')
    				v.push_back(1);
    		}
    
    		if (i - 2 >= 0) {
    			if (j + 1 < 8 && a[i - 2][j + 1] == 'O')
    				v.push_back(2);
    
    			if (j - 1 >= 0 && a[i - 2][j - 1] == 'O')
    				v.push_back(3);
    		}
    
    		if (j - 2 >= 0) {
    			if (i + 1 < 8 && a[j - 2][i + 1] == 'O')
    				v.push_back(4);
    
    			if (i - 1 >= 0 && a[j - 2][i - 1] == 'O')
    				v.push_back(5);
    		}
    
    		if (j + 2 < 8) {
    			if (i + 1 < 8 && a[j + 2][i + 1] == 'O')
    				v.push_back(6);
    
    			if (i - 1 >= 0 && a[j + 2][i - 1] == 'O')
    				v.push_back(7);
    		}
    
    		if (!v.empty()) {
    			switch (v[(std::uniform_int_distribution<int>(0, (int)(v.size() - 1))) (rng )]) {
    			case 0: disp(2, 1); i += 2; j += 1; break;
    			case 1: disp(2, -1); i += 2; j -= 1; break;
    			case 2: disp(-2, 1); i -= 2; j += 1; break;
    			case 3: disp(-2, -1); i -= 2; j -= 1; break;
    			case 4: disp(1, -2); i += 1; j -= 2; break;
    			case 5: disp(-1, -2); i -= 1; j -= 2; break;
    			case 6: disp(1, 2); i += 1; j += 2; break;
    			default: disp(-1, 2); i -= 1; j += 2; break;
    			}
    		} else
    			std::cout << "No movement possible\n";
    
    	} while (_getch() != 13 && !v.empty());
    }
    Last edited by 2kaud; June 13th, 2022 at 03:40 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.2.4)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured