Войти

Показать полную графическую версию : Помогите с кодом с++


Nerest
24-07-2014, 20:41
Итак, пытаюсь написать консольную змейку на c++. Однако возникли некоторые проблемы... С осуществлением движения змейки. Вот мой код. Я знаю, что проблема в функциях clear() и move(), но никак не доходит до меня, как эту проблему решить... Пожалуйста, помогите разобраться новичку... И просьба не кидать ссылок на готовые коды змейки. Я их видел, но хочу написать свою змейку сам =) Нужна лишь помощь в этом проблеме.

#include <iostream.h>
#include <stdio.h>
#include <time>
#include <conio>
using namespace std;

char pole[20][20]; int symbol;

int coordinatesX[1000], coordinatesY[1000];
int size;
int choiseX, choiseY;

void field()
{
for (int i = 0; i<20; i++)
{
for (int j = 0; j<20; j++)
{
if (i==0 || i == 19 || j == 0 || j == 19) {pole[i][j]='#';}
else {pole[i][j]=' ';}
}
}
cin.get();
}

void standart()
{
field();
coordinatesY[1]=2; coordinatesX[1]=3; coordinatesY[2]=2; coordinatesX[2]=2;
choiseX = 1; choiseY=0;
size = 2;
}

void display()
{
system ("cls");
for (int i = 0; i<20; i++)
{
for (int j = 0; j<20; j++)
{
cout << pole[i][j];
if (j == 19) cout << endl;
}
}
}


void snake()
{
switch (choiseX)
{
case 1: pole[coordinatesY[1]][coordinatesX[1]] = '>'; break;
case -1: pole[coordinatesY[1]][coordinatesX[1]] = '<'; break;}
switch (choiseY){
case 1: pole[coordinatesY[1]][coordinatesX[1]] = 'v'; break;
case -1: pole[coordinatesY[1]][coordinatesX[1]] = '^'; break;
}
for (int i = 2; i <= size; i++)
{
pole[coordinatesY[i]][coordinatesX[i]]='@' ;
}
}

void chlearing()
{
pole[coordinatesY[1]-choiseY][coordinatesX[1]-choiseX]=' ';
pole[coordinatesY[2]-choiseY][coordinatesX[2]-choiseX]=' ';
}

void clear()
{
for (int i = 1; i<=size; i++)
{pole[coordinatesY[i]][coordinatesX[i]]=' ';}
}

void move()
{
clear();
for (int i = size;i>=2;i--)
{
coordinatesX[i]=coordinatesX[i-1];
coordinatesY[i]=coordinatesY[i-1];
}
coordinatesX[1]=coordinatesX[1]+choiseX;
coordinatesY[1]=coordinatesY[1]+choiseY;
display();
}

void changing()
{
symbol = getch();
switch (symbol)
{
case 'd': if (choiseX!=-1) choiseX = 1; choiseY=0; break;
case 'a': if (choiseX!=1) choiseX = -1; choiseY=0; break;
case 's': if (choiseY!=-1) choiseY = 1; choiseX=0; break;
case 'w': if (choiseY!=1) choiseY = -1; choiseX=0; break;
case 'f': size++; break;
}
}




int main()
{
standart();
display();

while(1)
{
snake();
if (kbhit()==true){changing();}
move();
display();
Sleep(200);
}

cin.get();
}

pva
27-07-2014, 09:16
Nerest, советы:
1. обрамляй код тегом "code", иначе нечитаемо
2. твой код не собирается т.к. перепутано местами, где надо .h и где не надо
3. В с/c++ индекс массивов начинается с 0 (но твой код работоспособен). Это чаще бывает удобно, чем когда начинается с 1
4. if(x==true) сработает только тогда, когда int(x)=1, if (x) тогда, когда int(x)!=0. x лучше писать в виде is_XXX или have_XXX, например if (is_kbhit())
5. Проследи места, когда ты делаешь вывод на экран. Выводить нужно 1 раз за цикл, тогда, когда у тебя поле построено полностью
Вот так работает:

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

char pole[20][20]; int symbol;

int coordinatesX[1000], coordinatesY[1000];
int size;
int choiseX, choiseY;

void field()
{
for (int i = 0; i<20; i++)
{
for (int j = 0; j<20; j++)
{
if (i==0 || i == 19 || j == 0 || j == 19) {pole[i][j]='#';}
else {pole[i][j]=' ';}
}
}
cin.get();
}

