BS - карточная игра, целью которой является потеря всех ваших карт.
Игра состоит из четырех игроков и колоды из 52 карт. Каждый игрок случайным образом получает 13 карт. Обычно карты обозначены 2 - 10, туз, валет, дама, король, но для простоты карты будут обозначены цифрами от 0 до 12 включительно. Хотя количество карт в руке игрока является общедоступной информацией, только игрок знает, какие именно карты находятся в его руке.
Игра идет следующим образом: первый игрок кладет столько карт с меткой 0, сколько он хочет, в колоду сброса (обратите внимание, что он не обязан разыгрывать все свои карты с меткой 0 , хотя обычно это в его интересах ). Он должен сыграть хотя бы одну карту. Второй игрок разыгрывает столько карт, сколько он хочет, с меткой 1 , третий игрок разыгрывает 2 и так далее. После 12 сбрасывается до 0.
Что произойдет, если у вас нет карт, на которые вы должны играть? Помните, вы должны сыграть хотя бы одну карту - на самом деле, вы можете играть любые карты, которые хотите! (На самом деле, даже если у вас есть подходящая карта, вы можете лгать и разыгрывать другую карту). Тем не менее, кто-то может позвонить вам и сказать: «BS!» Если кто-то прав, и вы солгали, вы должны взять все карты из колоды сброса; в качестве награды игрок, который вызвал вас случайным образом, кладет одну из своих карт в колоду сброса. Однако, если обвинитель ошибается, он должен взять все карты из колоды сброса. Обратите внимание, что вы не можете лгать о количестве карт, которые вы играете.
Более подробная информация:
- В начале игры выбираются четыре случайных игрока. Поскольку будет не менее 1000 игр, у каждого игрока будет шанс сыграть. Порядок хода определяется случайным образом в начале игры.
- Если вы вернете одну правильную карту и одну неправильную карту, то это считается ложью (то есть, если вы должны были дать 2 с, а вы дали одну 2 и одну 1 , то это ложь)
- Если два или более игрока оба говорят BS одновременно, то один выбирается случайным образом.
- Ваш счет - это процент игр, которые вы выиграли.
- Существует максимум 1000 раундов, где один раунд - каждый игрок, идущий один раз. Обычно кто-то выигрывает до этого. Если никто не выигрывает, он засчитывается в общее количество сыгранных игр, но никто не выигрывает.
Spec:
Вы должны написать класс, который расширяется Player
. Это будет выглядеть так:
package players;
import java.util.ArrayList;
import java.util.List;
import controller.*;
public class Player1 extends Player {
@Override
protected List<Card> requestCards(int card, Controller controller) {
Card[] hand = getHand();
List<Card> ret = new ArrayList<Card>();
for (Card c : hand) {
if (c.getNumber() == card) {
ret.add(c);
}
}
if (ret.size() == 0) ret.add(hand[0]);
return ret;
}
@Override
protected boolean bs(Player player, int card, int numberOfCards, Controller controller) {
return numberOfCards >= 3;
}
protected void update(Controller controller) {
// This method gets called once at the end of every round
}
protected void initialize(Controller controller) {
// This method gets called once at the beginning once all the cards are dealt
}
public String toString() {
return "Player 1";
}
}
Метод requestCards
вызывается, когда ваша очередь. Аргументом card
является номер карты, который вы должны предоставить. Вы возвращаете список карт, которые хотите положить в колоду сброса. Игрок выше проверяет, есть ли у него карты запрошенного типа; если нет, он просто разыгрывает свою первую карту и надеется, что никто не проверит.
Метод bs
вызывается всякий раз, когда кто-то играет в карту. Первый аргумент - это игрок, второй - карта, которую он должен был сыграть, а третий - номер карты того типа, которую он утверждает, что разыграл. Вернитесь, true
если хотите позвонить «БС». В приведенном выше коде игрок вызывает «BS» только тогда, когда другой игрок утверждает, что имеет 3 или более карт запрошенного типа.
Последний аргумент для обоих методов: controller
контроллер, управляющий игрой. Из контроллера вы можете получить больше общедоступной информации, такой как количество карт в колоде сброса или список и порядок хода игроков.
toString
Метод является необязательным.
Контроллер на GitHub: https://github.com/prakol16/bs
Если вы хотите опубликовать решение, отличное от java, вы можете использовать интерфейс, предоставленный в https://github.com/LegionMammal978/bs (кредиты LegionMammal978), и я постараюсь интегрировать его.
Табло пока что:
class players.PlayerConMan: 2660/4446 = 59.82905982905983%
class players.CalculatingLiar: 2525/4426 = 57.049254405784005%
class players.PlayerTruthy: 1653/4497 = 36.75783855903936%
class players.Player4: 1446/4425 = 32.67796610169491%
class players.Player1: 536/4382 = 12.23185759926974%
class players.Player3: 493/4425 = 11.141242937853107%
class players.Player2: 370/4451 = 8.312738710402156%
class players.LiePlayer: 317/4432 = 7.152527075812275%
class players.Hoarder: 0/4516 = 0.0%
PlayerConMan выигрывает, но CalculatingLiar находится на втором месте. Эти оценки кажутся последовательными - они почти всегда одинаковы.
источник
Controller.toString()
публике, так как это возвращает руки всех игроков и колоду сброса.Ответы:
Мошенник
Конман наблюдает за каждой картой, которая проходит через его руку, вызывая BS, когда игра невозможна из-за того, где находятся карты.
Играет правду, когда может, но лжет разумно, используя последнюю карту, если победа произойдет.
Я потратил много времени, настраивая технику для вызова BS, когда высока вероятность того, что противник лжет, или когда вызов BS был выгоден (например, получение полезных карт из колоды сброса), но на практике, вообще не вызывая BS мне больше всего очков.
источник
Игрок 3131961357_10
Выбирает случайного игрока в каждой игре и всегда вызывает BS для этого игрока.
источник
Truthy
Не совсем закончено, так как я не знаю, как определить результат вызова BS (если они взяли кучу, или кто-то другой в случае ничьей, или я).
На данный момент, только позвоните в BS, если я могу доказать это. Не лги, если я не должен. Мне нужно улучшить алгоритм лжи. Я пытаюсь сделать это как можно ближе к тому, как я играю БС против других игроков (за исключением случайного помещения дополнительных карт внизу, чтобы играть 5 или 6 без их ведома).
источник
cards = cards.get(0)
.cards
это список, поэтому вы не можете присвоитьCard
aList<Card>
. Вы пытаетесь удалить все, кроме первого элемента?numberOfCards
что он уже сбрасывается приbs
вызове)CalculatingLiar
Этот пытается играть правду. Если он лжет, он использует карту, которую он не будет использовать в ближайшем будущем. Он также пытается выиграть через вызов BS на других игроках, так как последняя карта почти никогда не подходит.
источник
накопитель
Очень простая стратегия, собирать карты до тех пор, пока она не станет честной и победит. Не смог проверить это, надеюсь, моя Java не слишком ржавая.
источник
remainingCards.remove(card)
должен иметь приведение кInteger
, иначе Java думает, что вы звоните.remove(int)
, который удаляется по индексу.LiePlayer
Устанавливает как минимум 2 карты, даже если это означает растяжку правды.
источник
Card[] hand = getHand();
необходим в верхней частиbs(..)
(Player.hand
является частным). Кроме того, это дает сбой, если в вашей руке менее 2 карт.i<cards.length
; рука не определена вCard c : hand
. И иногда это входит в бесконечный цикл, потому что вы не делаете++i
в цикле. Я бы добавил это, но я не уверен, что именно так вы и хотите.