|
import java.awt.*;
import java.net.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
public class Network extends Applet
implements ActionListener, // Button
ItemListener, // Choice
MouseListener, // Mouse
BelotConstants
{
public void init ()
{
MediaTracker tracker = new MediaTracker(this);
int trackerID = 1;
URL url = getCodeBase();
String imageName;
Image image;
String suits [] = {"c", "d", "h", "s"};
String ranks [] = {"8", "9", "t", "j", "q", "k", "a"};
Font f = new Font("SansSerif", Font.BOLD, 14);
cardImageIndices = new int [CARDS_IN_HAND];
trump = "Unknown";
caller = "Unknown";
dealerName = "Unknown";
cardsToDisplay = 0;
myRawPoints = 0;
yourRawPoints = 0;
myGamePoints = 0;
yourGamePoints = 0;
myRawPoints = 0;
yourRawPoints = 0;
setMessages("Welcome", "to Belot!");
setBackground(new Color(0, 220, 220)); // light blue
setLayout(null);
setForeground(Color.black);
fm = getGraphics().getFontMetrics(f);
height = getSize().height;
width = getSize().width;
cardImages = new Image [CARDS_IN_DECK + 1];
for (int s = 0; s < suits.length; s++)
{
for (int r = 0; r < ranks.length; r++)
{
imageName = ranks[r] + suits[s] + ".gif";
image = getImage (url, imageName);
cardImages[s*ranks.length + r] = image;
tracker.addImage (image, trackerID);
trackerID++;
}
}
imageName = "cardback.gif";
cardBackImage = getImage(url, imageName);
cardImages[28] = cardBackImage;
tracker.addImage(cardBackImage, trackerID);
try { tracker.waitForAll(); }
catch (InterruptedException e) {}
addMouseListener(this);
joinButton = makeButton("Join", 2, 4);
joinButton.setVisible(true);
rulesButton = makeButton("Rules", 2, 5);
rulesButton.setVisible(true);
againButton = makeButton("Again", 2, 4);
quitButton = makeButton("Quit", 2, 5);
sendButton = makeButton("Send", 2, 0);
sendButton.setVisible(true);
outgoingField = new TextField("Outgoing Message");
add(outgoingField);
placeComponent(outgoingField, 2, 1, 1);
outgoingField.setVisible(true);
incomingField = new TextField("Incoming Message");
add(incomingField);
placeComponent(incomingField, 2, 1, 2);
incomingField.setVisible(true);
acceptTrumpChoice = new Choice();
acceptTrumpChoice.add ("Accept Trump");
acceptTrumpChoice.add ("Dont Accept");
add (acceptTrumpChoice);
placeComponent(acceptTrumpChoice, 2, 4);
acceptTrumpChoice.setVisible(false);
acceptTrumpChoice.addItemListener(this);
callTrumpChoice = new Choice();
callTrumpChoice.add("Clubs");
callTrumpChoice.add("Diamonds");
callTrumpChoice.add("Hearts");
callTrumpChoice.add("Spades");
callTrumpChoice.add("Nothing");
callTrumpChoice.add("Everything");
callTrumpChoice.add("Pass");
add (callTrumpChoice);
placeComponent(callTrumpChoice, 2, 4);
callTrumpChoice.setVisible(false);
callTrumpChoice.addItemListener(this);
cardOne = cardImages[CARDS_IN_DECK];
cardTwo = cardImages[CARDS_IN_DECK];
cardThree = cardImages[CARDS_IN_DECK];
}
private Button makeButton(String name, int row, int col)
{
Button tempButton = new Button(name);
add (tempButton);
placeComponent (tempButton, row, col);
tempButton.setVisible(false);
tempButton.addActionListener(this);
return tempButton;
}
public void paint (Graphics g)
{
for (int i = 1; i < NUMBER_ROWS; i++)
g.drawLine(0, i * height / NUMBER_ROWS, width,
i * height / NUMBER_ROWS);
for (int i = 1; i < NUMBER_COLUMNS; i++)
g.drawLine(i * width / NUMBER_COLUMNS, 0,
i * width / NUMBER_COLUMNS, height);
displayStrings(0, 0, "Your", "Play");
displayStrings(0, 3, "Opponent's", "Play");
displayStrings(0, 5, "Flipped", "Card");
setForeground(Color.red);
displayStrings(0, 8, "Trump:", "Caller:", "Dealer:");
setForeground(Color.black);
displayStrings(0, 9, trump, caller, dealerName);
displayStrings(1, 0, "Your", "Hand");
displayStrings(2, 6, "You:", "Opponent:");
displayStringsTop(2, 7, "Raw", "Score");
displayStringsTop(2, 8, "Game", "Points");
displayStringsTop(2, 9, "Total", "Points");
displayStrings(2, 3, message1, message2);
displayStrings(2, 7, Integer.toString(myRawPoints), Integer.toString(yourRawPoints));
displayStrings(2, 8, Integer.toString(myGamePoints), Integer.toString(yourGamePoints));
displayStrings(2, 9, Integer.toString(myTotalPoints), Integer.toString(yourTotalPoints));
for (int i = 0; i < cardsToDisplay; i++)
{ displayCard(cardImages[cardImageIndices[i]], 1, i + 1);
}
displayCard(cardOne, 0, 1);
displayCard(cardTwo, 0, 2);
displayCard(cardThree, 0, 6);
}
private boolean inImage (int x, int y, int imageNumber)
{
int cellWidth = width / NUMBER_COLUMNS;
int cellHeight = height / NUMBER_ROWS;
int upperLeftX = (imageNumber + 1) * cellWidth;
int upperLeftY = cellHeight;
upperLeftX += (int) (.1 * cellWidth);
upperLeftY += (int) (.1 * cellHeight);
cellWidth = (int) (.8 * cellWidth);
cellHeight = (int) (.8 * cellHeight);
return ((x >= upperLeftX) && (x <= upperLeftX + cellWidth) &&
(y >= upperLeftY) && (y <= upperLeftY + cellHeight));
}
private boolean legalPlay (int whichCard)
{
int cardsPerSuit = CARDS_IN_DECK / 4;
if (trickLeader == me)
{
return true;
}
else if ( (cardImageIndices[whichCard] / cardsPerSuit) == (cardTwoIndex / cardsPerSuit) )
{
return true;
}
else
{
for (int i = 0; i < cardsToDisplay; i++)
{
if ((cardImageIndices[i] / cardsPerSuit) == (cardTwoIndex / cardsPerSuit))
return false;
}
return true;
}
}
public void mousePressed (MouseEvent evt)
{
int x = evt.getX();
int y = evt.getY();
for (int i = 0; i < cardsToDisplay; i++)
{
if (clickableImages && inImage(x, y, i) && legalPlay(i))
{
cardOne = cardImages[cardImageIndices[i]];
if (trickLeader == me)
{
cardTwo = cardBackImage;
client.sendMessage("#CARD1#" + cardImageIndices[i] + "#");
}
else
{
client.sendMessage("#CARD2#" + cardImageIndices[i] + "#");
}
for (int j = i; j < cardsToDisplay - 1; j++)
{
cardImageIndices[j] = cardImageIndices[j+1];
}
setMessages("Wait", "");
cardsToDisplay--;
clickableImages = false;
repaint();
}
}
}
public void mouseClicked (MouseEvent evt) {}
public void mouseReleased (MouseEvent evt) {}
public void mouseEntered (MouseEvent evt) {}
public void mouseExited (MouseEvent evt) {}
public void itemStateChanged (ItemEvent evt)
{
if (evt.getStateChange() == ItemEvent.SELECTED)
{
String arg = (String) evt.getItem();
if (arg.equals ("Accept Trump"))
{
acceptTrumpChoice.setVisible(false);
client.sendMessage("#BID1#" + "Accept" + "#");
caller = "You";
setMessages("Wait for", "Final Deal");
}
else if (arg.equals ("Dont Accept"))
{
acceptTrumpChoice.setVisible(false);
client.sendMessage("#BID1#Pass#");
setMessages("Wait for", "Other Bid");
}
else if ((arg.equals("Clubs")) || (arg.equals("Diamonds")) ||
(arg.equals("Hearts")) || (arg.equals("Spades")) ||
(arg.equals("Nothing")) || (arg.equals("Everything")))
{
callTrumpChoice.setVisible(false);
client.sendMessage("#BID2#" + arg + "#");
caller = "You";
trump = arg;
setMessages("Wait", "");
}
else if (arg.equals("Pass"))
{
callTrumpChoice.setVisible(false);
client.sendMessage("#BID2#Pass#");
if (dealerName.equals("Opponent"))
{
setMessages("Wait for", "Other Bid");
}
else
{
setMessages("Passed Out", "Redeal");
client.sendMessage("#PASSOUT#");
}
}
}
repaint();
}
public void actionPerformed(ActionEvent evt)
{
String arg = evt.getActionCommand();
if (arg.equals("Join"))
{
client = new ClientListener(this);
client.start();
rulesButton.setVisible(false);
joinButton.setVisible(false);
setMessages("Wait for", "Opponent");
}
else if (arg.equals("Rules"))
{
URL url = null;
try
{
url = new URL("http://cs.montana.edu/~paxton/tutorial/belot.htm");
}
catch (MalformedURLException e) {}
getAppletContext().showDocument(url);
}
else if ((arg.equals("Again")) || (arg.equals("Quit")))
{
againButton.setVisible(false);
quitButton.setVisible(false);
client.sendMessage("#" + arg.toUpperCase() + "#");
setMessages("Wait", "");
}
else if (arg.equals("Send"))
{
String message = outgoingField.getText();
outgoingField.setText("");
client.sendMessage("#MESSAGE#" + message + "#");
}
repaint();
}
public void setMessages(String m1, String m2)
{
message1 = m1;
message2 = m2;
}
public void placeComponent (TextField field, int row, int column, int where)
{
int x = column * width / NUMBER_COLUMNS;
int y = row * height / NUMBER_ROWS;
y = y + where * (height / NUMBER_ROWS / 3 );
field.setBounds(x + 10, y, 2 * width / NUMBER_COLUMNS - 20, 20);
}
public void placeComponent (Component component, int row, int column)
{
int x = column * width / NUMBER_COLUMNS;
int y = row * height / NUMBER_ROWS;
component.setBounds(x + 10, y + 10, width/NUMBER_COLUMNS - 20,
height/NUMBER_ROWS - 20);
}
void displayString(int row, int column, String text)
{
Graphics g = getGraphics();
int x = column * width / NUMBER_COLUMNS + 10;
int y = row * height / NUMBER_ROWS + 70;
g.drawString(text, x, y);
}
void displayString(int row, int column, int whichOne,
int howMany, String text)
{
Graphics g = getGraphics();
int x = column * width / NUMBER_COLUMNS;
int y = row * height / NUMBER_ROWS;
int yGap = ((height / NUMBER_ROWS) - (fm.getHeight() * howMany) -
(howMany - 1)*(height/NUMBER_ROWS/20)) / 2;
x += (width/NUMBER_COLUMNS - fm.stringWidth(text)) / 2; // center horizontally
y += yGap + fm.getHeight()*whichOne + (height/NUMBER_ROWS/20*(whichOne - 1));
g.drawString(text, x, y);
}
void displayStringTop(int row, int column, int whichOne, String text)
{
Graphics g = getGraphics();
int x = column * width / NUMBER_COLUMNS;
x += (width/NUMBER_COLUMNS - fm.stringWidth(text)) / 2;
int y = row * height / NUMBER_ROWS + whichOne * fm.getHeight();
g.drawString(text, x, y);
}
void displayStrings (int row, int column, String text1, String text2)
{
displayString(row, column, 1, 2, text1);
displayString(row, column, 2, 2, text2);
}
void displayStrings (int row, int column, String text1,
String text2, String text3)
{
displayString(row, column, 1, 3, text1);
displayString(row, column, 2, 3, text2);
displayString(row, column, 3, 3, text3);
}
void displayStringsTop (int row, int column, String text1, String text2)
{
displayStringTop(row, column, 1, text1);
displayStringTop(row, column, 2, text2);
}
void displayCard (Image card, int row, int column)
{
int cellWidth = width / NUMBER_COLUMNS;
int cellHeight = height / NUMBER_ROWS;
int x = column * cellWidth;
int y = row * cellHeight;
x = x + (int) (.1 * cellWidth) ;
y = y + (int) (.1 * cellHeight);
cellWidth = (int) (.8 * cellWidth);
cellHeight = (int) (.8 * cellHeight);
getGraphics().drawImage(card, x, y, cellWidth, cellHeight, this);
}
private Button joinButton;
private Button rulesButton;
private Button sendButton;
protected Button againButton;
protected Button quitButton;
protected Choice acceptTrumpChoice;
protected Choice callTrumpChoice;
protected TextField outgoingField;
protected TextField incomingField;
protected Image cardOne;
protected Image cardTwo;
protected Image cardThree;
protected int cardTwoIndex;
protected Image cardBackImage;
protected boolean clickableImages;
protected int dealer;
protected int trickLeader;
private int height; // height of applet
private int width; // width of applet
private String message1;
private String message2;
private FontMetrics fm;
protected Image cardImages[];
protected int cardImageIndices[];
protected int cardsToDisplay;
protected String trump;
protected String caller;
protected String dealerName;
protected int myRawPoints;
protected int yourRawPoints;
protected int myGamePoints;
protected int yourGamePoints;
protected int myTotalPoints;
protected int yourTotalPoints;
protected int me;
protected int you;
private ClientListener client;
}
class ClientListener extends Thread implements BelotConstants
{
ClientListener (Network network)
{
parent = network;
if ( !connectToServer() )
{
parent.setBackground(Color.yellow);
}
try
{
clientInput = new DataInputStream
(new BufferedInputStream (clientSocket.getInputStream()));
clientOutput = new DataOutputStream
(new BufferedOutputStream (clientSocket.getOutputStream()));
}
catch (Exception e)
{
parent.setMessages("Stream", "Error");
}
}
private boolean connectToServer()
{
try
{
clientSocket = new Socket("cs.montana.edu", 41962);
return true;
}
catch (Exception e)
{
parent.setMessages("Connect", "Error");
return false;
}
}
public void sendMessage (String message)
{
try
{
clientOutput.writeUTF(message);
clientOutput.flush();
}
catch (Exception e)
{
parent.setMessages("Write", "Error");
parent.setBackground(Color.white);
parent.repaint();
}
}
public void run ()
{
String message;
String command = "";
int whichPosition;
int whichCard;
String whichSuit;
int pointsMe;
int pointsYou;
int who;
while (!command.equals("QUIT"))
{
try
{
message = clientInput.readUTF();
command = determineCommand ( message);
message = shortenCommand(message, command);
if (command.equals("CARD"))
{
command = determineCommand(message);
whichPosition = Integer.parseInt(command);
message = shortenCommand (message, command);
whichCard = Integer.parseInt(determineCommand(message));
if (whichPosition < CARDS_IN_HAND)
{
parent.cardImageIndices[whichPosition] = whichCard;
}
else if (whichPosition == CARDS_IN_HAND)
{
parent.cardOne = parent.cardImages[whichCard];
}
else if (whichPosition == CARDS_IN_HAND + 1)
{
parent.cardTwo = parent.cardImages[whichCard];
parent.cardTwoIndex = whichCard;
}
else if (whichPosition == CARDS_IN_HAND + 2)
{
parent.cardThree = parent.cardImages[whichCard];
}
}
else if (command.equals("CARDSTODISPLAY"))
{
parent.cardsToDisplay = Integer.parseInt(determineCommand(message));
}
else if (command.equals("DEALER"))
{
who = Integer.parseInt(determineCommand(message));
parent.caller = "Unknown";
parent.trump = "Unknown";
if (parent.me == who)
{
parent.dealerName = "You";
}
else
{
parent.dealerName = "Opponent";
}
}
else if (command.equals("FIRSTBID"))
{
whichSuit = determineCommand(message);
if (!whichSuit.equals("Pass"))
{
parent.caller = "Opponent";
parent.trump = whichSuit;
parent.setMessages("Wait", "");
}
else if (parent.dealerName.equals("You"))
{
parent.acceptTrumpChoice.setVisible(true);
parent.setMessages("Make a", "Bid");
}
else
{
parent.callTrumpChoice.setVisible(true);
parent.setMessages("Make a", "Bid");
}
}
else if (command.equals("FOLLOWCARD"))
{
whichCard = Integer.parseInt(determineCommand(message));
parent.cardTwo = parent.cardImages[whichCard];
parent.cardTwoIndex = whichCard;
parent.setMessages("Play a", "Card");
parent.clickableImages = true;
parent.trickLeader = parent.you;
parent.cardOne = parent.cardBackImage;
}
else if (command.equals("GAMEPOINTS"))
{
command = determineCommand(message);
pointsMe = Integer.parseInt(command);
message = shortenCommand(message, command);
command = determineCommand(message);
pointsYou = Integer.parseInt(command);
parent.myGamePoints = pointsMe;
parent.yourGamePoints = pointsYou;
}
else if (command.equals("MESSAGE"))
{
parent.incomingField.setText(determineCommand(message));
parent.repaint();
}
else if (command.equals("PAINT"))
{
parent.repaint();
}
else if (command.equals("PLAYCARD"))
{
parent.setMessages("Play a", "Card");
parent.clickableImages = true;
parent.trickLeader = parent.me;
}
else if (command.equals("QUIT"))
{
parent.setMessages("Player", "Quit");
sendMessage("#QUIT#");
parent.repaint();
}
else if (command.equals("RAWPOINTS"))
{
command = determineCommand(message);
pointsMe = Integer.parseInt(command);
message = shortenCommand(message, command);
command = determineCommand(message);
pointsYou = Integer.parseInt(command);
parent.myRawPoints = pointsMe;
parent.yourRawPoints = pointsYou;
}
else if (command.equals("SECONDBID"))
{
whichSuit = determineCommand(message);
if (!whichSuit.equals("Pass"))
{
parent.caller = "Opponent";
parent.trump = whichSuit;
parent.setMessages("Wait", "");
}
else if (parent.dealerName.equals("You"))
{
parent.callTrumpChoice.setVisible(true);
parent.setMessages("Make a", "Bid");
}
else
{
parent.setMessages("Passed", "Out");
}
}
else if (command.equals("SLEEP"))
{
sleep(5000);
}
else if (command.equals("STARTBIDDING"))
{
if (parent.dealerName.equals("Opponent"))
{
parent.setMessages("Make", "a Bid");
parent.acceptTrumpChoice.setVisible(true);
}
else
{
parent.setMessages("Wait for", "Opponent Bid");
}
}
else if (command.equals("TOTALPOINTS"))
{
command = determineCommand(message);
pointsMe = Integer.parseInt(command);
message = shortenCommand(message, command);
command = determineCommand(message);
pointsYou = Integer.parseInt(command);
parent.myTotalPoints = pointsMe;
parent.yourTotalPoints = pointsYou;
if ((pointsYou > POINTS_TO_WIN) && (pointsYou > pointsMe))
{
parent.setMessages("You", "Lose");
parent.againButton.setVisible(true);
parent.quitButton.setVisible(true);
}
else if ((pointsMe > POINTS_TO_WIN) && (pointsMe > pointsYou))
{
parent.setMessages("You", "Win");
parent.againButton.setVisible(true);
parent.quitButton.setVisible(true);
}
}
else if (command.equals("TRUMP"))
{
whichSuit = determineCommand(message);
parent.trump = whichSuit;
}
else if (command.equals("YOURNUMBER"))
{
parent.me = Integer.parseInt(determineCommand(message));
parent.you = 1 - parent.me;
}
}
catch (Exception e)
{
parent.setMessages("Command", "Error");
parent.setBackground(Color.green);
}
}
parent.repaint();
}
private String determineCommand (String message)
{
int secondHash = message.indexOf("#", 1);
return message.substring(1, secondHash);
}
private String shortenCommand (String message, String argument)
{
return message.substring(1 + argument.length());
}
private Socket clientSocket;
private DataInputStream clientInput;
private DataOutputStream clientOutput;
private Network parent;
}
|