Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- conversion constructor
- virtual inheritance
- base from member
- virtual function table
- std::vector
- virtual function
- member function pointer
- suffix return type
- operator overloading
- virtual destructor
- delete function
- dynamic_cast
- discord bot
- std::ostream
- constructor
- vector capacity
- placement new
- std::cout
- pointer to member data
- c++ multi chatting room
- c++ basic practice
- 더 지니어스 양면포커
- C++
- vector size
- return by reference
- diamond inheritance
- increment operator
- new&delete
- this call
- std::endl
Archives
- Today
- Total
I'm FanJae.
[Two Faced Poker] Day 6. Game Logic 처리 I 본문
1. 주요 구현 로직 (Client)
- 게임 시작
- 칩 정보 업데이트 및 기본 베팅 처리
- 카드 배분
- 베팅 처리
2. Client 처리 (게임 시작 Event)
2-1. 게임 시작
private void ChattingRoom_Form_KeyDown(object sender, KeyEventArgs e)
{
if (this.isGamePlaying == false && IsSocketConnected(socket))
{
if (e.KeyCode == Keys.F5 && My_Ready.Text == "<준비>") // F5를 눌렀을때
{
string request = Constants.ROOM_EVENT + Constants.USER_READY_STATE + Constants.DONE;
PacketHandler.SendPacket(socket, request);
My_Ready.Text = "<완료>";
}
else if (e.KeyCode == Keys.F5 && My_Ready.Text == "<완료>")
{
string request = Constants.ROOM_EVENT + Constants.USER_READY_STATE + Constants.READY;
PacketHandler.SendPacket(socket, request);
My_Ready.Text = "<준비>";
}
else if (e.KeyCode == Keys.F6 && My_Ready.Text == "<완료>" && Vs_Ready.Text == "<완료>") // F6를 눌렀을때
{
string request = Constants.GAME_CLIENT_EVENT + Constants.GAME_START;
PacketHandler.SendPacket(socket, request);
}
}
}
- Client에서는 키 입력을 처리한다. 이후, 상대방 클라이언트쪽에서도 이 정보를 알게 하기 위해 서버로 메시지를 보낸다.
2-2. 칩 정보 업데이트 및 기본 베팅 처리
else if ((message.Length >= Constants.GAME_INIT.Length && (message.Substring(0, Constants.GAME_INIT.Length) == Constants.GAME_INIT)))
{
InitTableChipSetting();
}
else if ((message.Length >= Constants.TURN.Length && (message.Substring(0, Constants.TURN.Length) == Constants.TURN)))
{
string State = message.Substring(Constants.TURN.Length);
if (State == Constants.MY)
{
if (InvokeRequired)
{
Invoke(new Action(() =>
{
System_Message.Text = "<System> : 당신의 차례입니다.";
My_Turn.Visible = true;
Vs_Turn.Visible = false;
Front_Bet_Button.Enabled = true;
Both_Bet_Button.Enabled = true;
Back_Bet_Button.Enabled = true;
}));
}
}
else if (State == Constants.OTHER)
{
if (InvokeRequired)
{
Invoke(new Action(() =>
{
System_Message.Text = "<System> : 상대방의 차례입니다.";
My_Turn.Visible = false;
Vs_Turn.Visible = true;
Front_Bet_Button.Enabled = false;
Both_Bet_Button.Enabled = false;
Back_Bet_Button.Enabled = false;
}));
}
}
}
private void InitTableChipSetting()
{
My_Front_Chip.Text = "0";
My_Back_Chip.Text = "0";
Vs_Front_Chip.Text = "0";
Vs_Back_Chip.Text = "0";
Dealer_Chip.Text = "0";
bet_type = 0;
}
- 게임 시작이 된 이후 시점에서는 베팅 관련 정보 초기화 및 턴 유무를 결정하고, 자신 턴이면 베팅 버튼을 활성화한다.
else if ((message.Length >= Constants.BASIC_BETTING.Length && (message.Substring(0, Constants.BASIC_BETTING.Length) == Constants.BASIC_BETTING)))
{
if (InvokeRequired)
{
Invoke(new Action(() =>
{
Dealer_Chip.Text = "2";
}));
}
}
else if ((message.Length >= Constants.MY.Length + Constants.CHIP_UPDATE.Length && (message.Substring(0, Constants.MY.Length + Constants.CHIP_UPDATE.Length) == Constants.MY + Constants.CHIP_UPDATE)))
{
string chip_count = message.Substring(Constants.MY.Length + Constants.CHIP_UPDATE.Length);
if (InvokeRequired)
{
Invoke(new Action(() =>
{
My_Chip.Text = chip_count;
chips = int.Parse(chip_count);
}));
}
}
else if ((message.Length >= Constants.OTHER.Length + Constants.CHIP_UPDATE.Length && (message.Substring(0, Constants.OTHER.Length + Constants.CHIP_UPDATE.Length) == Constants.OTHER + Constants.CHIP_UPDATE)))
{
string chip_count = message.Substring(Constants.OTHER.Length + Constants.CHIP_UPDATE.Length);
if (InvokeRequired)
{
Invoke(new Action(() =>
{
Vs_Chip.Text = chip_count;
vs_chips = int.Parse(chip_count);
}));
}
}
- 기본 베팅인 경우 딜러에게 가는 칩은 2개이다. 유저는 서로 1개의 칩을 딜러한테 주기 때문에 업데이트한다.
2-2. 카드 배분 Event
else if ((message.Length >= Constants.MY.Length + Constants.CARD_UPDATE.Length && (message.Substring(0, Constants.MY.Length + Constants.CARD_UPDATE.Length) == Constants.MY + Constants.CARD_UPDATE)))
{
string imagePath;
string valuePath;
string front_or_back = message.Substring(Constants.MY.Length + Constants.CARD_UPDATE.Length);
if (front_or_back.Length >= Constants.FRONT.Length && (front_or_back.Substring(0, Constants.FRONT.Length) == Constants.FRONT))
{
valuePath = "Front" + front_or_back.Substring(Constants.FRONT.Length) + ".jpg";
imagePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image", valuePath);
if (InvokeRequired)
{
Invoke(new Action(() =>
{
myFront_Card.Image = System.Drawing.Image.FromFile(imagePath);
}));
}
}
else if (front_or_back.Length >= Constants.BACK.Length && (front_or_back.Substring(0, Constants.BACK.Length) == Constants.BACK))
{
valuePath = "Back" + front_or_back.Substring(Constants.BACK.Length) + ".jpg";
imagePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image", valuePath);
if (InvokeRequired)
{
Invoke(new Action(() =>
{
myBack_Card.Image = System.Drawing.Image.FromFile(imagePath);
}));
}
}
}
else if ((message.Length >= Constants.OTHER.Length + Constants.CARD_UPDATE.Length && (message.Substring(0, Constants.OTHER.Length + Constants.CARD_UPDATE.Length) == Constants.OTHER + Constants.CARD_UPDATE)))
{
string other_Front_Value = "Front" + message.Substring(Constants.OTHER.Length + Constants.CARD_UPDATE.Length) + ".jpg";
string imagePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image", other_Front_Value);
if (InvokeRequired)
{
Invoke(new Action(() =>
{
vsFront_Card.Image = System.Drawing.Image.FromFile(imagePath);
}));
}
}
- Server가 보내준 카드 정보를 받아서 업데이트 해주도록 처리했다.
- Client에서 카드 정보를 가지고 있지만 실질적으론 실질적인 로직은 서버에서 처리한다.
2-3. 베팅 처리
private int Get_my_bet_chip()
{
return Math.Max(int.Parse(My_Front_Chip.Text), int.Parse(My_Back_Chip.Text));
}
private int Get_vs_bet_chip()
{
return Math.Max(int.Parse(Vs_Front_Chip.Text), int.Parse(Vs_Back_Chip.Text));
}
private bool Can_bet(int chip_check)
{
int my_Chips_Count = this.chips;
int vs_Chips_Count = this.vs_chips;
int my_bet_chip_count = Get_my_bet_chip();
int vs_bet_chip_count = Get_vs_bet_chip();
if (temp_bet_type == 0)
{
Bet_Chip_Count.Text = "";
MessageBox.Show("앞면 / 양면 / 뒷면 中 1개를 선택하여 주시길 바랍니다.", "베팅 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
else if (temp_bet_type == 2 && (my_Chips_Count < chip_check * 2 || vs_Chips_Count < chip_check * 2))
{
Bet_Chip_Count.Text = "";
MessageBox.Show("자신 또는 상대가 보유한 칩 보다 더 많은 숫자를 입력하였습니다.", "베팅 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
else if (vs_bet_chip_count > my_bet_chip_count + chip_check)
{
Bet_Chip_Count.Text = "";
MessageBox.Show("상대가 베팅한 칩 개수 이상 베팅해야 합니다.", "베팅 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
else
{
if (my_Chips_Count < chip_check || vs_Chips_Count < chip_check)
{
Bet_Chip_Count.Text = "";
MessageBox.Show("본인 혹은 상대가 보유한 칩보다 더 많은 숫자를 입력하였습니다.", "베팅 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
return true;
}
private void Bet_Chip_Click(object sender, EventArgs e)
{
try
{
int bet_Chip_Count_Value = int.Parse(Bet_Chip_Count.Text);
string game_type = "";
string request = "";
if (temp_bet_type == 1)
{
game_type = Constants.FRONT;
}
else if (temp_bet_type == 2)
{
game_type = Constants.BOTH;
}
else if (temp_bet_type == 3)
{
game_type = Constants.BACK;
}
if (Can_bet(bet_Chip_Count_Value) == true)
{
request = Constants.GAME_CLIENT_EVENT + Constants.BETTING + game_type + bet_Chip_Count_Value;
PacketHandler.SendPacket(socket, request);
}
}
catch (FormatException)
{
Bet_Chip_Count.Text = "";
MessageBox.Show("유효하지 않은 값을 입력하였습니다. 숫자만 입력 해주시길 바랍니다.", "베팅 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
private void Front_Bet_Button_Click(object sender, EventArgs e)
{
if (this.bet_type == 0)
{
Both_Bet_Button.Enabled = false;
Back_Bet_Button.Enabled = false;
temp_bet_type = 1;
System_Message.Text = "<System> : 앞면 베팅을 선택하였습니다. : ";
}
}
private void Both_Bet_Button_Click(object sender, EventArgs e)
{
if (this.bet_type == 0)
{
Front_Bet_Button.Enabled = false;
Back_Bet_Button.Enabled = false;
temp_bet_type = 2;
System_Message.Text = "<System> : 앙면 베팅을 선택하였습니다. : ";
}
}
private void Back_Bet_Button_Click(object sender, EventArgs e)
{
if (this.bet_type == 0)
{
Front_Bet_Button.Enabled = false;
Both_Bet_Button.Enabled = false;
temp_bet_type = 3;
System_Message.Text = "<System> : 뒷면 베팅을 선택하였습니다. : ";
}
}
private void Cancle_Button_Click(object sender, EventArgs e)
{
if (this.bet_type == 0)
{
Front_Bet_Button.Enabled = true;
Both_Bet_Button.Enabled = true;
Back_Bet_Button.Enabled = true;
temp_bet_type = 0;
}
}
- 베팅 관련 로직에서 가장 중요한 것은 칩을 베팅하는 개수에 대한 제한이다.
- 콜을 위해서는 최소 상대가 현재 베팅한 칩 만큼은 베팅해야하고, 상대가 가진 칩보다는 적게 베팅해야한다.
- 양면일때는, 앞 뒷면으로 베팅을 하기 때문에, 2배의 경우로 이를 계산해야한다.
3. TODO (Server)
- 게임 시작
- 칩 정보 업데이트 및 기본 베팅 처리
- 카드 배분
- 베팅 처리
'Toy Project > Two Faced Poker' 카테고리의 다른 글
[Two Faced Poker] Day 8. Game Logic 처리 III (0) | 2024.11.08 |
---|---|
[Two Faced Poker] Day 7. Game Logic 처리 II (0) | 2024.11.04 |
[Two Faced Poker] Day 5. Server 리팩토링 II. 서버 리팩토링에 따른 Client 대공사 (5) | 2024.10.20 |
[Two Faced Poker] Day 5. Server 리팩토링 I. 대공사 (0) | 2024.10.17 |
[Two Faced Poker] Day 4. 방에 아이디 정보나 준비 상태 정보를 받아오기 (7) | 2024.10.16 |
Comments