// Обработка сообщений private void ProcessMessage(string command, string message) { Dictionary<string, string> bParams = Helpers.SplitCommandString(message); switch (command) { // Обработка раздачи карт case Messages.MESSAGE_GAME_DISTRIBUTIONCARDS: { botCards = new CardList(bParams["Cards"]); IsMakingOrder = false; usedCards.Clear(); RenewDontUsedCards(); //int totalScore1 = Int32.Parse(bParams["Scores1"]); //int totalScore2 = Int32.Parse(bParams["Scores2"]); break; } // Обработка перехода хода к данному боту case Messages.MESSAGE_GAME_BAZAR_NEXTBETPLAYER: { BetType bType = (BetType)Int32.Parse(bParams["Type"]); int minSize = Int32.Parse(bParams["MinSize"]); // Расчет и совершение заказа Thread.Sleep(500); Order order; if (!IsMakingOrder) { order = GetMaxPossibleOrder(); if (order.Size < minSize) order = new Order(OrderType.ORDER_PASS, 0, CardSuit.C_NONE); IsMakingOrder = true; } else order = new Order(OrderType.ORDER_PASS, 0, CardSuit.C_NONE); MakeOrder(order); break; } // Название ставки другого игрока case Messages.MESSAGE_GAME_BAZAR_SAYBET: { // НЕ НУЖНО break; } // Завершение процесса торговли case Messages.MESSAGE_GAME_BAZAR_END: { // НЕ НУЖНО break; } // Завершение процесса торговли без выбора козыря case Messages.MESSAGE_GAME_BAZAR_PASS: { // НЕ НУЖНО break; } // Переход хода к боту case Messages.MESSAGE_GAME_GAMING_NEXTPLAYER: { CardList PossibleCards = new CardList(bParams["Cards"]); // Расчет и показ бонусов Thread.Sleep(500); if (botBonuses != null) { if (botBonuses.Count > 0) { for (var i = botBonuses.Count - 1; i >= 0; i--) { if (botBonuses[i] != botBonuses.SeniorBonus) botBonuses.Delete(botBonuses[i]); } } AnnounceBonuses(botBonuses); } Thread.Sleep(500); // Расчет и совершение хода MakeMove(GetMovingCard(PossibleCards)); break; } // Извещение о ходе картой другим игроком case Messages.MESSAGE_GAME_GAMING_REMINDCARD: { int cardPlace = Int32.Parse(bParams["Place"]); Card newCard = new Card(bParams["Card"]); // Запоминание похоженной карты usedCards.Add(newCard); dontUsedCards.Remove(dontUsedCards[newCard.Type, newCard.Suit]); // int LocalScore1 = Int32.Parse(bParams["Scores1"]); // int LocalScore2 = Int32.Parse(bParams["Scores2"]); // int beloteRemind = Int32.Parse(bParams["Belote"]); break; } // Получение списка возможных бонусов case Messages.MESSAGE_GAME_BONUSES_ALL: { botBonuses = new BonusList(message); break; } // Оглашение типов бонусов другими игроками case Messages.MESSAGE_GAME_BONUSES_TYPES: { // НЕ НУЖНО break; } // Оглашение победителя бонусов case Messages.MESSAGE_GAME_BONUSES_WINNER: { // НЕ НУЖНО break; } default: { break; } } }
// Совершение ботом заказа private void MakeOrder(Order Order) { if (ActiveTable != null) { lock (ActiveTable) { try { ActiveTable.AddOrder(Order); } catch (Exception ex) { #if DEBUG Debug.WriteLine(ex.Message); #endif } } } }
// Метод, добавляющий новый заказ игрока в список заказов public void AddOrder(Order order) { // Выбираем, какая из команд сделала заказ BeloteTeam team = (((currentPlayer == 1) || (currentPlayer == 3)) ? BeloteTeam.TEAM1_1_3 : BeloteTeam.TEAM2_2_4); // Добавляем заказ в список заказов текущей раздачи distributions.Current.Orders.Add(order, team); // Посылаем всем клиентам уведомление о том, какой заказ был сделан SendMessageToClients(String.Format("{4}Player={0},Type={1},Size={2},Trump={3}", currentPlayer, (int)order.Type, order.Size, Helpers.SuitToString(order.Trump), Messages.MESSAGE_GAME_BAZAR_SAYBET)); // В случае окончания процесса торговли if (distributions.Current.Orders.IsEnded()) { // Если торговля завершилась четырьмя пассами if (distributions.Current.Orders.IsPass) { SendMessageToClients(Messages.MESSAGE_GAME_BAZAR_PASS); distributions.Current.ChangeStatus(DistributionStatus.D_ENDED); NextDistribution(); } // Если торговля завершилась заказом else { // Завершаем торговлю, назначая козырь distributions.Current.EndBazar(); // Отсылаем всем клиентам сообщение о конце торговли SendMessageToClients(String.Format("{4}Team={0},Type={1},Size={2},Trump={3}", (int)distributions.Current.Orders.OrderedTeam, (int)distributions.Current.Orders.Current.Type, distributions.Current.Orders.Current.Size, (int)distributions.Current.Orders.Current.Trump, Messages.MESSAGE_GAME_BAZAR_END)); // Отсылаем все возможные бонус клиентам TableCreator.SendMessage(Messages.MESSAGE_GAME_BONUSES_ALL + distributions.Current.Player1Bonuses.ToString()); Player2.SendMessage(Messages.MESSAGE_GAME_BONUSES_ALL + distributions.Current.Player2Bonuses.ToString()); Player3.SendMessage(Messages.MESSAGE_GAME_BONUSES_ALL + distributions.Current.Player3Bonuses.ToString()); Player4.SendMessage(Messages.MESSAGE_GAME_BONUSES_ALL + distributions.Current.Player4Bonuses.ToString()); // Ход переходит к первому ходящему на раздаче currentPlayer = startedPlayer; // Передаем следующий ход со всеми возможными картами NextMove(); } } // Иначе продолжаем торговлю else { // Тип ставки для следующего игрока BetType betType; currentPlayer = NextPlayer(currentPlayer); // Если была оглашена контра if (distributions.Current.Orders.IsCoinched) { betType = BetType.BET_SURCOINCHE; // Если после контры уже был оглашен пасс, то перескакиваем еще одного игрока if (distributions.Current.Orders.Last.Type == OrderType.ORDER_PASS) { currentPlayer = NextPlayer(currentPlayer); } } else // Если последним был объявлен капут, то ответить на него можно только капутом или контрой if (distributions.Current.Orders.IsCapot) { betType = BetType.BET_CAPOT; } else // Если уже был сделан хотя бы один заказ, то можно ответить заказом или контрой на заказ другой команды if (distributions.Current.Orders.Current != null) { BeloteTeam curTeam = ((currentPlayer == 1) || (currentPlayer == 3)) ? BeloteTeam.TEAM1_1_3 : BeloteTeam.TEAM2_2_4; if (distributions.Current.Orders.OrderedTeam == curTeam) betType = BetType.T_BET; else betType = BetType.T_BETABET; } // Если еще ни одного заказа не сделано, то можно ответить только заказом else { betType = BetType.T_BET; } // Минимальный размер ставки для следующего игрока int minSize = (distributions.Current.Orders.Current == null) ? 80 : distributions.Current.Orders.Current.Size + 10; // Посылка сообщения GBN следующему в торговле игроку Client p = PlayerFromNumber(currentPlayer); p.SendMessage(String.Format("{2}Type={0},MinSize={1}", (int)betType, minSize, Messages.MESSAGE_GAME_BAZAR_NEXTBETPLAYER)); } }
// Получение максимального возможного заказа для одной масти private Order GetOrderForSuit(CardSuit Suit) { Order result; try { int KCount = 0; int Aces = 0; int AceAnd10 = 0; int Ace10K = 0; int Ace10KQ = 0; CardList tempCardList = new CardList(botCards.ToString()); tempCardList.SetTrump(Suit); // Подсчет количества козырных карт, некозырных тузов и пар некозырных туз-10, туз-10-к, туз-10-к-д for (var i = 0; i < tempCardList.Count; i++) { if (tempCardList[i].IsTrump) { KCount++; } else { if (tempCardList[i].Type == CardType.C_A) { Aces++; if (tempCardList.Exists(new Card(CardType.C_10, tempCardList[i].Suit))) { AceAnd10++; if (tempCardList.Exists(new Card(CardType.C_K, tempCardList[i].Suit))) { Ace10K++; if (tempCardList.Exists(new Card(CardType.C_Q, tempCardList[i].Suit))) { Ace10KQ++; } } } } } } int orderSize = 0; // Выбираем размер ставки при игре с козырем if (Suit != CardSuit.C_NONE) { bool JackK = tempCardList.Exists(new Card(CardType.C_J, Suit)); bool NineK = tempCardList.Exists(new Card(CardType.C_9, Suit)); if ((JackK) && (NineK) && ((KCount + Aces) >= 4)) orderSize = 80; if ((JackK) && (NineK) && ((KCount + Aces) >= 5)) orderSize = 90; if ((JackK) && (NineK) && ((KCount + Aces) >= 5) && (AceAnd10 > 0)) orderSize = 100; if ((JackK) && (NineK) && (KCount >= 4) && (Aces >= 2)) orderSize = 110; if ((JackK) && (NineK) && (KCount >= 5) && (Aces >= 1)) orderSize = 120; if ((JackK) && (NineK) && (KCount >= 5) && (Aces >= 2)) orderSize = 130; if ((JackK) && (NineK) && (KCount >= 5) && (Aces >= 2) && (AceAnd10 > 0)) orderSize = 140; if ((JackK) && (KCount >= 6) && (Aces >= 1)) orderSize = 150; if ((JackK) && (KCount >= 7)) orderSize = 160; if (KCount == 8) orderSize = 250; if ((tempCardList.IsBelote) && (orderSize != 0)) orderSize += 20; } // Выбираем размер ставки при игре без козыря else { if (Aces >= 3) orderSize = 80; if ((Aces >= 3) && (AceAnd10 >= 1)) orderSize = 90; if ((Aces >= 3) && (AceAnd10 >= 2)) orderSize = 100; if ((Aces >= 3) && (AceAnd10 >= 3)) orderSize = 110; if ((Aces >= 3) && (AceAnd10 >= 2) && (Ace10K > 0)) orderSize = 120; if ((Aces >= 3) && (AceAnd10 >= 2) && (Ace10KQ > 0)) orderSize = 130; if ((Aces >= 4) && (AceAnd10 >= 1)) orderSize = 140; if ((Aces >= 4) && (AceAnd10 >= 2)) orderSize = 150; if ((Aces >= 4) && (AceAnd10 >= 3)) orderSize = 160; if ((Aces >= 4) && (AceAnd10 >= 4)) orderSize = 250; } if (orderSize == 0) { result = new Order(OrderType.ORDER_PASS, orderSize, CardSuit.C_NONE); } else { if (orderSize >= 250) { result = new Order(OrderType.ORDER_CAPOT, orderSize, Suit); } else { result = new Order(OrderType.ORDER_BET, orderSize, Suit); } } return result; } catch { return new Order(OrderType.ORDER_PASS, 0, CardSuit.C_NONE); } }
// Добавление заказа в список public void Add(Order order, BeloteTeam Team) { list.Add(order); // Если в заказе содержится новая ставка, то обновляем "текущий заказ" до этой ставки - это возможно в случае заказа и в случае капута if ((order.Type == OrderType.ORDER_BET) || (order.Type == OrderType.ORDER_CAPOT)) { Current = order; OrderedTeam = Team; } // Проверяем, если это 4 пасс, то раздача завершена, можно переходить к следующей if (order.Type == OrderType.ORDER_PASS) { if (Test4Pass()) IsPass = true; } else // Далее устанавливаются флаги IsCapot и т.д. if (order.Type == OrderType.ORDER_CAPOT) { IsCapot = true; } else if (order.Type == OrderType.ORDER_COINCHE) { IsCoinched = true; } else if (order.Type == OrderType.ORDER_SURCOINCHE) { IsSurcoinched = true; } }