Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Game.java Update class to add the following member variable GameUi ui Add method setGameUi to do the following Return type void One parameter of data

Game.java

Update class to add the following member variable

GameUi ui

Add method setGameUi to do the following

Return type void

One parameter of data type GameUi

Set member variable ui equal to parameter

Add method getTeams to do the following

Return type ArrayList

Empty parameter list

Returns the member variable of data type ArrayList that contains elements of class Team

Add method getTrump to do the following

Return type Card

Empty parameter list

Returns the member variable of data type Card that represents the trump card for the dealt hand

Player.java

Update class to add the following member variable

JPanel ui

Generate a getter/setter for the member variable ui

images package

Add package images to the project

Add images for the cards to the package

userInterface package

GameUi.java

Update the class to add the following member variables

JPanel trumpPanel (if you added bidPanel in the last assignment, please rename it)

JLabel teamOneScoreLbl

JLabel teamOneScore

JLabel teamTwoScoreLbl

JLabel teamTwoScore

JLabel trumpCard

Update initComponents to do the following

Instantiate the member variable of class ArrayList containing elements of class JLabel that represents the card each player plays on the table JPanel

Loop through the four players and do the following

Instantiate an instance of class JLabel

Based on the position of the player set the size of the JLabel using class Dimension to be horizontal or vertical width and height

Instantiate an instance of class CardUi passing the JLabel from step 1 as an argument

Set the instance of class JLabel from step 1 equal to method call getLabel() on class CardUi

Add the instance of class JLabel from step 1 to the member variable of call ArrayList containing element of class JLabel representing the cards played on the table

Add each instance of class JLabel stored in the ArrayList containing elements of class JLabel representing the cards played so that

Human player JLabel for card played is in the SOUTH

The remaining AI players have a JLabel placed in from of their position at the table

AiPlayerUi.java

Update the class to add the following member variables

CardUi cardUi;

int width;

int height;

Update method initComponents() to do the following

Set the member variables width and height based on the orientation of the cards, vertical or horizontal

Update method displayCards() to do the followingIn the for loopInstantiate the instance of class CardUi passing as arguments

The instance of class Card in the players hand at the looping variables index

The instance of class JLabel created inside the for loop

The Players position at the table

Set local variable of class JLabel representing the card equal to method call getLabel() on class CardUi

Comment out the call to method setText() on the instance of class JLabel

HumanPlayerUi.java

Update the class to add the following member variables

CardUi cardUi;

Update method displayCards() to do the followingIn the for loopInstantiate the instance of class CardUi passing as arguments

The instance of class Card in the players hand at the looping variables index

The instance of class JButton created inside the for loop

Set local variable of class JButton representing the card equal to method call getButton() on class CardUi

Comment out the call to method setText() on the instance of class JButton

CardUi.java

Add member variables

Card card;

ImageIcon imageIcon;

JButton button;

JLabel label;

int position;

Generate getters for member variables

Of class JButton

Of class JLabel

Write a custom constructor that do the followingReceives two parameters

Class Card

Class JButton

Set member variable of class Card to the passed parameter

Set member variable of class JButton to the passed parameter

Call method selectFrontImage()

Write a custom constructor that does the followingReceives three parameters

Class Card

Class JLabel

Int

Set member variable of class Card to the passed parameter

Set member variable of class JLabel to the passed parameter

Set member variable of primitive data type int to the passed parameter

Based on the position of the player call method selectVerticalBackImage() or selectHorizontalBackImage()

Write a custom constructor that does the following

Received one parameter of class JLabel

Set member variable of class JLabel to the passed parameter

Calls method selectHorizontalBackImage()

Write method selectFrontImage() to do the following

Instantiate an instance of class String to represent the file name of the image file set equal to explicit text ../images/

Write a switch statement that evaluates the face of the instance of class Card

Based on the naming convention of your image files, concatenate to the String instantiated in step a with the appropriate value

