using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; using System.Runtime.Serialization.Formatters.Binary; using System.Collections; using Gin_Rummy_Game; namespace Gin_Rummy_Client { public partial class GinRummyClientForm : Form { private TcpClient socketForServer; private Thread thisThread; private static string CardImagesFolder = "C:\\Documents and Settings\\spannm\\Desktop\\Personal Stuff\\C#\\C# Projects VS2008\\Gin Rummy\\Gin Rummy Game\\Card Images\\"; private String playerName = null; private int numberOfPlayers = 4; private ArrayList namesList; private PictureBox[] selectedSwapPictureBoxes; private int numberOfSwapPictureBoxes; private static String faceDownCardFile = "b1fv.gif"; private Int32 serverPort = 10; private NetworkStream networkStream; private int playerID; private List hand=new List(); private PlayingCard drawDeckTopCard = null; private PlayingCard discardDeckTopCard = null; private static string cardFile = CardImagesFolder + faceDownCardFile; private PlayState rp=null; private int drawDeckCount; private int discardDeckCount; private Boolean guiInitialized = false; public GinRummyClientForm() { InitializeComponent(); selectedSwapPictureBoxes = new PictureBox[2]; TopMost = false; } private delegate void updateTextInfoDelegate(string s); private void updateTextInfo(string s) { gameTextBox.Clear(); gameTextBox.Text = s; } private delegate void makeVisibleDelegate(Control c); private void makeVisible(Control c) { c.Visible = true; } private void displayHand(GroupBox gb, List hand, Boolean faceDown) { if ((hand == null)&&(!faceDown)) return; if (hand!=null) hand.Sort(); int handSize = 7; if (hand!=null) handSize = hand.Count; for (int cardNo = 0; cardNo < handSize; cardNo++) { Control c = gb.Controls[handSize - cardNo - 1]; Type controlType = c.GetType(); if (!controlType.ToString().Equals("System.Windows.Forms.PictureBox")) return; PictureBox pb = (PictureBox)c; if (faceDown) pb.Image = Image.FromFile(cardFile); else { PlayingCard card = hand[cardNo]; pb.Image = card.getImage(); } } } private void initializeGUI() { playerPanels.Invoke(new makeVisibleDelegate(makeVisible), new object[] { playerPanels }); playerLabels.Invoke(new makeVisibleDelegate(makeVisible), new object[] { playerLabels }); player0PictureBoxes.Invoke(new makeVisibleDelegate(makeVisible), new object[] { player0PictureBoxes }); player3PictureBoxes.Invoke(new makeVisibleDelegate(makeVisible), new object[] { player3PictureBoxes }); player2PictureBoxes.Invoke(new makeVisibleDelegate(makeVisible), new object[] { player2PictureBoxes }); player1PictureBoxes.Invoke(new makeVisibleDelegate(makeVisible), new object[] { player1PictureBoxes }); deckPanel.Invoke(new makeVisibleDelegate(makeVisible), new object[] { deckPanel }); displayHand(player0PictureBoxes, hand, false); displayHand(player3PictureBoxes, null, true); displayHand(player2PictureBoxes, null, true); displayHand(player1PictureBoxes, null, true); drawDeckPictureBox.Image = Image.FromFile(cardFile); drawDeckCountLabel.Text = drawDeckCount + " cards"; discardDeckCountLabel.Text = discardDeckCount + " cards"; drawDeckPictureBox.Image = Image.FromFile(cardFile); // Disable picture boxes drawDeckPictureBox.Enabled = false; discardDeckPictureBox.Enabled = false; for (int i = 0; i < 7; i++) { PictureBox p = (PictureBox)(player0PictureBoxes.Controls[i]); p.Enabled = false; } guiInitialized = true; return; } private void updateGUI(PlayState rp) { PlayingCard card = rp.Card; if (rp.Deck == PlayState.DeckType.DISCARDDECK) discardDeckPictureBox.Image = card.getImage(); else if (rp.Deck == PlayState.DeckType.BOTHDECKS) { drawDeckPictureBox.Image = Image.FromFile(cardFile); return; } else if (rp.Deck == PlayState.DeckType.DRAWDECK) { discardDeckPictureBox.Image = card.getImage(); drawDeckPictureBox.Image = Image.FromFile(cardFile); } } private int getControlOfType(Panel p) { int controlIndex = 0; bool controlFound = false; do { if (p.Controls[controlIndex] is T) controlFound = true; else controlIndex++; } while ((!controlFound) && (controlIndex < p.Controls.Count)); return controlIndex; } private void runClientThread() { // read/write data from/to the server and display it string inputString; object inputObject; int charBase = Convert.ToInt16('0'); while (true) { inputObject = readObject(); if (inputObject is string) { inputString = (string)inputObject; if (inputString[0] == 'S') // Player starts game { newGameButton.Enabled = true; playerID = Convert.ToInt16(inputString[1]) - charBase; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { " Click 'New game' button to start" }); } else if (inputString[0] == 'P') // This players turn to play { interactivePlayButton.Enabled = true; TopMost = true; autonomousPlayButton.Enabled = true; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "Your turn to play" }); } else if (inputString[0] == 'W') // A player has won { int winPlayerID = Convert.ToInt16(inputString[1]) - charBase; string winner = (string)namesList[winPlayerID]; if (playerID == winPlayerID) gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "Congratulations " + winner + " you have won!" }); else gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "Player " + winner + " has won" }); // Enable new game button and disable everything else interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; drawDeckPictureBox.Enabled = false; discardDeckPictureBox.Enabled = false; for (int i = 0; i < 7; i++) { PictureBox p = (PictureBox)(player0PictureBoxes.Controls[i]); p.Enabled = false; } } else if (inputString[0] == 'C') // Server wants to close client connection { gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { " Server closing client connection" }); newGameButton.Enabled = false; sendMessage("C"); // Handshake signal socketForServer.Close(); thisThread.Abort(); } } else if (inputObject is ArrayList) // Player names { namesList = (ArrayList)inputObject; int listLength = namesList.Count; int groupControlLength = playerLabels.Controls.Count; string name = (string)namesList[playerID]; playerLabels.Controls[groupControlLength - 1].Text = name; // Write rest names to the labels groupbox int controlCount = 2; for (int i = 0; i < numberOfPlayers; i++) { if (i != playerID) { name = (string)namesList[i]; playerLabels.Controls[groupControlLength - controlCount].Text = name; controlCount++; } } } else if (inputObject is PlayingCard[]) // Players hand { PlayingCard[] cardArray = (PlayingCard[])inputObject; hand.Clear(); for (int j = 0; j < cardArray.Length; j++) hand.Add(cardArray[j]); if (!guiInitialized) // Display initial hands and deck counts initializeGUI(); else { hand.Sort(); displayHand(player0PictureBoxes, hand, false); } } else if (inputObject is PlayingCardFromDeck) // Discard deck topcard { PlayingCardFromDeck cardFromDeck = (PlayingCardFromDeck)inputObject; PlayingCard card = cardFromDeck.Card; if (cardFromDeck.Deck == PlayingCardFromDeck.DeckType.DISCARDDECK) { discardDeckTopCard = card; discardDeckPictureBox.Image = card.getImage(); } else if (cardFromDeck.Deck == PlayingCardFromDeck.DeckType.DRAWDECK) drawDeckTopCard = card; } else if (inputObject is int[]) // Label counts { int[] labelCounts = (int[])inputObject; drawDeckCount = labelCounts[0]; discardDeckCount = labelCounts[1]; drawDeckCountLabel.Text = drawDeckCount + " cards"; discardDeckCountLabel.Text = discardDeckCount + " cards"; } else if (inputObject is PlayState) { rp = (PlayState)inputObject; } else if (inputObject is PlayingCard[,]) // Hands to display { PlayingCard[,] playerHands = (PlayingCard[,])inputObject; List[] hands = new List[numberOfPlayers]; for (int i = 0; i < numberOfPlayers; i++) { hands[i] = new List(); for (int j = 0; j < 7; j++) hands[i].Add(playerHands[i, j]); } // Display current player on top row int groupControlLength = playerPanels.Controls.Count; displayHand(player0PictureBoxes, hands[playerID], false); // Now display the rest int controlCount = 1; for (int i = 0; i < numberOfPlayers; i++) { if (i != playerID) { GroupBox gb = (GroupBox)(playerPanels.Controls[groupControlLength - controlCount]); controlCount++; displayHand(gb, hands[i], false); } } } } } public void sendMessage(string message) { sendObject(message); } private void sendObject(Object obj) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(networkStream, obj); } public string getMessage() { string message = (string) readObject(); return message; } private Object readObject() { BinaryFormatter bf = new BinaryFormatter(); Object obj = bf.Deserialize(networkStream) as Object; return obj; } private int getSelectedPictureBoxIndex(PictureBox picBox) { int pictureBoxIndex = -1; for (int i = 0; i < 7; i++) { PictureBox p = (PictureBox)(player0PictureBoxes.Controls[i]); if (picBox == p) pictureBoxIndex = i; } return pictureBoxIndex; } private PlayState selectSwapPictureBoxes(PictureBox picBox) { // Controls the interactive playing of a hand PlayState returnObj = null; if (numberOfSwapPictureBoxes == 0) { if (picBox == discardDeckPictureBox) { selectedSwapPictureBoxes[numberOfSwapPictureBoxes++] = picBox; picBox.BorderStyle = BorderStyle.Fixed3D; picBox.Enabled = false; gameTextBox.Text = "Select a card from " + playerName + "'s hand to swap with"; drawDeckPictureBox.Enabled = false; return null; } else if (picBox == drawDeckPictureBox) { selectedSwapPictureBoxes[numberOfSwapPictureBoxes++] = picBox; picBox.BorderStyle = BorderStyle.Fixed3D; drawDeckTopCard = null; sendMessage("D"); // Indicates to server that drawdeck picture box selected picBox.Enabled = false; do {} while (drawDeckTopCard == null); gameTextBox.Text = "Either select the discard deck to reject or select a card from " + playerName + "'s hand to swap with"; drawDeckPictureBox.Image = drawDeckTopCard.getImage(); return null; } } else if (numberOfSwapPictureBoxes == 1) { if (selectedSwapPictureBoxes[0] == discardDeckPictureBox) { // Select a card from the current players hand int index = getSelectedPictureBoxIndex(picBox); selectedSwapPictureBoxes[numberOfSwapPictureBoxes] = (PictureBox)(player0PictureBoxes.Controls[index]); if (index >= 0) { picBox.BorderStyle = BorderStyle.Fixed3D; picBox.Enabled = false; numberOfSwapPictureBoxes++; PlayingCard card1 = hand[7 - index - 1]; returnObj = new PlayState(card1, PlayState.DeckType.DISCARDDECK); } } else if (selectedSwapPictureBoxes[0] == drawDeckPictureBox) { if (picBox == discardDeckPictureBox) { // Drawdeck card discarded picBox.BorderStyle = BorderStyle.Fixed3D; picBox.Enabled = false; numberOfSwapPictureBoxes++; returnObj = new PlayState(null, PlayState.DeckType.BOTHDECKS); } else { // Select a card from the current players hand int index = getSelectedPictureBoxIndex(picBox); selectedSwapPictureBoxes[numberOfSwapPictureBoxes] = (PictureBox)(player0PictureBoxes.Controls[index]); if (index >= 0) { picBox.BorderStyle = BorderStyle.Fixed3D; picBox.Enabled = false; numberOfSwapPictureBoxes++; PlayingCard card1 = hand[7 - index - 1]; returnObj = new PlayState(card1, PlayState.DeckType.DRAWDECK); } } } // Reset borders and disable drawDeckPictureBox.BorderStyle = BorderStyle.None; discardDeckPictureBox.BorderStyle = BorderStyle.None; drawDeckPictureBox.Enabled = false; discardDeckPictureBox.Enabled = false; for (int i = 0; i < 7; i++) { PictureBox p = (PictureBox)(player0PictureBoxes.Controls[i]); p.BorderStyle = BorderStyle.None; p.Enabled = false; } } return returnObj; } private void connectButton_Click(object sender, EventArgs e) { int index = gameTextBox.Lines[0].IndexOf(':'); String ipAddr = gameTextBox.Lines[0].Substring(index + 1); index = gameTextBox.Lines[1].IndexOf(':'); playerName = gameTextBox.Lines[1].Substring(index + 1); try { socketForServer = new TcpClient(ipAddr, serverPort); gameTextBox.Clear(); gameTextBox.Text = playerName + " connected to server at " + ipAddr; networkStream = socketForServer.GetStream(); sendMessage(playerName); } catch { Console.WriteLine("Failed to connect to server at {0}:999", ipAddr); return; } connectButton.Enabled = false; thisThread = new Thread(new ThreadStart(this.runClientThread)); thisThread.Start(); } private void newGameButton_Click(object sender, EventArgs e) { sendMessage("S"); newGameButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { playerName+ " is ready to play" }); } private void interactivePlayButton_Click(object sender, EventArgs e) { // Play the hand interactively drawDeckPictureBox.Enabled = true; discardDeckPictureBox.Enabled = true; for (int i = 0; i < 7; i++) { PictureBox p = (PictureBox)(player0PictureBoxes.Controls[i]); p.Enabled = true; } // No picture boxes to swap as yet numberOfSwapPictureBoxes = 0; selectedSwapPictureBoxes[0] = selectedSwapPictureBoxes[1] = null; } private void autonomousPlayButton_Click(object sender, EventArgs e) { // Hand played at the server. Send a no play object rp = new PlayState(null, PlayState.DeckType.NOPLAY); sendObject(rp); rp = null; while (rp == null) { /* Wait until server has played hand and return PlayReturn object */ } // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } private void card0PictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void card1PictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void card2PictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void card3PictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void card4PictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void card5PictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void card6PictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void drawDeckPictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } private void discardDeckPictureBox_Click(object sender, EventArgs e) { rp = selectSwapPictureBoxes((PictureBox)sender); if (numberOfSwapPictureBoxes == 2) { // Transmit PlayState object to server sendObject(rp); // Update GUI updateGUI(rp); interactivePlayButton.Enabled = false; autonomousPlayButton.Enabled = false; gameTextBox.Invoke(new updateTextInfoDelegate(updateTextInfo), new object[] { "" }); TopMost = false; } } } }