Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Определение цвета клетки на шахматной доске


Автор: Enya 15.1.2006, 23:27
Вот. Всего на шахматной доске получается 64 клетки. Программа запрашивает число и говорит какого цвета ячейка под этим номером. Я что-то выбилась из сил. smile
Цитата

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

Вот одна мысль по поводу этой задачи:
Код

#include <stdio.h>
    int main(void){
        int key, t, i, num[8][8];
            for(t=0; t<8; t++)
                for(i=0; i<8; i++){
                    num[t][i] = (t*8)+i+1;
                }                
                         printf("Введите номер ячейки:");
                         scanf("%i",&key);
            /* вывод матрицы */
            for(t=0; t<8; t++){
                for(i=0; i<8; i++)
                    printf("%3i ", num[t][i]);
                printf("\n");
            }
/*поиск */
            for(t=0; t<8; t++){
                for(i=0; i<8; i++){
            if(key==num[t][i]){
                 printf("Color - white\n");
           }else{ 
               printf("Color - black\n");
                   }
               }
            }               
        return 0;
    }

Вот что получается если ввести например номер 3:
Цитата

Введите номер ячёйки:3
  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
Color - black
Color - black
Color - white
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black
Color - black

Может у кого-нибудь родяться мысли? smile
Добавлено @ 23:28
Первая ячейка ЧЁРНАЯ.

Автор: DeadSoul 15.1.2006, 23:35
Enya, а не пробовал нумеровать шахматные клетки по-другому? Задавать координаты клетки двумя числами(координаты по x и y).
При переходе на соседнюю клетку(по горизонтали или вертикали) цвет клетки меняется. Таким образом, цвет клетки получается равен:
( x%2 + y%2 )%2 = (x+y)%2, где (x,y) - координата клетки

Автор: Enya 15.1.2006, 23:37
DeadSoul, вашу бы мысль да кодом выразить?!

Автор: DeadSoul 15.1.2006, 23:57
Цитата(Enya @ 15.1.2006, 23:37 Найти цитируемый пост)

DeadSoul, вашу бы мысль да кодом выразить?!

А чего тут выражать?

Автор: Enya 16.1.2006, 00:10
DeadSoul хотя бы кусок кода черкани...
smile

Автор: Fin 16.1.2006, 00:14
Вот в эту формулу вводиш номер ячейки (num) в пределах от 1 до 64
Код
 
color=(((((num-1) / 8) & 1)+(((num-1) % 8) & 1)) & 1);

color приобретает значение 0 если ячейка черная и 1 если ячейка белая. Все остальное уже дело техники.


Автор: Partizan 16.1.2006, 00:18
хех...а решение-то элементарное smile

советую завести двумерный массив типа, например bool, и не париться smile
то бишь 1- белый... 0 - чёрный smile
Код

void main()
{

bool CMarray[8][8] =  {
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1,
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1,
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1,
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1 
                                   };


int Num;
cout << "Enter the cell number \n";
cin >> Num;

CMarray[ Num/8 ][ Num%8-1 ]  ?  cout << "Black" : cout << "White";
}

Автор: DeadSoul 16.1.2006, 00:34
Цитата(Partizan @ 16.1.2006, 00:18 Найти цитируемый пост)

советую завести двумерный массив типа, например bool, и не париться

И зачем?

Автор: Partizan 16.1.2006, 00:40
CMarray[ Num/8 ][ Num%8-1 ] ? cout << "Black" : cout << "White";

за этим....

Автор: Fin 16.1.2006, 00:46
Partizan У тебя в выражении маленькая логическая ошибка. счисление начинается с 1. Надо скорее всего так:
Код

CMarray[ (Num-1)/8 ][ (Num-1)%8 ] ? cout << "Black" : cout << "White";

Автор: Enya 16.1.2006, 00:52
Fin, Partizan ребята спасибо. smile
Но вот только на языке Си есть булевые переменные?
И вот ещё вопрос массивчик CMarray
Код

