Không thể gameover khi thân rắn đụng thân rắn (game rắn)

#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>
void gotoxy(int x, int y)
{
    static HANDLE h = NULL;  
    if(!h)
        h = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD c = { x, y };  
    SetConsoleCursorPosition(h,c);
}
void clrscr(void)
{
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
HANDLE hConsoleOut;
COORD Home = {0,0};
DWORD dummy;

hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);

FillConsoleOutputCharacter(hConsoleOut,' ',csbiInfo.dwSize.X * csbiInfo.dwSize.Y,Home,&dummy);
csbiInfo.dwCursorPosition.X = 0; 
csbiInfo.dwCursorPosition.Y = 0; 
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); 
}

enum PHIMDUYCHUYEN
{
	LEFT,
	RIGHT,
	DOWN,
	UP,
};
typedef struct
{
	int x;
	int y;
}ToaDoRan;
typedef struct
{
	int x;
	int y;
}ToaDoF;
typedef struct
{
	ToaDoRan sodottoida[100];
	int sodothientai;
	PHIMDUYCHUYEN MOVE;
	
}CauTaoConRan;


CauTaoConRan ConRan;
ToaDoF F;
const int w=32;
const int h=32;
bool gameover;
///InLOGO
void  logo()

{   int count=0;
    int speed=1;
    int boss=0;
  
	gotoxy(201,200);
	
	for(int i=0;i<ConRan.sodothientai-1;i++)
	{
	count++;
	if(count==5||count==25||count==45||count==65||count==100)
	{
	speed++;
	}

	
    }
    
    
    
	 
    
	printf("\nDiem:= %d",count);
	printf("\nLevel= %d",speed);
}
int  speed(int *a)

{   int count=0;
    int speedt=1;
    int boss=0;
    a=&boss;
    a[100];
	gotoxy(201,200);
	
	for(int i=0;i<ConRan.sodothientai-1;i++)
	{
	count++;
	if(count==5||count==25||count==45||count==65||count==100)
	{
	speedt++;
	if(speedt==2)
	boss=boss+100;
	else
	if(speedt==3)
	boss=boss+200;
	else
	if(speedt==4)
	boss=boss+100;
	else
	if(speedt==5)
	boss=boss+50;
	}
    }
    return boss;
    
	
	
    
    
	 
    

}
 
// ?n hi?n con tr? nh?p nháy trong c?a s? Console
void ShowCur(bool CursorVisibility)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO cursor = {1, CursorVisibility};
    SetConsoleCursorInfo(handle, &cursor);
}
// Ð?t màu cho ch?
void SetColor(WORD color)
{
    HANDLE hConsoleOutput;
    hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 
    CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
    GetConsoleScreenBufferInfo(hConsoleOutput, &screen_buffer_info);
 
    WORD wAttributes = screen_buffer_info.wAttributes;
    color &= 0x000f;
    wAttributes &= 0xfff0;
    wAttributes |= color;
 
    SetConsoleTextAttribute(hConsoleOutput, wAttributes);
}
 
// Ð?t màu n?n cho ch?

 
 
void KhoiTao()
{
	gameover=false;
	ConRan.sodothientai=1;
	ConRan.MOVE = LEFT;
	ConRan.sodottoida[0].x=10;
	ConRan.sodottoida[0].y=10;
	F.x=20;
	F.y=20;
	// xuat hien o ban dau
	gotoxy(ConRan.sodottoida[0].x,ConRan.sodottoida[0].y);
	printf("O");
	
	
}
void Vetuong( )
{    
	for(int i=0;i<=32;i++)
	{
		gotoxy(0,i);
		putchar('|');
		
	}
		for(int i=0;i<=32;i++)
	{
		gotoxy(i,0);
		putchar('|');
		
	}
		for(int i=0;i<=32;i++)
	{
		gotoxy(32,i);
		putchar('|');
		
	}
		for(int i=0;i<=32;i++)
	{
		gotoxy(i,32);
		putchar('|');
		logo();
	}
}

void HinhAnh()
{   
	 Vetuong();
	////
      ////
  ////
	////
    // khoi tao vi tri va an moi
	for(int i=0;i<ConRan.sodothientai;i++)
		
	{
	gotoxy(ConRan.sodottoida[i].x,ConRan.sodottoida[i].y);
    if(i==0)
	printf("O");  
	else 
	printf("%c",4);
    }
    gotoxy(F.x,F.y);
    putchar('8');
	
}


void DieuKhien()
{
	
	
	//khoi tao vi tri moi
		for(int i=ConRan.sodothientai-1;i>0;i--)
	{
		ConRan.sodottoida[i]=ConRan.sodottoida[i-1];
	}
	
	if(_kbhit())
	{
		switch(_getch())
		{
			case 'a':
			ConRan.MOVE= LEFT;
			
			break;
			  case 'd':
		    
		      
		      ConRan.MOVE=   RIGHT;
			   
			   
			
			
			break;
			case 'w':
		
			 
			   ConRan.MOVE = UP;
			   
			   
			
			
			
			break;
			case 's':
			
			   
			   ConRan.MOVE=DOWN;
			   
			   
			break;
				case 'A':
			ConRan.MOVE= LEFT;
			
			break;
			  case 'D':
		    
		      
		      ConRan.MOVE=   RIGHT;
			   
			   
			
			
			break;
			case 'W':
		
			 
			   ConRan.MOVE = UP;
			   
			   
			
			
			
			break;
			case 'S':
			
			   
			   ConRan.MOVE=DOWN;
			   
			   
			break;

			default :
			break;
			
		}
    }   
    
        
	    
		
		
		
		
	}

	
	
	
	
	
	
	


