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);
}
}
Related
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
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.
I have been searching for answers for this but no success. I have two arrays that I insert objects into and print the result on the screen. Now what am trying to do is to move each stored object in the array to a different coordinate and print the result. Any assistance will be appreciated.
public class Board {
int row = 0;
int col = 0;
public Ships ships=new Ships();
Controller controller = new Controller();
public Board(int rows,int columns)
{
board = new Ships[rows][columns];
this.r=rows;
this.c=columns;
}
public void addShip(int x,int y,Ships s)
{
board[x][y]=s;
}
public void print(ArrayList<Ships> player1)
{
for(int i = 0; i<row; i++)
{
for(int j = 0; j<col; j++)
{
ships=board[i][j];
if(ships==null)
{
System.out.print("-");
System.out.print("\t");
}
else
{
System.out.print(ships.getID());
System.out.print("\t");
}
}
System.out.println();
System.out.print("\n");
}
Scanner readinput = new Scanner(System.in);
String enterkey = "press enter key to continue....";
System.out.print(enterkey);
enterkey = readinput.nextLine();
System.out.print(enterkey);
if (enterkey.equals("")){
System.out.println("\n");
System.out.println("\n");
System.out.println("\n");
System.out.println("\n");
System.out.println("\n");
System.out.println("\n");
System.out.println("\n");
System.out.println("\n");
}
}
}
Your question is relatively unclear, but I am assuming that you want to move a ship at a specific position in your 2-d array (board) to another position.
A method like this should do what you want:
public void moveShip(int xFrom, int yFrom, int xTo, int yTo){
board[xTo][yTo] = board[xFrom][yFrom];
board[xFrom][yFrom] = null;
}
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.
I know it may be weird question but I'm really stuck. I have simple program with two classes. I need pass array from class A to class B. I did it but I cannot test it because I have no idea how to run program. When I click on the run then only one class started. I wanted test whole program and cannot find anything how to do it. Is there any command or something which say run class A and then class B? Without it I cannot test class B because values from Array (class A) are not loaded :/ Hope you understand what I mean.
I'm using eclipse.
Thanks!
Class MarkCalculator
import java.util.Scanner;
public class MarkCalculator {
public static int[] exam_grade = new int[6];
public static int[] coursework_grade = new int[6];
public static int[] coursework_weight = new int[2];
public static int[] module_points = new int[6];
public static String module_grade, holder;
public static int counter1 = 0, counter2 = 0;
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
for (int i=0; i<3; i++){
System.out.printf(i+1+". Modelue"+" Enter grade of exam:");
while (!input.hasNextInt() ){
System.out.printf("Enter only numbers! Enter grade of your exam: ");
input.next();
}
exam_grade[i]=input.nextInt();
System.out.printf(i+1+". Modelue"+" Enter grade of coursework:");
while (!input.hasNextInt()){
System.out.printf("Enter only numbers! Enter grade of your coursework: ");
input.next();
}
coursework_grade[i]=input.nextInt();
}
computeMark(coursework_grade, exam_grade, module_points);
// calculate module grade
for(int i = 0 ;i < 3; i++){
if (module_points[i] < 35){
System.out.println(i+1+".Module: Fail");
}
else if (module_points[i] >= 35 && module_points[i] <= 40){
System.out.println(i+1+".Module: Pass by compensation");
counter1++;
}
else {
System.out.println(i+1+".Module: Pass");
counter2++;
}
}
holder = computeResult(module_points, counter1,counter2, module_grade);
System.out.println("Your stage result is: "+ holder);
input.close();
}
public static int[] computeMark (int coursework_grade[], int exam_grade[], int module_points[]){
coursework_weight[0]= 50;
coursework_weight[1]= 50;
for(int i=0;i<3;i++)
{
if (coursework_grade[i] < 35 || exam_grade[i] < 35){
module_points[i]=(coursework_grade[i]*coursework_weight[0] + (exam_grade[i]*(100-coursework_weight[1])))/100;
if (module_points[i] > 35){
module_points[i] = 35; }
else {
module_points[i] = 0;
}
}
else {
module_points[i]=((coursework_grade[i]*coursework_weight[0] + (exam_grade[i]*(100-coursework_weight[1])))/100); }
}
return module_points;
}
public static String computeResult (int module_points[], int counter1, int counter2, String module_grade ){
int sum = 0;
double average = 0;
for (int i = 0; i < 3; i++){
sum = sum + module_points[i];
average = sum / 3;
}
for (int i = 0; i < 3; i++){
if (counter2 == 3){
module_grade = "Pass";
}
else if (average >= 40 && counter1 <= 2) {
module_grade = "Pass by compensation";
}
else {
module_grade = "Fail";
}
}
return module_grade;
}
}
Class StudentChart
public class StudentChart {
public static void main(String[] args) {
for (int i = 0; i < 3; i++){
System.out.println(MarkCalculator.coursework_weight);
}
}
}
You only need one main method.
class A {
String s;
public A(String s){
this.s = s;
}
}
public class B {
public static void main(String[] args){
A a = new A("Hello");
System.out.println(a.s + " world!");
}
}
class B will be the application program, the one with the main method. It will get values from class A. class A does not need to run for class B app to work, even though it uses values from class A.
You can have a method with a different name in another class, and call that method from your main method.
Do not call it public static void main though - that should only be used for standalone programs. If the method requires some other code to be run prior to it, it should not be the main method of a Java program.