• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Ocena kodu gry snake w kosnoli

Object Storage Arubacloud
+1 głos
1,139 wizyt
pytanie zadane 30 maja 2016 w C i C++ przez Rolnik Nowicjusz (220 p.)

Witam, chciałbym aby ktoś z większym doświadczeniem ode mnie ocenił kod gry, którą napisałem. Prosiłbym również o rady, w miarę możliwości, jak się poprawić w danym zagadnieniu. Z góry dziękuje za komentarze. 

KOD GRY
 

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <ctime>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
char tab[50][15];
int n=3; //dlugość węża
int m=5; //ilość jedzenia 
struct pkt
{
		int x,y;
};
bool polozenia(pkt point[],int i,int j, int ilosc) //sprawdzanie położenia węża i "jedzenia" w tabeli
{
	bool t=false;
	for(int a=0;a<ilosc;a++)
	{
		if(i==point[a].y&&j==point[a].x)
		{
			t=true;
			break;
		}
	}
	return t;
}
void plansza(pkt point[], pkt jedzenie[]) //wyświetlanie planszy
{
	cout<<"----------------------------------------------------"<<endl;
	for(int i=0;i<15;i++)
	{
		cout<<"|";
		for(int j=0;j<50;j++)
		{	
			if(polozenia(jedzenie,i,j,m)==true)
			tab[j][i]=231;
			if(polozenia(point,i,j,n)==true)
			{
				if(point[0].x==j&&point[0].y==i)
				tab[j][i]=254;
				else
				tab[j][i]=219;
			}
			cout<<tab[j][i];
		}
		cout<<"|"<<endl;
	}
	cout<<"----------------------------------------------------"<<endl;
}
void czysc() //czyszczenie planszy
{
	system("CLS");
	for(int i=0;i<15;i++)
	{
		for(int j=0;j<50;j++)
		tab[j][i]=' ';
	}
}
pkt ruch(pkt point, char znak) // ruch glowa węża
{
	
	if(znak==-32)
	{
		znak=getch();
		switch(znak)
		{
			case 72:
				{
					if(point.y>0)
					point.y=point.y-1;
					break;
				}
			case 75:
			 	{	if(point.x>0)
			 		point.x=point.x-1;
			 		break;
				}
			case 77:
				{
					if(point.x<100)
					point.x=point.x+1;
					break;
				}
			case 80:
				{
					if(point.y<30)
					point.y=point.y+1;
					break;
				}
			default:
				return point;
				break;
		}	
	}
	return point;
}