void standart()
{
field();
coordinatesY[1]=2; coordinatesX[1]=3; coordinatesY[2]=2; coordinatesX[2]=2;
choiseX = 1; choiseY=0;
size = 2;
}

void display()
{
system ("cls");
for (int i = 0; i<20; i++)
{
for (int j = 0; j<20; j++)
{
cout << pole[i][j];
if (j == 19) cout << endl;
}
}
}


void snake()
{
switch (choiseX)
{
case 1: pole[coordinatesY[1]][coordinatesX[1]] = '>'; break;
case -1: pole[coordinatesY[1]][coordinatesX[1]] = '<'; break;}
switch (choiseY){
case 1: pole[coordinatesY[1]][coordinatesX[1]] = 'v'; break;
case -1: pole[coordinatesY[1]][coordinatesX[1]] = '^'; break;
}
for (int i = 2; i <= size; i++)
{
pole[coordinatesY[i]][coordinatesX[i]]='@' ;
}
}

void chlearing()
{
pole[coordinatesY[1]-choiseY][coordinatesX[1]-choiseX]=' ';
pole[coordinatesY[2]-choiseY][coordinatesX[2]-choiseX]=' ';
}

void clear()
{
for (int i = 1; i<=size; i++)
{pole[coordinatesY[i]][coordinatesX[i]]=' ';}
}

void move()
{
clear();
for (int i = size;i>=2;i--)
{
coordinatesX[i]=coordinatesX[i-1];
coordinatesY[i]=coordinatesY[i-1];
}
coordinatesX[1]=coordinatesX[1]+choiseX;
coordinatesY[1]=coordinatesY[1]+choiseY;
//display();
}

void changing()
{
symbol = getch();
switch (symbol)
{
case 'd': if (choiseX!=-1) choiseX = 1; choiseY=0; break;
case 'a': if (choiseX!=1) choiseX = -1; choiseY=0; break;
case 's': if (choiseY!=-1) choiseY = 1; choiseX=0; break;
case 'w': if (choiseY!=1) choiseY = -1; choiseX=0; break;
case 'f': size++; break;
}
}




int main()
{
standart();

while(1)
{
if (kbhit()==true){changing();}
move();
snake();
display();
Sleep(200);
}

cin.get();
}

Интересный эффект, когда змейка заходит за границу

Nerest
28-07-2014, 01:42
Спасибо огромное, добрый человек! =)) И впрямь заработало, как надо. Теперь два вопроса остались :D

1) Какое влияние оказывает порядок подключения .h файлов?
2) Если все-таки нажать f, исходя из моего кода, то не только увеличится размер, но и удалится верхний уголок карты... Не можешь подсказать, почему?..

pva
28-07-2014, 21:28
Какое влияние оказывает порядок подключения .h файлов? »
Грамотно написанные и используемые заголовочные файлы не должны иметь порядок подключения
твой код не собирается т.к. перепутано местами, где надо .h и где не надо »
в том смысле, что не <iostream.h>, а iostream, не <time>, а <time.h> и т.д.
Не можешь подсказать, почему?.. »
Я ограниченно добрый! Предлагаю научиться пользоваться отладчиком ;) Какой у тебя компилятор/IDE?

Nerest
29-07-2014, 02:24
А разве iostream.h и iostream - не одно и то же?) Какая разница между ними?)
Компилятор - borland c++ builder 6

THEDOGG
29-07-2014, 02:43
А разве iostream.h и iostream - не одно и то же?) Какая разница между ними?) »

В iostream.h все классы объявлены в глобальном пространстве имен, а в iostream - в пространстве std.

При использовании iostream в начале файла указывается \
using namespace std;

либо перед каждым упоминанием имени из iostream ставить std::

Nerest
29-07-2014, 14:10
либо перед каждым упоминанием имени из iostream ставить std:: »

А... видел такие коды =) только не понимаю, как людей не напрягает каждый раз это писать, если действительно можно отделаться строкой using namespace std;

THEDOGG
29-07-2014, 14:36
только не понимаю, как людей не напрягает каждый раз это писать, если действительно можно отделаться строкой using namespace std; »
using namespace std глобально вызывать не очень хорошо, для легких программ - можно. А если тебе понадобятся другие пространства имен?
Смысла нет включать пространство имен, ради двух функций




© OSzone.net 2001-2012