For example, I named my files as such AceHearts, AceEuchre, AceDiamonds, AceClubs

Therefore, I concatenate to the String instance ../images/ the explicit text Ace

Write a switch statement that evaluates the suit of the instance of class Card

Based on the naming convention of your image files, concatenate to the String instantiated in step a with the appropriate value

Concatenate the explicit file extension to the String instance that represents the filename based on your naming convention, the String instance should look something like ../images/AceClubs.png when finished

Instantiate an instance of class URL set equal to the static method call getClass().getResource() passing the String instance as an argument

Using exception handling (i.e. in a try block)Check if the instance of class URL is not null

If true, Instantiate the member variable of class ImageIcon passing the instance of class URL as an argument

Instantiate the member variable of class JButton passing the instance of class ImageIcon as an argument

In the catch block

Output an error message that the resource if not found

Set the instance of class ImageIcon equal to null

Write method selectVerticalBackImage() to do the following

Instantiate an instance of class String set to explicit text ../images/backVertical.jpg or whatever you named the back image of the card

Instantiate an instance of class URL set equal to the static method call getClass().getResource() passing the String instance as an argument

Using exception handling (i.e. in a try block)Check if the instance of class URL is not null

If true, Instantiate the member variable of class ImageIcon passing the instance of class URL as an argument

Instantiate the member variable of class JLabel passing the instance of class ImageIcon as an argument

In the catch block

Output an error message that the resource if not found

Set the instance of class ImageIcon equal to null

Write method selectHorizontalBackImage() to do the following

Instantiate an instance of class String set to explicit text ../images/backHorizontal.jpg or whatever you named the back image of the card

Instantiate an instance of class URL set equal to the static method call getClass().getResource() passing the String instance as an argument

Using exception handling (i.e. in a try block)Check if the instance of class URL is not null

If true, Instantiate the member variable of class ImageIcon passing the instance of class URL as an argument

Instantiate the member variable of class JLabel passing the instance of class ImageIcon as an argument

In the catch block

Output an error message that the resource if not found

Set the instance of class ImageIcon equal to null

code:

Game:

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package core;

import constants.Constants;

import constants.Constants.Suit; import java.util.ArrayList; import java.util.Iterator; import java.util.Random; import java.util.Scanner; import javax.swing.JFrame; import javax.swing.JOptionPane; import userinterface.GameUi;

