I am trying to write a code in which I construct a 52 card pile, then deal the cards out to n number of players (it is possible for some players to have an extra card). The winner is the one with the Ace of Spades card.
public class CardGame {
public static void main(String[] args) {
int numofPlayers = Integer.parseInt(args[0]);
CardPile gameDeck = CardPile.makeFullDeck();
CardPile [] players = new CardPile[numofPlayers];
for (int i=0;i<numofPlayers;i++) {
int numofnum = i%numofPlayers;
players[i] = new CardPile();
}
for (int i=0;i<52;i++) {
int numofnum =i%numofPlayers;
CardPile curPlayer = players[i%numofPlayers];
Card nextCard = gameDeck.get(i);
players[numofnum].addToBottom(nextCard);
}
for (int i=1;i<numofPlayers;i++) {
if (players[i].find(Suit.SPADES, Value.ACE) != -1) {
System.out.println("Player" + i + "has won!");
}
}
}
}
When i try to run it with the command "java CardGame 5" the program runs but nothing is printed. Can anyone help ? Thanks !
Change
for (int i=1;i<numofPlayers;i++) {
to:
for (int i=0;i<numofPlayers;i++) {
Since the index is zero based.
Related
I have an assinment for my university class to build a tic tac toe game. I am very new to Java (one week) but I have coded for about two years. The problem I am running into is in my parent class GAME, I have a 3d array for the board. To manipulate the board, I have two child classes, one for the player and one for the computer player. However, it seems that whenever the computer class or player class changes the board, they are accusing their own version of it, not the shared one in the parent class. I am sure this is just due to my lack of understanding of polymorphism in Java, so any advice would be greatly appreciated!
Parent Game class:
package ticTacToe;
import java.util.Scanner;
public class TicTacToe {
private String[][] NumberBoard;
protected String[][] GameBoard;
public TicTacToe() {
NumberBoard = new String[3][3];
GameBoard = new String[3][3];
int counter = 0;
for(int i=0; i<3; i++)
{
for(int k =0; k<3; k++)
{
counter++;
NumberBoard[i][k] = Integer.toString(counter);
GameBoard[i][k] = " ";
}
}
}
public void draw ( String[][] f) {
for(int i =0; i<3; i++)
{
for(int k =0; k<3; k++)
{
System.out.print(f[i][k]);
if(k<2)
System.out.print(" | ");
}
if(i<2) {
System.out.println();
System.out.print("---------");
System.out.println();
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
TicTacToe Game = new TicTacToe();
Player RealPerson = new Player();
Computer ComputerPlayer = new Computer();
int N = 0;
while(true) {
System.out.println();
System.out.println("PLease choose a spot to place in (0 to quit): ");
if(input.hasNextInt())
{
N = input.nextInt();
}
else
{
input.next();
System.out.println("That wasn't a number, please enter a number( 0 to quit)");
continue;
}
if(N < 0 || N > 9)
{
System.out.println("That's not a valid choice, please pick another!");
continue;
}
if (N != 0)
{
Game.GameBoard = ComputerPlayer.NormalEval(N+1);
Game.draw(Game.GameBoard);
System.out.println();
System.out.println();
System.out.println();
Game.draw(Game.GameBoard);
Game.GameBoard = RealPerson.BoardUpdater(N);
//Game.draw(Game.GameBoard);
System.out.println();
System.out.println();
System.out.println();
}
else
break;
}
input.close();
Game.draw(Game.NumberBoard);
System.out.println();
System.out.println();
}
}
Child Player class:
package ticTacToe;
public class Player extends TicTacToe {
public String[][] BoardUpdater(int N) {
if(N < 4 && N >=0)
GameBoard[0][N-1] = "X" ;
if(N > 3 && N < 7)
GameBoard[1][N-4] = "X";
if(N > 6 && N <10)
GameBoard[2][N-7] = "X";
//draw(GameBoard);
return GameBoard;
}
}
Child Computer Class:
package ticTacToe;
public class Computer extends TicTacToe {
public String[][] NormalEval(int N) {
//int a = 0;
if(N < 4 && N >=0)
GameBoard[0][N-1] = "O" ;
if(N > 3 && N < 7)
GameBoard[1][N-4] = "O";
if(N > 6 && N <10)
GameBoard[2][N-7] = "O";
//this.draw(GameBoard);
return GameBoard;
//return a;
}
}
Your inheritance structure is broken in that neither player class should extend from Game. Ask yourself -- is a person playing a game, a more specific version of a game? Answer: no, meaning that this structure does not pass the inheritance "is-a" test.
Instead of using inheritance, in this situation you should be using composition where the Game class should be a separate class and the two Player classes children of a distinct abstract parent player class with the Game class then holding two instances of the players (if a 2-player game) and likewise the Players each holding a reference to the single Game instance. This is referred to a "has-a" structure.
public class TicTacToe {
private AbstractPlayer human = new HumanPlayer(this);
private AbstractPlayer computer = new ComputerPlayer(this);
//....
}
public class AbstractPlayer {
private TicTacToe ticTacToe;
public AbstractPlayer(TicTacToe ticTacToe) {
this.ticTacToe = ticTacToe;
}
}
public class HumanPlayer extends AbstractPlayer {
public HumanPlayer(TicTacToe ticTacToe) {
super(ticTacToe);
}
}
I am creating an instance deck of cards that should display all 52 cards when built, then it should shuffle the cards and deal 5. After this the menu should prompt for either another 5 to be dealt, or the deck to be reshuffled, which adds all the drawn cards back in, or to exit the application. However, when I run the app, it just displays null for all 52 cards, and each card that is dealt. The application worked and almost met all the specification before I talked with my instructor, and what I have now is where I got during/ after our talk. I'm not sure what I'm doing wrong and could really use the help. Just for clarification I will post the requirements, then the code. I appreciate the help.
At startup, it constructs a Deck of Cards
52 distinct cards running from Ace - King, of suit Heart, Club, Diamond, or Spade
Shuffle the cards!!
For proof, print out all 52 cards to the console in a useful, readable way.
Then, deal the top five cards to the console (meaning print them to the console)
After all of this, allow the user choose between dealing the next five cards, reshuffling the deck, or quitting the application.
If the user chooses to deal the next 5 cards, do so based on which cards have not yet been dealt. DO NOT RESHUFFLE.
If the user chooses to reshuffle, simply repeat the process of shuffling, printing the deck, and dealing the top five cards.
If the user chooses to quit the application, simply end the app.
The code I'm practicing encapsulation so I will post each class broken up as is in eclipse.
Driver
public class Driver {
public static void main(String[] args) throws IOException {
DeckRun.run();
}
}
DeckRun
public class DeckRun {
static Card[] d1 = new Card[52];
public static void run() throws IOException {
printDeck();
System.out.println("");
Deal.dealCards(d1);
System.out.println("");
menu();
}
public static void printDeck() {
for (Card c : d1) {
System.out.println(c);
}
}
public static void menu() throws IOException{
BufferedReader readRacer = new BufferedReader(new InputStreamReader(System.in));
int menu = 0;
do {
System.out.println("Press 1 to be dealt 5 random cards.");
System.out.println("Press 2 to shuffle all the cards back into the deck.");
System.out.println("Press 3 to quit the application.");
String input = readRacer.readLine();
menu = Integer.parseInt(input);
switch (menu) {
case 1: Deal.dealCards(d1);
break;
case 2: System.out.println("The deck has been shuffled.");
Deck[] d1 = new Deck[52];
break;
case 3: System.out.println("I'm not bad, I'm just drawn that way.");
break;
}
} while (menu != 3);
}
}
Card
public class Card {
private Rank rank; // Variable to assign a card its rank.
private Suit suit; // Variable to assign a card its suit.
public Card (Rank rank, Suit suit) { // Constructor to build a card.
this.rank = rank;
this.suit = suit;
}
public Rank getRank() { // Retrieves the card's rank from the enum Rank.
return rank;
}
public Suit getSuit() { // Retrieves the card's suit from the enum Suit.
return suit;
}
#Override
public String toString() { //
return rank + " OF " + suit;
}
}
Deck
public class Deck {
private Card[] cards;
public Deck() {
int numberOfRanks = 13;
int numberOfSuits = 4;
int numberOfCards = numberOfRanks * numberOfSuits;
Rank[] rank = Rank.values();
Suit[] suit = Suit.values();
cards = new Card[numberOfCards];
for (int i = 0; i < numberOfRanks; i++) {
for (int j = 0; j < numberOfSuits; j++) {
cards[j * numberOfRanks + i] = new Card(rank[i], suit[j]);
}
}
}
public void shuffleCards() {
Random rand = new Random();
for (int c = rand.nextInt(6) + 5; c > 0; c--) {
for (int i = cards.length - 1; i > 0; i--) {
int index = rand.nextInt(i + 1);
Card card = cards[index];
cards[index] = cards[i];
cards[i] = card;
}
}
}
}
Deal
public class Deal {
private static int counter = 0;
public static void dealCards(Card[] d1) {
for (int i = 0; i < 5; i++) {
counter++;
System.out.println(d1[counter]);
if (counter == 50) {
System.out.println("Almost all cards have been used, please reshuffle.");
}
}
}
}
Rank (Enum)
public enum Rank { ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
NINE, TEN, JACK, QUEEN, KING, }
Suit (Enum)
public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES, }
Not really sure where the issue is, but what I've changed today is after realizing I need an instance of the deck, my professor helped me understand that instead of a method for the deck of cards in class Deck, i needed a constructor. I believe I'm going down the right path but I am just utterly stumped. Any help is appreciated and if you can explain my errors so I may learn and progress even more thanks.
In main you are calling DeckRun.run(), let's take a look at your definition of this method. It calls printDeck which iterates over an array of cards (d1), which is never populated. That's why you are getting a bunch of NULLs.
Your DeckRun should have an instance of Deck instead of cards array
public class DeckRun {
private Deck deck = new Deck();
public static void run() throws IOException {
printDeck();
System.out.println("");
Deal.dealCards(deck.getCards());
System.out.println("");
menu();
}
public static void printDeck() {
for (Card c : deck.getCards()) {
System.out.println(c);
}
}
public static void menu() throws IOException{
BufferedReader readRacer = new BufferedReader(new InputStreamReader(System.in));
int menu = 0;
do {
System.out.println("Press 1 to be dealt 5 random cards.");
System.out.println("Press 2 to shuffle all the cards back into the deck.");
System.out.println("Press 3 to quit the application.");
String input = readRacer.readLine();
menu = Integer.parseInt(input);
switch (menu) {
case 1:
Deal.dealCards(deck.getCards());
break;
case 2:
System.out.println("The deck has been shuffled.");
deck.shuffleCards();
break;
case 3:
System.out.println("I'm not bad, I'm just drawn that way.");
break;
}
} while (menu != 3);
}
}
you also need to add a getter for cards in Deck
so your problem lays in this loop
for (int i = 0; i < numberOfRanks; i++) {
for (int j = 0; j < numberOfSuits; j++) {
cards[j * numberOfRanks + i] = new Card(rank[i], suit[j]);
}
}
J*numOfRanks +i is basically saying 0*4 = 0+0 = 0
and so on, causing problems. To make this simpler i would recommend a 2D array, making 4 columns for the suits and 13 rows for the ranks then a similar loop would work perfectly. please let me know if this helps!
Okay guys. The answer was simple. I deleted the deal class, and moved the method to the deck class. I initialized the counter as a private, class-level int, which fixed the repetition issue. I will post the finished code below, so you can see.
DeckRun Class
public class DeckRun {
static Deck d1 = new Deck();
public static void run() throws IOException {
printDeck();
System.out.println("");
d1.dealCards();
System.out.println("");
menu();
}
public static void printDeck() {
System.out.println(d1.toString());
}
public static void menu() throws IOException{
BufferedReader readRacer = new BufferedReader(new InputStreamReader(System.in));
int menu = 0;
do {
System.out.println("Press 1 to be dealt 5 random cards.");
System.out.println("Press 2 to shuffle all the cards back into the deck.");
System.out.println("Press 3 to quit the application.");
String input = readRacer.readLine();
menu = Integer.parseInt(input);
switch (menu) {
case 1: d1.dealCards();
System.out.println("");
break;
case 2: System.out.println("The deck has been shuffled.");
d1.shuffleCards();
System.out.println("");
break;
case 3: System.out.println("I'm not bad, I'm just drawn that way.");
break;
}
} while (menu != 3);
}
}
Deck Class
public class Deck {
private Card[] cards;
public Deck() {
int numberOfRanks = 13;
int numberOfSuits = 4;
int numberOfCards = numberOfRanks * numberOfSuits;
Rank[] rank = Rank.values();
Suit[] suit = Suit.values();
cards = new Card[numberOfCards];
for (int i = 0; i < numberOfRanks; i++) {
for (int j = 0; j < numberOfSuits; j++) {
cards[i * numberOfSuits + j] = new Card(rank[i], suit[j]);
}
}
}
public void shuffleCards() {
Random rand = new Random();
counter = 0;
for (int c = rand.nextInt(6) + 5; c > 0; c--) {
for (int i = cards.length - 1; i > 0; i--) {
int index = rand.nextInt(i + 1);
Card card = cards[index];
cards[index] = cards[i];
cards[i] = card;
}
}
}
private int counter = 0;
public void dealCards() {
try{
for (int i = 0; i < 5; i++) {
counter++;
System.out.println(cards[counter]);
if (counter == 50) {
System.out.println("Almost all cards have been used, please reshuffle.");
// Either return 1 card or an array of 5 cards.
}
}
} catch (ArrayIndexOutOfBoundsException aioobe){
System.out.println("Caught an ArrayIndexOutOfBoundsException. Reshuffling deck.");
shuffleCards();
}
}
#Override
public String toString() {
String deckOfCards = "";
for (Card c : cards) {
deckOfCards += c.toString() + "\n";
}
return deckOfCards;
}
}
That is all I had to fix, but I appreciate the help. Thanks everyone.
Because I have a thread and in my main program I want to create multiple threads of the same thing and I don't want the same name I tried to create unique names for each thread, e.g Player_1, Player_2, etc.
The thing is that it throws Duplicate local variable which I know that is because I use the same variable but I don't know how else I can create multiple names for a thread without me writing them. Here is the code.
Original Question
for (int l=0; l < noPlayers; l++){
String name = P + "" + (l + 1);
System.out.println(name);
Player name = new Player(TURN);
}
*The Player is the thread which extends and TURN is just a variable that will be processed.
Updated Question
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
class Referee extends Thread{
}
class Player extends Thread{
private int TURN;
public Player(int TURN) {
this.TURN = TURN;
}
public void run(){
int win = 0;
int lose = 0;
int draw = 0;
boolean k = true;
int j = 0;
for (j=0;j<=TURN;j++){
String [] arr = {"ROCK", "PAPER", "SCISSORS"};
Random Pick = new Random();
// randomly selects an index from the arr
int select = Pick.nextInt(arr.length);
// prints out the value at the randomly selected index
System.out.println("Random String selected: " + arr[select]);
}
}
}
public class MainApp {
public static void main(String[] args) {
int TURN = 0;
int No_Players = 0;
int i=0;
boolean h= true;
int j=0;
boolean k = true;
System.out.println("Welcome to Rock-paper-scissors, this is a tutorial of threads");
Scanner number = new Scanner( System.in );
System.out.println("Insert the number of players that will play");
while (h){
while (!number.hasNextInt()){
System.out.println("You didnt insert a number please try again");
number.next();
}
if(number.hasNextInt()){
j = number.nextInt();
if(j>1){
No_Players = j;
h=false;
}
else {
System.out.println("You need a value bigger than 1");
}
}
}
System.out.println("Please enter how many turns you want each player to play");
while (k){
while (!number.hasNextInt()){
System.out.println("You didnt insert a number please try again");
number.next();
}
if(number.hasNextInt()){
i = number.nextInt();
if(i>0){
TURN = i;
k=false;
}
else {
System.out.println("You need a value bigger than 0");
}
}
}
System.out.println("This game will have " + No_Players +" players and each one will have " + TURN + " turns");
Map<String,Thread> map = new HashMap<>();
for (int l = 0; i < No_Players; ++i) {
String name = "Player_" + i;
Player player = new Player(TURN);
player.setName(name);
map.put(name, player);
player.start();
}
}
}
**Posted the whole code because of some misunderstandings.
Assuming that Player implements Runnable.
Map<String,Thread> map = new HashMap<>();
for (int i = 0; i < numPlayers; ++i) {
String name = "Player_" + i;
Player player = new Player(TURN);
Thread t = new Thread(player):
t.setName(name);
map.put(name, t);
t.start();
}
You can then retrieve the thread by the player name. You can also add a thread group if desired.
Based upon a comment that Player extends Thread (edit: fixed the Map definition to use Player rather than Thread).
Map<String,Player> map = new HashMap<>();
for (int i = 0; i < numPlayers; ++i) {
String name = "Player_" + i;
Player player = new Player(TURN);
player.setName(name);
map.put(name, player);
// thread may need to be started elsewhere depending upon the requirement
player.start();
}
Elsewhere to get the particular Player, just do:
Player p = map.get(playerName);
Based upon a comment, here is working example that show Player, extending Thread, using the Map suggested above, and displaying the players using the .getName() method on a Player object.
public class TestPlayer
{
public TestPlayer()
{
}
public static void main(String[] args)
{
int numPlayers = 5;
Map<String,Player> map = new HashMap<>();
for (int i = 0; i < numPlayers; ++i) {
String name = "Player_" + i;
Player player = new Player(0);
player.setName(name);
map.put(name, player);
// thread may need to be started elsewhere depending upon the requirement
player.start();
}
for (Player p : map.values()) {
System.out.println("Found player : " + p.getName());
}
}
static class Player extends Thread
{
private int turn;
public Player(int turn)
{
this.turn = turn;
}
#Override
public void run()
{
System.out.println("Running player " +
Thread.currentThread().getName() +
" turn " + this.turn);
}
}
}
Output:
Running player Player_1 turn 0
Running player Player_3 turn 0
Running player Player_0 turn 0
Running player Player_2 turn 0
Running player Player_4 turn 0
Found player : Player_3
Found player : Player_2
Found player : Player_4
Found player : Player_1
Found player : Player_0
My friend gave me a riddle to solve. It goes like this:
There are 100 people. Each one of them, in his turn, does the following:
The first person opens all the boxes. The second person change the
state to all the boxes whose number is divided by 2, without
remainders. For instance, if a box is open and its number is divided
by 2, it is closed. The same goes for a closed box.
The third person change the state to all the boxes whose number is
divided by 3, without remainders. The "i" person change the state to
all the boxes whose number is divided by i, without remainders.
Now, at then end of the process, I need to display all the boxes(their
numbers) who are open.
I tried to implement a solution but I think it's not efficient. Here it is:
public class BoxesExc {
public static void main(String[] args) {
Box[] boxes = new Box[100];
// Inflating the array with boxes
for(int i=0; i<boxes.length; i++) {
boxes[i] = new Box(i, false);
}
// Main part:
for(int i=1; i<=boxes.length; i++) {
for(int j=1; j<=i; j++) {
// If the number is even
if(i%2 == 0) {
if(j%i == 0) {
boxes[j].setOpen(!boxes[j].isOpen);
}
}
// If the number is odd
else {
if(j%2 != 0) {
if(j%i == 0) {
boxes[j].setOpen(!boxes[j].isOpen);
}
}
}
}
}
//Displaying the opened boxes:
for(Box box : boxes) {
if(box.isOpen)
System.out.println(box.getNum()+",");
}
}
public static class Box {
private int num;
private boolean isOpen;
public Box(int num, boolean isOpen) {
this.isOpen = isOpen;
}
public int getNum() {
return num;
}
public boolean isOpen() {
return isOpen;
}
public void setOpen(boolean isOpen) {
this.isOpen = isOpen;
}
}
}
I haven't tried that yet but I just by looking at it, it looks awful.
I need your help guys with finding a better solution.
EDIT: Alright guys I managed to solve this. Here is the solution:
public class BoxesExc {
public static void main(String[] args) {
int[] boxes = new int[101];
// Inflating the array with boxes
for(int i=1; i<boxes.length; i++) {
boxes[i] = i;
}
int counter = 0;
for(int i=1; i<boxes.length; i++) {
for(int j=1; j<=i; j++) {
if(i%j == 0)
counter++;
}
if(counter%2 != 0)
System.out.print(""+i+", ");
counter = 0;
}
}
}
it has very simple solution
the boxes which will be opened will be all the boxes which thier place is square exponentiation of a number.
for example in your question its between 1-100 so the answer will be:
1 4 9 16 25 36 49 64 81 100
also my solution is faster than yours because its order is θ(√n)
Iterate through all the boxes and modulate by your current indices. Do a switch to set the box open or closed depending on it's previous state. Then after you're done doing the 100 loop; do a secondary loop through the 100 boxes to see which ones are open and print them out.
Here is a quick implementation of what I described in the comment:
public class BoxesExc {
public static void main(String[] args) {
Box[] boxes = new Box[100];
// Inflating the array with boxes
for(int i=0; i<boxes.length; i++) {
boxes[i] = new Box(i, false);
}
// Main part:
for (int i=1; i < boxes.length; i++) {
// j+=i goes 3,6,9... for i = 3
for (int j = i; j < boxes.length; j+=i) {
boxes[j].setOpen(!boxes[j].isOpen);
}
}
//Displaying the opened boxes:
for(Box box : boxes) {
if(box.isOpen)
System.out.println(box.getNum()+",");
}
}
}
Nota: you can init the box status to open and skip the first iteration (start with i = 2)
Since you only need to print the numbers, I think following is enough:
public class BoxesExc {
public static void main(String[] args) {
int boxNum = 100;
for(int i = 1; i*i <= boxNum; i++) {
System.out.print(i*i+",");
}
}
}
public class Basic
{
public static int numGuess;
public int guess;
public int numHits = 0;
private static int[] ships;
private boolean hitShip;
public static boolean shipSunk;
private int[]board = new int[5];
public Basic()
{
numGuess = 0;
hitShip = false;
shipSunk = false;
}
public static void setShips (int[] loc)
{
ships = loc;
}
public int Check(int z)
{
for(int cell : ships)
{
if(z == cell)
{
hitShip = true;
System.out.println("\nYou hit an enemy ship!");
numHits++;
numGuess++;
if(numHits == ships.length)
{
shipSunk = true;
System.out.println("\nYou sunk the enemy ship!");
System.out.println("the number of guesses it took you to sink the ship is " + numGuess/3);
break;
}
}
else
{
System.out.println("You've missed the enemy ship!");
}
}
return z;
}
}
So I've been working on this battleship project for school and i made this 1-D board for my game. So far i think I've got my code correct, but now i'm stuck. In my for each loop, since it checks my guess with each of the three values of my ship, it prints whether or not i hit the ship three different times everytime i guess. I'm trying to get my program just to print whether or not i hit the ship once everytime i guess.
import java.util.Scanner;
import java.util.Random;
public class BasicTester
{
public static void main(String[] args)
{
Basic shipp = new Basic(); //initalizes basic class
int ship = (int)(Math.random() * 5); // gives ship a random # between 1 - 5
int ship1;
int ship2;
int guess;
if(ship <= 2)
{
ship1 = ship + 1;
ship2 = ship + 2;
}
else
{
ship1 = ship - 1;
ship2 = ship - 2;
}
int[] locations = {ship, ship1, ship2};// sets array of locations
shipp.setShips(locations); // sets locations to ships in other class
Scanner guesss = new Scanner(System.in); // Scanner
do
{
System.out.println("\nTell me where the enemy ship is.");
guess = guesss.nextInt(); // gives guess the int from Scanner
int resultb = shipp.Check(guess); // puts the int guess through the check method
}
while(Basic.shipSunk == false);
}
}
Instead of having your
else
{
System.out.println("You've missed the enemy ship!");
}
Inside the loop, you should set a flag before the loop
hitIt = false;
Then, when you check against the three "ships", you can set this flag to "true" when you find a hit. Finally, check the flag after the loop. If it is still false, print your message.