Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.03.2017, 12:49   #1
1nsan0
Новичок
Джуниор
 
Регистрация: 03.03.2017
Сообщений: 4
По умолчанию Оценка начинающему

Привет, гуру! Я начал изучать С++ после года кодинга на Дельфи/паскале, занимаюсь по книжке Лафоре 4-ый курс, далеко за 3-4 дня, конечно, не ушёл, но уже удалось написать терминальную имитацию видеопокера.
Я хотел бы попросить всех посетивших посмотреть на код и дать оценку, в том ли я направлении думаю, как у меня получается да и в целом код на продуманность, за плюсики в карму, разумеется.

Код:
#include <string>
#include <iostream>
#include <ctime>
using namespace std;

enum suit
{ clubs, diamonds, hearts, spades };
enum highCards
{ jack = 11, queen, king, ace };
string cardValues[4] = { "Jack", "Queen", "King", "Ace" };

string cardSuits[4] = { "clubs", "diamonds", "hearts", "spades" };


class card
{
  public:
	int number;
	suit s;
	  card()
	{
	};
	void set(int n, suit a)
	{
		number = n;
		s = a;
	};
	bool sameNumbers(card c2)
	{
		if (number == c2.number)
			return true;
		else
			return false;
	};

	void display()
	{
		cout << "\t";
		(number <= 10) ? cout << number : cout << cardValues[number - 11];
		cout << " of " << cardSuits[s] << endl;
	};

};


class deck
{
  private:
	card mainDeck[52];
	card hand[5];
	int top;
	int head;

  public:
	  deck()
	{
		card temp;
		  top = 0;
		  head = 0;
		for (int i = 0; i < 52; i++)
		{
			temp.set(((i % 13) + 2), suit(i / 13));
			push(temp);
		};
	};
	void shuffle(int times)
	{
		srand(time(NULL));
		for (int j = 0; j < times; j++)
			for (int i = 0; i < top; i++)
			{
				int k = (rand() % top);
				card temp = mainDeck[i];
				mainDeck[i] = mainDeck[k];
				mainDeck[k] = temp;
			};
	};
	void BubbleSort()
	{
		for (int i = 0; i < 5; i++)
			for (int j = 4; j >= (i + 1); j--)
				if (hand[j].number < hand[j - 1].number)
				{
					card temp = hand[j - 1];
					hand[j - 1] = hand[j];
					hand[j] = temp;
				};
	};
	void initHand()
	{
		for (int i = 0; i < 5; i++)
			hand[i] = pull();
	};
	void push(card a)
	{
		mainDeck[top++] = a;
	};
	card pull()
	{
		return card(mainDeck[head++]);
	};
	void changeHand(int i[], int count)
	{
		for (int j = 0; j < count; j++)
			hand[(i[j]) - 1] = pull();
	};
	void display()
	{
		cout << "Your hand now: " << endl;
		for (int i = 0; i < 5; i++)
			hand[i].display();
	};
	void checkHand()
	{
		int sameSuit = 0;
		int i = 0, j = 0, k = 0;
		string winnings[10]
		{
		"Jacks or better", "Two Pairs", "Three of a kind", "Straight", "Flush", "Full house",
				"Four of a kind", "Straight flush", "Royal flush", "Pair"};
		int varsArray[10]
		{
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		int count = 0;

		BubbleSort();

		// Подсчет количества одинаковых
		// мастей
		for (j = 0; j < 5; j++)
			if (hand[j].s == hand[0].s)
				sameSuit++;

		do
		{
			card temp = hand[i];
			count = findSameNumbers(i);
			i += count;

			// Проверка на * of a kind
			switch (count)
			{
			case 4:
				varsArray[6]++;
				break;
			case 3:
				varsArray[2]++;
				break;
			case 2:
				if (temp.number >= jack)
					varsArray[0]++;
				else
					varsArray[9]++;
				break;
			default:
				break;
			};

		}
		while (i < 5);

		// Проверка на Two pairs
		if (((varsArray[0] == 1) && (varsArray[9] == 1)) || (varsArray[9] == 2))
		{
			varsArray[0] = 0;
			varsArray[9] = 0;
			varsArray[1] = 1;
		};

		// Проверка на Full house
		if ((varsArray[0] == 1) || (varsArray[9] == 1))
		{
			if (varsArray[2] == 1)
			{
				varsArray[5]++;
				varsArray[2]--;
				varsArray[0]--;
				varsArray[9]--;
			};
		};

		// Проверка на Flush
		if (sameSuit == 5)
			varsArray[4]++;

		// Проверка на Straight
		if (hasStraight())
		{
			varsArray[3]++;

			// Проверка на Straight flush
			if (varsArray[4] == 1)
			{
				varsArray[3]--;
				varsArray[4]--;
				varsArray[7]++;

				// Проверка на Royal flush
				if (hand[0].number == 10)
				{
					varsArray[7]--;
					varsArray[8]++;
				};
			};

		};

		// Вывод выигрышной комбинации (если
		// есть)
		cout << "You have: ";
		for (i = 0; i < 9; i++)
			if (varsArray[i] > 0)
				cout << winnings[i] << " ";

	};

	// Поиск одинаковых 
	int findSameNumbers(int order)
	{
		int result = 0, i = order;
		do
		{
			result++;
		}
		while (hand[order].sameNumbers(hand[i++]) == true);
		return result - 1;
	};

	// Проверка на Straight
	bool hasStraight()
	{
		bool result;
		for (int i = 0; i < 4; i++)
			((hand[i].number + 1) == (hand[i + 1].number)) ? result = true : result = false;
		return result;
	};

	// Для дебага
	void cheats(int n)
	{
		switch (n)
		{
		case 1:
			for (int i = 0; i < 4; i++)
				hand[i].number = 2;
			break;
		case 2:
			for (int i = 0; i < 3; i++)
				hand[i].number = 2;
			for (int i = 3; i < 5; i++)
				hand[i].number = jack;
			break;
		case 3:
			hand[0].number = 2;
			hand[1].number = 2;
			hand[2].number = 3;
			hand[3].number = 3;
			hand[4].number = 2;
			break;
		case 4:
			for (int i = 0; i < 5; i++)
				hand[i].s = spades;
			break;
		case 5:
			for (int i = 0; i < 5; i++)
				hand[i].set(10 + i, spades);
			break;
		case 6:
			for (int i = 0; i < 5; i++)
				hand[i].number = (i + 6);
			break;
		};
	};
};