void uzup(pkt point[], int i) //ustawianie węża na początku gry
{
	point[i].x=point[i-1].x-1;
	point[i].y=point[i-1].y;
}
void uzup1(pkt point[],pkt point1[], int i) //uzupełnienie tabeli ze współrzędnymi w poprzednim ruchu
{

	point[i].x=point1[i-1].x;
	point[i].y=point1[i-1].y;
}
void swap(pkt point[],pkt point1[],int i) //funkcja pomocznica
{
	point1[i].x=point[i].x;
	point1[i].y=point[i].y;
}
void pokaz(pkt point[],pkt point1[]) //funkcja pomocnicza
{
	for(int i=0;i<n;i++)
	{
		cout<<point[i].x<<" "<<point[i].y<<endl;
		cout<<point1[i].x<<" "<<point1[i].y<<endl<<endl;
	}
}
void jedz(pkt jedzenie[], int a) //losowanie
{
	jedzenie[a].x=(rand() % 48 ) + 1;
	jedzenie[a].y=(rand() %	13 ) + 1;
}
bool dotyk(pkt point,pkt point1[]) //sprawdzenie czy waż nie zjada się lub nie dotyka ściany
{
	bool t=false;
	for(int i=1;i<n;i++)
	{
		if(point.x==point1[i].x&&point.y==point1[i].y) // waz
		{
			t=true;
			break;
		}
	}
	if(t==false) //sciany
	{
		
		if(point.x<0||point.x>49||point.y<0||point.y>14)
		t=true;
	}
	return t;
}
bool czyzjadl(pkt point, pkt jedzenie[]) //sprawdzanie czy wąż "zjadł"
{
	bool t=false;
	for(int i=0;i<m;i++)
	{
		if(point.x==jedzenie[i].x&&point.y==jedzenie[i].y)
		{
			t=true;
		}
	}
	return t;
}
void usunjedz(pkt point,pkt jedztab[], pkt point1[]) //usuwanie zjedzonego jedzenia
{
	int pomx,pomy;
	for(int i=0;i<m;i++)
	{
		if(point.x==jedztab[i].x&&point.y==jedztab[i].y)
		{
			do
			{
			jedztab[i].x=(rand() % 48 ) + 1;
			jedztab[i].y=(rand() % 13 ) + 1;
			}while(polozenia(point1,jedztab[i].x,jedztab[i].y,n)==true);
		}
	}

}
void dod(pkt point[], pkt pointpom[], pkt point1[]) //przedłużanie węża
{
	int pomx=2*point[n-2].x-point[n-3].x,pomy=2*point[n-2].y-point[n-3].y;
	pointpom[n-1].x=pomx;//2*point[n-2].x-point[n-3].x;
	pointpom[n-1].y=pomy;//2*point[n-2].y-point[n-3].y;
}
pkt symuluj(pkt point[]) //symulowanie ruchu węża
{
	pkt point1=point[0];
	if(point[0].x>point[1].x)
		point1.x=point1.x+1;
	else if(point[0].x<point[1].x)
		point1.x=point1.x-1;
	else if(point[0].y>point[1].y)
		point1.y=point1.y+1;
	else if(point[0].y<point[1].y)
		point1.y=point1.y-1;
	return point1;
}
int main(int argc, char** argv) {
	srand( time( NULL ) );
	char a;
	pkt *point;
	pkt *point1;
	point = new pkt [n];
	point1 = new pkt [n];
	pkt jedzenie [m];
	point[0].x=5;point[0].y=1;// początkowa pozycja głowy węża
	for(int i=1;i<n;i++)
		uzup(point,i);
	for(int i=0;i<m;i++)
		jedz(jedzenie,i);
	plansza(point, jedzenie);
	while(true)
	{
		
		for(int i=0;i<n;i++)
			swap(point,point1,i);
		for(int i=1;i<n;i++)
			uzup1(point,point1,i);
		Sleep(25);
		if(kbhit()==true)
		{
				a=getch();
				if(a==-32)
				point[0]=ruch(point[0],a);
				else 
				point[0]=symuluj(point1);
		}
		else
		point[0]=symuluj(point1);
		czysc();
		if(dotyk(point[0],point))
		{
			cout<<"Przegrales"<<endl;
			break;
		}
		if(czyzjadl(point[0],jedzenie)==true)
		{
			n++;
			pkt * pointpom = new pkt[ n ]; //tabela pomocnicza przed dodaniem pkt
			pkt * pointpom1 = new pkt[ n ]; //tabela pomocnicza przed dodaniem pkt
			for(int i=0;i<n-1;i++)
				swap(point,pointpom,i);
			for(int i=0;i<n-1;i++)
				swap(point1,pointpom1,i);
			if(n>2)
			dod(point,pointpom,point1);
			pointpom1[n-1].x=0;
			pointpom1[n-1].y=0;
			delete []point;
			delete []point1;
			point = new pkt[ n ];
			point1 = new pkt[ n ];
			for(int i=0;i<n;i++)
				swap(pointpom,point,i);
			for(int i=0;i<n;i++)
				swap(pointpom1,point1,i);
			delete []pointpom;
			delete []pointpom1;
			usunjedz(point[0],jedzenie,point);
		}
		plansza(point,jedzenie);

	}
	Sleep(500);
	return 0;
}

Ps. Uargumentowana krytyka mile widziana. 

komentarz 10 lipca 2016 przez obl Maniak (51,280 p.)
Wszystko ładnie i pięknie, tylko się nie kompiluje.

EDIT:

Dobra, poprawiłem sobie błędy twoje i skompilowałem :)

3 odpowiedzi

+2 głosów
odpowiedź 30 maja 2016 przez Patryk Krajewski Nałogowiec (26,170 p.)
wybrane 30 maja 2016 przez Rolnik
 
