Форум программистов, компьютерный форум CyberForum.ru

Шахматы(компьютер-компьютер) - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ проблема с проверкой вводимых данных http://www.cyberforum.ru/cpp-beginners/thread356175.html
#include <iostream> #include <conio.h> using namespace std; double c,f; int main() { setlocale(LC_ALL, "Russian"); setlocale(LC_ALL, "rus");
C++ Определить, принадлежит ли точка с координатами x, y заштрихованной части плоскости Здравствуйте! Помогите пожалуйста полному чайнику решить две задачки. 1) Даны действительные числа x1, y1, x2, y2. Вычислить min(x1, y1, x2, y2)+min(x1,x2,y1). 2) Даны вещественные числа x, y. Определить, принадлежит ли точка с координатами x, y заштрихованной части плоскости. Результат вывести в виде текстового сообщения. Представить варианты программы с использованием условного оператора... http://www.cyberforum.ru/cpp-beginners/thread356147.html
C++ Задача про шахматы
Все доброго времени. Помогите пожалуйста с заданием. Нужно с помощью двумерного массива вывести на экран шахматную доску с расставленными на начальных местах фигурами. Выглядеть результат, как я поняла должен как-то так : |1|1|1|1|1|1|1|1| |1|1|1|1|1|1|1|1| |o|o|o|o|o|o|o|o| |o|o|o|o|o|o|o|o|
C++ Проверка вводимых символов
Привет форум! Уже пытался кое-что найти в книжках по С++ по поводу сабжа, но многое мне не ясно, ибо я очень очень чайник. Вот что мне нужно: Пользователь должен ввести вещественное число с клавиатуры, но при этом он может допустить ошибку, т.е. ввести не только цифры, но и любые другие символы. Программа в случае неправильного ввода числа должна сообщить об этом, если же число введено верно,...
C++ Массивы: определить количество дней с осадками больше среднего http://www.cyberforum.ru/cpp-beginners/thread356131.html
Во всех приведенных ниже вариантах использовать меню для организации работы программы, исходные данные предварительно записать в текстовый файл. Разработать схему алгоритма и программу, используя функции с параметрами для ввода массива и его обработки. В массиве хранятся данные об осадках за месяц. Найти • Количество дней с осадками больше среднего • Самую «мокрую» декаду (декада – 10дней)...
C++ Написать функцию которая проверяет если число(простые числа) не делится на N и меньше N... Написать функцию которая проверяет если число(простые числа) не делится на N и меньше N... подробнее

Показать сообщение отдельно
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
25.09.2011, 22:07     Шахматы(компьютер-компьютер)
Раз народ просит...

Собственно, понятное дело, что через ООП будет проще. Создаём несколько классов (я не гуру ООП, поэтому возможно я вообще нифига не по парадигме ООП сделал, но самоучке, имхо, можно), а там начинаем мутить.
Я парился не особо. Получилось что-то вроде этого:
C++
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <iostream>
#include <algorithm>
#include <Windows.h>
 
using namespace std;
 
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
 
enum ConsoleColor
{Black,Blue,Green,Cyan,Red,Magenta,Brown,LightGray,DarkGray,LightBlue,LightGreen,LightCyan,LightRed,LightMagenta,Yellow,White};
 
enum Figures
{NULL1, Pawn, Rock, Knight, Bioshop, Queen, King};
 
enum Players//вроде оказалось пока не нужным... но пусть будет
{WhitePlayer, BlackPlayer};
 
 
/*
black +10
[2][3][4][5][6][4][3][2] => x
[1][1][1][1][1][1][1][1]
[ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ]
[1][1][1][1][1][1][1][1]
[2][3][4][5][6][4][3][2]
||                white
\/
y
*/
 
 
class CDesk{
public:
    int m_desk[8][8]; //m_desk[x][y]
    CDesk(){
        for(int i = 0; i < 8; i++)
            m_desk[i][1] = m_desk[i][6] = 1;//пешки
        for(int i = 0; i < 3; i++)
            m_desk[i][0] = m_desk[7-i][0] = m_desk[i][7] = m_desk[7-i][7] = i+2; //ладьи, потом кони, в конце слоны
        m_desk[4][0] = m_desk[4][7] = King; // король
        m_desk[3][0] = m_desk[3][7] = Queen; //королева
 
        for(int i = 0; i < 8; i++){ //красим фигуры в чёрный
            m_desk[i][0] += 10;
            m_desk[i][1] += 10;
        }
 
        for(int j = 2; j < 6; j++){//где-то должна быть чернота
            for(int i = 0; i < 8; i++){
                m_desk[i][j] = 0;
            }
        }
    }
 
    void Show(){
        int cell = Yellow;
        for(int j = 0; j < 8; j++){
            for(int i = 0; i < 8; i++){
                SetConsoleTextAttribute(hStdOut, cell);
                cout << '[';
                if(m_desk[i][j] > 10)   SetConsoleTextAttribute(hStdOut, DarkGray); //красим чёрных
                else                    SetConsoleTextAttribute(hStdOut, LightGray);//красим белых
                if(!m_desk[i][j])       SetConsoleTextAttribute(hStdOut, Black);//красим пустоту
                cout << m_desk[i][j]%10;
                SetConsoleTextAttribute(hStdOut, cell);
                cout << ']';
                //инверт
                if(cell == Brown)   cell = Yellow;
                else                cell = Brown;
            }
            //ещё один инверт, чтобы не инверт =)
            if(cell == Brown)   cell = Yellow;
            else                cell = Brown;
            cout << endl;
        }
    }
};
 
