Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Консольный морской бой, проблема с курсором 
V
    Опции темы
heforma
Дата 22.11.2011, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 9.8.2011

Репутация: нет
Всего: нет



Здравствуйте! у меня проблема =( 
вот код:
Код

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
#include <conio.h>
using namespace std;
char cursor='+';
int x=17,y=2;
HANDLE h=GetStdHandle(STD_OUTPUT_HANDLE);
COORD c={x,y};
#define s 12        //РАЗМЕР ПОЛЯ
#define FildSize 10
#define FildEnd 'J'
#define score 16
#define ShipSize4 4 //4х ПАЛУБНЫЙ КОРАБЫЛЬ
#define ShipSize3 3 //3х ПАЛУБНЫЙ КОРАБЫЛЬ
#define ShipSize2 2 //2х ПАЛУБНЫЙ КОРАБЫЛЬ
char plr[s][s];        //ПОЛЕ ИГРОКА
char sht[s][s];        //СТРЕЛЬБИЩЕ
char cmp[s][s];        //ПОЛЕ КОМПЬЮТЕРА
const char up1=201,up2=187;                //СИМВОЛЫ ЛЕВОГО-ВЕРХНЕГО И ПРАВОГО-ВЕРХНЕГО УГЛА
const char down1=200,down2=188;            //СИМВОЛЫ ЛЕВОГО-НИЖНЕГО И ПРАВОГО-ВЕРХНЕГО УГЛА
const char vertical=186,horizontal=205; //ВЕРТИКАЛЬНЫЙ И ГОРИЗОНТАЛЬНЫЙ СИМВОЛЫ
const char ship=219;                    //ОТОБРАЖЕНИЕ КОРАБЛЯ
const char round=250;                    //ОБЛАСТЬ ВОКРУГ КОРАБЛЯ
const char hit=177;
const char miss=253;
int PlrScore=score;
int CmpScore=score;
void begin(char arr[][s])//ФУНКЦИЯ РАСТАНОВКИ ПОЛЕЙ
{
    for(int i=0;i<s;i++)
    {
        for(int j=0;j<s;j++)
        {
        if(i==0||i==s-1) arr[i][j]=horizontal;// |ВЕРХ-НИЗ
        if(j==0||j==s-1) arr[i][j]=vertical;//     |ЛЕВО-ПРАВО

        if(i==0&&j==0) arr[i][j]=up1;//      |ЛЕВЫЙ ВЕРХНИЙ УГОЛ
        if(i==0&&j==s-1) arr[i][j]=up2;// |ПРАВЫЙ ВЕРХНИЙ УГОЛ

        if(i==s-1&&j==0) arr[i][j]=down1;//      |ЛЕВЫЙ НИЖНИЙ УГОЛ
        if(i==s-1&&j==s-1) arr[i][j]=down2;// |ПРАВЫЙ НИЖНИЙ УГОЛ
        }
    }
}
void TakePoint(int &hor,int &ver)// ФУНКЦИЯ ГЕНЕРАЦИИ КООРДИНАТЫ
{
    hor=rand()%(s-3)+1;// КООРДИНАТА 1
    ver=rand()%(s-3)+1;// КООРДИНАТА 2
}
int Test(char arr[][s],int &hor,int&ver,int pos,int size)//ФУНКЦИЯ ПРОВЕРКИ ПРАВИЛЬНОСТИ КООРДИНАТ
{
    int t=1;
    if(pos)
    {
        for(int i=0,j=hor;i<ShipSize3;i++,j++)
            {
                if(arr[j][ver]==ship||arr[j][ver]==round) {TakePoint(hor,ver);t=0;}
            }
    }
    else
    {
        for(int i=0,j=ver;i<size;i++,j++)
            {
                if(arr[hor][j]==ship||arr[hor][j]==round) {TakePoint(hor,ver);t=0;}
            }
    }
    return t;
}
void ShipIn(char arr[][s],int size)// ФУНКЦИЯ АВТОМАТИЧЕСКОЙ РАСТАНОВКИ КОРАБЛЕЙ
{
    int hor,ver;
    TakePoint(hor,ver);//ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ
    int nap=rand()%2;// НАПРАВЛЕНИЕ КОРАБЛЯ
    if(nap)// ВЕРТИКАЛЬНО
    {
        while(!Test(arr,hor,ver,nap,size)) Test(arr,hor,ver,nap,size);
        if(hor+size<s-1)
        {
            for(int i=0,j=hor;i<size;i++,j++)
            {
                if(ver>1) arr[j][ver-1]=round;//ЛЕВО
                if(ver<10)arr[j][ver+1]=round;//ПРАВО
                if(hor>1)arr[hor-1][ver]=round;
                if(hor>1&&ver>1) arr[hor-1][ver-1]=round;
                if(hor>1&&ver<10) arr[hor-1][ver+1]=round;
                if(hor+size<s-1)arr[hor+size][ver]=round;
                if(hor+size<s-1&&ver>1) arr[hor+size][ver-1]=round;
                if(hor+size<s-1&&ver<10) arr[hor+size][ver+1]=round;
                arr[j][ver]=ship;
            }
        }
            else ShipIn(arr,size);
    }
    else// ГОРИЗОНТАЛЬНО
    {
        while(!Test(arr,hor,ver,nap,size)) Test(arr,hor,ver,nap,size);
        if(ver+size<s-1)
        {
            for(int i=0,j=ver;i<size;i++,j++)
            {
                if(hor>1) arr[hor-1][j]=round;
                if(hor<10)arr[hor+1][j]=round;
                if(ver>1) arr[hor][ver-1]=round;
                if(ver>1&&hor>1) arr[hor-1][ver-1]=round;
                if(ver>1&&hor<10) arr[hor+1][ver-1]=round;
                if(ver+size<s-1)arr[hor][ver+size]=round;
                if(ver+size<s-1&&hor>1) arr[hor-1][ver+size]=round;
                if(ver+size<s-1&&hor<10) arr[hor+1][ver+size]=round;
                arr[hor][j]=ship;
            }
        }
            else ShipIn(arr,size);
    }
}
void AutoSet(char arr[][s])
{
    ShipIn(arr,ShipSize4);
    ShipIn(arr,ShipSize3);
    ShipIn(arr,ShipSize3);
    ShipIn(arr,ShipSize2);
    ShipIn(arr,ShipSize2);
    ShipIn(arr,ShipSize2);

}
void Vertical(int size)
{
    bool t=false;
    int h,v;
    char c;
    do
    {
    t=false;
    cout<<"Please, enter a coordinates\n"<<endl;
    do
    {
    cout<<"H ";
    cin>>h;
    if(h<1||h>=FildSize-size) cout<<"Error!"<<endl;
    }
    while(h<1||h>FildSize-size);
    do
    {
    cout<<"V ";
    cin>>c;
    if(c<'A'||c>'J') cout<<"Error!"<<endl;
    }
    while(c<'A'||c>'J');
    v=c%64;
    cout<<v<<endl;
    for(int i=0,j=h;i<size;i++,j++)
    {
        if(plr[j][v]==ship||plr[j][v]==round)
        {
            t=true;
            cout<<"Error!"<<endl;
        }
    }
    }
    while(t);
    for(int i=0,j=h;i<size;i++,j++)
            {
                if(v>1) plr[j][v-1]=round;//ЛЕВО
                if(v<10)plr[j][v+1]=round;//ПРАВО
                if(h>1) plr[h-1][v]=round;
                if(h>1&&v>1) plr[h-1][v-1]=round;
                if(h>1&&v<10) plr[h-1][v+1]=round;
                if(h+size<s-1) plr[h+size][v]=round;
                if(h+size<s-1&&v>1) plr[h+size][v-1]=round;
                if(h+size<s-1&&v<10) plr[h+size][v+1]=round;
                plr[j][v]=ship;
            }
}
void Horizontal(int size)
{
    bool t=false;
    int h,v;
    char c;
    do
    {
    t=false;
    cout<<"Please, enter a coordinates\n"<<endl;
    do
    {
    cout<<"H ";
    cin>>h;
    if(h<1||h>FildSize) cout<<"Error!"<<endl;
    }
    while(h<1||h>FildSize);
    do
    {
    cout<<"V ";
    cin>>c;
    if(c<'A'||c>=FildEnd-size) cout<<"Error!"<<endl;
    }
    while(c<'A'||c>=FildEnd-size);
    v=c%64;
    cout<<v<<endl;
    for(int i=0,j=v;i<size;i++,j++)
    {
        if(plr[h][j]==ship||plr[h][j]==round)
        {
            t=true;
            cout<<"Error!"<<endl;
        }
    }
    }
    while(t);
    for(int i=0,j=v;i<size;i++,j++)
            {
                if(h>1) plr[h-1][j]=round;
                if(h<10)plr[h+1][j]=round;
                if(v>1) plr[h][v-1]=round;
                if(v>1&&h>1) plr[h-1][v-1]=round;
                if(v>1&&h<10) plr[h+1][v-1]=round;
                if(v+size<s-1)plr[h][v+size]=round;
                if(v+size<s-1&&h>1) plr[h-1][v+size]=round;
                if(v+size<s-1&&h<10) plr[h+1][v+size]=round;
                plr[h][j]=ship;
            }
}
void show(char arr1[][s],char arr2[][s])
{
    cout<<"   ABCDEFGHIJ\t ABCDEFGHIJ"<<endl;
    for(int i=0;i<s;i++)
    {
        if(i>0&&i<s-2) cout<<i<<' ';
        else if(i==10) cout<<i;
        else cout<<"  ";
    for(int j=0,k=-s;k<s;j++,k++)
    {
        if(j==s) cout<<'\t';
        if(k<0) cout<<arr1[i][j];
        else cout<<arr2[i][k];
    }
        if(i>0&&i<s-2) cout<<i<<' ';
        else if(i==10) cout<<i;
        else cout<<"  ";
    cout<<endl;
    }
    cout<<"  ABCDEFGHIJ\t ABCDEFGHIJ"<<endl;
}
void HandSet()//ФУНКЦИЯ РУЧНОЙ РАСТАНОВКИ КОРАБЛЕЙ
{
    char key;
    show(plr,cmp);
    cout<<"Please, enter ship4"<<endl;
    cout<<"Vertical (V) or Horizontal(H)"<<endl;
    do
    {
    cin>>key;
    if(key!='V'||key!='H') cout<<"Error!"<<endl;
    }
    while(key!='V'||key!='H');
    if(key=='V')
    {
    Vertical(ShipSize4);
    }
    else
    {
    Horizontal(ShipSize4);
    }

}
void Move(char arr[][s],int &hor,int &ver)
{
    do
    {
    if((GetKeyState(VK_UP)&0x80)!=0)
    {
        if(c.Y>y)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.Y--;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    if((GetKeyState(VK_DOWN)&0x80)!=0)
    {
        if(c.Y<=FildSize)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.Y++;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    if((GetKeyState(VK_LEFT)&0x80)!=0)
    {
        if(c.X>17)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.X--;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    if((GetKeyState(VK_RIGHT)&0x80)!=0)
    {
        if(c.X<26)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.X++;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    }
    while(!GetKeyState(VK_RETURN));
    hor=c.Y-1;
    ver=c.X-16;
}
void PlrShot(char arr[][s])
{
    int hor,ver;
    bool chek=false;
    do{
    Move(sht,hor,ver);
    if(cmp[hor][ver]==ship)
    {
    cmp[hor][ver]=hit;
    arr[hor][ver]=hit;
    CmpScore--;
    system("cls");
    show(plr,sht);
    cout<<"\nWe have hit ship of enemy!\n"<<endl;
    if(CmpScore)chek=true;
    }
    else
    {
    if(cmp[hor][ver]==hit||cmp[hor][ver]==miss)
    {
    system("cls");
    show(plr,sht);
    cout<<"\nThis area was shot early!\n"<<endl;
    chek=true;
    }
    else
    {
    if(cmp[hor][ver]==0)
    {
    cmp[hor][ver]=miss;
    arr[hor][ver]=miss;
    system("cls");
    show(plr,sht);
    cout<<"\nWe have a miss =(\n"<<endl;
    chek=false;
    }
    }
    }
    }
    while(chek);
}
void CmpShot()
{
    int hor,ver;
    TakePoint(hor,ver);
    if(plr[hor][ver]==ship)
    {
    plr[hor][ver]=hit;
    PlrScore--;
    system("cls");
    show(plr,sht);
    CmpShot();
    }
    else
    {
    if(plr[hor][ver]==hit||plr[hor][ver]==miss) CmpShot();
    else
    {
        plr[hor][ver]=miss;
        system("cls");
        show(plr,sht);
        cout<<"\nEnemy was shot in "<<hor<<" "<<ver<<endl;
    }
    }
}
void Clean(char arr[][s])
{
    for(int i=0;i<s;i++){
        for(int j=0;j<s;j++){
        if(arr[i][j]==round)arr[i][j]=0;
        }
    }
}
void main()
{
    srand(time(0));
    begin(plr);
    begin(cmp);
    begin(sht);
    AutoSet(cmp);
    Clean(cmp);
    AutoSet(plr);
    Clean(plr);
    show(plr,sht);
    do
    {
    PlrShot(sht);
    CmpShot();
    }
    while(CmpScore&&PlrScore);
    
}


При выстреле кнопкой "Enter" цикл начинает постоянно срабатывать, при повторном нажатии все становится нормально и курсором можно пользоваться.
При использовании функции cin.ignore() в функции Move() начинаются другие проблемы после выстрела приходится вводить 2 любых не числа что бы пользоваться курсором =(

Помогите пожалуйста! я не знаю что делать =(((
PM MAIL   Вверх
bsa
Дата 22.11.2011, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 1
Всего: 196



Рекомендую тебе вообще отказаться от iostream в пользу функций прямого управления консолью средствами WinAPI. iostream, как и stdio, предназначены вообще для других целей и в твоем случае они будут тебе всегда мешать.
PM   Вверх
heforma
Дата 22.11.2011, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 9.8.2011

Репутация: нет
Всего: нет



Я бы с радостью но не могу =) WinAPI это очень далеко по программе, у меня постоянно срабатывает цикл в функции Move() что приводит к постоянной передачи координат =( как можно ещё можно очистить буфер кроме cin.ignore() ?
PM MAIL   Вверх
bsa
Дата 23.11.2011, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 1
Всего: 196



heforma, не вижу связи между WinAPI и функцией Move(). Ты постоянно используешь WinAPI для управления курсором. Так почему бы его не использовать и для очистки экрана (вместо запуска программы cls), и для вывода символов на экран...
Если так хочется, то используй функции управления консолью из conio.h. Там же есть функции чтения клавиш и пр. Но вот от iostream необходимо все же отказаться. Хотя бы в пользу cstdio.

Это сообщение отредактировал(а) bsa - 23.11.2011, 10:48
PM   Вверх
heforma
Дата 23.11.2011, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 9.8.2011

Репутация: нет
Всего: нет



Цитата(bsa @  23.11.2011,  10:47 Найти цитируемый пост)
Ты постоянно используешь WinAPI для управления курсором

Если честно я не знал что использую WinAPI =) приведите пожалуйста пример, функция clrscr() у меня не работает =( сижу на VS 2010
PM MAIL   Вверх
heforma
Дата 28.11.2011, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 9.8.2011

Репутация: нет
Всего: нет



С такой функцией Move() все работает хорошо =)

Код

void Move(char arr[][s],int &hor,int &ver)
{
    int but=0;
    do
    {
    but=getch();
    if(but==72)
    {
    if(c.Y>y)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.Y--;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    if(but==80)
    {
    if(c.Y<=FildSize)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.Y++;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    if(but==75)
    {
    if(c.X>17)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.X--;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    if(but==77)
    {
    if(c.X<26)
        {
            SetConsoleCursorPosition(h,c);
            cout<<arr[c.Y-(y-1)][c.X-(x-1)];
            c.X++;
        }
    SetConsoleCursorPosition(h,c);
    cout<<cursor;
    Sleep(150);
    }
    }
    while(but!=32);
    hor=c.Y-1;
    ver=c.X-16;
}


Это если студентам КА "ШАГ" нужно будет =)) или другим студентам с подобным заданием =)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1151 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.