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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 31, средняя оценка - 4.68
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 189
#1

Программа для игры в покер - C++

28.02.2013, 13:15. Просмотров 4131. Ответов 46
Метки нет (Все метки)

Никак не могу понять суть ооп.
До прихода в с++ програмировал на С микроконтроллеры.
Там всё просто. Есть начало программы, и пишеш инструкции последовательно чтоб устройство работало так, как задумано. Используя регистры, прерывания и тп.

Сейчас же выучив немного С++ пытаюсь написать консольное приложение для игры в покер сам с собой.
Написал функцию сравнения рук в покере. Даже написал обьект "Автомат игры" для безлимитного холдема
для 2-10 чел. (переписывал много много раз)
Последняя редакция подкупает своей лаконичностью. В этом обьекте нет "представления" типа ников игроков, аватарок и тп. Нет функции рисования игры в консоле и ввода от пользователя ходов.

Вопрос как мне организовать программу чтоб было красиво (понятно) и расширяемо и тп. Вобщем как это делают нормальные програмисты?

Вот у меня есть main(). Это точка входа. (в визуал С++ я так её и не нашол когда пытался )
Далее по логике я создаю экземпляры классов какие мне надо в программе.

Что дальше? Бесконечный цикл ожидания когда пользователь нажмёт кнопку? И вызов соответствующих функций какихто классов?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.02.2013, 13:15
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Программа для игры в покер (C++):

Моделирование игры в покер - C++
Недавно начал изучать С++,использую книгу Харви М. Детела Как программировать на С++.В конце одной из глав есть упражнение,в котором нужно...

Мне очень нужна программа для игры gta samp 0.3c для взлома базы данных - C++
Мне очень нужна программа для игры gta samp 0.3c для взлома базы данных

Исходники игры "Покер" - C++
Срочно нужны исходники "Покера" или "21-Очко". Буду очень благодарен за помощь.

Программа-бот для игры в покер. - C++
Здравствуйте. Сам я будующий программист, учусь на 2 курсе, потихоньку осваиваю С++. У меня вопрос к уже сложившимся и опытным...

Теория игр на примере С3 из ЕГЭ по информатике. Программа, которая выдает стратегии для игры - C++
Здравствуйте! Помогите с написанием программы, пожалуйста. Задача: есть 2 игрока(1-ый и 2-ой соответственно), перед ними лежи куча...

программа игры на С++ - C++
Составить программу, которая: 1) предлагает игроку числовые головоломки типа ОДИН + ОДИН = МНОГО из некоторого набора таких головоломок...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 189
02.03.2013, 01:52  [ТС] #31
Ну смотря что считать. Например если даны карманные карты 4х игроков, они все алин и надо посчитать % выигрыша каждого или мат ожидание выигрыша. Для нормальной точности надо скажем 10000 раздач.
Обычный покерный калькулятор. У меня на эту операцию (из жизни) уходит менее 1с.
Ждать 100с мало кто станет если это онлайн калькулятор к примеру.
Я пока не могу обосновать на 100% что это очень критично, но в любом случае быстрее лучше чем медленнее.
Видел много других реализаций сравнения рук. Скажу что они никак не более читабельны.

Добавлено через 3 минуты
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
for (i=0; i<7; i++)
* *if(card[i].suit==spades)
или что ты там хотел сказать?
Ну вот прочёл же, а говоришь не читабельно

В этом моменте да, можно написать короче.
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
02.03.2013, 03:13 #32
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
тут тоже
В принципе верно, но не совсем. Достаточно большой проект принято разделять и влавствовать чуть ли не до бесконечности. То есть по сути появляется большое количество модулей разделённых относительно кода (но не работы - они могут работать и параллельно). У каждого модуля есть своя "точка входа" и своя "точка выхода".

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
И к регистрам и прерываниям никто тебе доступа не даст, когда параллельно с тобой запущено ещё несполько приложений и сама операционка Windows.
Наглая ложь! Я хоть и пару месяцев кодил на асме, но что Linux, что Windows даёт полный доступ к любым прерываниям и регистрам. Как же другие приложения? Насколько я помню, регистров не мало + запоминаются состояния. К тому же шанс того, что система тебя вытолкнет из работы вне вызова какого-нибудь прерывания довольно мал, так что в принципе содержимому в регистрах можно доверять. И именно поэтому во времена Pentium II-III-IV винда могла очень легко "залипнуть".

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Ну в принципе да, а что? Методы классов - те же функциии. Вообще всё зависит, например, оконное у тебя приложение или консольное.
Ну в принципе да, на практике - иначе. ЯВУ позволяют обойтись без... такого цикла
C
1
for (;;) {...break;...}
То есть где-нибудь есть что-то вроде
C++ (Qt)
1
return app.exec()
который в неявном виде запускает цикл и настраивает events или систему сообщений, уведомлений, сигнал-слотов. По-разному...
Но на самом деле, это именно цикл. В цикле программа методично превреяет, не были нажаты определённые кнопки и как на их нажатие реагировать (изменять ход течения программы).
Цитата Сообщение от kravam Посмотреть сообщение
И я не сразу понял. Да и понял ли? Для меня ООП- возможность конструировать собственные типы данных
Вот-вот... Мне вообще кажется, что в этом мире только от силы полтора человека понимают суть ООП. Остальные умеют лишь пользоваться им...
ООП - совокупность методов, методик построения ПО. Нельзя взять и понять ООП. Для этого, имхо, может потребоваться десятки лет практики и тонны прочитанной литературы. Но если грубо, то во времена WWII не было даже ассемблера и всё кодилось прямо в двоичных (максимум - десятиричных) кодах. Приход ассемблера внёс первый уровень абстракции - мнемоники. Потом парни из AT&T решили создать хорошую ОС. Но это было сложно и вдобавок они сделали Си. В общем-то, первый ужасный и в то же время очень мощный системый ЯВУ. Хотя, скорее ЯСУ (среднего уровня), но не суть - это всё мелочи. Впоследствии, ОС'ы становились более громозкими, их API разрасталось, усложнялось, расслаивалось; ПО стало более комплексное и куда более сложное... Си стало не хватать и появился Си++ - улучшенный Си, на что намекает инкремент, или Си с классами в раннем варианте. И если сначала комманды были представлены цифрами, потом их обозвали буквами, в Си их стало возможным объединить в функции, то в Си++ класс - аггрегатор функций на основе используемых данных! Это самая обычная эволюция (есть неизвестная революция - функциональные ЯП, но... слишком она неизвестная).