public class Game { // member variables private Card trump; private Player leadPlayer; private Player dealer; private Player wonTrick; private int round; private ArrayList teams; private Deck deck; private Scanner scan; private ArrayList table; private int dealerIdx; private int leadIdx; private GameUi ui; //custom constructor public Game() { createTeams(); // outputTeams(); createDeck(); setTable(); dealHand(); displayHands(); play(); } private void createTeams() { // instantiate the teams ArrayList teams = new ArrayList(); // instantiate Team One and add to ArrayList Team teamOne = new Team(); teamOne.setTeamName("Team One"); teams.add(teamOne); // instantiate Team Two and add to ArrayList Team teamTwo = new Team(); teamTwo.setTeamName("Team Two"); teams.add(teamTwo); // adding Human Player to Team One String name = JOptionPane.showInputDialog("Enter human player name"); // scan = new Scanner(System.in); // System.out.println("Enter human player name"); // String name = scan.next(); HumanPlayer hp = new HumanPlayer(); hp.setName(name); System.out.println("Human Player added to Team One"); teamOne.getTeam().add(hp); // create the AI Players and add them to a team for(int p = 1; p <= Constants.NUM_AI_PLAYERS; p++) { AiPlayer aip = new AiPlayer(); aip.setName("AI-" + p); // add AI Player to a team if(teamOne.getTeam().size() < 2) teamOne.getTeam().add(aip); else teamTwo.getTeam().add(aip); } }

private void outputTeams() { for(Team team : teams) { team.outputTeam(); } } private void setTable() { // players are set up so that team members sit across from each other // therefore the deal would be to TeamOne.PlayerOne, TeamTwo.PlayerTwo, // TeamOne.PlayerTwo, TeamTwo.PlayerTwo as an example table = new ArrayList(); // get the teams in the game Team teamOne = teams.get(Constants.ONE); Team teamTwo = teams.get(Constants.TWO); // get the players from each team Player teamOnePlayerOne = teamOne.getTeam().get(Constants.ONE); Player teamOnePlayerTwo = teamOne.getTeam().get(Constants.TWO); Player teamTwoPlayerOne = teamTwo.getTeam().get(Constants.ONE); Player teamTwoPlayerTwo = teamTwo.getTeam().get(Constants.TWO); // we want to explicitly dictate which seat each player is in so we are // using the add method that takes two arguments, one to set the position // in the ArrayList and the associated object at that position table.add(0, teamOnePlayerOne); table.add(1, teamTwoPlayerOne); table.add(2, teamOnePlayerTwo); table.add(3, teamTwoPlayerTwo); System.out.println("************************"); System.out.println("Players at the table are"); System.out.println("************************");

for(Player player : table) { System.out.println(player.getName()); } } private void setDealerAndLead() { // select the first dealer Random random = new Random(); dealerIdx = random.nextInt(Constants.NUM_PLAYERS); dealer = table.get(dealerIdx); // create an index to keep track of which player got the card; // reset when get to 3 // set the leadIdx based on which player was selected as the dealer and // add one to it if(dealerIdx < 3) leadIdx = dealerIdx + 1; else leadIdx = 0; leadPlayer = table.get(leadIdx); } private void dealHand() { setDealerAndLead(); System.out.println("********************************"); System.out.println(" DEALING THE HAND"); System.out.println("********************************");

System.out.println("Player " + dealer.getName() + " will deal the hand");

int playerIdx = leadIdx; // loop through the shuffled deck and deal five cards to each player // first round, two at a time // second round, three at a time Iterator currentCard = deck.getCardList().iterator(); // System.out.println("********************************"); // System.out.println(" FIRST DEAL, TWO CARDS EACH"); // System.out.println("********************************");

for(int p = 0; p < Constants.NUM_PLAYERS; p++) { dealOne(playerIdx, currentCard); // increment the player index until value of 3, then reset to 0 if(playerIdx == 3) playerIdx = 0; else playerIdx++; }

// System.out.println("********************************"); // System.out.println(" SECOND DEAL, THREE CARDS EACH"); // System.out.println("********************************");

for(int p = 0; p < Constants.NUM_PLAYERS; p++) { dealTwo(playerIdx, currentCard); // increment the player index until value of 3, then reset to 0 if(playerIdx == 3) playerIdx = 0; else playerIdx++; } // set trump to next card on deck trump = currentCard.next(); System.out.println("********************************"); System.out.println("Trump card is " + trump.getFace() + " of " + trump.getSuit() + " color " + trump.getColor()); System.out.println("********************************"); }

public Card getTrump() { return trump; } private void dealOne(int playerIdx, Iterator currentCard) { for(int c = 0; c < Constants.DEAL_ONE; c++) { if(currentCard.hasNext()) { Card card = currentCard.next();

// System.out.println("Dealing " + card.getFace() + " of " + // card.getSuit() + " to player " + // table.get(playerIdx).getName()); // add card to a player's hand table.get(playerIdx).getHand().add(card); // remove the card from the deck after it has been dealt currentCard.remove(); } } } private void dealTwo(int playerIdx, Iterator currentCard) { for(int c = 0; c < Constants.DEAL_TWO; c++) { if(currentCard.hasNext()) { Card card = currentCard.next();

// System.out.println("Dealing " + card.getFace() + " of " + // card.getSuit() + " to player " + // table.get(playerIdx).getName()); // add card to a player's hand table.get(playerIdx).getHand().add(card);

// remove the card from the deck after it has been dealt currentCard.remove(); } } } private void displayHands() { for(Team team : teams) { team.outputHands(); } } private void createDeck() { deck = new Deck(); } public void play() { for(Player player : table) { player.makeTrump(); } } public void setGameUi(GameUi ui) { this.ui = ui; } /** * @return the wonTrick */ public Player getWonTrick() { return wonTrick; }

/** * @param wonTrick the wonTrick to set */ public void setWonTrick(Player wonTrick) { this.wonTrick = wonTrick; }

/** * @return the round */ public int getRound() { return round; }

/** * @param round the round to set */ public void setRound(int round) { this.round = round; }

/** * @return the leadPlayer */ public Player getLeadPlayer() { return leadPlayer; }

/** * @param leadPlayer the leadPlayer to set */ public void setLeadPlayer(Player leadPlayer) { this.leadPlayer = leadPlayer; }

/** * @return the dealer */ public Player getDealer() { return dealer; }

/** * @param dealer the dealer to set */ public void setDealer(Player dealer) { this.dealer = dealer; }

/** * @return the table */ public ArrayList getTable() { return table; } public ArrayList getTeams() { return teams; } }

Player:

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package core;

import java.util.ArrayList; import javax.swing.JPanel;

public abstract class Player implements IPlayer { // member variables private String name; private int tricks; private int score; private ArrayList hand; private JPanel ui; // abstract method from IPlayer public abstract Card playCard(); public abstract void makeTrump();

public Player() { hand = new ArrayList(); } public void setUi(JPanel ui) { this.ui = ui; } public JPanel getUi() { return ui; }

public void sortBySuit() { /** * Sorts the cards in the hand so that cards are sorted into * order of increasing value. Cards with the same value * are sorted by suit. Note that aces are considered * to have the highest value. */ ArrayList sortedHand = new ArrayList(); while (hand.size() > 0) { int position = 0; // Position of minimal card. Card firstCard = hand.get(0); // Minimal card. for (int i = 1; i < hand.size(); i++) { Card nextCard = hand.get(i); if (nextCard.getSuit().getRank() < firstCard.getSuit().getRank() || (nextCard.getSuit() == firstCard.getSuit() && nextCard.getFace().getValue() < firstCard.getFace().getValue())) { position = i; firstCard = nextCard; } } hand.remove(position); sortedHand.add(firstCard); } hand = sortedHand; } /** * @return the name */ public String getName() { return name; }

/** * @param name the name to set */ public void setName(String name) { this.name = name; }

/** * @return the tricks */ public int getTricks() { return tricks; }

/** * @param tricks the tricks to set */ public void setTricks(int tricks) { this.tricks = tricks; }

/** * @return the bid */

/** * @return the score */ public int getScore() { return score; }

/** * @param score the score to set */ public void setScore(int score) { this.score = score; }

/** * @return the hand */ public ArrayList getHand() { return hand; }

/** * @param hand the hand to set */ public void setHand(ArrayList hand) { this.hand = hand; } public void displayHand() { System.out.println("*************************"); System.out.println("Player " + name + " hand is "); System.out.println("*************************"); for(Card card : hand) { System.out.println(card.getFace() + " of " + card.getSuit()); } } }

GameUI.java:

/*

* To change this license header, choose License Headers in Project Properties.

* To change this template file, choose Tools | Templates

* and open the template in the editor.

*/

package userinterface;

import constants.Constants;

import constants.Constants.Face;

import constants.Constants.Suit;

import core.Card;

import core.Game;

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.ArrayList;

import javax.swing.BorderFactory;

import javax.swing.BoxLayout;

import javax.swing.JComponent;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

/**

*

* @author kwhiting

*/

public class GameUi

{

// the game

private Game game;

// the layout

private JFrame frame;

private JPanel aiOnePanel;

private JPanel tablePanel;

private JPanel aiTwoPanel;

private JPanel hpPanel;

private JPanel aiThreePanel;

private JPanel northPanel;

private JPanel scorePanel;

// the menu

private JMenuBar menuBar;

private JMenu gameMenu;

private JMenu helpMenu;

private JMenuItem newGameMenuItem;

private JMenuItem exitMenuItem;

private JMenuItem aboutMenuItem;

private JMenuItem rulesMenuItem;

public GameUi(Game game)

{

this.game = game;

initComponents();

game.setGameUi(this);

game.play();

}

private void initComponents()

{

initMenuBar();

layoutTable();

}

private void initMenuBar()

{

menuBar = new JMenuBar();

// game menu

gameMenu = new JMenu("Game");

newGameMenuItem = new JMenuItem("New Game");

newGameMenuItem.addActionListener(new NewGameListener());

exitMenuItem = new JMenuItem("Exit");

exitMenuItem.addActionListener(new ExitListener());

// help menu

helpMenu = new JMenu("Help");

aboutMenuItem = new JMenuItem("About");

aboutMenuItem.addActionListener(new AboutListener());

rulesMenuItem = new JMenuItem("Game Rules");

rulesMenuItem.addActionListener(new RulesListener());

// put it all together

gameMenu.add(newGameMenuItem);

gameMenu.add(exitMenuItem);

helpMenu.add(aboutMenuItem);

helpMenu.add(rulesMenuItem);

menuBar.add(gameMenu);

menuBar.add(helpMenu);

}

private void layoutTable()

{

// create the jframe

frame = new JFrame("Euchre");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setSize(700, 700);

// create the player's panels

aiOnePanel = new AiPlayerUi(game.getTable().get(Constants.POSITION_2), Constants.POSITION_2, this);

aiTwoPanel = new AiPlayerUi(game.getTable().get(Constants.POSITION_3), Constants.POSITION_3, this);

aiThreePanel = new AiPlayerUi(game.getTable().get(Constants.POSITION_4), Constants.POSITION_4, this);

hpPanel = new HumanPlayerUi(game.getTable().get(Constants.POSITION_1), this);

game.getTable().get(Constants.POSITION_1).setUi(hpPanel);

game.getTable().get(Constants.POSITION_2).setUi(aiOnePanel);

game.getTable().get(Constants.POSITION_3).setUi(aiTwoPanel);

game.getTable().get(Constants.POSITION_4).setUi(aiThreePanel);

initNorthPanel();

initTablePanel();

// add UI components

frame.add(aiOnePanel, BorderLayout.WEST);

frame.add(northPanel, BorderLayout.NORTH);

frame.add(aiThreePanel, BorderLayout.EAST);

frame.add(hpPanel, BorderLayout.SOUTH);

frame.add(tablePanel, BorderLayout.CENTER);

frame.setJMenuBar(menuBar);

frame.setVisible(true);

}

private void initNorthPanel()

{

northPanel = new JPanel();

northPanel.setMinimumSize(new Dimension(680, 170));

northPanel.setPreferredSize(new Dimension(680, 170));

initScorePanel();

aiTwoPanel.setMinimumSize(new Dimension(350, 160));

aiTwoPanel.setPreferredSize(new Dimension(350, 160));

northPanel.add(scorePanel);

northPanel.add(aiTwoPanel);

}

private void initTablePanel()

{

tablePanel = new JPanel();

tablePanel.setBorder(BorderFactory.createTitledBorder("EUCHRE"));

tablePanel.setMaximumSize(new Dimension(300,200));

tablePanel.setMinimumSize(new Dimension(300,200));

tablePanel.setPreferredSize(new Dimension(300,200));

}

private void initScorePanel()

{

scorePanel = new JPanel();

scorePanel.setBorder(BorderFactory.createTitledBorder("Scores"));

scorePanel.setMinimumSize(new Dimension(130, 160));

scorePanel.setPreferredSize(new Dimension(130, 160));

}

// inner classes

private class NewGameListener implements ActionListener

{

@Override

public void actionPerformed(ActionEvent ae)

{

}

}

private class ExitListener implements ActionListener

{

@Override

public void actionPerformed(ActionEvent ae)

{

int response = JOptionPane.showConfirmDialog(frame, "Confirm to exit Euchre?",

"Exit?", JOptionPane.YES_NO_OPTION);

if (response == JOptionPane.YES_OPTION)

System.exit(0);

}

}

private class AboutListener implements ActionListener

{

@Override

public void actionPerformed(ActionEvent ae)

{

String message = "Euchre version 1.0 Karin Whiting Summer 2018";

JOptionPane.showMessageDialog(frame, message);

}

}

private class RulesListener implements ActionListener

{

@Override

public void actionPerformed(ActionEvent ae)

{

}

}

}

AIplayerUI.java:

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package userinterface;

import constants.Constants; import constants.Constants.Face; import constants.Constants.Suit; import core.AiPlayer; import core.Player; import java.awt.Color; import java.awt.Dimension; import java.util.ArrayList; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel;

public class AiPlayerUi extends JPanel { private AiPlayer ai; private int position; private ArrayList cards; private CardUi cardUi; private GameUi gameUi; private int width; private int height; public AiPlayerUi(Player player, int position, GameUi gameUi) { ai = (AiPlayer)player; this.position = position; this.gameUi = gameUi; initComponents(); } private void initComponents() { this.setBorder(BorderFactory.createTitledBorder(ai.getName())); this.setMinimumSize(new Dimension(200, 250)); this.setPreferredSize(new Dimension(200, 250)); cards = new ArrayList();

if(position == 1 || position == 3) { this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.width = 100; this.height = 50; } else { this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); this.width = 50; this.height = 100; } displayCards(); } private void displayCards() { cards = new ArrayList();

for(int c = 0; c < Constants.CARDS_EACH; c++) { JLabel card = new JLabel(); card.setMinimumSize(new Dimension(width, height)); card.setPreferredSize(new Dimension(width, height)); card.setBorder(BorderFactory.createLineBorder(Color.BLACK)); card.setText("Card" + c); cards.add(card); this.add(card); } } }

HumanPlayerUI.java:

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package userinterface;

import core.HumanPlayer; import core.Player; import constants.Constants; import constants.Constants.Face; import constants.Constants.Suit; import core.Card;

import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.logging.Logger; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel;

public class HumanPlayerUi extends JPanel { private HumanPlayer human; private ArrayList cards; private CardUi cardUi; private GameUi gameUi; private JFrame parent; private Suit suit; public HumanPlayerUi(Player player, GameUi gameUi) { human = (HumanPlayer)player; this.gameUi = gameUi; initComponents(); } private void initComponents() { this.setBorder(BorderFactory.createTitledBorder(human.getName())); this.setMinimumSize(new Dimension(250, 150)); this.setPreferredSize(new Dimension(250, 150)); this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

displayCards(); } private void displayCards() { cards = new ArrayList();

for(int c = 0; c < Constants.CARDS_EACH; c++) { // instantiate the JButton JButton card = new JButton(); // update the JButton and format it card.setMinimumSize(new Dimension(60,100)); card.setPreferredSize(new Dimension(60,100)); card.setBorder(BorderFactory.createLineBorder(Color.BLACK)); card.setText("Card" + c); // add the object to the the ArrayList and UI cards.add(card); for(JButton button : cards) this.add(button); } }

}

CardUI.java:

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package userinterface;

public class CardUi {

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Machine Learning And Knowledge Discovery In Databases European Conference Ecml Pkdd 2016 Riva Del Garda Italy September 19 23 2016 Proceedings Part 1 Lnai 9851

Authors: Paolo Frasconi ,Niels Landwehr ,Giuseppe Manco ,Jilles Vreeken

1st Edition

3319461273, 978-3319461274

More Books

Students also viewed these Databases questions

Question

5-8 What are the advantages and disadvantages of the BYOD movement?

Answered: 1 week ago