 int main()
{

	int arraySize;
	deck Main;
	Main.shuffle(2);
	Main.initHand();
	Main.display();

	cout << "How much cards do you want to change (0 - 5)";
	cin >> arraySize;
	if (arraySize > 0)
	{
		int cardsToChange[arraySize];
		cout << "Which cards: ";
		for (int i = 0; i < arraySize; i++)
			cin >> cardsToChange[i];
		Main.changeHand(cardsToChange, arraySize);
	};
	
	Main.display();
	Main.checkHand();
};
То же самое на пэйстбине http://pastebin.com/eQNKw3bR
Заранее спасибо.
1nsan0 вне форума Ответить с цитированием
Старый 03.03.2017, 13:06   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

А по каким критериям оценивать?)

Форматирование кода в некоторых местах немного не очень (отступы). Если Visual Studio, то Ctrl+A, Ctrl+K, Ctrl+F.
И между функциями то есть пустая строка, то нет (обычно отделяют 1 пустой строкой).

Но хорошо что хоть какое-то есть и имена более-менее нормальные, часто новички забивают на них

; в конце блоков { } не нужен (кроме классов и енумов).
И я б советовал всегда ставить { } в for/if даже если 1 операция.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 03.03.2017 в 13:08.
Alex11223 вне форума Ответить с цитированием
Старый 03.03.2017, 13:11   #3
1nsan0
Новичок
Джуниор
 
Регистрация: 03.03.2017
Сообщений: 4
По умолчанию

С форматированием мне CodeBeautifier помог. Дело в том, что я пишу с мобилки в C4Droid и не всегда видно.
Критерии просты: как сильно я нагрязекодил. Развел лишнего, может быть, может что-то можно было сделать проще.
1nsan0 вне форума Ответить с цитированием
Старый 03.03.2017, 13:16   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от 1nsan0 Посмотреть сообщение
Дело в том, что я пишу с мобилки в C4Droid
0_о
В армии что ли?)
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 03.03.2017, 13:18   #5
1nsan0
Новичок
Джуниор
 
Регистрация: 03.03.2017
Сообщений: 4
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
0_о
В армии что ли?)
Повар...
1nsan0 вне форума Ответить с цитированием
Старый 03.03.2017, 14:18   #6
GreenWizard
мальчик-помогай =)
Форумчанин
 
Регистрация: 16.09.2010
Сообщений: 522
По умолчанию

1) много "магических" констант... например, 52 меняем на CARDS_IN_DECK (deck - колода же? проверь переводчиком)
2) стиль именования типов и переменных должен отличаться.... TDeck - один из общепринятых вариантов, хотя я часто именую классы с С, но это дело вкуса
аналогично с полями и, пусть и менее критично, с параметрами и лок. переменными
3) местами очень длинный код методов\функций.... старайся укладываться в 3-5 строк.
4) в sameNumber можно\лучше убрать условие, а вот в Card:: display разверни тернарку в if т. к. не читаемо и весьма опасно
5) я бы выделил класс "рука", а в "колоде" сделал бы метод, который забирает из колоды карту и перемещает в руку... тогда рук может быть почти любое количество

