I'm FanJae.

[Two Faced Poker] Day 6. Game Logic 처리 I 본문

Toy Project/Two Faced Poker

[Two Faced Poker] Day 6. Game Logic 처리 I

FanJae 2024. 10. 31. 23:52

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)

- 게임 시작

- 칩 정보 업데이트 및 기본 베팅 처리

- 카드 배분

- 베팅 처리

Comments