fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6.  
  7. class Main {
  8. public static void main(String[] args) {
  9. long t = System.nanoTime();
  10. Controller c = new Controller();
  11. c.playGames();
  12.  
  13. c.printResults();
  14. //System.out.println("");
  15. //System.out.println("Time (in ns): "+(System.nanoTime()-t));
  16. }
  17. }
  18.  
  19. class Controller {
  20. private static final int NUMBER_OF_GAMES = 100;
  21. public Game game;
  22. private int[][] results;
  23.  
  24. Controller() {
  25. game = new Game();
  26. game.players = new LinkedHashMap<String, Player>();
  27. game.remainingPlayers = new LinkedHashMap<String, Player>();
  28. Player[] players = getPlayers();
  29. // TODO: Worry about player order
  30. for (int i = 0; i < players.size(); i++) {
  31. game.players.put(players[i].getName(), players[i]);
  32. game.remainingPlayers.put(players[i].getName(), players[i]);
  33. }
  34. results = new int[players.length()][NUMBER_OF_GAMES];
  35. }
  36.  
  37. public Player[] getPlayers() {
  38. Player[] players = new Player[] { /* PLAYERS */ };
  39. }
  40.  
  41. void playGames() {
  42.  
  43. }
  44.  
  45. int playGame() {
  46.  
  47.  
  48. return 0;
  49. }
  50.  
  51. void playTurn(Player player) {
  52. Action action;
  53. Player target;
  54. while (player.turnsToTake > 0) {
  55. action = player.playCard();
  56. target = null;
  57.  
  58. if (action == null || action.card == null) {
  59. // Player decided to draw a card, ending this turn.
  60. player.turnsToTake -= 1;
  61. }
  62. else {
  63. // Player played a card.
  64. if (game.remainingPlayers.containsKey(action.target)) {
  65. target = game.remainingPlayers.get(action.target);
  66. }
  67.  
  68. // Remove card/pair played.
  69. if (!player.hand.remove(action.card)) {
  70. "Player "+player.getName()+" played a card they don't have: "+action.card.name());
  71. }
  72. player.removeCard(action.card);
  73. if (action.card >= Card.BEARD_CAT) {
  74. if (!player.hand.remove(action.card)) {
  75. "Player "+player.getName()+" played a card they don't have: "+action.card.name());
  76. }
  77. player.removeCard(action.card);
  78. }
  79.  
  80. // See who wants to play a NOPE
  81. if resolveNopes(player, target) {
  82. action.card.play(game, player, target);
  83. }
  84. }
  85. } // end while
  86. }
  87.  
  88. boolean resolveNopes(Player player, Player target) {
  89.  
  90. }
  91.  
  92. void printResults() {
  93.  
  94. }
  95. }
  96.  
  97. /* Game info. Bots have read-only access. */
  98. class Game {
  99. public final long MAX_TURN_TIME = 100 * 1000000; // 100ms
  100. LinkedHashMap<String, Player> players;
  101. LinkedHashMap<String, Player> remainingPlayers;
  102. List<Card> deck;
  103. List<Card> discardPile;
  104. Random rnd;
  105.  
  106. public List<String> getPlayers() {
  107. return Collections.unmodifiableMap(players);
  108. }
  109. public List<String> getRemainingPlayers() {
  110. return Collections.unmodifiableMap(remainingPlayers);
  111. }
  112. public List<String> getDiscardPile() {
  113. return Collections.unmodifiableList(discardPile);
  114. }
  115. public int getDeckSize() {
  116. return deck.size();
  117. }
  118. public int getDrawPileSize() {
  119. return deck.size() - discardPile.size();
  120. }
  121. }
  122.  
  123. /* Goes in the Controller's package */
  124. enum Card {
  125. EXPLODING_KITTEN,
  126. DIFFUSE,
  127. NOPE,
  128.  
  129. // All of the below may be played as an action:
  130. ATTACK,
  131. SKIP
  132. SHUFFLE,
  133. SEE_THE_FUTURE,
  134.  
  135. // All of the below require a target:
  136. FAVOR,
  137.  
  138. // All of the below require a pair to play:
  139. BEARD_CAT,
  140. CATERMELON,
  141. HAIRY_POTATOCAT,
  142. RAINBOW_RALPHING_CAT,
  143. TACOCAT // I'm a PALINDROME!
  144.  
  145. void play(Game game, Player player, Player target) {
  146.  
  147. switch(this) {
  148. case EXPLODING_KITTEN, DIFFUSE, NOPE:
  149. "Cannot play reaction card from hand: "+player.getName());
  150. break;
  151.  
  152. case ATTACK:
  153. player.turnsToTake = 0;
  154. // TODO: Get next player and set their turnsToTake = 2;
  155.  
  156. break;
  157.  
  158. case SKIP:
  159. player.turnsToTake -= 1;
  160. break;
  161.  
  162. case SHUFFLE:
  163. Collections.shuffle(game.deck, game.rnd);
  164. break;
  165.  
  166. case SEE_THE_FUTURE:
  167. player.seeTheFuture(game.deck.subList(0, 3));
  168. break;
  169.  
  170. case FAVOR:
  171. Card card = target.giveFavor(player.getName());
  172. target.hand.remove(card);
  173. target.removeCard(card);
  174. player.hand.add(card);
  175. player.addCard(card);
  176. break;
  177.  
  178. default:
  179. // Collections.shuffle(target.hand, game.rnd);
  180. Card card = target.hand.get(game.rnd.nextInt(target.hand.size()));
  181. target.hand.remove(card);
  182. target.removeCard(card);
  183. player.hand.add(card);
  184. player.addCard(card);
  185. break;
  186. } // switch
  187. } // play()
  188. }
  189.  
  190. /*
  191. Put this class into the Controller's package,
  192. but subclasses must be in a separate package.
  193. */
  194. /*public*/
  195. abstract class Player {
  196. List<Card> hand;
  197. int turnsToTake = 0;
  198. boolean hasNope = false;
  199.  
  200. protected String getName() {
  201. return this.getClass().getName();
  202. }
  203.  
  204. protected List<Card> getHand() {
  205. return Collections.unmodifiableList(this.hand);
  206. }
  207.  
  208. /* Called after any card is added to your hand, including cards you are dealt. */
  209. protected void addCard(Card card) {}
  210.  
  211. /* Called after any card is removed from your hand. */
  212. protected void removeCard(Card card) {}
  213.  
  214. /* Number of turns you have left. (2 if you were ATTACKed) */
  215. protected int turnsToTake() {
  216. return this.turnsToTake;
  217. }
  218.  
  219. /* Returns a list of playable cards requiring at least a pair to play. */
  220. protected List<Card> getPlayablePairs() {
  221. List<Card> pairs = new List<Card>();
  222. Card c = null;
  223. Card prev = null;
  224.  
  225. ListIterator li = this.hand.listIterator(this.hand.size());
  226. if (li.hasPrevious()) {
  227. c = li.previous();
  228. } else {
  229. return pairs;
  230. }
  231.  
  232. while (li.hasPrevious()) {
  233. if (c < Card.BEARD_CAT) {
  234. return pairs;
  235. }
  236. else {
  237. prev = c
  238. c = li.previous();
  239. if (c == prev) {
  240. pairs.add(c);
  241. while (li.hasPrevious() && c == prev) {
  242. c = li.previous();
  243. }
  244. }
  245. }
  246. }
  247. return pairs;
  248. }
  249.  
  250. /* When will you play a DIFFUSE (you can diffuse any card you draw)?
  251. Played automatically upon drawing an EXPLODING_KITTEN. */
  252. protected boolean playDiffuse() { return false; }
  253.  
  254. /* Where in the deck to put the card you just used a DIFFUSE on.
  255. @param card Probably an EXPLODING_KITTEN.
  256. @return Range of indices to randomly insert the card between, inclusive.
  257. [0, 0] = top
  258. [drawPileSize, drawPileSize] = bottom
  259. [0, drawPileSize] = anywhere
  260. [drawPileSize/3, 2*drawPileSize/3+1] = somewhere in the middle third
  261. */
  262. abstract int[] diffuseCard(Card card);
  263.  
  264. /* Called after you play SEE_THE_FUTURE.
  265. @param future The top three cards of the deck, ordered top first.
  266. */
  267. protected void seeTheFuture(List<Card> future) {}
  268.  
  269. /* What player to take a card from if you play FAVOR. */
  270. abstract String takeFavor();
  271.  
  272. /* What card to give if an opponent plays FAVOR on you. */
  273. abstract Card giveFavor(String opponent);
  274.  
  275. /* When will you play a NOPE on another player?
  276. This is called if and only if you have a NOPE,
  277. after any other player takes an action or plays a NOPE.
  278. If more than one player would play a NOPE,
  279. the player who's next turn is earlier plays theirs.
  280. This will never be called for a DIFFUSE.
  281. If you are the passed player, this will only be called if your card will otherwise fail...
  282. so if one player used a NOPE then another NOPEs that NOPE, then your play will succeed,
  283. since the second NOPE negated the first.
  284. In short, you cannot accidentally negate your own play.
  285. @param card The card that was just played.
  286. @param player Name of player that just played the card.
  287. @param target Their target. No target is "" (a SHUFFLE, for example).
  288. @return Whether you want to play your NOPE.
  289. */
  290. abstract boolean playNope(Card card, String player, String target);
  291.  
  292. /* This is the most important method.
  293. Called on your turn repeatedly until you return null,
  294. thus drawing a card and ending your turn. */
  295. abstract Action playCard();
  296. }
  297.  
  298. /* Used to return the card played and its target, if needed. */
  299. /*public*/
  300. class Action {
  301. Card card;
  302. String target;
  303.  
  304. Action(Card card) {
  305. this(card, "")
  306. }
  307.  
  308. Action(Card card, String target) {
  309. this.card = card;
  310. this.target = target;
  311. }
  312. }
  313.  
Success #stdin #stdout 0.1s 320576KB
stdin
Standard input is empty
stdout
Time (in ns): 1585087