bool CMarray[8][8] =  {
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1,
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1,
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1,
                                      1, 0, 1, 0, 1, 0, 1, 0,
                                      0, 1, 0, 1, 0, 1, 0, 1 
                                   };
Не ручками же писать, можно ведь и вложенными циклами забить матрицу?!

Автор: DeadSoul 16.1.2006, 00:52
Цитата(Partizan @ 16.1.2006, 00:40 Найти цитируемый пост)

CMarray[ Num/8 ][ Num%8-1 ] ? cout << "Black" : cout << "White";
за этим....

У меня нумерация идет с нуля и используется одномерный массив размера 64:
Код

bool IsBlack(int number)
{
  return (number%8 + number/8)&1;// % и / можно заменить &0xFF и >>8
}

if ( IsBlack(number) )
 cout<<"Black";
else
 cout<<"White";


В чем выражается премущество твоего варианта?

Автор: Partizan 16.1.2006, 01:34
Собственно зря вы так smile... я же не говорил, что предложенное мной решение единственно...
Человек попросил код решения, я его написал вот и всё..... чей код использовать это уже его(её) личый выбор...

Автор: Helicopterr 16.1.2006, 02:51
int number;
cin >> number;

if ( (number % 2) > NULL )
cout<<"Black";
else
cout<<"White";

smile

Partizan создавать массив 8х8 ради этой задачи? Я плакал. smile

Автор: Partizan 16.1.2006, 03:11
Helicopterr я бы советовал вам подумать, прежде чем писать оскорбления...
заметьте 1-я клетка имеет Чёрный цвет.... 9-я - белый....
а в вашем коде и 1 и 9 имеют чёрный цвет....
то бишь получется что столбцы с нечетными номерами чёрные, а с чётными - белые...

вот так... -1.....

Автор: darkart 16.1.2006, 03:23
Наверное так...
Код

#include<stdio.h>
int main()
{
        const int n=8;//размер доски
        int num;//вводимый номер
        printf("Please enter a number(1-64):\n");
        scanf("%d",&num);
        printf("Result:");
        (((num-1)/n+num%n)%2)?printf("black\n"):printf("white\n");//проверка на четность/нечетность суммы номеров строки и столбца номера num
        return 0;
}

Автор: Helicopterr 16.1.2006, 03:41
Partizan
Смотря с какой стороны смотреть на доску и в каком порядке отсчитывать поля.
А насчет "оскорблений" я что-то не понял.

Автор: Enya 16.1.2006, 09:26
darkart, ваша мысль наиболее чёткая.
Всем спасибо.
Ночью будет время, расскажу что было на занятиях по програмированию. smile

Автор: Partizan 16.1.2006, 11:10
Цитата(Helicopterr @ 16.1.2006, 03:41)
Partizan
Смотря с какой стороны смотреть на доску и в каком порядке отсчитывать поля.
А насчет "оскорблений" я что-то не понял.

вы плакали? smile...

хорошо... покажите мне,пожалуйста такой пример отсчета, чтобы ваша формула была верна....
смотреть на доску можете хоть с какой стороны...
ну и конечно последовательность клеток должна сохраняться...то есть нумерация должна быть строго последовательна...а не нумеровать по диагоналям...

Автор: Helicopterr 16.1.2006, 15:52
Partizan
Зачем по диагоналям? змейкой или по кругу вполне можно. Но предлагаю всё же уточнить начальные условия.
Итак условия, как я понял: счёт полей по вертикалям слево направо т.е. будто текст читаем, ввод пользователя от 1 до 64. Ещё напомню, что в шахматах первое поле - а1 (1) черное, как и последнее - h8 (64). Тогда получим:

Код

   int number;
   cin>>number; number--;
   if( (number - (int)number/8) % 2 > NULL )
   cout<<"cell is white";
   else
   cout<<"cell is black";


Думаю, вполне лаконично. smile
Насчёт варианта darkart незнаю, сейчас посмотрю...

Автор: Partizan 16.1.2006, 17:06
а теперь, пожалуйста, сравните то, что у вас было раньше, и то, что у вас есть сейчас...
ибо результаты работы программ Разные(!).

