using System; using System.Collections.Generic; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using System.IO; using System.Threading; using System.Net; namespace ihb_seewar { public partial class Form1 : Form { private enum ServerStatus { server, client, none } private enum GameStatus { prepare, game, end } // game vars private int[,] mapMY = new int[10, 10]; private int[,] mapEN = new int[10, 10]; private int shipNr = 10; private bool turn = false; private int shipCountM = 20; private int shipCountE = 20; private GameStatus gg = GameStatus.prepare; // server vars private ServerStatus myStatus = ServerStatus.none; private int cport = 8789; private ArrayList mSocketList = ArrayList.Synchronized(new ArrayList()); private int m_clientCount = 0; public AsyncCallback pfnWorkerCallBack; private Socket m_mainSocket; // client vars private Socket m_clientSocket; IAsyncResult m_result; private AsyncCallback m_pfnCallBack; // drawing const int mapx = 20; const int mapy = 20; const int mapxe = 240; public delegate void UpdateClientListCallback(string str); private void Piesti() { Graphics g = CreateGraphics(); Pen pn = new Pen(Color.Blue); SolidBrush brWhite = new SolidBrush(Color.White); SolidBrush brRed = new SolidBrush(Color.Tomato); SolidBrush brGreen = new SolidBrush(Color.Green); // g.FillRectangle(brWhite, mapx, mapy, 200, 200); for (int i = 0; i < 11; i++) { g.DrawLine(pn, mapx, i * 20 + mapy, 200 + mapx, i * 20 + mapy); g.DrawLine(pn, i * 20 + mapx, mapy, i * 20 + mapx, 200 + mapy); g.DrawLine(pn, mapxe, i * 20 + mapy, 200 + mapxe, i * 20 + mapy); g.DrawLine(pn, i * 20 + mapxe, mapy, i * 20 + mapxe, 200 + mapy); } for (int i = 0; i < 10; i++) { for (int u = 0; u < 10; u++) { if (mapMY[i, u] == 8) { g.FillRectangle(brGreen, i * 20 + 3 + mapx, u * 20 + 3 + mapy, 14, 14); } else if (mapMY[i, u] == 2) { g.FillRectangle(brWhite, i * 20 + 2 + mapx, u * 20 + 2 + mapy, 16, 16); } else if (mapMY[i, u] == 9) { g.FillRectangle(brRed, i * 20 + 2 + mapx, u * 20 + 2 + mapy, 16, 16); } //else { g.FillRectangle(brRed, i * 20 + 3 + mapx, u * 20 + 3 + mapy, 14, 14); } if (mapEN[i, u] == 8) { g.FillRectangle(brGreen, i * 20 + 3 + mapxe, u * 20 + 3 + mapy, 14, 14); } else if (mapEN[i, u] == 2) { g.FillRectangle(brWhite, i * 20 + 2 + mapxe, u * 20 + 2 + mapy, 16, 16); } else if (mapEN[i, u] == 9) { g.FillRectangle(brRed, i * 20 + 2 + mapxe, u * 20 + 2 + mapy, 16, 16); } } } UpdateTurn1(); } private void shipAdd(Point p) { int k = 0; int[,] tmas = new int[10, 10]; if (checkBox1.Checked) { if ((shipNr < 5) && (shipNr > 0)) { tmas[p.X, p.Y] = 8; k = 1; } else if ((shipNr < 8) && (p.Y + 1 < 10)) { tmas[p.X, p.Y] = 8; tmas[p.X, p.Y + 1] = 8; k = 1; } else if ((shipNr < 10) && (p.Y + 2 < 10)) { tmas[p.X, p.Y] = 8; tmas[p.X, p.Y + 1] = 8; tmas[p.X, p.Y + 2] = 8; k = 1; } else if ((shipNr == 10) && (p.Y + 3 < 10)) { tmas[p.X, p.Y] = 8; tmas[p.X, p.Y + 1] = 8; tmas[p.X, p.Y + 2] = 8; tmas[p.X, p.Y + 3] = 8; k = 1; } } else { if ((shipNr < 5) && (shipNr > 0)) { tmas[p.X, p.Y] = 8; k = 1; } else if ((shipNr < 8) && (p.X + 1 < 10)) { tmas[p.X, p.Y] = 8; tmas[p.X + 1, p.Y] = 8; k = 1; } else if ((shipNr < 10) && (p.X + 2 < 10)) { tmas[p.X, p.Y] = 8; tmas[p.X + 1, p.Y] = 8; tmas[p.X + 2, p.Y] = 8; k = 1; } else if ((shipNr == 10) && (p.X + 3 < 10)) { tmas[p.X, p.Y] = 8; tmas[p.X + 1, p.Y] = 8; tmas[p.X + 2, p.Y] = 8; tmas[p.X + 3, p.Y] = 8; k = 1; } } if (k == 1) { if (seeCheck(tmas) == 1) { //MessageBox.Show("galima"); seeAddShip(tmas); seeFill(); shipNr--; if (shipNr == 0) { updateText1("DONE\r\nhosting serva arba concect" + Environment.NewLine); UpdateControls(true); } } } } private int seeCheck(int[,] tmas) { for (int i = 0; i < 10; i++) { for (int u = 0; u < 10; u++) { if (mapMY[i, u] + tmas[i, u] > 8) { return 0; } } } return 1; } private void seeAddShip(int[,] tmas) { for (int i = 0; i < 10; i++) { for (int u = 0; u < 10; u++) { mapMY[i, u] += tmas[i, u]; } } } private void seeFill() { for (int i = 0; i < 10; i++) { for (int u = 0; u < 10; u++) { if (mapMY[i, u] == 8) { if ((i - 1 >= 0) && (u - 1 >= 0)) { if (mapMY[i - 1, u - 1] == 0) { mapMY[i - 1, u - 1] = 1; } } if ((i < 10) && (u - 1 >= 0)) { if (mapMY[i, u - 1] == 0) { mapMY[i, u - 1] = 1; } } if ((i + 1 < 10) && (u - 1 >= 0)) { if (mapMY[i + 1, u - 1] == 0) { mapMY[i + 1, u - 1] = 1; } } if ((i - 1 >= 0) && (u >= 0)) { if (mapMY[i - 1, u] == 0) { mapMY[i - 1, u] = 1; } } if ((i + 1 < 10) && (u >= 0)) { if (mapMY[i + 1, u] == 0) { mapMY[i + 1, u] = 1; } } if ((i - 1 >= 0) && (u + 1 < 10)) { if (mapMY[i - 1, u + 1] == 0) { mapMY[i - 1, u + 1] = 1; } } if ((i < 10) && (u + 1 < 10)) { if (mapMY[i, u + 1] == 0) { mapMY[i, u + 1] = 1; } } if ((i + 1 < 10) && (u + 1 < 10)) { if (mapMY[i + 1, u + 1] == 0) { mapMY[i + 1, u + 1] = 1; } } } } } } private void ShipHit(Point p) { string ans = ""; if (mapMY[p.X, p.Y] == 8) { ans = "y" + p.X.ToString() + p.Y.ToString(); mapMY[p.X, p.Y] = 9; if ((p.X - 1 >= 0) && (p.Y - 1 >= 0)) { mapMY[p.X - 1, p.Y - 1] = 2; } if ((p.X + 1 < 10) && (p.Y - 1 >= 0)) { mapMY[p.X + 1, p.Y - 1] = 2; } if ((p.X - 1 >= 0) && (p.Y + 1 < 10)) { mapMY[p.X - 1, p.Y + 1] = 2; } if ((p.X + 1 < 10) && (p.Y + 1 < 10)) { mapMY[p.X + 1, p.Y + 1] = 2; } shipCountM--; turn = false; WinCheck(); } else { ans = "n" + p.X.ToString() + p.Y.ToString(); mapMY[p.X, p.Y] = 2; turn = true; } SendAns(ans); } private void SeeENUpdate(string str) { Point p = new Point(); p.X = int.Parse(str.Substring(2, 1)); p.Y = int.Parse(str.Substring(3, 1)); if (str.Substring(1, 1) == "y") { mapEN[p.X, p.Y] = 9; if ((p.X - 1 >= 0) && (p.Y - 1 >= 0)) { mapEN[p.X - 1, p.Y - 1] = 2; } if ((p.X + 1 < 10) && (p.Y - 1 >= 0)) { mapEN[p.X + 1, p.Y - 1] = 2; } if ((p.X - 1 >= 0) && (p.Y + 1 < 10)) { mapEN[p.X - 1, p.Y + 1] = 2; } if ((p.X + 1 < 10) && (p.Y + 1 < 10)) { mapEN[p.X + 1, p.Y + 1] = 2; } shipCountE--; turn = true; WinCheck(); } else { mapEN[p.X, p.Y] = 2; turn = false; } } private void WinCheck() { if (shipCountE == 0) { updateText1("---laimejai---\r\n"); updateText1("---laimejai---\r\n"); updateText1("---laimejai---\r\n"); UpdateTurn1(); gg = GameStatus.end; } if (shipCountM == 0) { updateText1("---pralaimejai---\r\n"); updateText1("---pralaimejai---\r\n"); updateText1("---pralaimejai---\r\n"); UpdateTurn1(); gg = GameStatus.end; } } public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // updateUI(); UpdateControls(false); button3.Enabled = false; updateText1("susidek laivus..."); label3.Text = ""; } private void button1_Click(object sender, EventArgs e) { m_mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, cport); m_mainSocket.Bind(ipLocal); m_mainSocket.Listen(4); m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); updateText1("IP: " + ipLocal.Address.ToString() + " PORT: " + ipLocal.Port.ToString() + Environment.NewLine); updateText1("waiting..." + Environment.NewLine); myStatus = ServerStatus.server; UpdateControls(false); turn = true; } private void OnClientConnect(IAsyncResult asyn) { Socket workerSocket = m_mainSocket.EndAccept(asyn); Interlocked.Increment(ref m_clientCount); mSocketList.Add(workerSocket); // Send a welcome message to client string msg = "mWelcome client " + m_clientCount + ""; SendMsgToClient(msg, m_clientCount); string str = "client " + m_clientCount + " connected" + Environment.NewLine; updateText1(str); // just connected client WaitForData(workerSocket, m_clientCount); m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); gg = GameStatus.game; } public class SocketPacket { public System.Net.Sockets.Socket m_currentSocket; public int m_clientNumber; public byte[] dataBuffer = new byte[1024]; public SocketPacket(System.Net.Sockets.Socket socket, int clientNumber) { m_currentSocket = socket; m_clientNumber = clientNumber; } } private void SendMsgToClient(string msg, int clientNumber) { // Convert the reply to byte array byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg); Socket workerSocket = (Socket)mSocketList[clientNumber - 1]; workerSocket.Send(byData); } public void OnDataReceived(IAsyncResult asyn) { try { SocketPacket socketData = (SocketPacket)asyn.AsyncState; int iRx = socketData.m_currentSocket.EndReceive(asyn); char[] chars = new char[iRx + 1]; System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0); System.String szData = new System.String(chars); MsgIdent(szData.Remove(szData.Length - 1, 1)); //string msg = "Client: " + szData.Remove(szData.Length - 1, 2) + Environment.NewLine; //updateText1(msg); WaitForData(socketData.m_currentSocket, socketData.m_clientNumber); } catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n"); } catch (SocketException se) { if (se.ErrorCode == 10054) // Error code for Connection reset by peer { string msg = "Client Disconnected" + "\n"; updateText1(msg); } else { MessageBox.Show(se.Message); } } } private void WaitForData(System.Net.Sockets.Socket soc, int clientNumber) { if (pfnWorkerCallBack == null) { // Specify the call back function which is to be // invoked when there is any write activity by the // connected client pfnWorkerCallBack = new AsyncCallback(OnDataReceived); } SocketPacket theSocPkt = new SocketPacket(soc, clientNumber); soc.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length, SocketFlags.None, pfnWorkerCallBack, theSocPkt); } private void button2_Click(object sender, EventArgs e) { cConnect(); } private void cConnect() { if (textBox2.Text == "") { MessageBox.Show("IP Address and Port Number are required to connect to the Server\n"); return; } try { // Create the socket instance m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Cet the remote IP address IPAddress ip = IPAddress.Parse(textBox2.Text); int iPortNo = cport; // Create the end point IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo); // Connect to the remote host m_clientSocket.Connect(ipEnd); if (m_clientSocket.Connected) { myStatus = ServerStatus.client; turn = false; gg = GameStatus.game; UpdateControls(false); WaitForData(); } } catch (SocketException se) { string str; str = "\nConnection failed, is the server running?\n" + se.Message; MessageBox.Show(str); UpdateControls(true); } } public void WaitForData() { try { if (m_pfnCallBack == null) { m_pfnCallBack = new AsyncCallback(cOnDataReceived); } cSocketPacket theSocPkt = new cSocketPacket(); theSocPkt.thisSocket = m_clientSocket; // Start listening to the data asynchronously m_result = m_clientSocket.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length, SocketFlags.None, m_pfnCallBack, theSocPkt); } catch (SocketException se) { MessageBox.Show(se.Message); } } public class cSocketPacket { public System.Net.Sockets.Socket thisSocket; public byte[] dataBuffer = new byte[1024]; } public void cOnDataReceived(IAsyncResult asyn) { try { cSocketPacket theSockId = (cSocketPacket)asyn.AsyncState; int iRx = theSockId.thisSocket.EndReceive(asyn); char[] chars = new char[iRx + 1]; System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0); System.String szData = new System.String(chars); szData = szData.Remove(szData.Length - 1, 1); MsgIdent(szData); WaitForData(); } catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n"); } catch (SocketException se) { MessageBox.Show(se.Message); } } private void UpdateControls(bool connected) { button1.Enabled = connected; button2.Enabled = connected; button3.Enabled = !connected; } private void updateText1(string str) { if (InvokeRequired) { object[] pList = { str }; textBox1.BeginInvoke(new UpdateClientListCallback(updateText), pList); } else { updateText(str); } } private void updateText(string str) { textBox1.Text += str; textBox1.Select(textBox1.Text.Length - 1, 1); textBox1.ScrollToCaret(); } private void UpdateTurn1() { if (gg == GameStatus.game) { string str = ""; if (turn == true) { str = "t"; } else { str = "f"; } if (InvokeRequired) { object[] pList = { str }; label3.BeginInvoke(new UpdateClientListCallback(UpdateTurn), pList); } else { UpdateTurn(str); } } } private void UpdateTurn(string str) { if (str == "t") { label3.Text = "Tavo eile"; label3.BackColor = Color.Green; } else { label3.BackColor = Color.Tomato; label3.Text = "Draugo eile"; } } private void MsgIdent(string str) { if (str.Substring(0, 1) == "m") { if (myStatus == ServerStatus.server) { str = "Client: " + str.Substring(1) + Environment.NewLine; } else { str = "Server: " + str.Substring(1) + Environment.NewLine; } updateText1(str); } else if (str.Substring(0, 1) == "p") { Point p = new Point(); p.X = int.Parse(str.Substring(1, 1)); p.Y = int.Parse(str.Substring(2, 1)); ShipHit(p); Piesti(); } else if (str.Substring(0, 1) == "a") { SeeENUpdate(str); Piesti(); } } private void button3_Click(object sender, EventArgs e) { updateText1("As: " + textBox2.Text + Environment.NewLine); string msg = "m" + textBox2.Text; byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg); if (myStatus == ServerStatus.server) { Socket workerSocket = (Socket)mSocketList[0]; workerSocket.Send(byData); } else if (m_clientSocket != null) { m_clientSocket.Send(byData); } } private void SendPoint(string msg) { turn = false; msg = "p" + msg; byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg); if (myStatus == ServerStatus.server) { Socket workerSocket = (Socket)mSocketList[0]; workerSocket.Send(byData); } else if (m_clientSocket != null) { m_clientSocket.Send(byData); } } private void SendAns(string msg) { msg = "a" + msg; byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg); if (myStatus == ServerStatus.server) { Socket workerSocket = (Socket)mSocketList[0]; workerSocket.Send(byData); } else if (m_clientSocket != null) { m_clientSocket.Send(byData); } } private void Form1_Click(object sender, EventArgs e) { MouseEventArgs me = (MouseEventArgs)e; Point p = me.Location; if (me.Button == MouseButtons.Left) { checkBox1.Checked = false; } else if (me.Button == MouseButtons.Right) { checkBox1.Checked = true; } if ((p.X > mapx) && (p.Y > mapy) && (p.X < mapx + 200) && (p.Y < mapy + 200) && (shipNr > 0)) { p.X = (p.X - mapx) / 20; p.Y = (p.Y - mapy) / 20; shipAdd(p); } if ((p.X > mapxe) && (p.Y > mapy) && (p.X < mapxe + 200) && (p.Y < mapy + 200)) { if ((gg != GameStatus.prepare) && (gg != GameStatus.end)) { if (turn == true) { p.X = (p.X - mapxe) / 20; p.Y = (p.Y - mapy) / 20; if (mapEN[p.X, p.Y] == 0) { SendPoint(p.X.ToString() + p.Y.ToString()); } else { MessageBox.Show("U cant hit tis"); } } else { MessageBox.Show("ne tavo eile"); } } } Piesti(); } protected override void OnPaint(PaintEventArgs pevent) { Piesti(); } protected override void OnResize(System.EventArgs e) { Piesti(); } private void Form1_Activated(object sender, EventArgs e) { Piesti(); } } }