Ну вот, собственно и ответ. Как организовывать программу? Всё просто - пишем коды. Когда видим, что функция стала слишком большой, делаем больше функций. В идеале функции должны быть длиной 10-15 символов (хотя краткость - сестра таланта, не забываем), а размером - 5-6 строк максимум (содержательных, офк).
Так же и с классами - видем, что он ожирел - время рефакторинга. Разделяем сначала данные на классы (семантически, офк), после чего переписываем методы классов.
Из вредных советов, имхо:
+ должна быть структурка (или класс) GameState, массив этих GameState'ов и указатель на текущий. У них должны быть методы, вроде updateState()...
+ игрок человек и игрок компьютер не должны быть разделены классом - это одна сущность и не стоит плодить их по напрасну, лучше проверять тип внутри update() и либо ждать ввода, либо ходить самому каким-то образом.
+ бумага - лучший друг человека; она всё стерпит, а если писать карандашом - долго прослужит... хотя если есть комманда, white-board всё же лучше.


Это всё мнение человека (кроме исторических фактов, офк) и оно не претендует быть истинной в первой инстанции.

Добавлено через 2 минуты
Алсо, рекомендую [перевод].

Добавлено через 10 минут
Цитата Сообщение от nefton Посмотреть сообщение
Микроконтроллеры (точнее компиляторы для них) не поддержуют С++ и уж точно не поддерживают его полностью.
Не знаю о чём Вы, но Си++11 сейчас вообще никто полностью не поддерживает, а Си++ начала двухтысячных прекрасно транслируется в Си99 код. Тем более, что древние компиляторы именно так и делали Си++ -> Си -> ассемблер -> бинарник.