Автор: DeadSoul 16.1.2006, 22:46
Цитата(Partizan @ 16.1.2006, 03:11 Найти цитируемый пост)

Helicopterr я бы советовал вам подумать, прежде чем писать оскорбления...

Это констатация факта. Я, например, не получил внятного ответа на вопрос за каким лешим там нужен массив
Добавлено @ 22:47
Цитата(Partizan @ 16.1.2006, 17:06 Найти цитируемый пост)

а теперь, пожалуйста, сравните то, что у вас было раньше, и то, что у вас есть сейчас...
ибо результаты работы программ Разные(!).

На каких компиляторах проверял и с какими настройками?

Автор: Fin 16.1.2006, 23:01
Ребята smile . Задача простая, но тот вариант, который предложил Partizan не лишен смысла. Конечно в данной задаче он чуть чуть тяжеловесен. Но когда у Вас стоит задача разделять на группы символы приходяшие на вход функции (например: число, латиница большая, латиница маленькая, кирилица большая, кирилица маленькая, символы, недопустимые значения). Этот способ намного эффективнее в работе и намного более легко настраиваемый.

Автор: Enya 17.1.2006, 00:28
darkart, ваше решение наиболее оптимальное!

Автор: DeadSoul 17.1.2006, 01:04
Цитата(Enya @ 17.1.2006, 00:28 Найти цитируемый пост)

darkart, ваше решение наиболее оптимальное!

Неа, для int-ов вместо
a%2
выгоднее писать
a&1

Автор: azesmcar 17.1.2006, 09:47
Меня кое что другое очень заинтересовало..почему все решают задачу находя координаты шахматного поля одним int num?

Почему не двумя координатами? Для решения шахматных задач насколько я знаю используются два...

Автор: Partizan 17.1.2006, 11:33
Цитата(DeadSoul @ 16.1.2006, 22:46 Найти цитируемый пост)

Добавлено @ 22:47

Цитата(Partizan @ 16.1.2006, 17:06 )

а теперь, пожалуйста, сравните то, что у вас было раньше, и то, что у вас есть сейчас...
ибо результаты работы программ Разные(!).


На каких компиляторах проверял и с какими настройками?


проверял в своей голове....чтобы понять что эти 2 кода различны совсем не обязательно пытаться их скомпилировать....если не верите можете скомпилировать их...
1-й его код(неверный)(это из мессаги, в которой он плакал smile (я кстати тоже плакал, увидев этот код smile ) а вообще давайте не будем ругаться smile ...):
Код

int number;
cin >> number;

if ( (number % 2) > NULL )
cout<<"Black";
else
cout<<"White";


2-й его код (верный):
Код

 int number;    
   cin>>number; number--;    
   if( (number - (int)number/8) % 2 > NULL )    
   cout<<"cell is white";    
   else    
   cout<<"cell is black";


Автор: threef 17.1.2006, 11:49

Цитата(azesmcar @ 17.1.2006, 08:47 Найти цитируемый пост)

Почему не двумя координатами?

Потому, что при обращении к двумерному массиву x[a][b] оно преобразуется компилятором в выражение вида
*(*(x+a)+b). Поэтому нет противопоказаний, чтобы это же сделать самому :
x[64], *(x+a*8+b)==*(x+a<<3+b).

Автор: azesmcar 17.1.2006, 12:21
Цитата
Потому, что при обращении к двумерному массиву x[a][b] оно преобразуется компилятором в выражение вида
*(*(x+a)+b). Поэтому нет противопоказаний, чтобы это же сделать самому :
x[64], *(x+a*8+b)==*(x+a<<3+b).


Ну это то ясно...меня интересует почему функции с одним параметром???
Ну так давайте сразу забудем о двумерных массивах будем использовать одномерные и каждый раз вычислять из заданых координатов...какой смысл??? если работаем как с двумерным массивом то и индексы обращения должны быть как у двумерного...

Я же не говорю что это противопоказано...просто думаю что неудобно, ведь работать с этой доской придеться потом как с двумерным массивом, вместо одного индекса будут два...не преобразовывать же его каждый раз?