void TinhToan( )
{  
    
	switch(ConRan.MOVE)
	{
		case LEFT:
		ConRan.sodottoida[0].x--;
			break;
			
		case RIGHT:
		ConRan.sodottoida[0].x++;
			break;
		case UP:
		ConRan.sodottoida[0].y--;
			break;
		case DOWN:
		ConRan.sodottoida[0].y++;
			break;
		default : break;
	}
       
	    int i=0;
	    // an thuc an o day 
		
		if(ConRan.sodottoida[0].x==F.x&&ConRan.sodottoida[0].y==F.y)
		
	{   
		   
			for(i=ConRan.sodothientai;i>0;i--)
       { 
            
	        ConRan.sodottoida[i]=ConRan.sodottoida[i-1]; 
		
       }
      
		ConRan.sodothientai++;
	    srand(time(NULL));
	    F.x=rand()%29+1;
	    F.y=rand()%29+1;
	}
        
       
	
		
	    
	    
	

	// chay xuyen tuong
	     
	    for( i=0;i<ConRan.sodothientai;i++)
	    {
	    	
	    if (ConRan.sodottoida[i].x >= w)ConRan.sodottoida[i].x = 1;
        if (ConRan.sodottoida[i].x < 0) ConRan.sodottoida[i].x = w - 2;
        if (ConRan.sodottoida[i].y >= h) ConRan.sodottoida[i].y = 1;
        if (ConRan.sodottoida[i].y < 0)ConRan.sodottoida[i].y = h - 2;
         }
}
       
  	    

////
bool ThangThua()
{
	for(int i=0;i<ConRan.sodothientai-1;i++)
	if(ConRan.sodottoida[0].x==ConRan.sodottoida[i].x&&ConRan.sodottoida[0].y==ConRan.sodottoida[i].y)
	return false;
	
	return true;
}
	
	
	
	
	
	


int main()
 
{   
    
    ShowCur(false);
    int *a;
    int count=0;
    a=&count;
    
    SetColor(14);
    KhoiTao();
    


	
	speed(a);
	
	if(ThangThua()==true)
	{
	while(!gameover)
	{
	
	clrscr();
	HinhAnh();
	DieuKhien();
	TinhToan();
	
	Sleep(500-speed(a));
	
	}
   }
    else
    {
    if(ThangThua()==false)
    printf("GAMEover");
    }
    getch();
	return 0;
}

Code bạn viết hơi bị thảm hoạ (cách dòng lung tung, căn lề cũng lung tung,…). Bạn quăng mỗi quả code thế kia khiến mọi người khó mà giúp bạn được. Mình chỉ gợi ý là thêm 1 mảng 2 chiều toạ độ

int coor[1000][1000]; // có thể thay 1000 bằng 1 con số bất kì

coor[x][y] cho biết toạ độ (x, y) có bất kì vật thể nào hay không:
           == 0 <-> chả có gì cả
           == -1 <-> có 1 thân rắn
           == -2 <-> có tường
           == 1 số > 0 <-> có đồ ăn

Khi kiểm tra đụng vật thể nào sẽ dễ hơn rất nhiều:

xét rắn i với x, y là toạ độ của đầu rắn i:
    if (coor[x][y] > 0) {
        // cộng điểm vì đã ăn vào thức ăn, +1 độ dài rắn
    } else if (coor[x][y] == -1) {
        // oops, đụng rắn khác rồi
    } else if (coor[x][y] == -2) {
        // oops, đụng tường rồi
    }

Lưu ý là khi di chuyển rắn thì phải cập nhật lại bảng coor:

khi rắn i di chuyển:
    coor[x_đầu_mới][y_đầu_mới] = -1 // (x_đầu_mới, y_đầu_mới) là toạ độ mới của đầu rắn
    coor[x_đuôi_cũ][y_đuôi_cũ] = 0 // (x_đuôi_cũ, y_đuôi_cũ) là toạ độ cũ của đuôi rắn,
                                   // khi nó đi thì đuôi không có ở ô cũ
                                   // -> ô cũ không có bất kì phần nào của rắn ở đó

Trường hợp +1 độ dài rắn cũng làm tương tự.

1 Like

Bạn có thể chỉ mình rang bạn học c++ ở đâu không? Mình thấy bạn có kiến thức khá tốt

Trả lời bạn:

  • Từ cmt này:
  • Mình không đi học ở đâu mà mình tự học. Về sau C++ là chương trình bắt buộc phải học của mình nên mình được học nhiều thứ hơn.

Mà khoan, off-topic rồi :smile: Nếu muốn hỏi thêm về vấn đề này thì bạn lập topic mới hoặc inb trực tiếp cho mình trên DNH. Nói luôn là mình không xài fb :v

1 Like

Thank bạn tại mình mới học với lại hổm gài sửa lỗi đủ thứ nên ko để ý mình sẽ cố rắng khắc phục

Mình cũng vừa mới làm game rắn săn mồi. Bạn có thể xem của mình để tham khảo
https://github.com/53k41iga/simple-console-snake-game/blob/master/snake-game.c.c

P.s: Có thể còn hơi lộn xộn và khó hiểu mong bạn thông cảm

1 Like

Góp vui luôn. Viết cũng lẩuooif

1 Like

cảm ơn bạn nhé rất nhiều

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?