Najlepsza
Czytelność kodu leży. Wszystko posklejane, nazwy zmiennych raz jaką jedna litera, wyraz, pół wyrazu,  i jeszcze funkcja nazwana po angielsku(Tak, powinno się nazywać po angielsku, ale jak już coś to wszystko). Funkcję usunjedz można zrozumiemć jaką deleteAndEat(usuń i jedz). Zamiast komentarzy przy funkcji w nazwie funkcji opisz co robi np.: dotyk() rozdziel na dwie funkcje bool isCollisionWithWall() i bool isOwnCollision(). Jak kod będzię trochę czytelniejszy to mogę ocenić resztę :D
komentarz 30 maja 2016 przez Rolnik Nowicjusz (220 p.)
Okej, wielkie dzięki za radę.
komentarz 30 maja 2016 przez Rolnik Nowicjusz (220 p.)
Jeszcze jedno pytanie w jaki sposób prócz zmiany nazwy funkcji sprawić by kod był czytleniejszy?
komentarz 30 maja 2016 przez Patryk Krajewski Nałogowiec (26,170 p.)
Pisać mało komentarzy, krótkie funkcję i tak samo jak zmienne mają mówić do czego służą, robić jakieś odstępy w kodzie, bo u ciebie jest sklejony, pisać obiektowo. Polecam ci książke "Czysty Kod": http://helion.pl/ksiazki/czysty-kod-podrecznik-dobrego-programisty-robert-c-martin,czykov.htm ale to jak zapoznasz się z programowaniem obiektowym i napiszesz kilka programów. Tam masz opisane przez profesjonalistę.
komentarz 30 maja 2016 przez Rolnik Nowicjusz (220 p.)

Wielkie dzięki jeszcze raz, nikt nigdy nie uczył mnie jak pisać przejrzysty kod, więc taka lekcja się przyda. Zastosowałem się do Twoich rad, co jeszcze mogę zmienić w moim kodzie? 

 

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <ctime>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
char tab[50][15];
int snake_length=3; 			
int amount_of_food=5; 			

struct pkt
{
		int x,y;
};

bool site (pkt array[], int x, int y, int ilosc) 					
{
	bool tag = false;
	for(int i = 0; i < ilosc; i++)
	{
		if(y == array[i].y && x == array[i].x)
		{
			tag = true;
			break;
		}
	}
	return tag;
}

void show_board (pkt point_array[], pkt food_array[]) 						
{
	cout << "----------------------------------------------------" << endl;
	for(int y = 0; y < 15; y++)
	{
		cout << "|";
		for(int x = 0; x < 50; x++)
		{	
			if(site (food_array, x, y, amount_of_food) == true)
				tab[x][y] = 231;
				
			if(site (point_array, x, y, snake_length) == true)
			{
				if(point_array[0].x == x && point_array[0].y == y)
					tab[x][y] = 254;
				else
					tab[x][y] = 219;
			}
			cout << tab[x][y];
		}
		cout << "|" << endl;
	}
	cout << "----------------------------------------------------" << endl;
}

void clear () 
{
	system ("CLS");
	
	for(int y = 0; y < 15; y++)
	{
		for(int x = 0; x < 50; x++)
		tab[x][y] = ' ';
	}
}

pkt head_move (pkt point, char mark) 
{
	
	if(mark == -32)
	{
		mark = getch();
		switch(mark)
		{
			case 72:
				{
					if(point.y > 0)
					point.y = point.y-1;
					break;
				}
			case 75:
			 	{	if(point.x > 0)
			 		point.x = point.x-1;
			 		break;
				}
			case 77:
				{
					if(point.x < 100)
					point.x = point.x+1;
					break;
				}
			case 80:
				{
					if(point.y < 30)
					point.y = point.y+1;
					break;
				}
			default:
				return point;
				break;
		}	
	}
	return point;
}

void basic_supply (pkt point_array[], int i)  
{
	point_array[i].x = point_array[i-1].x-1;
	point_array[i].y = point_array[i-1].y;
}

void supply (pkt point_array[], pkt point_array1[], int i) 
{

	point_array[i].x = point_array1[i-1].x;
	point_array[i].y = point_array1[i-1].y;
}

void swap (pkt point_array[],pkt point1_array[],int i) 
{
	point1_array[i].x = point_array[i].x;
	point1_array[i].y = point_array[i].y;
}

void show_content (pkt point_array[], pkt point_array1[]) 
{
	for(int i = 0 ; i < snake_length; i++)
	{
		cout << point_array[i].x << " " << point_array[i].y << endl;
		cout << point_array1[i].x << " " << point_array1[i].y << endl;
	}
}

