Snake Game Problem

Hey! So for an assignment I have I have to create a snake game along with adding a couple of my own features. I'm able to run the game perfectly, but I'm having a little trouble with the features I want to add. So when the program is run, there's a welcome screen that gives two options, 1. is to start the game, and 2. is to exit the program. I'm able to do 1, but I'm having trouble with 2. It seems simple but for some reason I can't get it so I was hoping someone could help with that. The other feature I want to add is for the program to output the score (aka how many times the snake reaches the "food") before it dies. The code I'm including is the main .cpp file where these changes would be made. This code by itself won't run the game as there are other .h and .cpp files to go along with this, but I think this will be enough. If you feel you need to see the rest of the files let me know and I will find a way to show you. Thanks in advance!

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include "game.h"
#include <thread> 
 
//get_key will return the key user typed
char Game::get_key() 
{
    int n;
    char buf[3];
    n = read(0,buf,sizeof(buf));
    if(3 == n && buf[0] == 27 && buf[1] == 91)
    {
        return buf[2];
    }
    else if(1 == n)
    {
        return buf[0];
    }
    return 0;
}


//need to implement end funtion()
int Game::end()                  //exit game function
{
	pen.goto_xy(ROW + 3,1);
    system("stty echo icanon");     //restart cache
	pen.show_cur();
	//need to make cursor goto the bottom
	//need to show cursor
	exit(0);                        //exit
}

int Game::getKey()                  //key control function
{
    //TODO
	//need to implement this function
	int quit = 0;
	int flag = 1;
	while(!quit){
		char key;
		key = get_key();
		
		switch(key)
		{
			case UP:
				snake.head.direction = UP;
				break;
			
			case DOWN:
				snake.head.direction = DOWN;
				break;
				
			case RIGHT:
				snake.head.direction = RIGHT;
				break;
			
			case LEFT:
				snake.head.direction = LEFT;
			default:	
				break;
		}
	}
	return 0;
}


//function use to draw a box
void Game::drawBox()                     //draw the outer range
{
	pen.clr_scrn();
    pen.draw_box(1,20,ROW,COL,44,34,'#');
}
 
void Game::drawSnake(void)                   // draw snake
{
    int i;
	pen.draw_rect(snake.head.pos.x,snake.head.pos.y + 20,1,1,43,33, 'x');
	for(i=0; i<= snake.body.count() - 1; i++){
		pen.draw_rect(snake.body.body_[i].x,snake.body.body_[i].y+20,1,1,3,32,'@');
	}
}

void Game::snakeMove(void)                   //move snake
{
    int i;
	
	if(snake.head.pos.x<=1 || snake.head.pos.x >= ROW+1 || snake.head.pos.y <=0 || snake.head.pos.y >= COL){
		end();
	}
	//for when the snake hits itself
	for(i=0; i<snake.body.count();i++){
		if(snake.head.pos.x==snake.body.body_[i].x && snake.head.pos.y==snake.body.body_[i].y){
            std::cout<<snake.head.pos.x<<" "<<snake.head.pos.y<<std::endl;
            std::cout<<snake.body.body_[i].x<<" "<<snake.body.body_[i].y<<std::endl;
            std::cout<<"Don't hit yourself!!!"<<std::endl;
			end();
		}
	}
	//for when the snake hits the food
	if(snake.head.pos.x==food.pos.x && snake.head.pos.y==food.pos.y){
		food.update(snake.body.body_,snake.head.pos.x,snake.head.pos.y);
		snake.body.add(0,0);
        
	}
	
	snake.body.move(snake.head.pos.x,snake.head.pos.y);
	switch(snake.head.direction){
		case UP:
			if(fkey!='d'){
				snake.head.pos.x -= 1;
				fkey='u';
			}
			else{
				snake.head.pos.x += 1;
			}
			break;
		
		case DOWN:
			if(fkey!='u'){
				snake.head.pos.x += 1;
				fkey='d';
			}
			else{
				snake.head.pos.x -= 1;
			}
			break;
		
		case RIGHT:
			if(fkey!='l'){
				snake.head.pos.y += 1;
				fkey='r';
			}
			else{
				snake.head.pos.y -= 1;
			}
			break;
		
		case LEFT:
			if(fkey!='r'){
				snake.head.pos.y -= 1;
				fkey='l';
			}
			else{
				snake.head.pos.y += 1;
			}
			break;	
	}
}

void Game::start(){
    int quit = 0;
    while(!quit)
    {
        system("stty -echo -icanon");   //cancel cacheļ¼›
        pen.hide_cur();                     
        pen.clr_scrn();                     
        drawBox();                     
 
        //need to draw a welcome page
		//need to add more feature in the switch below
		pen.goto_xy(8,33);
		pen.putstr(31,1,"   Snake");
		pen.goto_xy(10,33);
		pen.putstr(31,1,"1. New Game");
		pen.goto_xy(11,33);
		pen.putstr(31,1,"2. Exit");
		
        fflush(stdout); //flush the buffer
        int back = 0;
        while(!back)
        {
            int ret;
            char key = '0';
            int i;
            key = get_key();            //get key
            switch(key)
            {
                case 49:                // start game,??? is the key you use to start game
					gameStart();
                    std::thread f1([&](){
						while(true){
							drawBox();
							pen.draw_rect(food.pos.x,food.pos.y + 20,1,1,46,36,'#');
							snakeMove();
							drawSnake();
							fflush(stdout);
							usleep(200000);
						}
					});
					std::thread f2([&](){
						getKey();
					});
					f1.join();
					f2.join(); 
 
                    back = 1;           // note for end
                    break;
            }   
 
        }
    }
    end();                     // end of game
}

void Game::gameStart(){
    snake.head.pos.x = 10;                  //init the head position
    snake.head.pos.y = 20; 
	snake.body.add(10,19);			//init the body position
	snake.body.add(10,18); 
	snake.body.add(10,17);          
    fkey = 'r';                   //direction
    snake.head.direction = RIGHT;                //head direction
    speed=401;
    food.update(snake.body.body_,snake.head.pos.x,snake.head.pos.y);                      //init food position
}
Last edited on
Your problem is that you actually start a thread, but due to the joins it is not like a thread, but like a function call. So no join. Make sure that you protect shared variables across the thread with a mutex. Especially get_key().

If the user presses '2' you need to quit the while loop on line 181. The switch might look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            switch(key)
            {
                case '1':                // start game,??? is the key you use to start game
					gameStart();
                    std::thread f1([&](){
						while(!quit){
...
					f1.join();
					f2.join(); 
 
                    back = 1;           // note for end
                    break;

                case '2':
                    quit = 1;
                    back = 1;           // note for end
					f1.join();
					f2.join();
                    break;
            }   





Topic archived. No new replies allowed.