/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
class Main {
public static void main
(String[] args
) { Controller c = new Controller();
c.playGames();
c.printResults();
//System.out.println("");
//System.out.println("Time (in ns): "+(System.nanoTime()-t));
}
}
class Controller {
private static final int NUMBER_OF_GAMES = 100;
public Game game;
private int[][] results;
Controller() {
game = new Game();
game.
players = new LinkedHashMap
<String, Player
>(); game.
remainingPlayers = new LinkedHashMap
<String, Player
>(); Player[] players = getPlayers();
// TODO: Worry about player order
for (int i = 0; i < players.size(); i++) {
game.players.put(players[i].getName(), players[i]);
game.remainingPlayers.put(players[i].getName(), players[i]);
}
results = new int[players.length()][NUMBER_OF_GAMES];
}
public Player[] getPlayers() {
Player[] players = new Player[] { /* PLAYERS */ };
}
void playGames() {
}
int playGame() {
return 0;
}
void playTurn(Player player) {
Player target;
while (player.turnsToTake > 0) {
action = player.playCard();
target = null;
if (action == null || action.card == null) {
// Player decided to draw a card, ending this turn.
player.turnsToTake -= 1;
}
else {
// Player played a card.
if (game.remainingPlayers.containsKey(action.target)) {
target = game.remainingPlayers.get(action.target);
}
// Remove card/pair played.
if (!player.hand.remove(action.card)) {
"Player "+player.getName()+" played a card they don't have: "+action.card.name());
}
player.removeCard(action.card);
if (action.card >= Card.BEARD_CAT) {
if (!player.hand.remove(action.card)) {
"Player "+player.getName()+" played a card they don't have: "+action.card.name());
}
player.removeCard(action.card);
}
// See who wants to play a NOPE
if resolveNopes(player, target) {
action.card.play(game, player, target);
}
}
} // end while
}
boolean resolveNopes(Player player, Player target) {
}
void printResults() {
}
}
/* Game info. Bots have read-only access. */
class Game {
public final long MAX_TURN_TIME = 100 * 1000000; // 100ms
LinkedHashMap
<String, Player
> players
; LinkedHashMap
<String, Player
> remainingPlayers
; List<Card> deck;
List<Card> discardPile;
public List<String> getPlayers() {
}
public List<String> getRemainingPlayers() {
}
public List<String> getDiscardPile() {
}
public int getDeckSize() {
return deck.size();
}
public int getDrawPileSize() {
return deck.size() - discardPile.size();
}
}
/* Goes in the Controller's package */
enum Card {
EXPLODING_KITTEN,
DIFFUSE,
NOPE,
// All of the below may be played as an action:
ATTACK,
SKIP
SHUFFLE,
SEE_THE_FUTURE,
// All of the below require a target:
FAVOR,
// All of the below require a pair to play:
BEARD_CAT,
CATERMELON,
HAIRY_POTATOCAT,
RAINBOW_RALPHING_CAT,
TACOCAT // I'm a PALINDROME!
void play(Game game, Player player, Player target) {
switch(this) {
case EXPLODING_KITTEN, DIFFUSE, NOPE:
"Cannot play reaction card from hand: "+player.getName());
break;
case ATTACK:
player.turnsToTake = 0;
// TODO: Get next player and set their turnsToTake = 2;
break;
case SKIP:
player.turnsToTake -= 1;
break;
case SHUFFLE:
break;
case SEE_THE_FUTURE:
player.seeTheFuture(game.deck.subList(0, 3));
break;
case FAVOR:
Card card = target.giveFavor(player.getName());
target.hand.remove(card);
target.removeCard(card);
player.hand.add(card);
player.addCard(card);
break;
default:
// Collections.shuffle(target.hand, game.rnd);
Card card = target.hand.get(game.rnd.nextInt(target.hand.size()));
target.hand.remove(card);
target.removeCard(card);
player.hand.add(card);
player.addCard(card);
break;
} // switch
} // play()
}
/*
Put this class into the Controller's package,
but subclasses must be in a separate package.
*/
/*public*/
abstract class Player {
List<Card> hand;
int turnsToTake = 0;
boolean hasNope = false;
return this.getClass().getName();
}
protected List<Card> getHand() {
}
/* Called after any card is added to your hand, including cards you are dealt. */
protected void addCard(Card card) {}
/* Called after any card is removed from your hand. */
protected void removeCard(Card card) {}
/* Number of turns you have left. (2 if you were ATTACKed) */
protected int turnsToTake() {
return this.turnsToTake;
}
/* Returns a list of playable cards requiring at least a pair to play. */
protected List<Card> getPlayablePairs() {
List<Card> pairs = new List<Card>();
Card c = null;
Card prev = null;
if (li.hasPrevious()) {
c = li.previous();
} else {
return pairs;
}
while (li.hasPrevious()) {
if (c < Card.BEARD_CAT) {
return pairs;
}
else {
prev = c
c = li.previous();
if (c == prev) {
pairs.add(c);
while (li.hasPrevious() && c == prev) {
c = li.previous();
}
}
}
}
return pairs;
}
/* When will you play a DIFFUSE (you can diffuse any card you draw)?
Played automatically upon drawing an EXPLODING_KITTEN. */
protected boolean playDiffuse() { return false; }
/* Where in the deck to put the card you just used a DIFFUSE on.
@param card Probably an EXPLODING_KITTEN.
@return Range of indices to randomly insert the card between, inclusive.
[0, 0] = top
[drawPileSize, drawPileSize] = bottom
[0, drawPileSize] = anywhere
[drawPileSize/3, 2*drawPileSize/3+1] = somewhere in the middle third
*/
abstract int[] diffuseCard(Card card);
/* Called after you play SEE_THE_FUTURE.
@param future The top three cards of the deck, ordered top first.
*/
protected void seeTheFuture(List<Card> future) {}
/* What player to take a card from if you play FAVOR. */
/* What card to give if an opponent plays FAVOR on you. */
abstract Card giveFavor
(String opponent
);
/* When will you play a NOPE on another player?
This is called if and only if you have a NOPE,
after any other player takes an action or plays a NOPE.
If more than one player would play a NOPE,
the player who's next turn is earlier plays theirs.
This will never be called for a DIFFUSE.
If you are the passed player, this will only be called if your card will otherwise fail...
so if one player used a NOPE then another NOPEs that NOPE, then your play will succeed,
since the second NOPE negated the first.
In short, you cannot accidentally negate your own play.
@param card The card that was just played.
@param player Name of player that just played the card.
@param target Their target. No target is "" (a SHUFFLE, for example).
@return Whether you want to play your NOPE.
*/
abstract boolean playNope
(Card card,
String player,
String target
);
/* This is the most important method.
Called on your turn repeatedly until you return null,
thus drawing a card and ending your turn. */
}
/* Used to return the card played and its target, if needed. */
/*public*/
Card card;
this(card, "")
}
this.card = card;
this.target = target;
}
}