# 暗棋程式碼(peer to peer & UDP) > 使用語言:C# > 使用框架:.NET framework4.6.1 ```csharp using System; using System.Text; using System.Drawing; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Threading; namespace 網路暗棋 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } Bitmap[] chessbmp = new Bitmap[33];//0~32 Bitmap[] blank = new Bitmap[2];//深色淺色的空白 Bitmap board;//棋盤的底色 Bitmap platebmp = new Bitmap(800, 400);//存棋盤800*400,每個棋子100*100 Bitmap move_platebmp = new Bitmap(800, 400); int offsetx, offsety,original_x,original_y; Graphics g; int[,] chesstable = new int[5, 9]; //記錄目前棋子狀況,蓋棋為負,正棋為正,0為空,棋盤左上角為1,1 UdpClient u, s; Thread th; string myIP; string enemyIP = ""; int enemy=1000; string sendstr = ""; Boolean play = true; int playchess = -1; //紅子 0 藍子 1 若還未確定(第一步)-1 private void loadbitmap() { chessbmp[0] = new Bitmap(網路暗棋.Properties.Resources.背面); chessbmp[1] = new Bitmap(網路暗棋.Properties.Resources.帥); chessbmp[2] = new Bitmap(網路暗棋.Properties.Resources.仕); chessbmp[3] = new Bitmap(網路暗棋.Properties.Resources.仕); chessbmp[4] = new Bitmap(網路暗棋.Properties.Resources.相); chessbmp[5] = new Bitmap(網路暗棋.Properties.Resources.相); chessbmp[6] = new Bitmap(網路暗棋.Properties.Resources.車); chessbmp[7] = new Bitmap(網路暗棋.Properties.Resources.車); chessbmp[8] = new Bitmap(網路暗棋.Properties.Resources.傌); chessbmp[9] = new Bitmap(網路暗棋.Properties.Resources.傌); chessbmp[10] = new Bitmap(網路暗棋.Properties.Resources.砲); chessbmp[11] = new Bitmap(網路暗棋.Properties.Resources.砲); chessbmp[12] = new Bitmap(網路暗棋.Properties.Resources.兵); chessbmp[13] = new Bitmap(網路暗棋.Properties.Resources.兵); chessbmp[14] = new Bitmap(網路暗棋.Properties.Resources.兵); chessbmp[15] = new Bitmap(網路暗棋.Properties.Resources.兵); chessbmp[16] = new Bitmap(網路暗棋.Properties.Resources.兵); chessbmp[17] = new Bitmap(網路暗棋.Properties.Resources.將); chessbmp[18] = new Bitmap(網路暗棋.Properties.Resources.士); chessbmp[19] = new Bitmap(網路暗棋.Properties.Resources.士); chessbmp[20] = new Bitmap(網路暗棋.Properties.Resources.象); chessbmp[21] = new Bitmap(網路暗棋.Properties.Resources.象); chessbmp[22] = new Bitmap(網路暗棋.Properties.Resources.車藍); chessbmp[23] = new Bitmap(網路暗棋.Properties.Resources.車藍); chessbmp[24] = new Bitmap(網路暗棋.Properties.Resources.馬); chessbmp[25] = new Bitmap(網路暗棋.Properties.Resources.馬); chessbmp[26] = new Bitmap(網路暗棋.Properties.Resources.包); chessbmp[27] = new Bitmap(網路暗棋.Properties.Resources.包); chessbmp[28] = new Bitmap(網路暗棋.Properties.Resources.卒); chessbmp[29] = new Bitmap(網路暗棋.Properties.Resources.卒); chessbmp[30] = new Bitmap(網路暗棋.Properties.Resources.卒); chessbmp[31] = new Bitmap(網路暗棋.Properties.Resources.卒); chessbmp[32] = new Bitmap(網路暗棋.Properties.Resources.卒); blank[0] = new Bitmap(網路暗棋.Properties.Resources.blank0); blank[1] = new Bitmap(網路暗棋.Properties.Resources.blank1); board = new Bitmap(網路暗棋.Properties.Resources.底板); } private void resetboard() { int[] temp = new int[33]; int tmp; Random rnd = new Random(); for (int i=1;i<5;i++) for (int j = 1; j < 9; j++) { do tmp = rnd.Next(1, 33); while (temp[tmp] == 1); temp[tmp] = 1; chesstable[i, j] = -tmp; } } private void printboard() { for (int i = 1; i < 5; i++) { for (int j = 1; j < 9; j++) Console.Write("{0,4}", chesstable[i, j] + " "); Console.WriteLine(); } } private void redraw() { if (plate.Image != null) plate.Image.Dispose(); plate.Image = platebmp.Clone(new Rectangle(0, 0, platebmp.Width, platebmp.Height), platebmp.PixelFormat); } private string getmyIP() { string hn = Dns.GetHostName(); IPAddress[] ip = Dns.GetHostEntry(hn).AddressList; for (int i = 0; i < ip.Length; i++) if (ip[i].AddressFamily == AddressFamily.InterNetwork) return ip[i].ToString(); return ""; } private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; myIP = getmyIP(); this.Text = myIP; resetboard(); printboard(); loadbitmap(); g = Graphics.FromImage(platebmp); g.DrawImage(board, new Rectangle(0, 0, 800, 400)); for (int i = 0; i < 4; i++) for (int j = 0; j < 8; j++) g.DrawImage(chessbmp[0], new Rectangle(j * 100, i * 100, 100, 100)); redraw(); } private void button1_Click(object sender, EventArgs e) { enemyIP = EnemyPort.Text; s = new UdpClient(enemyIP, 1000); th = new Thread(listen); th.Start(); button1.Enabled = false; } private void listen() { int self = 1000; int x, y, ox, oy; u = new UdpClient(self); IPEndPoint EP = new IPEndPoint(IPAddress.Parse(myIP), self); while (true) { byte[] bu = u.Receive(ref EP); string[] cmd = Encoding.Default.GetString(bu).Split(','); switch (cmd[0]) { case "0": for (int i = 0; i < 4; i++) for (int j = 0; j < 8; j++) g.DrawImage(chessbmp[0], new Rectangle(j * 100, i * 100, 100, 100)); redraw(); for (int i = 1; i < 33; i++) chesstable[(i - 1) / 8 + 1, (i - 1) % 8 + 1] = int.Parse(cmd[i]); play = true; playchess = -1; this.BackColor = Color.Yellow; saybox.Text = "我先下!!" + "\n\r"; break; case "1": y = int.Parse(cmd[1]); x = int.Parse(cmd[2]); oy = int.Parse(cmd[3]); ox = int.Parse(cmd[4]); g.DrawImage(chessbmp[chesstable[oy, ox]], new Rectangle((x - 1)*100,(y - 1)*100,100,100)); g.DrawImage(blank[(ox + oy) % 2], new Rectangle((ox - 1) * 100, (oy - 1) * 100, 100, 100)); redraw(); chesstable[y, x] = chesstable[oy, ox]; chesstable[oy, ox] = 0; play = true; this.BackColor = Color.Yellow; break; case "2": y = int.Parse(cmd[1]); x = int.Parse(cmd[2]); chesstable[y, x] = -chesstable[y, x]; g.DrawImage(chessbmp[chesstable[y, x]], new Rectangle((x - 1) * 100, (y - 1) * 100, 100, 100)); redraw(); play = true; this.BackColor = Color.Yellow; break; case "3": y = int.Parse(cmd[1]);x = int.Parse(cmd[2]); if (int.Parse(cmd[3])==0) { playchess = 1;this.Text = "藍棋"; } else { playchess = 0; this.Text = "紅棋"; } chesstable[y, x] = -chesstable[y, x]; g.DrawImage(chessbmp[chesstable[y, x]], new Rectangle((x - 1) * 100, (y - 1) * 100, 100, 100)); redraw(); play = true; this.BackColor = Color.Yellow; break; case "4": saybox.Text = "對手說:" + cmd[1] + "\r\n" + saybox.Text; break; } } } private void send(string str) { byte[] bs = Encoding.Default.GetBytes(str); s.Send(bs, bs.Length); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if(th!=null) th.Abort(); if (u!=null) u.Close(); if (s != null) s.Close(); } private void msgbox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { saybox.Text = "我說:" + msgbox.Text + "\r\n" + saybox.Text; send("4," + msgbox.Text); msgbox.Text = ""; } } private void restart_Click(object sender, EventArgs e) { resetboard(); for(int i = 0; i < 4; i++) for (int j = 0; j < 8; j++) g.DrawImage(chessbmp[0], new Rectangle(j * 100, i * 100, 100, 100)); redraw(); sendstr = "0"; for (int i = 1; i < 5; i++) for (int j = 1; j < 9; j++) sendstr += "," + chesstable[i, j]; send(sendstr); Console.WriteLine(sendstr); play = false; playchess = -1; this.BackColor = Color.Ivory; saybox.Text = ""; } private void plate_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && play ) { if (chesstable[original_y / 100 + 1, original_x / 100 + 1]>0) { g.DrawImage(move_platebmp, new Rectangle(0, 0, 800, 400)); g.DrawImage(chessbmp[chesstable[original_y / 100 + 1, original_x / 100 + 1]], new Rectangle(e.X - offsetx, e.Y - offsety, 100, 100)); redraw(); } } } private Boolean movable(int y,int x,int y1,int x1) { int self = chesstable[y1 / 100 + 1, x1 / 100 + 1]; int enemy = chesstable[y / 100 + 1, x / 100 + 1]; if ((self - 1) / 16 != playchess) return false; if (y >= 400 || x >= 800 || y < 0 || x < 0) return false; if (y == y1 && x == x1) return false; if ((self == 26 || self == 27 || self == 10 || self == 11) && enemy > 0 && Math.Abs(enemy / 17 - self / 17) == 1) { if (Math.Abs(y1 - y) == 100 && Math.Abs(x1 - x) == 0 || Math.Abs(y1 - y) == 0 && Math.Abs(x1 - x) == 100) { return false; } int count = 0; if (x1 / 100 == x / 100) //同一行 { if (y / 100 > y1 / 100) {//向下 for (int i = y1 / 100 + 1; i <= y / 100 + 1; i++) if (chesstable[i, x / 100 + 1] != 0) count++; } else {//向上 for (int i = y1 / 100 + 1; i>= y / 100 + 1; i--) if (chesstable[i, x / 100 + 1] != 0) count++; } if (count == 3) return true; } if (y1 / 100 == y / 100)//同一列 { if (x / 100 > x1 / 100) {//向右 for (int i = x1 / 100 + 1; i <= x / 100 + 1; i++) if (chesstable[y / 100 + 1, i] != 0) count++; } else {//向左 for (int i = x1 / 100 + 1; i >= x / 100 + 1; i--) if (chesstable[y / 100 + 1, i] != 0) count++; } if (count == 3) return true; } } if (Math.Abs(y1-y)==100 && Math.Abs(x1-x)==0 || Math.Abs(y1-y)==0 && Math.Abs(x1-x)==100) { if (enemy < 0) return false; if (enemy == 0) return true; if (enemy >0 && Math.Abs(self / 17 - enemy / 17) == 1) { if (enemy > 16) enemy -= 16; if (self > 16) self -= 16; if (self >= 12 && self <= 16 && enemy >= 12 && enemy <= 16) return true; if (self >= 12 & self <= 16 && enemy == 1) return true; if (self == 1 && enemy >= 12 && enemy <= 16) return false; if (self / 2 <= enemy / 2) return true; } } else return false; return false; } private void plate_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && play ) { int x = e.X / 100 * 100; int y = e.Y / 100 * 100; if (chesstable[original_y / 100 + 1, original_x / 100 + 1] > 0) { if (movable(y, x, original_y, original_x)) { g.DrawImage(move_platebmp, new Rectangle(0, 0, 800, 400)); g.DrawImage(chessbmp[chesstable[original_y / 100 + 1, original_x / 100 + 1]], new Rectangle(x, y, 100, 100)); redraw(); chesstable[y / 100 + 1, x / 100 + 1] = chesstable[original_y / 100 + 1, original_x / 100 + 1]; chesstable[original_y / 100 + 1, original_x / 100 + 1] = 0; send("1," +( y / 100 + 1) + "," + (x / 100 + 1) + "," + (original_y / 100 + 1) + "," + (original_x / 100 + 1)); //1,目標位置Y,目標位置X,來源為至Y,來源位置X play = false; this.BackColor = Color.Ivory; } else { g.DrawImage(move_platebmp, new Rectangle(0, 0, 800, 400)); g.DrawImage(chessbmp[chesstable[original_y / 100 + 1, original_x / 100 + 1]], new Rectangle(original_x, original_y, 100, 100)); redraw(); } } else if (chesstable[y / 100 + 1, x / 100 + 1] < 0) { chesstable[y / 100 + 1, x / 100 + 1] = -chesstable[y / 100 + 1, x / 100 + 1]; g.DrawImage(chessbmp[chesstable[y / 100 + 1, x / 100 + 1]], new Rectangle(x, y, 100, 100)); redraw(); if (playchess == -1) { if (chesstable[y / 100 + 1, x / 100 + 1] >= 1 && chesstable[y / 100 + 1, x / 100 + 1] <= 16) { playchess = 0; this.Text = "紅棋"; }//Red else { playchess = 1; this.Text = "藍棋"; }//Blue send("3," + (y / 100 + 1) + "," + (x / 100 + 1)+"," + playchess); } else { send("2," + (y / 100 + 1) + "," + (x / 100 + 1)); } play = false; this.BackColor = Color.Ivory; } } } private void plate_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && play ) { int x = e.X / 100 * 100; int y = e.Y / 100 * 100; original_x = x; original_y = y; if (chesstable[y/100+1,x/100+1] > 0) { offsetx = e.X - x; offsety = e.Y - y; g.DrawImage(blank[(x / 100 + y / 100) % 2], new Rectangle(x, y, 100, 100)); move_platebmp = platebmp.Clone(new Rectangle(0, 0, 800, 400), platebmp.PixelFormat); g.DrawImage(chessbmp[chesstable[y / 100 + 1, x / 100 + 1]], new Rectangle(x, y, 100, 100)); redraw(); } } } } } ```