Main.java
import java.util.Scanner; import java.util.ArrayList; import java.util.Arrays; import java.util.InputMismatchException; public class CardBattler { //NOTE: Red is Intellisense, the bot. //These are the standard cards players start with (each player has their own set of cards) static ArrayList<Integer> cardsBlue = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); static ArrayList<Integer> cardsRed = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); //NOTE: Make sure columnValues.length() equals numColumns! static final int numColumns = 6; //These track the total value each player has on each column static final int[] blueValue = new int[numColumns]; static final int[] redValue = new int[numColumns]; //This is how much a column is worth in game points static final int[] columnValues = {4, 5, 6, 7, 8, 9}; //Score tracker, used when counting points in the end static int blueScore = 0; static int redScore = 0; static Scanner read = new Scanner(System.in); public static void main(String[] args) { System.out.println("Column Battler Game! \nHave more sum of cards in a column that your opponent to win points for the column.\nWhoever scores more points wins!"); System.out.println("\nYou will play against Intellisense, a bot."); for(int i = 0; i < numColumns; i++) { System.out.println("Column " + (i+1) + " is worth " + columnValues[i] + " points"); } int toPlace = 0; //This variable represents the card that was drawn // This while loop ensures that the game only ends once both sides have used up all their cards (a.k.a. the game is still running System.out.println("\nPlease choose a difficulty level"); System.out.println("A: You add a 1 card to a random column 4 times"); System.out.println("B: You add a 1 card to a random column 2 times"); System.out.println("C: Standard rules"); System.out.println("D: Intellisense adds a 1 card to a random column 3 times"); System.out.println("Please enter \"A\", \"B\", \"C\", or \"D\""); boolean validReply = false; while(!validReply) { String reply = read.next(); reply.toUpperCase(); if((reply.equals("A") || reply.equals("B") || reply.equals("C") || reply.equals("D"))) { validReply = true; if(reply.equals("A")) { for(int i = 0; i < 4; i++) { int location = (int)(Math.random() * numColumns); blueValue[location]++; } System.out.println("You have selected difficulty A!"); } else if(reply.equals("B")) { for(int i = 0; i < 2; i++) { int location = (int)(Math.random() * numColumns); blueValue[location]++; } System.out.println("You have selected difficulty B!"); } else if(reply.equals("D")){ for(int i = 0; i < 3; i++) { int location = (int)(Math.random() * numColumns); redValue[location]++; } System.out.println("You have selected difficulty D!"); } else { //reply was "C" System.out.println("You have selected difficulty C!"); } } if(!validReply) { System.out.println("Please enter \"A\", \"B\", \"C\", or \"D\""); } } while(cardsBlue.size() != 0 && cardsRed.size() != 0) { //Blue's turn toPlace = drawCard("blue"); int location = 0; //This represents which column the card was assigned boolean validLocation = false; //This variable checks if the player entered a valid value while(!validLocation) { try { System.out.println("\nYou have drawn the " + toPlace + " card. \nSelect the column you want to place it! (1~" + numColumns + ")"); location = read.nextInt(); for(int i = 1; i <= numColumns; i++) { if(location == i) { validLocation = true; break; } } } catch (InputMismatchException e) { System.out.println("Invalid input. Please enter a valid number."); read.next(); } if(!validLocation) { System.out.println("Invalid column! Please enter an integer between 1 and " + numColumns + "."); } } //The player can only exit this loop until they entered a valid value System.out.println("You have placed the " + toPlace + " card at column " + location + "!"); location--; //User enters 1~6, computer processes 0~5 blueValue[location] += toPlace; printStatus(); //Intellisense's turn toPlace = drawCard("red"); location = red(toPlace); System.out.println("\nIntellisense placed the " + toPlace + " card at column " + (location+1) + "!"); redValue[location] += toPlace; printStatus(); } //Scoring logic System.out.println("\n\nGame finished! \nLet's count our points!"); for(int i = 0; i < numColumns; i++) { if(redValue[i] > blueValue[i]) { System.out.println("Intellisense has won column " + (i+1) + "! " + columnValues[i] + " points for Intellisense!"); redScore += columnValues[i]; } else if(blueValue[i] > redValue[i]) { System.out.println("You won column " + (i+1) + "'s " + columnValues[i] + " points!"); blueScore += columnValues[i]; } else { //Draw System.out.println("Column " + (i+1) + " was tied!"); } } //Print results System.out.println("You: " + blueScore + " points"); System.out.println("Intellisense: " + redScore + " points"); //Determine winner if(redScore > blueScore) { System.out.println("Intellisense wins!"); } else if(blueScore > redScore) { System.out.println("You win!"); } else { //Draw System.out.println("It's a draw!"); } } //This method simulates a random card drawn from the deck public static int drawCard(String player) { int cardDrawn = 0; //This represents the card drawn if(player.equals("blue")) { cardDrawn = cardsBlue.remove((int)(Math.random() * cardsBlue.size())); } else { //Player is red cardDrawn = cardsRed.remove((int)(Math.random() * cardsBlue.size())); } return cardDrawn; } //This method prints the game board each time public static void printStatus() { for(int i = 0; i < numColumns; i++) { System.out.print(blueValue[i] + " "); } System.out.println(); for(int i = 0; i < numColumns; i++) { System.out.print(redValue[i] + " "); } } //This method simulates Intellisense's actions public static int red(int card) { int columnChosen = (numColumns-1); //The column where Intellisense thinks is the best place to put the card int bestPoints = 0; //This is the internal score rating of the best column int redPower = 0; //Remaining cards' value for Intellisense int bluePower = 0; //Remaining cards' value of the player for(int i = 0; i < redValue.length; i++) { //Calculate remaining cards' value for Intellisense redPower += redValue[i]; } for(int i = 0; i < blueValue.length; i++) { //Calculate remaining cards' value for the player bluePower += blueValue[i]; } for(int x = (numColumns-1); x >= 0; x--) { //Assess each column int pointValue = 0; //Internal score rating of the column in question int maxCard = 0; for(int i = 0; i < cardsBlue.size(); i++) { //This is the highest card value in the player's hand if(cardsBlue.get(i) > maxCard) { maxCard = cardsBlue.get(i); } } if((redValue[x]) > (maxCard + blueValue[x])) { //Already winning by one turn, no need to reinforce yet } else if((redPower + redValue[x]) < blueValue[x]) { //Give up because it's impossible to win } else { //Only then consider adding the card to this column if(redValue[x] < blueValue[x]) { //We are losing in this column right now if((redValue[x] + card) > blueValue[x]) { //I am losing right now, but if I drop the card here, I can retake it (priority consideration) pointValue = columnValues[x] * 200; //Emphasis on changing control of column } else if ((redValue[x] + card) == blueValue[x]) { //I can prevent the player from getting points on this column by making it a draw (big consideration) pointValue = columnValues[x] * 100; } else { //Emphasis on closing the gap pointValue = columnValues[x] * (100 - (blueValue[x] - redValue[x] - card)); } } else if (redValue[x] > blueValue[x]) { //Winning in this column right now if(cardsBlue.isEmpty()) { //If I am winning and the player has no cards left, there's absolutely no reason to add a card here pointValue = Integer.MIN_VALUE; } else if((cardsBlue.size() == 1) && ((redPower + redValue[x]) < (bluePower + blueValue[x]))) { //The player have their last card, and if the player uses it on this column they will win in the end, even if I put my remaining cards here pointValue = Integer.MIN_VALUE; } else { pointValue = (int)(columnValues[x] * 50 - Math.pow(redValue[x] - blueValue[x] + card , 2)); //Dis-incentive for overkill } } else { //Draw in this column right now pointValue = columnValues[x] * 100 - card; //Win it but not by a lot } } if((card == 1) && (redValue[x] == 0) && (blueValue[x] == 0)) { //A 1 card can be strategically used in an empty column to force a reply or take points uncontested. OVERRIDE all other rules if this is possible. pointValue = 100_000_000 + columnValues[x]; } if(bestPoints < pointValue) { bestPoints = pointValue; columnChosen = x; } } return columnChosen; } }
Output