void food_draw (pkt food_array[] , int a) 
{
	food_array[a].x = (rand() % 48 ) + 1;
	food_array[a].y = (rand() %	13 ) + 1;
}

bool is_own_collision (pkt point , pkt point_array1[]) 							
{
	bool tag = false;
	
	for(int i = 1 ; i < snake_length; i++)
	{
		if(point.x == point_array1[i].x && point.y == point_array1[i].y) 		
		{
			tag = true;
			break;
		}
	}
	return tag;
}

bool is_collision_with_wall (pkt point)
{
	bool tag=false;
	
	if(point.x < 0 || point.x > 49 || point.y < 0 || point.y>14)
		tag = true;
		
	return tag;
}

bool food_check (pkt point, pkt food_array[]) 									
{
	bool tag = false;
	for(int i = 0; i < amount_of_food; i++)
	{
		if(point.x == food_array[i].x && point.y == food_array[i].y)
		{
			tag = true;
			break; 
		}
	}
	
	return tag;
}

void delete_food (pkt point_array ,pkt food_array[], pkt point_array1[])			 
{
	for(int i = 0; i < amount_of_food; i++)
	{
		if(point_array.x==food_array[i].x&&point_array.y==food_array[i].y)
		{
			do
			{
			food_array[i].x = (rand() % 48 ) + 1;
			food_array[i].y = (rand() % 13 ) + 1;
			} while (site (point_array1, food_array[i].x, food_array[i].y, snake_length) == true);
		}
	}

}

void snake_lengthen (pkt point_array[], pkt point_array_pom[], pkt point1_array[])			 
{
	int pom_x = 2 * point_array[snake_length-2].x - point_array[snake_length-3].x, pom+y = 2 * point_array[snake_length-2].y - point_array[snake_length-3].y;
	point_array_pom[snake_length-1].x = pom_x;		
	point_array_pom[snake_length-1].y = pom_y; 		
}

pkt simulate_move (pkt point_array[]) 										
{
	pkt point_pom = point_array[0];
	
	if(point_array[0].x > point_array[1].x)
		point_pom.x = point_pom.x+1;
		
	else if(point_array[0].x < point_array[1].x)
		point_pom.x = point_pom.x-1;
		
	else if(point_array[0].y > point_array[1].y)
		point_pom.y = point_pom.y+1;
		
	else if(point_array[0].y < point_array[1].y)
		point_pom.y = point_pom.y-1;
		
	return point_pom;
}

int main(int argc, char** argv) {
	srand( time( NULL ) );
	char mark;
	pkt *point_array;
	pkt *point_array1;
	pkt food_array [amount_of_food];
	
	point_array = new pkt [snake_length];
	point_array1 = new pkt [snake_length];
	
	
	point_array[0].x = 5;
	point_array[0].y = 1; 													
	
	for(int i = 1; i < snake_length; i++)
		basic_supply (point_array, i);
		
	for(int i = 0; i < amount_of_food; i++)
		food_draw (food_array, i);
		
	show_board (point_array, food_array);
	
	while(true)
	{
		for(int i = 0 ; i < snake_length ; i++)
			swap (point_array , point_array1 , i );
			
		for(int i = 1 ; i < snake_length ; i++)
			supply (point_array , point_array1 , i);
			
		Sleep(25);
		
		if(kbhit() == true)
		{
				mark = getch();
				
				if(mark == -32)
					point_array[0] = head_move (point_array[0], mark);
				else 
					point_array[0] = simulate_move (point_array1);
		}
		
		else
		point_array[0] = simulate_move (point_array1);
		
		clear();
		
		if(is_own_collision (point_array[0], point_array) || is_collision_with_wall (point_array[0]) )
		{
			cout << "Przegrales" << endl;
			break;
		}
		
		if(food_check (point_array[0], food_array) == true)
		{
			snake_length++;
			
			pkt * point_array_pom = new pkt[ snake_length ];				 
			
			pkt * point_array_pom1 = new pkt[ snake_length ];				 
			
			for(int i = 0; i < snake_length-1; i++)
				swap (point_array, point_array_pom, i);
				
			for(int i = 0; i < snake_length-1; i++)
				swap (point_array1, point_array_pom1, i);
				
			snake_lengthen (point_array, point_array_pom, point_array1);
			
			point_array_pom1[snake_length-1].x=0;
			
			point_array_pom1[snake_length-1].y=0;
			
			delete []point_array;
			
			delete []point_array1;
			
			point_array = new pkt[ snake_length ];
			
			point_array1 = new pkt[ snake_length ];
			
			for(int i = 0 ; i < snake_length; i++)
				swap(point_array_pom, point_array,i);
				
			for(int i = 0; i < snake_length; i++)
				swap(point_array_pom1, point_array1,i);
				
			delete []point_array_pom;
			
			delete []point_array_pom1;
			
			delete_food (point_array[0], food_array, point_array);
		}
		
		show_board (point_array, food_array);

	}
	
	Sleep(500);
	return 0;
}

 

