I'm FanJae.

[Two Faced Poker] Day 8. Game Logic 처리 III 본문

Toy Project/Two Faced Poker

[Two Faced Poker] Day 8. Game Logic 처리 III

FanJae 2024. 11. 8. 21:19

1. 주요 구현 로직 

- 카드 비교 로직

- CALL, RAISE 상황에 따른 처리


2. Server 처리

- 카드 비교 로직

GameType Room_Manager::compareCard(const SOCKET socket, BetType bet_type)
{
	BetType bet_type_info[2] = { BetType::NONE, BetType::NONE };
	int user_card_info[2] = { 0 };
	int vs_card_info[2] = { 0 };

	
	for (auto& pair : users)
	{
		auto& user = pair.second;
		if (pair.first == getUserNumberFromSocket(socket))
		{
			bet_type_info[0] = user->getBetType();
			user_card_info[0] = user->getFrontCard();
			user_card_info[1] = user->getBackCard();
			
			user->setBetType(BetType::NONE);

		}
		else
		{
			bet_type_info[1] = user->getBetType();
			vs_card_info[0] = user->getFrontCard();
			vs_card_info[1] = user->getBackCard();

			user->setBetType(BetType::NONE);
		}
	}

	if (bet_type == BetType::DIE)
	{
		if (bet_type_info[1] == BetType::BOTH)
		{
			return GameType::BOTHLOSE;
		}
		else
		{
			return GameType::LOSE;
		}
	}

	int user_index = (bet_type_info[0] == BetType::FRONT) ? 0 : 1;
	int vs_index = (bet_type_info[1] == BetType::FRONT) ? 0 : 1;
	if (bet_type_info[0] != BetType::BOTH)
	{
		if (bet_type_info[1] == BetType::BOTH)
		{
			if (user_card_info[user_index] < vs_card_info[0] && user_card_info[user_index] < vs_card_info[1])
			{
				return GameType::BOTHLOSE;
			}
			else
			{
				return GameType::WIN;
			}
		}
		else
		{
			if (user_card_info[user_index] > vs_card_info[vs_index])
			{
				return GameType::WIN;
			}
			else if (user_card_info[user_index] < vs_card_info[vs_index])
			{
				return GameType::LOSE;
			}
			else
			{
				return GameType::DRAW;
			}
		}
	}
	else
	{
		if (bet_type_info[1] == BetType::BOTH)
		{
			return GameType::IMPOSSIBLE;
		}
		else
		{
			if (user_card_info[0] > vs_card_info[vs_index] && user_card_info[1] > vs_card_info[vs_index])
			{
				return GameType::BOTHWIN;
			}
			else
			{
				return GameType::LOSE;
			}
		}
	}
	return GameType::IMPOSSIBLE;
}

- 카드 비교 로직은 다음과 같이 처리하였다. 상대의 카드 베팅 정보를 확인하고, 비교를 하는 방식으로 처리한다.

- 단, 양면 베팅에 대해서는 상대가 베팅한 칩을 내가 모두 이겨야 승리하는 것으로 처리했다.

- 또, 죽은 상황에 대해서는 별도로 처리했다.

 