Автор: Guest 17.1.2006, 12:39
bool Value; - 1 байт в откомпилированном exe, соответственно в памяти тоже. 8*8=64 байта? И вы предлагаете массив для решения тривиальной задачи. smile

Автор: _hunter 17.1.2006, 13:02
охренительно огромный объем оперативки. где б еще ком найти, чтобы там эта жутко огромная программа запустилась?

Автор: Fin 17.1.2006, 17:02
azesmcar
Цитата

Меня кое что другое очень заинтересовало..почему все решают задачу находя координаты шахматного поля одним int num?

Почему не двумя координатами? Для решения шахматных задач насколько я знаю используются два...

Чтобы понять, почему именно такие решения даются, прочти условия задачи.

Цитата

Вот. Всего на шахматной доске получается 64 клетки. Программа запрашивает число и говорит какого цвета ячейка под этим номером. Я что-то выбилась из сил. smile
Цитата

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


Автор: azesmcar 17.1.2006, 17:06
Цитата
Чтобы понять, почему именно такие решения даются, прочти условия задачи.


Этот вопрос и автора касается... smile

Автор: Exekutor 21.1.2006, 14:33
Забавно, что вокруг такой тривиальной задачки разгорелась такая дискуссия. Каждый начинающий программист решал такую или похожую задачку. Согласен с Helicopterr это решение самое эффективное.

З. Ы.
Цитата

Partizan создавать массив 8х8 ради этой задачи? Я плакал. 
smile smile

Автор: Helicopterr 24.1.2006, 00:40
Exekutor
Спасибо! Хоть кто-то понял...
smile

Автор: DeadSoul 24.1.2006, 22:11
Цитата(Exekutor @ 21.1.2006, 14:33 Найти цитируемый пост)

Забавно, что вокруг такой тривиальной задачки разгорелась такая дискуссия

Exekutor, это нормально. Просто начинающий не видит некоторые вещи, которые увидит более опытный
Добавлено @ 22:19
Вот пример вопроса:
Код

class DoublePtr
{
public:
  DoublePtr( A* pA, B* pB );
 ~DoublePtr()
 
 A* GetA();
 B* GetB();
private:
  A* m_pA;
  B*m_pB;
};

DoublePtr::DoublePtr( int* pInt, double* pDouble ),m_pA(pA),m_pB(pB)
{
}

DoublePtr::~DoublePtr()
{
delete m_pA;
delete m_pB;
 }

A* DoublePtr::GetA(){return m_pA;};
B* DoublePtr::GetB(){return m_pB;};


Классы A и B реализованы где-то выше. С данным классом все в порядке?

Автор: Partizan 25.1.2006, 02:00
Цитата

Exekutor
Спасибо! Хоть кто-то понял...


Я не утверждал что предложенное мной решение единственно...тем не менее оно имеет право на существование.... но вы, согласитесь, в первом варианте решения не то совсем написали, что нужно...

Цитата

Классы A и B реализованы где-то выше. С данным классом все в порядке?


Конструктор в обявлении класса и реализация разные smile

DoublePtr( int* pInt, double* pDouble ) не есть конструктор класса DoublePtr smile

Автор: DeadSoul 26.1.2006, 22:23
Цитата(Partizan @ 25.1.2006, 02:00 Найти цитируемый пост)

DoublePtr( int* pInt, double* pDouble ) не есть конструктор класса DoublePtr 

Описался, блин.

"Правильный" код выглядит так:
Код

class DoublePtr
{
public:
  DoublePtr( A* pA, B* pB );
 ~DoublePtr()
 
 A* GetA();
 B* GetB();
private:
  A* m_pA;
  B*m_pB;
};

DoublePtr::DoublePtr( A* pInt, B* pDouble ),m_pA(pA),m_pB(pB)
{
}

DoublePtr::~DoublePtr()
{
delete m_pA;
delete m_pB;
 }

A* DoublePtr::GetA(){return m_pA;};
B* DoublePtr::GetB(){return m_pB;};

Так с этим кодом все в порядке?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)