---
# System prepended metadata

title: 暗棋程式碼(peer to peer & UDP)

---

# 暗棋程式碼(peer to peer & UDP)

> 使用語言：C#
> 使用框架：.NET framework4.6.1
```
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();
                }
                
            }
        }
    }
}

```