menu selection not working properly

Okay so I'm making a game and I have a menu that allows you to chose from 3 different options. When I select settings and change the options inside of it, I can no longer scroll freely in my menu like I was able to beforehand. I would appreciate a solution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

#include <iostream>
#include <conio.h>
#include <windows.h>

using namespace std;

char menu_choice =   0;
int rpgf         =   0;
int rcb          =   0;

void settings();
void gotoXY(int x, int y);
void multiplayer();

int main ()
{
    int menu_item = 0;
    int x         = 7;
    bool running  = true;

    gotoXY(18,5);
    cout << "Main Menu";
    gotoXY(18,7);
    cout << "->";

    do
    {
        gotoXY(20,7);
        cout << "1) Multiplayer";
        gotoXY(20,8);
        cout << "2) Settings";
        gotoXY(20,9);
        cout << "3) Quit Program";

        system("pause>nul");

        if(GetAsyncKeyState(VK_DOWN) && x != 9)
        {
            gotoXY(18,x);
            cout << "  ";
            x++;
            gotoXY(18,x);
            cout << "->";
            menu_item++;
        }

        if(GetAsyncKeyState(VK_UP) && x != 7)
        {
            gotoXY(18,x);
            cout << "  ";
            x--;
            gotoXY(18,x);
            cout << "->";
            menu_item--;
        }

        if(GetAsyncKeyState(VK_RETURN))
        {

            switch(menu_item)
            {

            case 0:
            {
                gotoXY(20,16);
                cout << "You chose Multiplayer!";
                Sleep(1500);
                system("CLS");
                multiplayer();
                running = false;
                break;
            }

            case 1:
            {
                gotoXY(20,16);
                cout << "You chose Settings!";
                Sleep(1500);
                system("CLS");
                settings();
                break;
            }

            case 2:
            {
                gotoXY(20,16);
                cout << "The program has now terminated.";
                running = false;
            }

            }

        }

    }
    while (running == true);


    gotoXY(20,21);
    return 0;

}

void settings ()
{
    cout << "Randomized colored board (Y/N): ";
    cin >> menu_choice;
    menu_choice = toupper(menu_choice);
    if (menu_choice == 'Y')
    {
        rcb = 1;
    }
    cout << endl;

    cout << "Random player goes first (Y/N): ";
    cin >> menu_choice;
    menu_choice = toupper(menu_choice);
    if (menu_choice == 'Y')
    {
        rpgf = 1;
    }
}

void gotoXY(int x, int y)
{

    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD CursorPosition;

    CursorPosition.X = x;
    CursorPosition.Y = y;
    SetConsoleCursorPosition(console,CursorPosition);
}
void multiplayer()
{
    cout << "NOT RELEVANT" << endl;
}
 I would appreciate a solution.

Appreciation goes without saying, and most times it does.

But overall, if life was only that simple.

Anyway here are 2 pointers to how you can solve your problem and appreciate the outcome much more:
1. Finding errors or mis-functioning in 138 lines of code is just wasting time - yours especially. 'unit testing' is always a good move. A unit with more than about 5-10 lines is too complex to test.

2. If it was working to your satisfaction, perhaps even properly, and then you changed something means a couple of things:
a) You aren't keeping track of the changes
b) You are writing spaghetti code - hoping for the best to 'jag' the solution - we've all done it
c) You haven't narrowed down the possibility by examining the changes you made

3. Feel free to show us the offending line that broke the camel's back :).
Last edited on
GetAsyncKeyState is probably not the right function to use. Try _getch() instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <cctype>
#include <conio.h>
using namespace std;

enum { RETURN = 13, UP = 72, LEFT = 75, RIGHT = 77, DOWN = 80 };

HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);

void gotoXY(short x, short y) {
    SetConsoleCursorPosition(console, COORD{x, y});
}

void ShowCursor(bool show) {
    CONSOLE_CURSOR_INFO cursor;
    GetConsoleCursorInfo(console, &cursor);
    cursor.bVisible = show;
    SetConsoleCursorInfo(console, &cursor);
}

void settings(bool& rcb, bool& rpgf) {
    char menu_choice = 0;
    cout << "Randomized colored board (Y/N): ";
    cin >> menu_choice;
    rcb = (toupper(menu_choice) == 'Y');
    cout << "\nRandom player goes first (Y/N): ";
    cin >> menu_choice;
    rpgf = (toupper(menu_choice) == 'Y');
    cin.ignore(999, '\n');
}

void multiplayer() {
    cout << "Multiplayer\n";
}

int main () {
    int menu_item = 0;
    bool running  = true;
    bool rcb = false, rpgf = false;

    ShowCursor(false);

    while (running) {
        gotoXY(18, 5);
        cout << "Main Menu";
        gotoXY(20,7);
        cout << "1) Multiplayer";
        gotoXY(20,8);
        cout << "2) Settings";
        gotoXY(20,9);
        cout << "3) Quit Program";

        gotoXY(18, 7);
        cout << "->";

        int ch = _getch();
        
        if (ch == 224) {
            ch = _getch();
            if (ch == DOWN && menu_item != 2) {
                gotoXY(18, menu_item + 7);
                cout << "  ";
                ++menu_item;
            }
            else if (ch == UP && menu_item != 0) {
                gotoXY(18, menu_item + 7);
                cout << "  ";
                --menu_item;
            }
        }
        else if (ch == RETURN) {
            switch (menu_item) {
            case 0:
                gotoXY(20, 16);
                cout << "You chose Multiplayer!";
                Sleep(1000);
                system("cls");
                multiplayer();
                running = false;
                break;
            case 1:
                gotoXY(20, 16);
                cout << "You chose Settings!";
                Sleep(1000);
                system("cls");
                settings(rcb, rpgf);
                break;
            case 2:
                gotoXY(20, 16);
                cout << "Terminating...";
                Sleep(1000);
                system("cls");
                running = false;
                break;
            }
        }
    }

    gotoXY(20, 21);
    ShowCursor(true);
}