По поводу алгоритма? Что за сила руки? Есть вполне определённые алгоритмы рассчёта вероятности выигрыша. Нужно всего лишь посмотреть на свою руку, посчитать (читай, найти) лучшую комбинацию (что очень легко считается с помощью деревьев) и определить вероятность, что у противника рука слабее (с рассчётом на вылетевшие карты, размер колоды и возможности на флопе, тёрне и ривере получить что-нибудь интересное.
Это не так просто с точки зрения математики, но с точки зрения кода это довольно просто.

Добавлено через 6 минут
Цитата Сообщение от XRuZzz Посмотреть сообщение
вы не сможите скомпилировать класс с_Figure на компиляторе для микроконтроллера пока не уберете строчку
C
1
#include "stdafx.h"
Простите, что!? Причём здесь невозможность откомпилировать на микро- контроллер или процессор и прекомпилированные хэдеры?
Kuzia domovenok
1891 / 1746 / 118
Регистрация: 25.03.2012
Сообщений: 5,925
Записей в блоге: 1
02.03.2013, 03:52 #33
Цитата Сообщение от AnyOne697 Посмотреть сообщение
Наглая ложь! Я хоть и пару месяцев кодил на асме, но что Linux, что Windows даёт полный доступ к любым прерываниям и регистрам. Как же другие приложения? Насколько я помню, регистров не мало + запоминаются состояния. К тому же шанс того, что система тебя вытолкнет из работы вне вызова какого-нибудь прерывания довольно мал, так что в принципе содержимому в регистрах можно доверять. И именно поэтому во времена Pentium II-III-IV винда могла очень легко "залипнуть".
к регистрам да. К прерываниям. Ну попробуй запиши что-нибудь по вектору прерываний реального процессора. Да вообще хоть к какому-то реальному устройству получи доступ под Windows.

Добавлено через 1 минуту
Цитата Сообщение от AnyOne697 Посмотреть сообщение
Простите, что!? Причём здесь невозможность откомпилировать на микро- контроллер или процессор и прекомпилированные хэдеры?
и какой компилятор для микроконтроллеров их использует?

Добавлено через 2 минуты
Цитата Сообщение от AnyOne697 Посмотреть сообщение
Микроконтроллеры (точнее компиляторы для них) не поддержуют С++ и уж точно не поддерживают его полностью.
Не знаю о чём Вы, но Си++11 сейчас вообще никто полностью не поддерживает, а Си++ начала двухтысячных прекрасно транслируется в Си99 код. Тем более, что древние компиляторы именно так и делали Си++ -> Си -> ассемблер -> бинарник.
При чём тут компиляторы Си++ для микроконтроллеров? Они вообще существуют такие? Не, может и есть, кто знает, но как-то я не встречал их пока.

Добавлено через 1 минуту
Цитата Сообщение от AnyOne697 Посмотреть сообщение
WWII
это ещё что?
XRuZzz
Антикодер
675 / 576 / 28
Регистрация: 15.09.2012
Сообщений: 2,522
02.03.2013, 12:00 #34
Я видел мощные проекты на C++ для cortex в Keile. Я конечно не вникал особо в чем там ограничения для C++, но мне это никак не мешало в работе.

Тут нужно религиозно верить, либо не верить в ООП(C++).

Просто те исходники, которые я писал на C мне никак не пригодились в будующем.(может коряво писал)
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
02.03.2013, 12:10 #35
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
и какой компилятор для микроконтроллеров их использует?
Ничего сложного в precompiled headers нет и это зависит только от компилятора. Все современные компиляторы поддерживают такие заголовки, впрочем, насчёт микроконтроллеров не знаю, проекты там может быть и небольшие и библиотек мало, так что не знаю...
и какой компилятор для микроконтроллеров их использует?
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
При чём тут компиляторы Си++ для микроконтроллеров? Они вообще существуют такие? Не, может и есть, кто знает, но как-то я не встречал их пока.
Если честно, то не знаю. Знаю, что можно (можно было в какой-то степени) транслировать Си++ код в Си. Отсюда, я так думаю, можно и в микроконтроллер запихать Си++ проект. Правда если микроконтроллер 8-ми битный, то есть шанс поймать проблем.


Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Цитата Сообщение от AnyOne697 Посмотреть сообщение
WWII
это ещё что?
World War II, вестимо.

Добавлено через 4 минуты
Цитата Сообщение от XRuZzz Посмотреть сообщение
Тут нужно религиозно верить, либо не верить в ООП
Вот только не надо начинать холивар. С ООП проще поддерживать большие проекты, а Си быстрее (впрочем, не намного) и даёт больший контроль над компьютером (или микроконтроллером). Да и вообще тема пошла в оффтопик =(
XRuZzz
Антикодер
675 / 576 / 28
Регистрация: 15.09.2012
Сообщений: 2,522
02.03.2013, 12:28 #36
приведу пример своего класса Figures
файл #include "AsteriskFigures.h"
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
#ifndef ASTERISKFIGURES_H_
#define ASTERISKFIGURES_H_
 
#include "IAsteriskFigures.h"
#include "ILineParts.h"
#include "HollowLineFoundations.h"
#include "BlackLineFoundations.h"
#include "LineParts.h"
#include "CenterLineParts.h"
#include "math.h"
 
namespace deitel
{
 
class AsteriskFigures: public IAsteriskFigures
{
    public:
        AsteriskFigures();
        virtual ~AsteriskFigures();
        string getLinePart(ILineParts * pTypeLine);
        int getType() const;
        void setType(int type);
        int getXmax() const;
        void setXmax(int xmax);
        int getYmax() const;
        void setYmax(int ymax);
    protected:
        int x;
        int y;
        LineParts *pLine;
        CenterLineParts cntrLine;
        int stepCnt;
    private:
        int type;
        int Xmax;
        int Ymax;
};
 
}
#endif
файл #include "AsteriskFigures.cpp"
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
#include "AsteriskFigures.h"
#include "HollowLineFoundations.h"
 
namespace deitel
{
 
AsteriskFigures::AsteriskFigures()
{
    setXmax(9);
    setYmax(9);
    pLine = &cntrLine;
    stepCnt = 1;
}
 
AsteriskFigures::~AsteriskFigures()
{
}
 
int AsteriskFigures::getType() const
{
    return type;
}
 
void AsteriskFigures::setType(int type)
{
    this->type = type;
}
 
int AsteriskFigures::getXmax() const
{
    return Xmax;
}
 
void AsteriskFigures::setXmax(int xmax)
{
    Xmax = xmax;
}
 
int AsteriskFigures::getYmax() const
{
    return Ymax;
}
 
void AsteriskFigures::setYmax(int ymax)
{
    Ymax = ymax;
}
 
/**
 */
string AsteriskFigures::getLinePart(ILineParts * pTypeLine)
{
    string data;
    HollowLineFoundations hollow;
    data = pTypeLine->getLinePart(&hollow, 9);
    return data;
}
 
}
Конечно код не идеален, но он зависит только от моих интерфейсов и от стандартных библиотек.
NEbO
587 / 455 / 49
Регистрация: 22.01.2009
Сообщений: 1,180
Записей в блоге: 1
Завершенные тесты: 2
03.03.2013, 03:05 #37
Сообщение было отмечено автором темы, экспертом или модератором как ответ
По поводу начала темы вставлю свои пять копеек. Может я несколько неправильно понял, но в самом топике автор говорит не о сложности самого ООП, а о сложности разработки GUI-приложений. Исхожу из того, что автору все-таки нужно добиться результата, и судя по опыту программирования микроконтроллеров, разобраться в том, что и как происходит.
Abstract
Почему? Вообще, когда я увидел название топика, я подумал, что какой-то [n]-классник в очередной раз пытается написать бота к покерстарзу/паразиду/леону/титану/ftt/ge/другое (подчеркнуть нужное, что там сейчас популярно?). Ну и сообщение в духе
Здравствуйте, я слышал, что для искусственного интеллекта применяются ГА и НС. Скажите, пожалуйста, что это такое? A еще: на каком языке лучше написать?
UPD:я вот знаю паскаль, я так понимаю, нужно завести два массива, в одном должен быть массив карт, в другом -- массив игроков? да? так?
ну итд итп, конечно. Однако, посмотрел на количество сообщений и все же заглянул посмотреть
Имхо, основной вопрос nefton-а заключается в последней строчке:
Цитата Сообщение от nefton Посмотреть сообщение
Что дальше? Бесконечный цикл ожидания когда пользователь нажмёт кнопку? И вызов соответствующих функций какихто классов?
Программист-системщик разбирается в написании удобного пользовательского интерфейса: это, на самом деле, очень интересно. И системное программное обеспечение, и прикладное, и разработка и даже проектирование UI: все интересно. Ну а то, что старые подходы не меняются, и хочется досконально разобраться в том, как все устроено, а не тупо(?) делать так, как предлагает компилятор/система/IDE/платформа: это возводит в квадрат интерес в написании развернутого (насколько смогу) ответа.
Возможно, конечно, я щас лишь напугаю, или оттолкну чем-то, в интересе изучения всего этого, хотя может оно и не нужно никому. Не знаю. Но все-таки я постараюсь объяснить принципы, по которым строится и как работает GUI-приложение, насколько удалось разобраться в этом мне. Ну и, если повезет, постараюсь намекнуть, почему разработку GUI и ООП вообще реально перепутать.
Поскольку буков многа, а я скромный по натуре, думаю, всем будет лучше, если я все это дело засуну под спойлер.
Кликните здесь для просмотра всего текста

Intro
Начну с того, что любое GUI-приложение можно разработать на чистом си, без плюсов. Да какой там си. Ассемблер тоже годится! Достаточно скачать FASM (http://flatassembler.net/), и заглянуть в примеры, чтобы убедиться, что вполне себе рабочий GUI можно писать даже на нем.
// Сразу скажу, что с иксами непосредственно я не работал, и на низком уровне писал только на WinAPI. Поэтому отталкиваюсь от него. В иксах же, как известно, добавляется еще и клиент/серверное взаимодействие, и, наверное, еще что-то, так что модель WinAPI, пожалуй, самый простой вариант.
Пробуем написать приложение, выводящее форму на экран и делает что-то при нажатии на левую кнопку мыши.
Начало стандартное:
C
1
2
3
int main() {
    return 0;
}

Не по теме:

заранее извиняюсь за K&R, знаю, что бОльшая часть сишников уважают ANSI-стиль


Ну и что же теперь? Известно, что при нажатии мышки возникает некоторое прерывание, обработчик которого, разумеется, находится в ОС. ОС также занимается обработкой прерываний при перемещении мышки, поэтому она точно может знать, в какой позиции экрана находится курсор. То есть при нажатии клавиши мышки, ОС сама по себе запросто определяет, какая клавиша была нажата (берется с аппаратуры), и позиция курсора.
Чтобы понять, на каком элементе, и в каком окне произошло нажатие, нужно, чтобы ОС знала, где располагаются эти элементы. Для этой цели ОС должна предоставлять функции регистрации некоторых прямоугольников, которые будут чем-то вроде "областей нажатия": при нажатии мышки на этом прямоугольнике, система должна запоминать, что в этом прямоугольнике клавиша была нажата.
Поэтому, определим структуру:
C
1
2
3
4
struct Rect {
    int x, y, width, height; // заполняются нашим приложением: оно как бы говорит операционке, что я хочу находиться там-то и там-то и иметь такой-то размер
    char isClicked; // флаг, который устанавливает система, когда произошло нажатие по этому прямоугольнику. пока что отбросим вопрос о том, кто и когда его должен сбрасывать
}
В ОС определим массив указателей на эти Rect-ы. Чтобы приложение и ОС оперировали одними и теми же Rect-ами, введем функцию регистрации Rect-а в ОС. Вызывать эту функцию должно приложение. Пусть оно изначально задает размер окна, мы же не хотим, чтобы наша псевдо-ОС всегда создавала прямоугольники одинаковых размеров?
Наглядное применение нашего "свежесозданного" апи, с применением for( ; ; ):
C
1
2
3
4
5
6
7
8
9
10
11
12
int main() {
    struct Rect rect;
    rect.x = 0; rect.y = 0; rect.width = 50; rect.height = 50; 
    rect.isClicked = 0; // хотя эту операцию может вызывать и ОС, при регистрации, так будет даже правильней
    registerRect(&rect);
    for ( ; ; ) {
        if (rect.isClicked) {
            // произошло нажатие. выполняем какие-то действия
        }
    }
    return 0;
}
И такой код даже будет работать! Но приложение будет занимать 100% ресурсов хотябы одного ядра (хотя, при гипертрединге, даже не знаю как правильно назвать, потока чтоли). Это очевидно. отбросим все до и после цикла: в цикле банальная проверка переменной на истинность. Причем, от того, что rect -- структура, код более волшебным не становится. На уровне ассемблера, в лучшем случае, это будет:
Assembler
1
2
3
4
5
6
7
mov  ebx, _rect + 12    ; смещение внутри структуры Rect до поля isClicked
_next:
    mov  al, [ebx]
    test al, al
    jz   _next
    ...                 ; тут наш код обработки нажатия
    jmp  _next
Как же избавиться от этой загрузки процессора?
В книге Таненбаума "Операционные системы. Разработка и реализация" упоминалось, что у каждого процесса есть некий флаг загруженности. То есть если программа была прервана операционной системой (кстати, делается это по таймеру, или IRQ0, при вытесняющей многозадачности), то ей нетрудно догадаться, что программа то еще работает! С другой стороны, если программа сама передала управление в ОС, сказав: "щас мне нечего делать. я жду ввода", ОС не зачем вхолостую тратить драгоценные такты на десятки, да или сотни даже таких процессов.
Значит, после создания Rect-а, программа должна передать управление в ОС специальным образом, и тогда флаг занятости будет установлен в 1, а планировщик не будет передавать управление нашей программе. При этом, из самой очереди планировщика ее можно не исключать, ведь ОС в любой момент может сбросить флаг занятости, и тогда ему нужно будет вновь передавать управление в нашу программу.

Не по теме:

Будь благословенен каждый, кто дочитал до сюда и все понял.


Как жеж такое сделать?
На самом деле все просто до безумия. Если подумать, когда жеж должно передаваться управление в программу, если та ожидает, что пользователь нажмет на мышку в окошке? Правильно: тогда, когда пользователь нажмет на мышку в этом окошке! А от мышки управление, как уже говорилось, поступает непосредственно к ОС: возникает некое прерывание. точно также от клавиатуры (для PS/2 это IRQ1), точно также при любом движении мышки/сенсорника, или любого другого устройства ввода (и не только). при этом, ОС отдает управление некоторому системному процессу.

Не по теме:

Это необходимо, т.к. сами прерывания должны обрабатываться моментально, ибо когда обрабатывается одно прерывание, по-хорошему, не может возникнуть другое. В итоге, скажем, если реализовать логику поиска среди всех зарегистрированных прямоугольников на экране именно в обработчике прерывания от мышки, то в это время будут теряться все "сообщения" от клавиатуры и от других устройств, вплоть до жесткого диска, который тоже вызывает некоторый IRQ в начале/конце записи/чтения блока данных. С учетом того, что логика поиска нужного прямоугольника по заданной точке может занять не один десяток килотактов, то может "потеряться" приличное количество прерываний.


Системный процесс реализует алгоритм поиска точки внутри заданного массива прямоугольников (все они зарегистрированы в системе, и этот системный процесс имеет доступ по крайней мере, на чтение этого массива). Определяет нужный прямоугольник, и .... Что? Правильно! Нужен некоторый идентификатор процесса, к которому привязываются все создаваемые в нем прямоугольники! А еще лучше, если у каждого прямоугольника будет указатель на процесс, ну или хотябы его идентификатор.
Так. Теперь уж точно хватит прямоугольников. Прямоугольник, имеющий какой то непонятный идентификатор на что-то вообще левое -- разве это прямоугольник? Назовем эту нашу штуку, имеющую размер, позицию, и ID процесса, окном (Window).

Не по теме:

На самом деле, в винапи, да я думаю, и в других подобных апи, определяется абстракция "приложение" (Application), к которому можно привязать n-ое количество этих окон. Window-ы привязываются к Application-у, а тот, уже, в свою очередь, связан с некоторым процессом в системе.


После того, как системный процесс определил нужное окно, он считывает из его структуры id процесса и сбрасывает его флаг занятости. Планировщик через какое-то время передает управление этому процессу. Процесс обрабатывает нажатие мышки и снова должен вызвать функцию ожидания клика, или завершиться. Получаем код типа:
C
1
2
3
4
5
6
7
8
9
10
11
12
int main(){
    struct Window wnd;
    wnd.x = 0; wnd.y = 0; wnd.width = 100; wnd.height = 100;
    wnd.pid = getpid(); // некоторая функция определения идентификатора текущего процесса.
    registerWindow(&wnd); // регрстрируем окно в системе
    for ( ; ; ) {
        waitForClick(&wnd); // ожидаем клик в окне. управление передается в ОС, она сбрасывает флаг занятости процесса wnd->pid
        ...
        // сюда передается управление, когда в окне был сделан клик
    }
    return 0;
}
Все, приложение больше не виснет, и обрабатывает клики как положено. Несмотря на бесконечный for( ; ; ).
Остаются "сущие пустяки": разобраться, как можно одновременно обрабатывать и клики мышки, и нажатия клавиш на клавиатуре, и какие-нибудь таймеры, "прокрутку" "колесиком" ну и прочее и прочее...
Я как-то уже упоминал слово "событие". Так вот. Всем этим нажатиям, движениям, прокруткам, таймерам, можно дать одно название: все это является событием (Event). Все эти события берутся от операционной системы. А откуда они берутся в операционной системе, было описано выше, на примере с кликом. События бывают разные, и описать его, например, так:
C
1
2
3
4
struct Event {
    int pos_x;
    int pos_y;
}
не получится, ибо при нажатии на кнопочку несколько непонятно, зачем передавать координаты мыши. Зато связать с этим событием нажатую клавишу, пожалуй, более чем желательно. Что делать? Конечно, есть замечательный способ: все запихать в одну кучу, и клавишу, и координаты мыши, и, скажем, смещение колесика мыши, и контекст рисования (да-да, события могут поступать не только от аппаратуры, но еще и от самой ОС. Например, как раз когда нам нужно наше окошко "отрисовать", ОС передает управление окну, ибо только оно знает, как оно должно выглядеть) и еще кучу всего. Но память при этом будет использоваться неэффективно. Можно попытаться сделать какие-нибудь union-ы, но в итоге мы все равно наверняка придем к достаточно сложным структурам
Кликните здесь для просмотра всего текста
Пример все с той же клавиатурой: при нажатии на клавишу передается только сама клавиша. На самом деле этого мало. Хотя, в принципе, конечно, этого достаточно, но удобнее, если нажатие по Ctrl или Alt или Shift не вызывало никаких событий, а всего лишь меняло бы некоторые флаги. А вот уже при нажатии на букву или цифру(например), мы получили бы целое, "большое" сообщение: с битовой маской зажатых клавиш-модификаторов. Также, CapsLock-и, ScrollLock-и, и NumLock-и должны автоматически менять нажатую клавишу внутри операционки, а в сообщении должна быть указана уже измененная клавиша.

Поэтому тут логично применить наследование (да-да, то самое, из ООП). Варианты возможной реализации я нашел тут: http://stackoverflow.com/questions/1...heritance-in-c. Но здесь я намеренно не буду их употреблять, ибо и так уже многа букав:
C
1
2
3
4
5
6
7
8
9
10
11
12
struct MouseEvent {
    int pos_x;
    int pos_y;
    int key_modifiers;
    int button;
};
struct KeyboardEvent {
    int key;
    int scanCode;
    int key_modifiers;
};
...
Конечно, я забыл рассказать о том, как передавать все эти события в приложение. Хотя, я думаю, если уж дочитали до сюда, то скорее всего, уже у вас есть какие-то мысли по этому поводу. Вот один из простейших вариантов, на основе очереди сообщений (инспайред бай винапи). События -- это частный случай сообщения. Например, так можно реализовать возможность посылки сообщений не только от системы, но и от окна другому окну, или даже самому себе.
  • Для начала убедимся, что у нас есть id текущего активного окна системы, activeWindowId, которое является глобальным. Также как в любой оконной среде вы можете выбрать только одно окно, и оно будет "основным", то есть, по умолчанию, события клавиатуры поступают к нему. Аналогично можно реализовать поведение "посылать события в окно под курсом": нам просто понадобится найти и сделать текущим окно под курсором в случае, когда пришло любое событие от клавиатуры или от мыши.
  • добавляем в структуру Window еще три поля:
    C
    1
    2
    3
    4
    5
    6
    
    struct Window {
        int x, y, width, height;
        int pid;
        list *messages;
        int window_id;
    }
    новые поля last_evt, last_evt_type, window_id должны заполняться ОС. Причем последний является уникальным глобальным идентификатором внутри всей системы. Это поле заполняется при регистрации окна.
  • В ядре системы добавим следующие структуры и функции:
    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
    
    list *messagesQueue; // глобальный список событий
     
    struct Message {
        int wnd; // id окна, которому предназначается сообщение
        int type; // тип сообщения. служит только для того, чтобы правильно прочитать структуру message
        void *message; // тело сообщения, например, это может быть экземпляр структуры KeyboardEvent или MouseEvent
    }
     
    void sendMessage(int window_id, int message_type, void *message) { // message -- указатель на одну из структур, MouseEvent или KeyboardEvent и т.д. 
        struct Message msg;
        msg.wnd = window_id;
        msg.type = message_type;
        msg.message = message;
        list_append(messagesQueue, msg);
    }
     
    void process_events() { // код, исполняющийся в системном процессе, о котором я говорил раньше
        struct Message buf;
        while (list_unshift(messagesQueue, &buf)) { // извлечение из списка событий первого события. 
            // Эта операция должна быть атомарной, либо нужно ставить синхронизацию. 
            // Критическая секция возникает при возникновении прерывания во время удаления элемента из списка. 
            // Или, может, не возникает?? (добавление в конец, извлечение из начала. причем, при пустом списке сюда не войдет)
            // В любом случае, это всего лишь опытный образец, слава богу:)
            struct Window *wnd = getWindowById(buf.wnd);
            ... // вот тут как раз может идти обработка события: добавление и обработка различных флагов, модификаторов и прочей дребедени
                // также, сообщение можно не посылать, а запоминать где-то, напимер, для определения двойного щелчка мыши или тех же модификаторов
            list_append(wnd.messages, buf); // добавляем обработанное событие в очередь окна. 
                // Эта операция не должна выполняться для некоторых сообщений: например, как винда, Ctrl+Alt+Del обрабатывает сама, а окну сообщение с такой комбинацией не приходит.
            setProcessActive(wnd.pid, 1); // важно также установить флаг активности процесса, которое получило сообщение. Получило, значит, ему есть что обрабатывать. Пусть сделает это
        }
    }
     
    void waitForMessages(struct Window *wnd) { // ожидание сообщений
        setProcessActive(wnd->pid, 0); // сбрасываем флаг активности процесса. собствнно, все, пожалуй
    }
  • обработчики irq (аппаратные прерывания) пусть выглядят примерно таким образом:
    C
    1
    2
    3
    4
    5
    6
    
    __declspec(naked) void irq1_handler(int ch) { // событие от клавиатуры, на входе -- считанный с портов клавиатуры и преобразованный в "нормальный" вид скан-код нажатой клавиши
        struct KeyboardEvent *evt = malloc(sizeof(KeyboardEvent));
        evt->scanCode = ch;
        sendMessage(activeWindowId, EVT_KEYBOARD, evt); 
        asm("iretd"); // хотя, там еще надо APIC сбросить, ага, я помню, пару операций записи в порты. только не помню, в какие, да и сейчас на smp и x64 могло все поменяться, поэтому врать не буду
    }

Не по теме:

Разумеется, код упрощен до безумия. Смысл его только в том, чтобы показать принцип, на самом низком уровне, доступном программисту. Как оно от аппаратуры приходит "в жизнь", ну приблизительно. Не учтены по крайней мере переходы из ring0 в ring3, и наоборот, еще __declspec(naked) не поддерживает, скажем, gcc под x86 (и x86_64, разумеется, тоже). хотя как-то мною был сделан на 70% рабочий патч, исправляющий это. Кроме того, я никогда не находил информации о том, как в действительности работать с мышью. Видел только несколько реализаций на основе int 33h, но разумеется, тут это не прокатит, хотя бы потому что это софтвеерное досовское прерывание доки по юсб не осилил, ну а 2ой ps/2 не нашел из каких портов читать. в этом я, разумеется, каюсь, но на сами принципы это никак не влияет



Затем, с этими событиями и обработкой сообщений все становится крайне просто:
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
int main(){
    struct Window wnd;
    int finished = 0;
    wnd.x = 0; wnd.y = 0; wnd.width = 100; wnd.height = 100;
    wnd.pid = getpid(); // некоторая функция определения идентификатора текущего процесса.
    registerWindow(&wnd); // регрстрируем окно в системе
    while (!finished) { // основной цикл обработки сообщений
        waitForMessage(&wnd); // вот она, волшебная функция!
        struct Message msg;
        while (list_unshift(wnd.messages, &msg)) { // читаются все поступившие сообщения из очереди
            switch (msg.type) {
            case MSG_CLICK: // один из видов MouseEvent: клик в окне
                MouseEvent *evt = (MouseEvent*)msg.message;
                if (evt->button == MOUSE_BUTTON_LEFT) {
                    setWindowTitle(&wnd, "Mouse Left Button Clicked");
                }
                break;
            case MSG_DBLCLICK: // двойной клик
                closeWindow(&wnd); // система вычищает все лишнее, связанное с этим окном и посылает последнее сообщение, "перед смертью" окна: MSG_EXIT
                break;
            case MSG_EXIT:
                finished = 1;
                break;
            }
        }
    }
    return 0;
}
Примерно такой же подход, только с утроенным количеством кода, можно найти в любом хеллоуворлде на си для винапи. Конечно, где-то наверняка можно найти документацию по каждой из функций, которая там применяется, и имея относительно небольшой опыт и желание понять, как все это устроено, до всего вышеописанного можно дойти самому. Но, надеюсь, я своим постом хоть кому-то смог донести, как работают волшебные "Application.ProcessMessages; Application.DispatchMessage; Application.TranslateMessage" в делфях, что находится внутри qt-шной app.exec(), а также его механизм сигналов и слотов (они вставляются в этот основной цикл обработки сообщений), ну и что, на самом низком уровне, скрыто за main() в MFC, да и, впрочем, любой гуи-шной либы.

Вот. ну а по поводу библиотек разработки, помоему у qt самый низкий порог вхождения, плюс собственная неплохая гуи, плюс кроссплатформенность. На нем же, пожалуй, хорошо учиться основным паттернам проектирования. Впрочем, теми же качествами обладает и wxWidgets, но он немного посложнее сам по себе, и его, говорят, сложнее портировать на некоторые платформы. Из плюсов wx: огромное количество поддерживаемых языков (в т.ч. луа, хаскель и эрланг, к примеру). Visual Studio тяжелый, работает только под винду, из достоинств разве что отладка поприятнее в чем-то. Если вдруг понадобится распространять приложение, то у qt LGPL лицензия (нельзя изменять саму библиотеку и при этом не открывать код. при динамической компоновке код своего приложения можно никогда никому не показывать и продавать до тех пор, пока налоговая не возмет за одно место), у wx -- BSD подобная (делай вообще все что хочешь, желательно только лишь положить текст самой лицензии в папку с приложением, хотя и это не очень-то и обязательно). Ну а VS работает со своими runtime библиотеками, устанавливающимися на целевой машине, отдельно. там разумеется лицензий 0, так как попросту лицензировать нечего, тем более что компилятор бесплатный.

По поводу расширяемости программы. Нужно так прикинуть, насколько оно должно быть расширяемо (ну например, если это только для того, чтобы играть с другими игроками, по сети, на одном столе, и расширять нужно только всякие там карты, анимации движения, -- это одно. или все же может захотеться когда-нибудь сделать возможность игры МТТ, -- это другое). Нужно это для того, чтобы определить API (Application Programming Interface: тот функционал (интерфейс), который будет доступен плагинам) программы. Есть технологии плагинов с разделяемыми библиотеками и скриптовые. В первом случае на тех же плюсах создается длл-ка, которой при инициализации передается некий объект, содержащий реализацию функций API. Она этот указатель на этот объект сохраняет, во внутренней переменной, а потом им пользуется, когда нужно что-то сделать в контексте основной программы. Для полного щастья для разделения интерфейса/реализации API используется паттерн "мост", либо банально массив(или сложная структура) указателей на функции (неужели после первой части звучит ужасающе? вот пример, как это делается). Во втором случае, программа содержит в себе реализацию небольшой виртуальной машины для скриптового языка. При этом она (программа) также передает ей (виртуальной машине) некий объект, содержащий реализацию того, что можно сделать с основной программой. машина регистрирует у себя этот объект под некоторым именем (в самих виртуальных машинах чуть менее чем всегда используются строки, для именования переменных, это все сильно резко упрощает). Далее, когда основная программа решила, что пора бы уже поработать плагину, она дает ВМ (виртуальной машине) соответсвующее указание: мол запусти-ка скриптик из такого-то файла. и та запускает, и этому скрипту разумеется, передается то самое API в том самом глобальном объекте, которым всегда ему можно будет воспользоваться, чтобы совершить действия с основной программой (пример).
По первому варианту все ясно с деталями реализации (плюсы, компиляция, dll/so). По второму: реализаций ВМ полно. По большому счету, кроме синтаксиса языка, они различаются только производительностью. Так вот, в этом плане наиболее удачные, на данный момент, реализации -- это Google V8 и LuaJIT. Есть и еще несколько, если синтаксис этих ну совсем не катит

Не по теме:

приведенные ссылки -- это именно встраиваемые языки, то есть относительно легко прикручивающиеся к другим программам. в действительности, их тысячи


Для сведения, Google V8 наоптимизировали по самое небалуйся, и результат сопоставим по скорости даже с тем же си, в вычислительных задачах (!!!), по крайней мере на одном ядре. Хотя никто не мешает все трудоемкие операции перенести в плюсы, тем более, что раз уж на нем пишется приложение, это будет сделать очень и очень просто. Так что, я бы в первую очередь при выборе скриптового языка обратил бы внимание на то, насколько мне понравился его синтаксис, и насколько интересно мне его будет изучать (если придется).

По поводу алгоритма подсчета вероятности на вскрытии. Когда-то сам думал, что эта задача решается только моделированием. Но вот только пока сочинял эту хрень, я придумал следующий алгоритм.
Весь алгоритм делится на две возможности:
  • после флопа. 3 карты уже открыты, а значит, осталось перебрать всего лишь (54 - 3 - 2*2) * ( (54 - 3 - 2*2) - 1 ) варианта всех возможных раскладов (для количеечтва игроков = 2 останется наибольшее количество возможных карт) в худшем случае. Это всего лишь 2162 итерации. На каждой итерации прибавляем по 1 очку игроку(ам), которые выйграли, а после всего делим количество этих очков обратно на 2162 (точнее, на 54 - 3 - N*2, где N -- количество игроков. Ну я думаю, это элементарно, если вдуматься), получая количество положительных исходов на общее их число (я не силен в теории вероятностей, но все-таки умножив на 100, вроде получим количество процентов, верно?).
  • на префлопе. Таблицы. Заранее просчитанные. Еще раз напоминаю, что я не силен в тервере, однако я думаю, можно практически точно определить вероятность победы игрока A против игроков B и C, когда известны вероятности победы A против B, A против C и B против C. Я попробую как нибудь решить систему уравнений, но сейчас мозг плохо соображает, что там еще можно добавить... <аттеншен>я реально не сильно хорошо разбираюсь в тервере. если это невозможно, пожалуйста, придумайте алгоритм для решения этой, на мой взгляд, уже сильно упрощенной задачи</аттеншен>
  • рекомендации по представлениям. Каждую комбинацию из 5ти карт можно представить в виде 54*53*52*51*50 карт, что составляет 379 501 200 комбинаций. То есть вполне можно уложить в обычный int. Также, учтем, что условная сила руки (это с учетом "прикупа", ну то есть как его там.. кикера. во) будет не больше, чем это число. ну никак, верно? то есть тоже int. Тогда, если делать сервер для такой игры,где все должно просчитываться со сложностью O(1), можно составить табличку на каждую комбинацию (ну, в виде массива, конечно), где A=B. A -- смещение, B -- сила. и оба -- инты.

    Не по теме:

    Даже не думайте воспроизводить это на 64 битных системах!!! используте short int, все равно все уложится в него


    тогда табличка будет занимать в памяти 379501200 * 4 + 379501200 * 4 = 1518004800 * 2 = 3036009600. т.е. примерно 3 гига памяти. щас по 16-32 устанавливают, даже на не очень больших серверах, так что вполне можно справиться.
    Ну а если не нужна константая сложность, то пожалуйста, просчет, на каждый вариант. Правда, по-моему, это очень много тактов. Не уверен, что уложится в десятилетие секунду, хотя, возможно, я и неправ.
  • еще рах подумать над задачей о префлопе. Остальное перебором спокойно решается, я это уже показал. А вот с префлопом... хз. ну, придумать можно, что нибудь, я уверен! (даже не почти, я реально уверен... интуиция!!!)

Conslusion
Вообще, лично я бы на вашем месте подумал о реализации всего этого дела на html5+javascript(canvas). Недавно как раз познакомился с Google Closure Library, крутая штука. Производительность у canvas очень неплохая (ибо аппаратное ускорение, в большинстве современных браузеров), и есть несколько неплохих библиотек для него (пока что мне больше всех понравился fabric.js, хотя в той же GCL есть Canvas, пока еще с ним не разобрался). Хотя, скорее всего, можно обойтись для начала и без canvas-а, там и так можно сделать прикольную анимацию, и кучу красивостей. А сервер бы реализовал на эрланге. Но это конечно, только лишь мое личное предпочтение, ибо я, по большей части, web-программист, хоть и не фронтэндер (пхп-шник, разумеется). Просто прельщает возможность, скажем, зайти на сайт, и ничего не устанавливая, поиграть в онлайне с кем угодно.

Не по теме:

так, стоп, разве такого еще нет? гуглить стремно, не хочу, ато вдруг получится что зря все писал


NEbO
587 / 455 / 49
Регистрация: 22.01.2009
Сообщений: 1,180
Записей в блоге: 1
Завершенные тесты: 2
03.03.2013, 03:17 #38
Черт. примеры-то забыл!
Простая реализация плагинной системы через шаред-либрариз: attach1.zip
Реализация через ВМ скриптового языка: attach2.zip
Для запуска без перекомпиляции требуются рантайм либы Qt5 (QtCore5.dll, QtScript5.dll, QtGui5.dll, QtWidgets5.dll) и mingwwm[чета там].dll. Должно компилиться под 4ую версию.
Не включил их потому что не понимаю, зачем их запускать. главное код. просто убедиться что все работает, разве что можно.
Еще, если интересна вдруг станет эта тема, могу более подробно объяснить, в картинках (uml диаграммы), как и что работает в общем случае, просто надо отыскать свой диплом первый
Вложения
Тип файла: zip attach1.zip (36.3 Кб, 4 просмотров)
Тип файла: zip attach2.zip (33.4 Кб, 3 просмотров)
XRuZzz
03.03.2013, 12:21
  #39

Не по теме:

это стоило оформить в качестве статьи(в каком нибудь блоге например), и в этой теме дать на неё ссылку, а теперь если аналогичный вопрос будет задан на киберфоруме или на другом сайте, придётся давать ссылку на эту тему.
и не факт, что человек найдёт статью в теме.
в общем хорошо зарыли ценный клад

nefton
03.03.2013, 12:41  [ТС]
  #40

Не по теме:

У каждого поста вроде есть ссылка.


Не по теме:

Попробую как то накидать схему приложения (в фотошопе???), а то можно обобщать обобщать и в конечном итоге всегда один и тот же вопрос - в чём смысл жизни

kura007
1 / 1 / 0
Регистрация: 02.12.2012
Сообщений: 17
03.03.2013, 12:51 #41
было бы неплохо написать программу, которая играет в покер за тебя. к примеру просто ставил олл ин с руками начиная с карманки 9 9 +, и А J +)как то так)
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 189
03.03.2013, 13:19  [ТС] #42
Пока что дела обстоят так.
Что смущает:
- ни одного наследования
- в классе c_Deck есть функция отрисовки
(перевод из внутр представление в текст для консольного приложения)

Когда я выкинул всю отрисовку из класса c_Deal - мне он начал нравится

Нет даже задания для приложения. В том то и дело. что сейчас мне надо приложение для обкатки класса c_Deal
Логично ли для этого просто написать в main кучу кода малоструктурированого, или же пытатся как то развивать
идею классов с пом наследования, создания новых классов (чтоб в main было потом пару строчек)
Миниатюры
Программа для игры в покер  
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 189
03.03.2013, 13:33  [ТС] #43
Да и вообще нормальный ли это подход - делать кирпичики ( по сути самостоятельные классы или функции)
их обкатывать, чтоб они работали как часы и к ним больше не вовзращатся. А потом из них делать приложение какое захочется.
Или следует сначала накидать както структуру конечного приложения (а если мне их надо много разных или я сам до сих пор не уверен чего хочу)
Например сейчас мне надо просто консольное приложение для обкатки классов.
Потом мне надо будет консольный клиент-сервер для игры
Потом я захочу смотреть текстовые истории рук, с них выковыривать историю, переводить её в свой формат
как то анализировать и выдавать результаты. (при том как анализировать и выдавать бесконечно вариантов)
Потом я захочу играть с ботом
Или боты меж собою.
XRuZzz
Антикодер
675 / 576 / 28
Регистрация: 15.09.2012
Сообщений: 2,522
03.03.2013, 16:37 #44

Не по теме:


Забыл сказать на Eclipse можно программировать микроконтроллеры ( с дополнительными плагинами и приложениями), писать GUI приложения, подключать различные компиляторы.



Добавлено через 10 минут

Не по теме:


Если бы вы оформили свой "спойлер" в качестве статьи в блоге, я бы вам сказал, что ссылки "пример" после ссылки "паттерн мост" не нажимаются



Добавлено через 6 минут
Да и вообще нормальный ли это подход - делать кирпичики ( по сути самостоятельные классы или функции)
их обкатывать, чтоб они работали как часы и к ним больше не вовзращатся. А потом из них делать приложение какое захочется.
Или следует сначала накидать както структуру конечного приложения (а если мне их надо много разных или я сам до сих пор не уверен чего хочу)
можно свести к вопросу, что лучше - восходящее или нисходящее проектирование.

во втором случае системные аналитики обычно выясняют кто будет пользователем системы, какова бизнес-модель предметной области, какие существуют проблемы в предметной области, пишут описание предметной области, составляют сценарии вариантов использования(это конечно больше относится к RUP).
NEbO
587 / 455 / 49
Регистрация: 22.01.2009
Сообщений: 1,180
Записей в блоге: 1
Завершенные тесты: 2
03.03.2013, 23:09 #45
вот я тоже уже год пытаюсь написать довольно небольшое приложение. программа для создания схем вышивки бисером. на настоящий момент в паблике есть только одна, но вышивальщицам она не нравится (писал программист, у него там этот бисер можно на 20 частей поделить, работает медленно, криво, и в новых версиях все больше бесполезных возможностей), и при этом замечания вышивальщиц он игнорирует.
по сложности, наверное, примерно как ваше, если учесть, что у вас там и работа с сетью, и есть над чем над алгоритмами подумать, плагинная система и прочее и прочее. вначале выбирал, сделать его на wx или qt. долго выбирал. потом узнал про канвас джаваскиптовский, решил сделать на нем. потом позучал, как оно на практике, это прототипное наследование, плюнул, начал писать на qt (уже прошло несколько месяцев). начал проектировать, составлять uml диаграммы, составил эдак классов на 50, потом что-то решил разделить, переделать, поменять... потом еще какую то книгу по проектированию почитал, еще вспомнил, что будут применяться svg изображения, причем с шаблонами (очень много одинаковых элементов со сложной форме, но различающиеся, например, одним цветом заливки). вот думал-думал, как это сделать. придумал.
потом подумал, а может мне еще захочется прикрутить вышивку крестиком. и опять, сразу все начал продумывать -- как мне сделать, чтоб можно было разместить материал, закрасить текстурой, или еще что-то, как в конце концов вообще эти нитки описывать, чтоб выглядело более-менее реалистично? пока я решал все это, прошло уже больше полугода. там какие-то другие дела появились, еще что-то...
да, я узнал о куче разных технологий, методов, и прочего и прочего. но программа как была на нуле, так и осталась. и тут я вспомнил, как раньше было просто писать на делфи 7, когда я толком не понимал, что такое классы, наследование, полиморфизм. да, выходила хрень, которую повторно использовать было нельзя и расширить тоже проблематично. но оно работало! как-то, где-то, но все же я был удовлетворен теми возможностями, которые я хотел видеть в своей программе. она их выполняла, и я был очень этому рад.
поэтому, мой вам совет, не парьтесь. нет наследования -- и не надо. еще классики (банда четырех) советовала по возможности применять делегирование, вместо наследования. если вы считаете, что находитесь на том уровне, что программу не потянете, немного все же стоит почитать теорию. книги фаулера, особенно "экстремальное программирование" -- имхо, то что нужно сейчас вам. ну и немного по паттернам, та же книга банды четырех (Гамма, Хелм, Джонсон, Влиссидес, "Приёмы объектно-ориентированного проектирования. Паттерны проектирования"), в первой части рассматривает, как проектировать небольшой текстовый редактор. когда я читал, я вообще не представлял, как такое возможно! но если дочитать до конца, становится понятным очень многое из мира ооп.
вот. ну а как захочется вернуться непосредственно к приложению: имхо, забудьте что такое ооп! забудьте про технологии, про которые прочитали, которые понравились -- без опыта применения мне они не помогали, а только лишь мешали. может, конечно, у вас получится по-другому, но в любом случае, это всего лишь средство. а средства не должны управлять всеми тонкостями вашего приложения. вы ж не STL (или другой фреймворк) пишите, в конце концов!
имхо, первое что нужно сделать: четко определиться, что будет в первой версии приложения. думаете, зная о паттернах, вы напишите код так, что его невозможно будет изменить? значит, ооп вам только помешало в реализации. я уверен, что на си вы бы не смогли написать абсолютно нерасширяемое приложение (ну разве что специально только). и пишите уже код! по фаулеру, как в экстремальном программировании. вот вам еще один пример: http://habrahabr.ru/post/153225/ (настоящий шедевр!).
А пока не определитесь чего конкретно хотите, у вас будет получиться то же, что и у меня. многому научитесь, поймете, но так ничего толкового не напишите. и будете постоянно злиться на себя за то, что ничего не получается. А как только четко поставите себе задачу, вы поймете, где должны быть все эти "синглтоны", "мосты", "стратегии" и прочее. главное, сделайте первую версию, минимальную. увидите, как все движется, работает, пусть сначала кое-как, но все же! улыбнетесь, увидите какие-то маленькие проблемы, захотите добавить анимацию. заметите где-то какие то тормоза... вообщем, всегда будет что улучшать, но главное, что все будет получаться.
а еще, можете посмотреть функциональный подход. тот же эрланг, например (хаскель я до сих пор считаю чем-то вроде китайского языка, по-моему там одни иероглифы). там вообще нет классов, и тем не менее это никак не мешает писать сложные, и порой даже более понятные программы. загляните в код какой-нибудь небольшой, но более-менее известной java-программы, и убедитесь, что ~1000 классов по 3-4 кбайта -- это не то, что вам нужно. Зато там соблюдаются (почти?) все паттерны.
я думаю, что у вас все получится. я например, пока что тоже с ходу не вижу, где у вас должно быть тут наследование. а кирпичики -- это самое то, что нужно! с ними потом будет легко и приятно работать. удачи!)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.03.2013, 23:09
Привет! Вот еще темы с ответами:

Программа поверх игры - C++
Какими способами можно заставить программу отображаться и работать поверх игры. (не поверх всех окон, а именно поверх игры)? Например, в...

Программа учета результатов игры в гольф - C++
Напишите программу, которая запрашивает у пользователя 10 результатов игры в гольф, сохраняя их в массиве. При этом необходимо обеспечить...

Что необходимо для написания читов для игры? - C++
По мере изучения СИ++ все больше и больше наталкиваюсь на мысль &quot;А не написать мне какой-нибудь чит для игры&quot;, но проштудировав весь...

Покер - C++
Прошу помощи. Болел - ничего не понял. Скоро экзамен, а я ничего не понимаю в С++. Дали примерные задачи, а я не понимаю как решать. Вот...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
03.03.2013, 23:09
Ответ Создать тему
Опции темы

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