if(game_type == GameType::RAISE)
{
	send_message = GAME_CLIENT_EVENT + TURN + OTHER;
	roomManager->broadcast_Message(send_message, socket, TargetType::SELF);

	send_message = GAME_CLIENT_EVENT + TURN + MY;
	roomManager->broadcast_Message(send_message, socket, TargetType::OTHERS);
}
else if(game_type == GameType::CALL)
{
	send_message = GAME_CLIENT_EVENT + BATTLE;
	roomManager->broadcast_Message(send_message, socket, TargetType::ALL);

	roomManager->printCard(socket);

	result_type = battleCard(socket, bet_type);
	roomManager->updateChips(socket, result_type, 0);

	check_win = roomManager->endCheck(socket);
	if (result_type == GameType::DRAW)
	{
		check_win = GameType::PROGRESS;
	}

	if (check_win == GameType::FINALWIN)
	{
		send_message = GAME_CLIENT_EVENT + GAME_RESULT + FINALWIN;
		roomManager->broadcast_Message(send_message, socket, TargetType::SELF);

		send_message = GAME_CLIENT_EVENT + GAME_RESULT + FINALLOSE;
		roomManager->broadcast_Message(send_message, socket, TargetType::OTHERS);
	}
	else if (check_win == GameType::FINALLOSE)
	{
		send_message = GAME_CLIENT_EVENT + GAME_RESULT + FINALLOSE;
		roomManager->broadcast_Message(send_message, socket, TargetType::SELF);

		send_message = GAME_CLIENT_EVENT + GAME_RESULT + FINALWIN;
		roomManager->broadcast_Message(send_message, socket, TargetType::OTHERS);
	}
	else if (check_win == GameType::PROGRESS)
	{
		giveBasicBetting(socket, result_type);
		check_win = roomManager->endCheck(socket);

		if (check_win == GameType::FINALWIN || check_win == GameType::FINALLOSE)
		{
			send_message = GAME_CLIENT_EVENT + GAME_INIT;
			roomManager->broadcast_Message(send_message, socket, TargetType::ALL);

			send_message = GAME_CLIENT_EVENT + SPECIAL + MY;
			roomManager->broadcast_Message(send_message, socket, TargetType::SELF);

			send_message = GAME_CLIENT_EVENT + SPECIAL + OTHER;
			roomManager->broadcast_Message(send_message, socket, TargetType::OTHERS);
			return;
		}

		send_message = GAME_CLIENT_EVENT + GAME_INIT;
		roomManager->broadcast_Message(send_message, socket, TargetType::ALL);

		send_message = GAME_CLIENT_EVENT + TURN + OTHER;
		roomManager->broadcast_Message(send_message, socket, TargetType::SELF);

		send_message = GAME_CLIENT_EVENT + TURN + MY;
		roomManager->broadcast_Message(send_message, socket, TargetType::OTHERS);
	}
}

- RAISE일때는 카드를 비교하지 않고, 턴을 넘기는 방식으로 처리했다.

- CALL일때는 카드를 비교하는 로직을 처리한다.

- DRAW가 나온 경우에는 카드를 새로 받는 작업을 진행한다.

- 이후, 칩이 0개인 인원을 체크한다. (endCheck() 함수)

GameType Room_Manager::endCheck(const SOCKET socket)
{
	int user_chip_info[2] = { 0 };
	std::shared_ptr<User> user_data[2];
	for (auto& pair : users)
	{
		auto& user = pair.second;
		if (pair.first == getUserNumberFromSocket(socket))
		{
			user_data[0] = user;
			user_chip_info[0] = user->getChips();
		}
		else
		{
			user_data[1] = user;
			user_chip_info[1] = user->getChips();
		}
	}

	if (user_chip_info[0] == 0)
	{
		user_data[0]->setisReady(false);
		user_data[1]->setisReady(false);
		return GameType::FINALLOSE;
	}
	if (user_chip_info[1] == 0)
	{
		user_data[0]->setisReady(false);
		user_data[1]->setisReady(false);
		return GameType::FINALWIN;
	}
	else
	{
		return GameType::PROGRESS;
	}
}

-  만약, 최종 승자가 결정된 상황이라면, FINALWIN,FINALLOSE로 최종 승리 및 패배 처리를 진행해준다.


3. 플레이 이미지

- 양면 베팅 등도 정상적으로 진행되는 것을 확인할 수 있다.

- 기본적인 구현은 모두 마쳤으니, 이제 작업하면서 바로 잡아야할 부분을 바로 잡아야 할 것 같다.

 

4. TODO

- 리팩토링 진행 (Server)

- 리팩토링 진행 (Client)

 

Comments