Последний раз редактировалось GreenWizard; 03.03.2017 в 14:24.
GreenWizard вне форума Ответить с цитированием
Старый 03.03.2017, 14:36   #7
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от GreenWizard Посмотреть сообщение
TDeck - один из общепринятых вариантов,
В Дельфи да, в С++ — нет.
В С++ обычно просто с большой буквы.
Цитата:
Сообщение от GreenWizard Посмотреть сообщение
но это дело вкуса
Да, но главное придерживаться чего-то одного в пределах проекта и т.п.

В некоторых языках есть более-менее общепринятые/официальные соглашения, в С++ к сожалению нет.
Цитата:
Сообщение от GreenWizard Посмотреть сообщение
старайся укладываться в 3-5 строк.
3-5 чот слишком сурово.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 03.03.2017 в 14:43.
Alex11223 вне форума Ответить с цитированием
Старый 03.03.2017, 14:53   #8
GreenWizard
мальчик-помогай =)
Форумчанин
 
Регистрация: 16.09.2010
Сообщений: 522
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
3-5 чот слишком сурово.
Строго соблюсти - да, сурово слишком, но если ставить такую планку, то будет, в среднем, приемлемая длина по проекту :-) И то, это в реальных проектах, где куча др. нюансов, а вот в учебных проектах можно и нужно максимально ограничивать размеры функций. Во-первых, чтоб их хорошо освоить. Во-вторых, чтоб научиться разбивать код, выделяя повторяющиеся участки.
Цитата:
Сообщение от Alex11223 Посмотреть сообщение
В некоторых языках есть более-менее общепринятые/официальные соглашения, в С++ к сожалению нет.
эм.... если это про именование классов, то да, а так-то в с++ весьма строго со стандартами.

Последний раз редактировалось GreenWizard; 03.03.2017 в 14:56.
GreenWizard вне форума Ответить с цитированием
Старый 03.03.2017, 14:55   #9
1nsan0
Новичок
Джуниор
 
Регистрация: 03.03.2017
Сообщений: 4
По умолчанию

1) Да, относительно констант - абсолютная правда, я обязательно это учту.
2) Учту, спасибо.. К слову, как обозначить переменнные? По типу переменной? Мол iIterations (как int) или же vIterations (как var)?
3) Я следовал логике: меньше кода в мейне - четче ясен алгоритм работы, я был не прав? Просто, разбивка функции checkHand приведет к созданию 6-8 других, работающих по тому же принципу, но просто самостоятельных. Так будет правильнее?
4) Можно подробнее про сравнение в sameNumber?
5) В условиях работы моей программы достаточно только одной "руки", но я обязательно учту про вынос класса.
1nsan0 вне форума Ответить с цитированием
Старый 03.03.2017, 15:14   #10
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от GreenWizard Посмотреть сообщение
если это про именование классов, то да, а так-то в с++ весьма строго со стандартами.
про стиль кода. Имена, форматирование, ...
Например как https://www.python.org/dev/peps/pep-0008/, http://www.php-fig.org/psr/psr-2/, http://www.oracle.com/technetwork/ja...oc-136057.html

В С++ их много и все разные.


Цитата:
Сообщение от 1nsan0 Посмотреть сообщение
меньше кода в мейне - четче ясен алгоритм работы, я был не прав?
Да, но не только в меине же

В целом функции с понятными именами выполняющие какую-то четкую задачу — лучше, чем просто куча строк кода.
Например первый попавшийся кусок:
Цитата:
Код:
		// Подсчет количества одинаковых
		// мастей
		for (j = 0; j < 5; j++)
			if (hand[j].s == hand[0].s)
				sameSuit++;
Можно легко вынести в функцию и тогда и комментарий не понадобится

Кстати, переменные лучше держать в максимально маленькой области видимости и не переиспользовать одну и ту же переменную для разных задач.
Например тут j можно сделать локальной переменной цикла:
Код:
for (int j = 0; j < 5; j++)
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 03.03.2017 в 15:19.
Alex11223 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Оценка кода Lokki1723 Общие вопросы по Java, Java SE, Kotlin 0 19.05.2016 17:53
Оценка потребляемой памяти и оценка времени выполнения. halcyon Общие вопросы C/C++ 0 22.03.2015 13:42
Оценка и хвастанье) helper999999 Общие вопросы по программированию, компьютерный форум 3 26.03.2014 06:37
оценка проекта skaj Общие вопросы по программированию, компьютерный форум 2 28.08.2013 00:12
Оценка алгоритма Алежа Помощь студентам 7 20.01.2009 14:28