как я выпиливал лобзиком

Dec 22, 2012 17:45

Имея некоторый опыт печатания шахматных диаграмм из шрифтов на PHP, я решил применить его в С++. И вот что из этого получилось:
Доска представляется таблицей 8*8 символов. Например:

{
' ', ' ', ' ', ' ', ' ', ' ', ' ', 'K',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
'k', ' ', 'P', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', 'p',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
};


Теперь оставалось создать строку, представляющую доску. Простейший вариант:

23 const std::string Board::ToString() const {
24 std::string board;
25 int i, j;
26
27 for (i = 0; i != 8; ++i) {
28 for (j = 0; j != 8; ++j) {
29 board.push_back(brd[i][j]);
30 }
31 board.push_back('\n');
32 }
33 return board;
34 }

Однако, в шахматных шрифтах для отображения белого короля на черной клетке надо использовать символ 'k', а для черного короля на черной клетке - 'l' (зависит от шрифта). Поэтому проще всего сделать ассоциативный массив, который будет возвращать в зависимости от фигуры и цвета поля нужный символ. Ассоциативных массивов в С++ нет, зато есть map. Однако первый подход к снаряду мне дал ошибку (вероятно, потоому что понадеялся на С++х11), поэтому я решил написать свой собственный ассоциативный массив (дурной пример!!!):

18 template
19 struct associative{
20 std::vector key;
21 std::vector value;
22
23 T2 operator [](const T1& k) const {
24 typename std::vector::const_iterator i = key.begin();
25 typename std::vector::const_iterator j = value.begin();
26 while(i != key.end()){
27 if(*i == k) break;
28 ++i;
29 ++j;
30 }
31
32 if(i == key.end()) return T2(); // throw std::exception();
33 return *j;
34 }
35
36 void addElement(T1 k, T2 v){
37 key.push_back(k);
38 value.push_back(v);
39 }
40 };

Как видно, мой массив умеет только добавлять пары и извлекать значения. После этого идёт создание карты преобразования и её инициализация:

36 // chess merida font
37 typedef unsigned char color_t;
38 const color_t white = 0;
39 const color_t black = 1;
40
41 associative< std::pair, char > char_map;
42
43 int init_map(){
44 char_map.addElement(std::make_pair(' ', white), ' ');
45 char_map.addElement(std::make_pair(' ', black), '+');
46
47 char_map.addElement(std::make_pair('p', white), 'o');
48 char_map.addElement(std::make_pair('n', white), 'm');
49 char_map.addElement(std::make_pair('b', white), 'v');
50 char_map.addElement(std::make_pair('r', white), 't');
51 char_map.addElement(std::make_pair('q', white), 'w');
52 char_map.addElement(std::make_pair('k', white), 'l');
53
54 char_map.addElement(std::make_pair('p', black), 'O');
55 char_map.addElement(std::make_pair('n', black), 'M');
56 char_map.addElement(std::make_pair('b', black), 'V');
57 char_map.addElement(std::make_pair('r', black), 'T');
58 char_map.addElement(std::make_pair('q', black), 'W');
59 char_map.addElement(std::make_pair('k', black), 'L');
60
61 char_map.addElement(std::make_pair('P', white), 'p');
62 char_map.addElement(std::make_pair('N', white), 'n');
63 char_map.addElement(std::make_pair('B', white), 'b');
64 char_map.addElement(std::make_pair('R', white), 'r');
65 char_map.addElement(std::make_pair('Q', white), 'q');
66 char_map.addElement(std::make_pair('K', white), 'k');
67
68 char_map.addElement(std::make_pair('P', black), 'P');
69 char_map.addElement(std::make_pair('N', black), 'N');
70 char_map.addElement(std::make_pair('B', black), 'B');
71 char_map.addElement(std::make_pair('R', black), 'R');
72 char_map.addElement(std::make_pair('Q', black), 'Q');
73 char_map.addElement(std::make_pair('K', black), 'K');
74 }

Теперь преобразование в "шахматную доску" будет совпадать с методом ToString:

36 const std::string Board::ForPrint() const{
37 init_map();
38 std::string print = "A\"\"\"\"\"\"\"\"S\n";
39 int i, j;
40
41 for (i = 0; i != 8; ++i) {
42 print.push_back('$');
43 for (j = 0; j != 8; ++j) {
44 char chr = char_map[std::make_pair(brd[i][j], (i+j)%2)];
45 print.push_back(chr);
46 }
47 print.push_back('%');
48 print.push_back('\n');
49 }
50
51 print = print + "D((((((((F";
52 return print;
53 }

Разве что добавятся новые символы, которые обозначают границы доски.

С++, программирование, шахматные диаграммы, много букв

Previous post Next post
Up