| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- constructor
- std::cout
- conversion constructor
- std::ostream
- virtual destructor
- pointer to member data
- dynamic_cast
- suffix return type
- C++
- diamond inheritance
- delete function
- placement new
- increment operator
- base from member
- vector size
- operator overloading
- 더 지니어스 양면포커
- return by reference
- std::vector
- new&delete
- virtual function table
- virtual function
- c++ basic practice
- virtual inheritance
- this call
- discord bot
- member function pointer
- std::endl
- vector capacity
- c++ multi chatting room
- Today
- Total
I'm FanJae.
[Two Faced Poker] Day 1. 일부 기능 추가 및 Client 로직 개선 본문
[Two Faced Poker] Day 1. 일부 기능 추가 및 Client 로직 개선
FanJae 2024. 10. 8. 23:511. Client 및 Server 정보
- 기본적인 서버는 이전에 구현했던 서버와 코드를 활용하였다.
2. 서버 정보 (게임 관련 필요 정보)
2-1. 게임에 필요한 기본적인 정보 추가
(foundation.h)
// 유저 이름과 승리 횟수 표기
class User
{
private:
std::string name;
int winCount;
int chips;
public:
User(std::string name, int winCount) : name(name), winCount(winCount), chips(0) { }
std::string getName() const {
return name;
}
int getwinCount() const {
return winCount;
}
};
// 카드의 앞면 뒷면
class Card
{
private:
int front;
int back;
public:
Card(int front, int back) : front(front), back(back) { }
int getFront() const {
return front;
}
int getBack() const {
return back;
}
};
(deck.h & deck.cpp)
#pragma once
#include <algorithm>
#include <vector>
#include <random>
#include "foundation.h"
class Deck
{
private:
std::vector<Card> cards;
public:
Deck();
void shuffleCard();
};
// deck.cpp
#include <random>
#include <chrono>
#include "deck.h"
Deck::Deck()
{
for (int i = 1; i <= 10; i++)
{
for (int j = 1; j <= 10; j++)
{
if (i == j) continue; // 서로 앞 뒷면 서로 숫자
cards.push_back(Card(i, j));
}
}
}
void Deck::shuffleCard()
{
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // 현재 시각 기반 시드 생성
std::shuffle(cards.begin(), cards.end(), std::default_random_engine(seed));
}
- 유저 정보에는 유저 ID와 현재까지의 승리 횟수 정보와 현재 칩 개수 정도를 두려한다.
- 이 게임에 특성에 맞게 카드에는 앞, 뒷면이 존재하며, 양면 숫자가 서로 다른 숫자로 이루어진 90장의 카드가 주어진다.
- 이를 섞는 기준은 현재 시간 기반으로 시드를 생성하도록 처리했다.
2-2. 로그인 추가
void ClientEventHandler::Handle_Login()
{
std::string send_message = "ID : Guest" + std::to_string(clientNumber);
clientNumber++;
send(socket, send_message.c_str(), send_message.length(), 0);
}
- 보통은 로그인 할때 DB에 저장을 하여 처리하는 것이 일반적이지만 DB를 사용하지 않았다.
- 임의로 첫번째 접속한 유저부터 Guest1과 같이 받도록 처리하였다.
3. Client 처리

3-1. 서버 연결 로직 개선
- 기존에는 사용자가 직접 IP와 Port를 입력하도록 처리하였지만, server.ini 폴더에 있는 값을 사용하도록 수정했다.
- 테스트를 할때마다 이를 입력하는 것이 번거롭기도 했고, 관리 편의성적 측면도 있다.
private void ConnectButton_Click(object sender, EventArgs e)
{
string path = Constants.INI_FILE_PATH;
string serverIp;
int serverPort;
(serverIp, serverPort) = Read_Server_Config(path);
IPAddress Ip = IPAddress.Parse(serverIp);
IPEndPoint endPoint = new IPEndPoint(Ip, serverPort);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Connect(endPoint);
string request = Constants.LOGIN;
byte[] buffer = Encoding.UTF8.GetBytes(request);
socket.Send(buffer);
byte[] recvBuffer = new byte[1024];
int recvLength = socket.Receive(recvBuffer);
string ID = Encoding.UTF8.GetString(recvBuffer, 0, recvLength);
IDLabel.Text = ID;
client_ID = ID.Substring("ID :".Length);
MessageBox.Show("서버에 연결되었습니다.", "연결 성공", MessageBoxButtons.OK, MessageBoxIcon.Information);
LogTextBox.Text += "[Log] 서버 연결을 성공하였습니다. \r\n";
}
catch (SocketException ex)
{
MessageBox.Show("서버에 연결할 수 없습니다: " + ex.Message, "연결 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private static (string, int) Read_Server_Config(string path)
{
string serverIp = "";
int serverPort = 0;
try
{
string[] lines = File.ReadAllLines(path);
foreach (string line in lines)
{
if (line.StartsWith("server="))
{
serverIp = line.Substring("server=".Length);
}
else if (line.StartsWith("port="))
{
serverPort = int.Parse(line.Substring("port=".Length));
}
}
}
catch (Exception ex)
{
MessageBox.Show($"server.ini 파일을 읽는 중 오류가 발생했습니다: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(1); // 파일을 읽지 못하면 프로그램 종료
}
return (serverIp, serverPort);
- 기존 버튼을 이용해서 입력하는 방식보다는 조금 복잡해지만, 매번 입력하지 않아도 되는 장점이 존재한다.
3-2. 방 로직 개선 구상

- 오른쪽을 게임 판으로 사용하고자 한다. 구상은 다음과 같은 형태로 예상하고 있다.
3-3. 게임판 구상
① (손그림 버전...)

- 디자인은 원래 잘 못하니까라는 위안을 삼으며, 그래도 그럴듯하게 배치를 해본다.
② 구체화

- 항상 본인이 아래쪽이다. 카드의 앞면이 7, 뒷면이 3으로 상대는 앞면이 3이고 뒷면은 알 수 없다.
- 빨간 사각형은 배팅 상황을 표기한 것이고 오른쪽 가운데 부분은 자신의 턴에 맞게 베팅할때 사용할 것이다.
4. TODO
- 방 인원에 대한 로직 개선(2인 이상 들어가지 못하도록 처리 및 이미 다 찬 방은 검색이 되지 않게 개선)
- 게임 진행과 관련된 전반적인 Logic 설계 필요
'Toy Project > Two Faced Poker' 카테고리의 다른 글
| [Two Faced Poker] Day 5. Server 리팩토링 I. 대공사 (0) | 2024.10.17 |
|---|---|
| [Two Faced Poker] Day 4. 방에 아이디 정보나 준비 상태 정보를 받아오기 (8) | 2024.10.16 |
| [Two Faced Poker] Day 3. Server 방 인원수 제한 및 GameManager 추가, Client GUI 버튼 추가 (1) | 2024.10.15 |
| [Two Faced Poker] Day 2. Server 로직 개선 및 Client Game 판 구성. (2) | 2024.10.14 |
| [Two Faced Poker] Day 0. 양면 포커 프로젝트 (0) | 2024.10.07 |