komentarz 30 maja 2016 przez Patryk Krajewski Nałogowiec (26,170 p.)
Nie dziękuj w każdej wypowiedzi :D

Jest już lepiej, ale tych wskaźników używasz, żeby zmieniać ciągle rozmiar tablicy?, jeśli tak to lepiej użyć Vectora czyli taki kontener, który działa jak zwykła tablica, ale jego rozmiar się ciągle zmienia. Zresztą co będę ci opowiadał, przetestuj sam. Tu masz artykuł o nim: http://cpp0x.pl/kursy/Kurs-STL-C++/Kontener-tablicy-std-vector/119 Pomyśl trochę dłużej nad niektórymi nazwami. Te while(true) {..} to pewnie jakaś pętla gry? Jak tak to możesz to dodać do jakiejś funkcji np.: update(); Nie mówię, że kod SFML jest jakiś doskonały, ale zobacz jak on mniej więcej wygląda i spróbuj podobnie pisać. Wiem, że tam są klasy, ale na to nie zwracaj uwagi.
komentarz 30 maja 2016 przez Rolnik Nowicjusz (220 p.)
Wiem słyszałem o vectorze nawet kilka programów zrobiłem używająć głównie jego gdyż ma większe możliwości niż tablice, lecz problem polegał na tym, że przy moim sposobie funkcja, która miała dodawać kolejny punkt węża przy "zjedzeniu" zwracała złe współrzędne. Spróbuje przysiąść do tego jeszcze raz i znaleźć błąd, który to powodował :D
komentarz 29 lipca 2016 przez smh Obywatel (1,940 p.)
bool tag = false;
for(int i = 0; i < ilosc; i++)
{
    if(y == array[i].y && x == array[i].x)
    {
        tag = true;
        break;
    }
}
return tag;

a można

for(int i = 0; i < ilosc; ++i)
{
    if(y == array[i].y && x == array[i].x)
        return true;
}
return false;

(dalej to tylko jedna rzecz z mnóstwa)

0 głosów
odpowiedź 10 lipca 2016 przez Mikusbombro Użytkownik (990 p.)
Wypróbowałem twoją grę i powiem ci, że dobrze zrobiona, tylko jak się wyjdzie poza pole, to program od razu się wyłącza. Jest jeszcze kilka bugów i niedociągnięć, np. jeśli się wciśnie klawisz przeciwny do kierunku ruchu węża gra się sypie. A jeśli wąż porusza się pionowo, to się wydłuża i jest szybszy, a jeśli rusza się poziomo, to jest mniejszy i wolniejszy.

Mógłbyś to poprawić.
0 głosów
odpowiedź 10 lipca 2016 przez obl Maniak (51,280 p.)

Gra nawet fajna, ale po co sprawdzasz w funkcji head_move drugi raz czy mark jest równie -32 jak już wcześniej to zostało zrobione w funkcji main zanim użyłeś funkcji head_move. Linia 219 i linia 63.

Podobne pytania

+4 głosów
5 odpowiedzi 4,272 wizyt
pytanie zadane 8 marca 2016 w C i C++ przez Pixel040 Gaduła (3,100 p.)
+1 głos
2 odpowiedzi 639 wizyt
pytanie zadane 1 maja 2016 w C i C++ przez Curiosity Nowicjusz (130 p.)
+2 głosów
1 odpowiedź 803 wizyt
pytanie zadane 2 czerwca 2016 w C i C++ przez Pixel040 Gaduła (3,100 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...