Last edited on
I do not think the arrow keys can be safely handled with getch ()? Not 100% sure on that, but be warned that arrow keys are 'different'. I believe the above code handled it; are you getting 2 chars for one keypress? Pay attention to what he did if you want to do it that way, and I believe it can change across OS as well (?).
Last edited on
I believe it can change across OS as well

I figured since he was using GetAsyncKeyState he was bound to the Windows OS.
I actually fired up a windows laptop (yuck) to test it, although I didn't test it that much.
Definitely two chars for one arrow keypress on windows.
Three chars per keypress on linux!
Something like ncurses allows you to do it cross-platform.
I thought I had remembered getting 3 chars from them. Anyway, it was just a friendly warning that the arrow keys can be tricksy. if you stick to windows only, it will be fine.
This code should work - just made some minor tweaks to dutch's code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <cctype>
#include <conio.h>
#include <windows.h>
using namespace std;

enum { RETURN = 13, UP = 72, LEFT = 75, RIGHT = 77, DOWN = 80 };

HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);

void gotoXY(short x, short y) {
	SetConsoleCursorPosition(console, COORD{ x, y });
}

void ShowCursor(bool show) {
	CONSOLE_CURSOR_INFO cursor;
	GetConsoleCursorInfo(console, &cursor);
	cursor.bVisible = show;
	SetConsoleCursorInfo(console, &cursor);
}

void settings(bool& rcb, bool& rpgf) {
	char menu_choice = 0;
	cout << "Randomized colored board (Y/N): ";
	cin >> menu_choice;
	rcb = (toupper(menu_choice) == 'Y');
	cout << "\nRandom player goes first (Y/N): ";
	cin >> menu_choice;
	rpgf = (toupper(menu_choice) == 'Y');
	cin.ignore(999, '\n');
}

void multiplayer() {
	cout << "Multiplayer\n";
}

int main() {
	int menu_item = 0;
	bool running = true;
	bool rcb = false, rpgf = false;
	int x = 7;

	ShowCursor(false);

	gotoXY(18, 5);
	cout << "Main Menu";
	gotoXY(20, 7);
	cout << "1) Multiplayer";
	gotoXY(20, 8);
	cout << "2) Settings";
	gotoXY(20, 9);
	cout << "3) Quit Program";

	gotoXY(18, 7);
	cout << "->";

	while (running) {
		gotoXY(18, 5);
		cout << "Main Menu";
		gotoXY(20, 7);
		cout << "1) Multiplayer";
		gotoXY(20, 8);
		cout << "2) Settings";
		gotoXY(20, 9);
		cout << "3) Quit Program";

		int ch = _getch();

		if (ch == 224) {
			ch = _getch();
			if (ch == DOWN && menu_item != 2) {
				gotoXY(18, menu_item + 7);
				cout << "  ";
				x++;
				gotoXY(18, x);
				cout << "->";
				++menu_item;
			}
			else if (ch == UP && menu_item != 0) {
				gotoXY(18, menu_item + 7);
				cout << "  ";
				x--;
				gotoXY(18, x);
				cout << "->";
				--menu_item;
			}
		}
		else if (ch == RETURN) {
			switch (menu_item) {
			case 0:
				gotoXY(20, 16);
				cout << "You chose Multiplayer!";
				Sleep(1000);
				system("cls");
				multiplayer();
				running = false;
				break;
			case 1:
				gotoXY(20, 16);
				cout << "You chose Settings!";
				Sleep(1000);
				system("cls");
				settings(rcb, rpgf);
				break;
			case 2:
				gotoXY(20, 16);
				cout << "Terminating...";
				Sleep(1000);
				system("cls");
				running = false;
				break;
			}
		}
	}

	gotoXY(20, 21);
	ShowCursor(true);
}
@zapshe, What didn't work in my code? I see I left out windows.h (somehow). But you put x back in, which is an unneeded variable since it is always menu_Item + 7. I still think mine's better. :)
@dutch

Your code didn't allow the arrow to follow the selections. The arrow was static on the first option. You could pick other options, but the arrow wouldn't show you what you were picking.

EDIT: Yea, you can use menu_item + 7, but it makes it easier to know what's happening having a different variable.
Last edited on
@zapshe, It works perfectly for me. But the OP doesn't seem to give a shit, so I don't either. Fuck it.
@dutch No idea how it works perfectly for you when the only time you print out the arrow is when you set it to a hard-coded location:

1
2
gotoXY(18, 7);
cout << "->";


You may have uploaded the wrong code?

But the OP doesn't seem to give a shit, so I don't either. Fuck it.

This OP didn't say anything in response in his last question either. Probably reads and doesn't bother to thank anyone or update.
Topic archived. No new replies allowed.