class CGame{
private:
    CDesk m_d;
    bool m_mask[8][8];
    bool CheckFigure(int player, int x, int y){
        if(!m_d.m_desk[x][y]) return false;
        if(m_d.m_desk[x][y] > 10) return false ^ player;
        else                      return true  ^ player;
    }
public:
    void ShowDesk(){
        m_d.Show();
    }
    void resetMask(){
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
                m_mask[i][j] = false;
    }
    CGame(){
        resetMask();
    }
//ОСНОВНАЯ ФУНКЦИЯ. ОСНОВНАЯ ЛОГИКА ДОЛЖНа БЫТЬ ЗДЕСЬ
    void makeMask(int x, int y){
        for(int j = 0; j < 8; j++){
            for(int i = 0; i < 8; i++){
                cerr << "WTF!!!!!!!!!!!?..\n";
                bool temp = (x == i || y == j && !(x == i && y == j));
                if(temp){
                    m_mask[i][j] == true;
                }
            }
        }
    }
//основная функция. основная логика должнА быть там
    void makeTurn(int player){
        int x = rand()%8, y = rand()%8;
        while(!CheckFigure(player, x, y)){
            x = rand()%8;
            y = rand()%8;
        }
        makeMask(x, y);
        int temp = m_d.m_desk[x][y]; //как бы поднимаем фигуру в воздух
        m_d.m_desk[x][y] = 0; //мы же уходим от туда
        do{
            x = rand()%8; y = rand()%8; //выбираем куда-бы нам поставить её
        }while(!m_mask[x][y]); //собственно, проверяем, хотим мы её поставить ПО ПРАВИЛАМ или нет
        m_d.m_desk[x][y] = temp; //а теперь мы ставим фигуру на выбранное место
    }
};
 
void main(){
    CGame game;
    for(int i = 0;;i++){//ещё надо бы сделать проверку на шах-мат. Это тоже важно! Не буду лишать удовольствия.
        game.ShowDesk();
        game.makeTurn(i%2);
        Sleep(1000);
    }
}
У меня не работает.
+ логика, конечно, не правильная. Нужно обработать правила игры, про которые вики говорит "Сложные". Ну, собственно, и почти всё. Останется за тривиальным - сделать по красивее (можно, например, юникодовые символы заюзать, думаю там есть и Unicode).

Задача решилась гениально (то есть просто).

Сначала мы делаем доску и расставляем фигуры.
Потом первый игрок (белый видимо) выбирает случайным образом фигуру, которой будет ходить.
Прим. Здесь надо бы поправить логику, чтобы если некуда ходить, выбиралась другая фигура, но это тривиал.
Теперь, надо выбрать куда ходить. Для этого я использовал булеву маску: создаём маску возможных ходов, а потом аналогичным рандомом ходим. Здесь очень хорошо реализуется "съедание" фигуры, без лишних функций.
Собственно, передаём ход другому игроку и всё повторяется.
В принципе, всё делается элементарно (так же) и без ООП: нужно два масива (целочисленный и булевый), несколько десяток функций, switch-case-технология, ну, собственно, и всё.

Ах да, проверка на шах и мат. В принципе - не сложная. Нужно пройтись по всему полю, там найти все фигуры и посмотреть, может ли он "съесть" короля. Если может, то "походить" королём - и снова проверить. Можно скопировать для этого поле.

Немного лирики про ООП.
О да, можно, конечно, создать класс фигуры, а не юзать целочисленную. Здесь, тогда, прямо в классе можно хранить правила создания маски, функцию ходя, координаты, но смысл?.. Мат. модель не Crysis и усложнять её достаточно сложным и немного не в тему ООП нет смысла. А понятный код достигается введением банального перечисления - теперь не нужно запоминать, какая цифра что означает...
Вроде всё =)

Теперь, про улучшение:
Во-первых, можно рандомить не координаты (когда фигуру выбираем), а номер клетки. Зачем? Ввести динамику - когда проходим по массиву в поиске рандомизированной фигуры, можно легко найти кол-во фигур, делать более быструю проверку шах-мата, можно ещё подумать над некоторыми пряниками. Да и выбирать будет побыстрее (если без пряников) чаще, чем рандом координатами, особенно если фигур осталось мало - здесь мы не будем часто "мазать", а просто идти по массиву с проверкой (сам рандом медленнее перехода к следующей клетке).

Но зачем?.. 64 клетки, даже если осталось два короля, то выбирать игроку фигуру рандомом будем с вероятностью 1/64. Уже на 1000-ом выборе шанс выбрать будет очень близок к 100 процентам. Так что, обойдёмся этим =)

Добавлено через 24 минуты
*facepalm*
Там где "WTF" два знака равно - этим я хотел провести операцию присваивания...
Да, всё "почти" работает... Если не брать в расчёт логику...

Добавлено через 17 минут
*facepalm*
Забыл ресетить маску.

Добавлено через 29 минут
В принципе, для ладьи можно сделать проще - случайный выбор одной из координат, для слона - выбранные координаты должны быть пропорциональны (прибавляем или вычитаем случайное число), для пешки - если ордината (y) на одну больше (меньше) или если враг рядом... В общем, можно и без маски, просто маска позволяет программировать более универсально и в switch-case'е и самое главное - проще обрабатывать дополнительные условия, вроде преград или фигур свой-чужой...

В общем, в такой задаче можно сделать и такой подход...
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru