I'm FanJae.

[Two Faced Poker] Day 3. Server 방 인원수 제한 및 GameManager 추가, Client GUI 버튼 추가 본문

Toy Project/Two Faced Poker

[Two Faced Poker] Day 3. Server 방 인원수 제한 및 GameManager 추가, Client GUI 버튼 추가

FanJae 2024. 10. 15. 23:48

1. 방 로직 개선

 

1-1. 방의 인원수 제한 처리

① 생성 

- 앞서 포스트에서 다뤘던 것처럼 현재 방에서는 방의 인원수 제한 처리가 필요했다.

- 관전자를 추가할까 고민하였으나, 우선은 관전자가 없는 형태로 처리할 것이다.

 

chatRooms[message].insert(socket);
Room_count[message] = 0;

std::shared_ptr<Game_Manager> roomGameManager = std::make_shared<Game_Manager>(roomName);
gameManagers[roomName] = roomGameManager;

send_message = roomName;

- 방을 생성할 때 Room_count를 초기화 한다.

- 현재  서버의 Logic에 의해서 방을 생성시 입장도 동시에 일어나기 때문에 입장하는 부분에서 Room_count가 증가한다.

- gameManagers에서 대해서는 아래에서 다시 설명한다.

 

② 검색

void ClientEventHandler::Handle_Get_Chatting_Room()
{
	std::string room_List = "";
	std::cout << "[Log] : " << chatRooms.size() << std::endl;
	if (chatRooms.empty())
	{
		room_List += NO_ROOM;
	}
	else
	{
		for (auto& room : chatRooms)
		{
			if (Room_count[room.first] < 2)
			{
				room_List += room.first + "\n";
				std::cout << room.first << std::endl;
			}
		}
		if (room_List == "")
		{
			room_List += NO_ROOM;
		}
	}
	send(socket, room_List.c_str(), room_List.length(), 0);
}

- 주요 추가 로직은 Room_count에 대한 처리다.

- 방의 인원수를 체크해서 2인 이하일때만 검색이 가능하게 하고, 그렇지 않은 경우 검색해도 나오지 않게 만들었다.

 

③ 삭제

const std::lock_guard<std::mutex> lock(chatRoom_mutex);
chatRooms[roomName].erase(this->socket);
Room_count[roomName]--;
if (chatRooms[roomName].empty())
{
	chatRooms.erase(roomName);
}
if (Room_count[roomName] == 0)
{
	gameManagers.erase(roomName);
	Room_count.erase(roomName);
}

- 방을 삭제 하는 경우, Room_count 값을 체크해서, 해당 방에 대한 room_count 자체를 erase 시킨다.

 

1-2. GameManager 설계

① 설계 의도

const std::string CLOSE_SOCKET = "/Close_Socket";
const std::string COMPLETE_CREATE_ROOM = "/Complete_Create_Room";
const std::string EXIST_ROOM = "/Exist_Room";
const std::string NOT_EXIST_ROOM = "/Not_Exist_Room";
const std::string NO_ROOM = "/No_Room";
const std::string EXIT_ROOM = "/Exit_Room";
const std::string GET_CHATTING_ROOM = "/Get_Chatting_Room";
const std::string CREATE_CHATTING_ROOM = "/Create_Chatting_Room ";
const std::string JOIN_CHATTING_ROOM = "/Join_Chatting_Room ";
const std::string LOGIN = "/Login";
const std::string GAME_EVENT = "/Game ";

- 현재 Client_Handler가 처리하는 Message(Event)이다.

- Event 종류가 상당히 다양하기 때문에 이제 방 안에서 게임 관련 Event는 따로 처리하도록 하고자 한다. 

 

② Game_Manager.h

#pragma once
#include "deck.h"
#include <string>
#include <winsock2.h>

const std::string GAME_READY = "/Game Ready";
const std::string GAME_START = "/Game Start";


class Game_Manager
{
private:
	std::string roomName;
	Deck deck;
public:
	Game_Manager(const std::string& roomName);
	void Handle_Game_Event(SOCKET& socket, const std::string& message);
};

- 더 이상적인 설계 방법도 있었을거 같다. 

- Game_Manager라는 것을 Room_name에 매핑시켜서 각 방에 대해서 Game_Manager 객체를 생성하게 만들었다.

 

③ Smart Pointer를 사용한 Game_Manager 자원 관리

static std::map<std::string, std::shared_ptr<Game_Manager>> gameManagers;

- 단, gameManagers에 대해서는 매핑된 방이 제거되는 시점에서 할당된 객체가 자동으로 반납되도록, 스마트 포인터를

사용하였다.

 

chatRooms[message].insert(socket);
Room_count[message] = 0;

std::shared_ptr<Game_Manager> roomGameManager = std::make_shared<Game_Manager>(roomName);
gameManagers[roomName] = roomGameManager;

send_message = roomName;

- 앞서 보았던 생성 코드를 보면, shared_ptr을 사용해서 방을 생성하는 시점에 할당해 주었다.

 


2. Client

 

2-1. 버튼 및 <준비> 창 구현

- 음.. 이 부분은 특별히 언급할 내용이 없다.


3. TODO

1) Server

- 게임 로직 처리 (카드 비교 및 베팅에 따른 정보 처리 등)

 

2) Client

- 게임 로직 처리

 

Comments